From 94cf161ba4ccb9c9a4b99715fedac4444200ab33 Mon Sep 17 00:00:00 2001 From: koushiro Date: Fri, 17 Sep 2021 14:47:45 +0800 Subject: [PATCH 01/72] Add pallet-alliance Signed-off-by: koushiro --- Cargo.lock | 99 ++- Cargo.toml | 1 + frame/alliance/Cargo.toml | 63 ++ frame/alliance/README.md | 74 +++ frame/alliance/src/benchmarking.rs | 312 ++++++++++ frame/alliance/src/lib.rs | 961 +++++++++++++++++++++++++++++ frame/alliance/src/mock.rs | 226 +++++++ frame/alliance/src/tests.rs | 507 +++++++++++++++ frame/alliance/src/types.rs | 225 +++++++ frame/alliance/src/weights.rs | 1 + frame/collective/src/lib.rs | 321 +++++----- 11 files changed, 2638 insertions(+), 152 deletions(-) create mode 100644 frame/alliance/Cargo.toml create mode 100644 frame/alliance/README.md create mode 100644 frame/alliance/src/benchmarking.rs create mode 100644 frame/alliance/src/lib.rs create mode 100644 frame/alliance/src/mock.rs create mode 100644 frame/alliance/src/tests.rs create mode 100644 frame/alliance/src/types.rs create mode 100644 frame/alliance/src/weights.rs diff --git a/Cargo.lock b/Cargo.lock index db6edfa81d539..f0feea0d5756d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -959,11 +959,23 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff0e3bc0b6446b3f9663c1a6aba6ef06c5aeaa1bc92bd18077be337198ab9768" dependencies = [ - "multibase", + "multibase 0.8.0", "multihash 0.13.2", "unsigned-varint 0.5.1", ] +[[package]] +name = "cid" +version = "0.7.0" +source = "git+https://github.com/patractlabs/rust-cid?branch=alliance#d5aaa1c115b52e75b1cd513a4b866912d944a6bd" +dependencies = [ + "multibase 0.9.1", + "multihash 0.14.0 (git+https://github.com/patractlabs/rust-multihash?branch=alliance)", + "parity-scale-codec", + "scale-info", + "unsigned-varint 0.7.0", +] + [[package]] name = "cipher" version = "0.3.0" @@ -3722,7 +3734,7 @@ dependencies = [ "libsecp256k1", "log 0.4.14", "multiaddr", - "multihash 0.14.0", + "multihash 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "multistream-select", "parking_lot 0.11.2", "pin-project 1.0.10", @@ -4574,7 +4586,7 @@ dependencies = [ "bs58", "byteorder", "data-encoding", - "multihash 0.14.0", + "multihash 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 2.1.0", "serde", "static_assertions", @@ -4593,6 +4605,17 @@ dependencies = [ "data-encoding-macro", ] +[[package]] +name = "multibase" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404" +dependencies = [ + "base-x", + "data-encoding", + "data-encoding-macro", +] + [[package]] name = "multihash" version = "0.13.2" @@ -4604,9 +4627,15 @@ dependencies = [ "blake3", "digest 0.9.0", "generic-array 0.14.4", +<<<<<<< HEAD "multihash-derive", "sha2 0.9.8", "sha3 0.9.1", +======= + "multihash-derive 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.9.3", + "sha3", +>>>>>>> 2369417073 (Add pallet-alliance) "unsigned-varint 0.5.1", ] @@ -4616,10 +4645,31 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "752a61cd890ff691b4411423d23816d5866dd5621e4d1c5687a53b94b5a979d8" dependencies = [ + "blake2b_simd", + "blake2s_simd", + "blake3", "digest 0.9.0", "generic-array 0.14.4", - "multihash-derive", - "sha2 0.9.8", + "multihash-derive 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.9.3", + "sha3", + "unsigned-varint 0.7.0", +] + +[[package]] +name = "multihash" +version = "0.14.0" +source = "git+https://github.com/patractlabs/rust-multihash?branch=alliance#7dc4858d2f07c9e377be05393cc5acb84368f7bb" +dependencies = [ + "blake2b_simd", + "blake2s_simd", + "blake3", + "digest 0.9.0", + "multihash-derive 0.7.2 (git+https://github.com/patractlabs/rust-multihash?branch=alliance)", + "parity-scale-codec", + "scale-info", + "sha2 0.9.3", + "sha3", "unsigned-varint 0.7.0", ] @@ -4637,6 +4687,19 @@ dependencies = [ "synstructure", ] +[[package]] +name = "multihash-derive" +version = "0.7.2" +source = "git+https://github.com/patractlabs/rust-multihash?branch=alliance#7dc4858d2f07c9e377be05393cc5acb84368f7bb" +dependencies = [ + "proc-macro-crate 1.0.0", + "proc-macro-error 1.0.4", + "proc-macro2", + "quote", + "syn", + "synstructure", +] + [[package]] name = "multimap" version = "0.8.2" @@ -5408,6 +5471,7 @@ dependencies = [ ] [[package]] +<<<<<<< HEAD name = "pallet-asset-tx-payment" version = "4.0.0-dev" dependencies = [ @@ -5422,11 +5486,30 @@ dependencies = [ "serde", "serde_json", "smallvec 1.8.0", +======= +name = "pallet-alliance" +version = "4.0.0-dev" +dependencies = [ + "cid 0.7.0", + "frame-benchmarking", + "frame-support", + "frame-system", + "hex-literal", + "log 0.4.14", + "multihash 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pallet-balances", + "pallet-collective", + "parity-scale-codec", + "scale-info", +>>>>>>> 2369417073 (Add pallet-alliance) "sp-core", "sp-io", "sp-runtime", "sp-std", +<<<<<<< HEAD "sp-storage", +======= +>>>>>>> 2369417073 (Add pallet-alliance) ] [[package]] @@ -8629,8 +8712,14 @@ dependencies = [ "async-trait", "asynchronous-codec 0.5.0", "bitflags", +<<<<<<< HEAD "bytes 1.1.0", "cid", +======= + "bytes 1.0.1", + "cid 0.6.1", + "derive_more", +>>>>>>> 2369417073 (Add pallet-alliance) "either", "fnv", "fork-tree", diff --git a/Cargo.toml b/Cargo.toml index f24ff6d04980a..2ee7f06c61cd3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,6 +61,7 @@ members = [ "client/transaction-pool", "client/transaction-pool/api", "client/utils", + "frame/alliance", "frame/assets", "frame/atomic-swap", "frame/aura", diff --git a/frame/alliance/Cargo.toml b/frame/alliance/Cargo.toml new file mode 100644 index 0000000000000..f888fb22536b3 --- /dev/null +++ b/frame/alliance/Cargo.toml @@ -0,0 +1,63 @@ +[package] +name = "pallet-alliance" +version = "4.0.0-dev" +authors = ["Parity Technologies "] +edition = "2018" +license = "Apache-2.0" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" +description = "Collective system: Members of a set of account IDs can make their collective feelings known through dispatched calls from one of two specialized origins." +readme = "README.md" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +cid = { git = "https://github.com/patractlabs/rust-cid", branch = "alliance", default-features = false, features = ["scale-codec","scale-info"] } +log = { version = "0.4.14", default-features = false } + +codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive"] } +scale-info = { version = "1.0", default-features = false, features = ["derive"] } + +sp-std = { version = "4.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-core = { version = "4.0.0-dev", default-features = false, path = "../../primitives/core" } +sp-io = { version = "4.0.0-dev", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "4.0.0-dev", default-features = false, path = "../../primitives/runtime" } + +frame-benchmarking = { version = "4.0.0-dev", default-features = false, path = "../benchmarking", optional = true } +frame-support = { version = "4.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "4.0.0-dev", default-features = false, path = "../system" } + +[dev-dependencies] +cid = { git = "https://github.com/patractlabs/rust-cid", branch = "alliance" } +hex-literal = "0.3.1" +multihash = "0.14.0" +pallet-balances = { version = "4.0.0-dev", path = "../balances" } +pallet-collective = { version = "4.0.0-dev", path = "../collective" } + +[features] +default = ["std"] +std = [ + "cid/std", + "log/std", + "codec/std", + "scale-info/std", + "sp-std/std", + "sp-core/std", + "sp-io/std", + "sp-runtime/std", + "frame-support/std", + "frame-system/std", +] +runtime-benchmarks = [ + "frame-benchmarking", + "sp-runtime/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "pallet-collective/runtime-benchmarks", +] +try-runtime = [ + "frame-support/try-runtime", + "frame-system/try-runtime", +] diff --git a/frame/alliance/README.md b/frame/alliance/README.md new file mode 100644 index 0000000000000..fb74b07201370 --- /dev/null +++ b/frame/alliance/README.md @@ -0,0 +1,74 @@ +# Alliance Pallet + +The Alliance Pallet provides a DAO to form an industry group that does two main things: + +- provide a set of ethics against bad behaviors. +- provide recognition and influence for those teams that contribute something back to the ecosystem. + +## Overview + +The Alliance first needs to initialize the Founders with sudo permissions. +After that, anyone with an approved identity and website can apply to become a Candidate. +Members will initiate a motion to determine whether a Candidate can join the Alliance or not. +The motion requires the approval of over 2/3 majority. +The Alliance can also maintain a blacklist list about accounts and websites. +Members can also vote to update the alliance's rule and make announcements. + +### Terminology + +- Rule: The IPFS Hash of the Alliance Rule for the community to read + and the alliance members to enforce for the management. + +- Announcement: An IPFS hash of some content that the Alliance want to announce. + +- Member: An account which is already in the group of the Alliance, + including three types: Founder, Fellow, Ally. + Member can also be kicked by super majority motion or retire by itself. + +- Founder: An account who is initiated by sudo with normal voting rights for basic motions + and special veto rights for rule change and ally elevation motions. + +- Fellow: An account who is elevated from Ally by Founders and other Fellows from Ally. + +- Ally: An account who is approved by Founders and Fellows from Candidate. + An Ally doesn't have voting rights. + +- Candidate: An account who is trying to become a member. + The applicant should already have an approved identity with website. + The application should be submitted by the account itself with some token as deposit, + or be nominated by an existing Founder or Fellow for free. + +- Blacklist: A list of bad websites and addresses, and can be added or removed items by Founders and Fellows. + +## Interface + +### Dispatchable Functions + +#### For General Users +- `submit_candidacy` - Submit the application to become a candidate with deposit. + +#### For Members (All) +- `retire` - Member retire to out of the Alliance and release its deposit. + +#### For Members (Founders/Fellows) + +- `propose` - Propose a motion. +- `vote` - Vote on a motion. +- `close` - Close a motion with enough votes or expired. +- `set_rule` - Initialize or update the alliance's rule by IPFS hash. +- `announce` - Make announcement by IPFS hash. +- `nominate_candidacy` - Nominate a non-member to become a Candidate for free. +- `approve_candidate` - Approve a candidate to become an Ally. +- `reject_candidate` - Reject a candidate and slash its deposit. +- `elevate_ally` - Approve an ally to become a Fellow. +- `kick_member` - Kick a member and slash its deposit. +- `add_blacklist` - Add some items of account and website in the blacklist. +- `remove_blacklist` - Remove some items of account and website from the blacklist. + +#### For Members (Only Founders) +- `veto` - Veto on a motion about `set_rule` and `elevate_ally`. + +#### For Super Users +- `init_founders` - Initialize the founding members. + +License: Apache-2.0 diff --git a/frame/alliance/src/benchmarking.rs b/frame/alliance/src/benchmarking.rs new file mode 100644 index 0000000000000..fe7bc7e1d077a --- /dev/null +++ b/frame/alliance/src/benchmarking.rs @@ -0,0 +1,312 @@ +// This file is part of Substrate. + +// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Alliance pallet benchmarking. + +use sp_runtime::traits::Zero; + +use frame_benchmarking::{account, benchmarks_instance_pallet, impl_benchmark_test_suite}; +use frame_support::traits::{EnsureOrigin, Get, UnfilteredDispatchable}; +use frame_system::RawOrigin; + +use super::{Pallet as Alliance, *}; + +const SEED: u32 = 0; + +fn assert_last_event, I: 'static>(generic_event: >::Event) { + frame_system::Pallet::::assert_last_event(generic_event.into()); +} + +fn test_cid() -> Cid { + "QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n".parse().unwrap() +} + +fn funded_account, I: 'static>(name: &'static str, index: u32) -> T::AccountId { + let account: T::AccountId = account(name, index, SEED); + T::Currency::make_free_balance_be(&account, T::CandidateDeposit::get() * 2u32.into()); + account +} + +fn set_members, I: 'static>() { + let founders = vec![ + funded_account::("founder", 1), + funded_account::("founder", 2), + funded_account::("founder", 3), + ]; + Members::::insert(MemberRole::Founder, founders.clone()); + + let fellows = vec![funded_account::("fellow", 1), funded_account::("fellow", 2)]; + fellows.iter().for_each(|who| { + T::Currency::reserve(&who, T::CandidateDeposit::get()).unwrap(); + >::insert(&who, T::CandidateDeposit::get()); + }); + Members::::insert(MemberRole::Fellow, fellows.clone()); + + let allies = vec![funded_account::("ally", 1)]; + allies.iter().for_each(|who| { + T::Currency::reserve(&who, T::CandidateDeposit::get()).unwrap(); + >::insert(&who, T::CandidateDeposit::get()); + }); + Members::::insert(MemberRole::Ally, allies); + + T::InitializeMembers::initialize_members(&[founders.as_slice(), fellows.as_slice()].concat()); +} + +fn founder1, I: 'static>() -> T::AccountId { + funded_account::("founder", 1) +} + +fn fellow2, I: 'static>() -> T::AccountId { + funded_account::("fellow", 2) +} + +fn kicking_fellow2, I: 'static>() -> T::AccountId { + let fellow2 = funded_account::("fellow", 2); + KickingMembers::::insert(&fellow2, true); + fellow2 +} + +fn ally1, I: 'static>() -> T::AccountId { + funded_account::("ally", 1) +} + +fn set_candidates, I: 'static>() { + let candidates = vec![funded_account::("candidate", 1)]; + candidates.iter().for_each(|who| { + T::Currency::reserve(&who, T::CandidateDeposit::get()).unwrap(); + >::insert(&who, T::CandidateDeposit::get()); + }); + Candidates::::put(candidates); +} + +fn candidate1, I: 'static>() -> T::AccountId { + funded_account::("candidate", 1) +} + +fn create_outsider, I: 'static>() -> T::AccountId { + funded_account::("outsider", 1) +} + +fn blacklist_account, I: 'static>(index: u32) -> T::AccountId { + funded_account::("blacklist", index) +} + +fn set_blacklist, I: 'static>() { + let mut account_blacklist = (0..T::MaxBlacklistCount::get()) + .map(|i| blacklist_account::(i)) + .collect::>(); + account_blacklist.sort(); + AccountBlacklist::::put(account_blacklist); + + let mut website_blacklist = + (0..T::MaxBlacklistCount::get()).map(|i| vec![i as u8]).collect::>(); + website_blacklist.sort(); + WebsiteBlacklist::::put(website_blacklist); +} + +benchmarks_instance_pallet! { + set_rule { + set_members::(); + + let rule = test_cid(); + let call = Call::::set_rule { rule }; + let origin = T::SuperMajorityOrigin::successful_origin(); + }: { call.dispatch_bypass_filter(origin)? } + verify { + assert_eq!(Alliance::::rule(), Some(rule)); + assert_last_event::(Event::NewRule(rule).into()); + } + + announce { + set_members::(); + + let announcement = test_cid(); + let call = Call::::announce { announcement }; + let origin = T::SuperMajorityOrigin::successful_origin(); + }: { call.dispatch_bypass_filter(origin)? } + verify { + assert!(Alliance::::announcements().contains(&announcement)); + assert_last_event::(Event::NewAnnouncement(announcement).into()); + } + + submit_candidacy { + set_members::(); + + let outsider = create_outsider::(); + assert!(!Alliance::::is_member(&outsider)); + assert!(!Alliance::::is_candidate(&outsider)); + assert_eq!(T::Currency::reserved_balance(&outsider), BalanceOf::::zero()); + }: _(RawOrigin::Signed(outsider.clone())) + verify { + assert!(!Alliance::::is_member(&outsider)); + assert!(Alliance::::is_candidate(&outsider)); + assert_eq!(T::Currency::reserved_balance(&outsider), T::CandidateDeposit::get()); + assert_last_event::(Event::CandidateAdded(outsider, None, Some(T::CandidateDeposit::get())).into()); + } + + nominate_candidacy { + set_members::(); + + let founder1 = founder1::(); + assert!(Alliance::::is_member_of(&founder1, MemberRole::Founder)); + + let outsider = create_outsider::(); + assert!(!Alliance::::is_member(&outsider)); + assert!(!Alliance::::is_candidate(&outsider)); + assert_eq!(T::Currency::reserved_balance(&outsider), BalanceOf::::zero()); + let outsider_lookup: ::Source = T::Lookup::unlookup(outsider.clone()); + }: _(RawOrigin::Signed(founder1.clone()), outsider_lookup) + verify { + assert!(!Alliance::::is_member(&outsider)); + assert!(Alliance::::is_candidate(&outsider)); + assert_eq!(T::Currency::reserved_balance(&outsider), BalanceOf::::zero()); + assert_last_event::(Event::CandidateAdded(outsider, Some(founder1), None).into()); + } + + approve_candidate { + set_members::(); + set_candidates::(); + + let candidate1 = candidate1::(); + assert!(Alliance::::is_candidate(&candidate1)); + assert!(!Alliance::::is_member(&candidate1)); + + assert_eq!(T::Currency::reserved_balance(&candidate1), T::CandidateDeposit::get()); + assert_eq!(DepositOf::::get(&candidate1), Some(T::CandidateDeposit::get())); + + let candidate1_lookup: ::Source = T::Lookup::unlookup(candidate1.clone()); + let call = Call::::approve_candidate { candidate: candidate1_lookup }; + let origin = T::SuperMajorityOrigin::successful_origin(); + }: { call.dispatch_bypass_filter(origin)? } + verify { + assert!(!Alliance::::is_candidate(&candidate1)); + assert!(Alliance::::is_ally(&candidate1)); + assert_eq!(T::Currency::reserved_balance(&candidate1), T::CandidateDeposit::get()); + assert_eq!(DepositOf::::get(&candidate1), Some(T::CandidateDeposit::get())); + assert_last_event::(Event::CandidateApproved(candidate1).into()); + } + + reject_candidate { + set_members::(); + set_candidates::(); + + let candidate1 = candidate1::(); + assert!(Alliance::::is_candidate(&candidate1)); + assert!(!Alliance::::is_member(&candidate1)); + + assert_eq!(T::Currency::reserved_balance(&candidate1), T::CandidateDeposit::get()); + assert_eq!(DepositOf::::get(&candidate1), Some(T::CandidateDeposit::get())); + + let candidate1_lookup: ::Source = T::Lookup::unlookup(candidate1.clone()); + let call = Call::::reject_candidate { candidate: candidate1_lookup }; + let origin = T::SuperMajorityOrigin::successful_origin(); + }: { call.dispatch_bypass_filter(origin)? } + verify { + assert!(!Alliance::::is_candidate(&candidate1)); + assert!(!Alliance::::is_member(&candidate1)); + assert_eq!(T::Currency::reserved_balance(&candidate1), BalanceOf::::zero()); + assert_eq!(DepositOf::::get(&candidate1), None); + assert_last_event::(Event::CandidateRejected(candidate1).into()); + } + + elevate_ally { + set_members::(); + + let ally1 = ally1::(); + assert!(Alliance::::is_ally(&ally1)); + + let ally1_lookup: ::Source = T::Lookup::unlookup(ally1.clone()); + let call = Call::::elevate_ally { ally: ally1_lookup }; + let origin = T::SuperMajorityOrigin::successful_origin(); + }: { call.dispatch_bypass_filter(origin)? } + verify { + assert!(!Alliance::::is_ally(&ally1)); + assert!(Alliance::::is_fellow(&ally1)); + assert_last_event::(Event::AllyElevated(ally1).into()); + } + + retire { + set_members::(); + + let fellow2 = fellow2::(); + assert!(Alliance::::is_fellow(&fellow2)); + assert!(!Alliance::::is_kicking(&fellow2)); + + assert_eq!(T::Currency::reserved_balance(&fellow2), T::CandidateDeposit::get()); + assert_eq!(DepositOf::::get(&fellow2), Some(T::CandidateDeposit::get())); + }: _(RawOrigin::Signed(fellow2.clone())) + verify { + assert!(!Alliance::::is_member(&fellow2)); + assert_eq!(T::Currency::reserved_balance(&fellow2), BalanceOf::::zero()); + assert_eq!(DepositOf::::get(&fellow2), None); + assert_last_event::(Event::MemberRetired(fellow2, Some(T::CandidateDeposit::get())).into()); + } + + kick_member { + set_members::(); + + let fellow2 = kicking_fellow2::(); + assert!(Alliance::::is_member_of(&fellow2, MemberRole::Fellow)); + assert!(Alliance::::is_kicking(&fellow2)); + + assert_eq!(T::Currency::reserved_balance(&fellow2), T::CandidateDeposit::get()); + assert_eq!(DepositOf::::get(&fellow2), Some(T::CandidateDeposit::get())); + + let fellow2_lookup: ::Source = T::Lookup::unlookup(fellow2.clone()); + let call = Call::::kick_member { who: fellow2_lookup }; + let origin = T::SuperMajorityOrigin::successful_origin(); + }: { call.dispatch_bypass_filter(origin)? } + verify { + assert!(!Alliance::::is_member(&fellow2)); + assert_eq!(T::Currency::reserved_balance(&fellow2), BalanceOf::::zero()); + assert_eq!(DepositOf::::get(&fellow2), None); + assert_last_event::(Event::MemberKicked(fellow2, Some(T::CandidateDeposit::get())).into()); + } + + add_blacklist { + let n in 0 .. T::MaxBlacklistCount::get(); + + let mut blacklist = (0..n).map(|i| BlacklistItem::AccountId(blacklist_account::(i))).collect::>(); + blacklist.extend((0..n).map(|i| BlacklistItem::Website(vec![i as u8]))); + + set_members::(); + + let call = Call::::add_blacklist { infos: blacklist.clone() }; + let origin = T::SuperMajorityOrigin::successful_origin(); + }: { call.dispatch_bypass_filter(origin)? } + verify { + assert_last_event::(Event::BlacklistAdded(blacklist).into()); + } + + remove_blacklist { + let n in 0 .. T::MaxBlacklistCount::get(); + + let mut blacklist = (0..n).map(|i| BlacklistItem::AccountId(blacklist_account::(i))).collect::>(); + blacklist.extend((0..n).map(|i| BlacklistItem::Website(vec![i as u8]))); + + set_members::(); + set_blacklist::(); + + let call = Call::::remove_blacklist { infos: blacklist.clone() }; + let origin = T::SuperMajorityOrigin::successful_origin(); + }: { call.dispatch_bypass_filter(origin)? } + verify { + assert_last_event::(Event::BlacklistRemoved(blacklist).into()); + } +} + +impl_benchmark_test_suite!(Alliance, crate::mock::new_bench_ext(), crate::mock::Test); diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs new file mode 100644 index 0000000000000..60529836bdc52 --- /dev/null +++ b/frame/alliance/src/lib.rs @@ -0,0 +1,961 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! # Alliance Pallet +//! +//! The Alliance Pallet provides a DAO to form an industry group that does two main things: +//! +//! - provide a set of ethics against bad behaviors. +//! - provide recognition and influence for those teams that contribute something back to the +//! ecosystem. +//! +//! ## Overview +//! +//! The Alliance first needs to initialize the Founders with sudo permissions. +//! After that, anyone with an approved identity and website can apply to become a Candidate. +//! Members will initiate a motion to determine whether a Candidate can join the Alliance or not. +//! The motion requires the approval of over 2/3 majority. +//! The Alliance can also maintain a blacklist list about accounts and websites. +//! Members can also vote to update the alliance's rule and make announcements. +//! +//! ### Terminology +//! +//! - Rule: The IPFS Hash of the Alliance Rule for the community to read and the alliance members to +//! enforce for the management. +//! +//! - Announcement: An IPFS hash of some content that the Alliance want to announce. +//! +//! - Member: An account which is already in the group of the Alliance, including three types: +//! Founder, Fellow, Ally. Member can also be kicked by super majority motion or retire by itself. +//! +//! - Founder: An account who is initiated by sudo with normal voting rights for basic motions and +//! special veto rights for rule change and ally elevation motions. +//! +//! - Fellow: An account who is elevated from Ally by Founders and other Fellows from Ally. +//! +//! - Ally: An account who is approved by Founders and Fellows from Candidate. An Ally doesn't have +//! voting rights. +//! +//! - Candidate: An account who is trying to become a member. The applicant should already have an +//! approved identity with website. The application should be submitted by the account itself with +//! some token as deposit, or be nominated by an existing Founder or Fellow for free. +//! +//! - Blacklist: A list of bad websites and addresses, and can be added or removed items by Founders +//! and Fellows. +//! +//! ## Interface +//! +//! ### Dispatchable Functions +//! +//! #### For General Users +//! - `submit_candidacy` - Submit the application to become a candidate with deposit. +//! +//! #### For Members (All) +//! - `retire` - Member retire to out of the Alliance and release its deposit. +//! +//! #### For Members (Founders/Fellows) +//! +//! - `propose` - Propose a motion. +//! - `vote` - Vote on a motion. +//! - `close` - Close a motion with enough votes or expired. +//! - `set_rule` - Initialize or update the alliance's rule by IPFS hash. +//! - `announce` - Make announcement by IPFS hash. +//! - `nominate_candidacy` - Nominate a non-member to become a Candidate for free. +//! - `approve_candidate` - Approve a candidate to become an Ally. +//! - `reject_candidate` - Reject a candidate and slash its deposit. +//! - `elevate_ally` - Approve an ally to become a Fellow. +//! - `kick_member` - Kick a member and slash its deposit. +//! - `add_blacklist` - Add some items of account and website in the blacklist. +//! - `remove_blacklist` - Remove some items of account and website from the blacklist. +//! +//! #### For Members (Only Founders) +//! - `veto` - Veto on a motion about `set_rule` and `elevate_ally`. +//! +//! #### For Super Users +//! - `init_founders` - Initialize the founding members. + +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(test)] +mod mock; +#[cfg(test)] +mod tests; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; +pub mod weights; + +use sp_runtime::{ + traits::{StaticLookup, Zero}, + RuntimeDebug, +}; +use sp_std::prelude::*; + +use frame_support::{ + codec::{Decode, Encode}, + dispatch::{ + DispatchError, DispatchResult, DispatchResultWithPostInfo, Dispatchable, GetDispatchInfo, + PostDispatchInfo, + }, + ensure, + scale_info::TypeInfo, + traits::{ + ChangeMembers, Currency, Get, InitializeMembers, IsSubType, LockableCurrency, OnUnbalanced, + ReservableCurrency, + }, + weights::{Pays, Weight}, +}; + +pub use cid::Cid; +pub use pallet::*; +pub use weights::*; + +/// Simple index type for proposal counting. +pub type ProposalIndex = u32; + +type Url = Vec; + +type BalanceOf = + <>::Currency as Currency<::AccountId>>::Balance; +type NegativeImbalanceOf = <>::Currency as Currency< + ::AccountId, +>>::NegativeImbalance; + +const IDENTITY_FIELD_DISPLAY: u64 = + 0b0000000000000000000000000000000000000000000000000000000000000001; +const IDENTITY_FIELD_WEB: u64 = 0b0000000000000000000000000000000000000000000000000000000000000100; + +pub trait IdentityVerifier { + fn super_account_id(who: &AccountId) -> Option; + + fn verify_identity(who: &AccountId, fields: u64) -> bool; + + fn verify_judgement(who: &AccountId) -> bool; +} + +pub trait ProposalProvider { + fn propose_proposal( + who: AccountId, + threshold: u32, + proposal: Proposal, + ) -> Result; + + fn vote_proposal( + who: AccountId, + proposal: Hash, + index: ProposalIndex, + approve: bool, + ) -> Result; + + fn veto_proposal(proposal_hash: Hash) -> u32; + + fn close_proposal( + proposal_hash: Hash, + index: ProposalIndex, + proposal_weight_bound: Weight, + length_bound: u32, + ) -> DispatchResultWithPostInfo; + + fn proposal_of(proposal_hash: Hash) -> Option; +} + +/// The role of members. +#[derive(Copy, Clone, PartialEq, Eq, RuntimeDebug, Encode, Decode, TypeInfo)] +pub enum MemberRole { + Founder, + Fellow, + Ally, +} + +/// The item type of blacklist. +#[derive(Clone, PartialEq, Eq, RuntimeDebug, Encode, Decode, TypeInfo)] +pub enum BlacklistItem { + AccountId(AccountId), + Website(Url), +} + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::pallet] + #[pallet::generate_store(pub (super) trait Store)] + pub struct Pallet(PhantomData<(T, I)>); + + #[pallet::config] + pub trait Config: frame_system::Config { + /// The overarching event type. + type Event: From> + IsType<::Event>; + + /// The outer call dispatch type. + type Proposal: Parameter + + Dispatchable + + GetDispatchInfo + + From> + + IsSubType> + + IsType<::Call>; + + /// Origin from which the next tabled referendum may be forced; this allows for the tabling + /// of a majority-carries referendum. + type SuperMajorityOrigin: EnsureOrigin; + + /// The currency used for deposits. + type Currency: LockableCurrency + + ReservableCurrency; + + /// What to do with slashed funds. + type Slashed: OnUnbalanced>; + + /// What to do with genesis members + type InitializeMembers: InitializeMembers; + + /// The receiver of the signal for when the members have changed. + type MembershipChanged: ChangeMembers; + + /// The identity verifier of alliance member. + type IdentityVerifier: IdentityVerifier; + + /// The provider of the proposal operation. + type ProposalProvider: ProposalProvider; + + /// The maximum number of blacklist supported by the pallet. Used for weight estimation. + /// + /// NOTE: + /// + Benchmarks will need to be re-run and weights adjusted if this changes. + /// + This pallet assumes that dependents keep to the limit without enforcing it. + type MaxBlacklistCount: Get; + + /// The amount of a deposit required for submitting candidacy. + #[pallet::constant] + type CandidateDeposit: Get>; + } + + #[pallet::error] + pub enum Error { + /// The founders have already been initialized. + FoundersAlreadyInitialized, + /// Already be a candidate. + AlreadyCandidate, + /// Not be a candidate. + NotCandidate, + /// Already be a member. + AlreadyMember, + /// Not be a member. + NotMember, + /// Not be an ally member. + NotAlly, + /// Not be a founder member. + NotFounder, + /// Not be a kicking member. + NotKickingMember, + /// Not be a votable (founder or fellow) member. + NotVotableMember, + /// Already be an elevated (fellow) member. + AlreadyElevated, + /// Already be a blacklist item. + AlreadyInBlacklist, + /// Not be a blacklist item. + NotInBlacklist, + /// The member is kicking. + KickingMember, + /// Balance is insufficient to be a candidate. + InsufficientCandidateFunds, + /// The account's identity has not been judged. + WithoutVerifiedIdentity, + /// The account's identity has not display field. + WithoutIdentityDisplay, + /// The account' identity has not website field. + WithoutIdentityWebsite, + /// The proposal hash is not found. + MissingProposalHash, + /// The proposal is not vetoable. + NotVetoableProposal, + } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event, I: 'static = ()> { + /// A new rule has been set. \[rule\] + NewRule(Cid), + /// A new announcement has been proposed. \[announcement\] + NewAnnouncement(Cid), + /// Some accounts have been initialized to founders. \[founders\] + FoundersInitialized(Vec), + /// An account has been added as a candidate and lock its deposit. \[candidate, nominator, + /// reserved\] + CandidateAdded(T::AccountId, Option, Option>), + /// A proposal has been proposed to approve the candidate. \[candidate\] + CandidateApproved(T::AccountId), + /// A proposal has been proposed to reject the candidate. \[candidate\] + CandidateRejected(T::AccountId), + /// As an active member, an ally has been elevated to fellow. \[ally\] + AllyElevated(T::AccountId), + /// A member has retired to an ordinary account with its deposit unreserved. \[member, + /// unreserved\] + MemberRetired(T::AccountId, Option>), + /// A member has been kicked out to an ordinary account with its deposit slashed. \[member, + /// slashed\] + MemberKicked(T::AccountId, Option>), + /// Accounts or websites have been added into blacklist. \[items\] + BlacklistAdded(Vec>), + /// Accounts or websites have been removed from blacklist. \[items\] + BlacklistRemoved(Vec>), + } + + #[pallet::genesis_config] + pub struct GenesisConfig, I: 'static = ()> { + pub founders: Vec, + pub fellows: Vec, + pub allies: Vec, + pub phantom: PhantomData<(T, I)>, + } + + #[cfg(feature = "std")] + impl, I: 'static> Default for GenesisConfig { + fn default() -> Self { + Self { + founders: Vec::new(), + fellows: Vec::new(), + allies: Vec::new(), + phantom: Default::default(), + } + } + } + + #[pallet::genesis_build] + impl, I: 'static> GenesisBuild for GenesisConfig { + fn build(&self) { + for m in self.founders.iter().chain(self.fellows.iter()).chain(self.allies.iter()) { + assert!(Pallet::::has_identity(m).is_ok(), "Member does not set identity!"); + } + + if !self.founders.is_empty() { + assert!( + !Pallet::::has_member(MemberRole::Founder), + "Founders are already initialized!" + ); + Members::::insert(MemberRole::Founder, self.founders.clone()); + } + if !self.fellows.is_empty() { + assert!( + !Pallet::::has_member(MemberRole::Fellow), + "Fellows are already initialized!" + ); + Members::::insert(MemberRole::Fellow, self.fellows.clone()); + } + if !self.allies.is_empty() { + Members::::insert(MemberRole::Ally, self.allies.clone()) + } + + T::InitializeMembers::initialize_members( + &[self.founders.as_slice(), self.fellows.as_slice()].concat(), + ) + } + } + + /// The IPFS cid of the alliance rule. + /// Founders and fellows can propose a new rule, other founders and fellows make a traditional + /// super-majority votes, vote to determine if the rules take effect. + /// + /// Any founder has a special one-vote veto right to the rule setting. + #[pallet::storage] + #[pallet::getter(fn rule)] + pub type Rule, I: 'static = ()> = StorageValue<_, Cid, OptionQuery>; + + /// The current IPFS cids of the announcements. + #[pallet::storage] + #[pallet::getter(fn announcements)] + pub type Announcements, I: 'static = ()> = StorageValue<_, Vec, ValueQuery>; + + /// Maps member and their candidate deposit. + #[pallet::storage] + #[pallet::getter(fn deposit_of)] + pub type DepositOf, I: 'static = ()> = + StorageMap<_, Blake2_128Concat, T::AccountId, BalanceOf, OptionQuery>; + + /// The current set of candidates. + /// If the candidacy is approved by a motion, then it will become an ally member. + #[pallet::storage] + #[pallet::getter(fn candidates)] + pub type Candidates, I: 'static = ()> = + StorageValue<_, Vec, ValueQuery>; + + /// Maps member type to alliance members, including founder, fellow and ally. + /// Founders and fellows can propose and vote on alliance motions, + /// and ally can only wait to be elevated to fellow. + #[pallet::storage] + #[pallet::getter(fn members)] + pub type Members, I: 'static = ()> = + StorageMap<_, Twox64Concat, MemberRole, Vec, ValueQuery>; + + /// The members are being kicked out. They can't retire during the motion. + #[pallet::storage] + #[pallet::getter(fn kicking_member)] + pub type KickingMembers, I: 'static = ()> = + StorageMap<_, Blake2_128Concat, T::AccountId, bool, ValueQuery>; + + /// The current blacklist of accounts. The accounts can't submit candidacy. + #[pallet::storage] + #[pallet::getter(fn account_blacklist)] + pub type AccountBlacklist, I: 'static = ()> = + StorageValue<_, Vec, ValueQuery>; + + /// The current blacklist of websites. + #[pallet::storage] + #[pallet::getter(fn website_blacklist)] + pub type WebsiteBlacklist, I: 'static = ()> = + StorageValue<_, Vec, ValueQuery>; + + #[pallet::call] + impl, I: 'static> Pallet { + /// Add a new proposal to be voted on. + /// + /// Requires the sender to be founder or fellow. + #[pallet::weight(0)] + pub fn propose( + origin: OriginFor, + proposal: Box<>::Proposal>, + ) -> DispatchResultWithPostInfo { + let proposor = ensure_signed(origin)?; + ensure!(Self::is_votable_member(&proposor), Error::::NotVotableMember); + + if let Some(Call::kick_member { who }) = proposal.is_sub_type() { + let strike = T::Lookup::lookup(who.clone())?; + >::insert(strike, true); + } + + let threshold = 2 * Self::votable_member_count() / 3 + 1; + T::ProposalProvider::propose_proposal(proposor, threshold, *proposal)?; + Ok(().into()) + } + + /// Add an aye or nay vote for the sender to the given proposal. + /// + /// Requires the sender to be founder or fellow. + #[pallet::weight(0)] + pub fn vote( + origin: OriginFor, + proposal: T::Hash, + index: ProposalIndex, + approve: bool, + ) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + ensure!(Self::is_votable_member(&who), Error::::NotVotableMember); + + T::ProposalProvider::vote_proposal(who, proposal, index, approve)?; + Ok(().into()) + } + + /// Disapprove a proposal about set_rule and elevate_ally, close, and remove it from + /// the system, regardless of its current state. + /// + /// Must be called by a founder. + #[pallet::weight(0)] + pub fn veto(origin: OriginFor, proposal_hash: T::Hash) -> DispatchResultWithPostInfo { + let proposor = ensure_signed(origin)?; + ensure!(Self::is_founder(&proposor), Error::::NotFounder); + + let proposal = T::ProposalProvider::proposal_of(proposal_hash); + ensure!(proposal.is_some(), Error::::MissingProposalHash); + match proposal.expect("proposal must be exist; qed").is_sub_type() { + Some(Call::set_rule { .. }) | Some(Call::elevate_ally { .. }) => { + T::ProposalProvider::veto_proposal(proposal_hash); + Ok(().into()) + }, + _ => Err(Error::::NotVetoableProposal.into()), + } + } + + /// Close a vote that is either approved, disapproved or whose voting period has ended. + /// + /// Requires the sender to be founder or fellow. + #[pallet::weight(0)] + pub fn close( + origin: OriginFor, + proposal_hash: T::Hash, + index: ProposalIndex, + proposal_weight_bound: Weight, + length_bound: u32, + ) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + ensure!(Self::is_votable_member(&who), Error::::NotVotableMember); + + let proposal = T::ProposalProvider::proposal_of(proposal_hash); + ensure!(proposal.is_some(), Error::::MissingProposalHash); + + let info = T::ProposalProvider::close_proposal( + proposal_hash, + index, + proposal_weight_bound, + length_bound, + )?; + if Pays::No == info.pays_fee { + if let Some(Call::kick_member { who }) = + proposal.expect("proposal must be exist; qed").is_sub_type() + { + let strike = T::Lookup::lookup(who.clone())?; + >::remove(strike); + } + } + Ok(().into()) + } + + /// IInitialize the founders to the given members. + /// + /// This should be called by the referendum and can only be called once. + #[pallet::weight(0)] + pub fn init_founders( + origin: OriginFor, + founders: Vec, + ) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + ensure!( + !Self::has_member(MemberRole::Founder), + Error::::FoundersAlreadyInitialized + ); + for founder in &founders { + Self::has_identity(founder)?; + } + + let mut founders = founders; + founders.sort(); + T::InitializeMembers::initialize_members(&founders); + Members::::insert(&MemberRole::Founder, founders.clone()); + + log::debug!( + target: "runtime::alliance", + "Initialize alliance founders: {:?}", + founders, + ); + + Self::deposit_event(Event::FoundersInitialized(founders)); + Ok(().into()) + } + + /// Set a new IPFS cid to the alliance rule. + #[pallet::weight(0)] + pub fn set_rule(origin: OriginFor, rule: Cid) -> DispatchResultWithPostInfo { + T::SuperMajorityOrigin::ensure_origin(origin)?; + + Rule::::put(&rule); + + Self::deposit_event(Event::NewRule(rule)); + Ok(().into()) + } + + /// Make a new announcement by a new IPFS cid about the alliance issues. + #[pallet::weight(0)] + pub fn announce(origin: OriginFor, announcement: Cid) -> DispatchResultWithPostInfo { + T::SuperMajorityOrigin::ensure_origin(origin)?; + + let mut announcements = >::get(); + announcements.push(announcement); + >::put(announcements); + + Self::deposit_event(Event::NewAnnouncement(announcement)); + Ok(().into()) + } + + /// Submit oneself for candidacy. + /// Account must have enough transferable funds in it to pay the candidate deposit. + #[pallet::weight(0)] + pub fn submit_candidacy(origin: OriginFor) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + ensure!(!Self::is_account_blacklist(&who), Error::::AlreadyInBlacklist); + ensure!(!Self::is_candidate(&who), Error::::AlreadyCandidate); + ensure!(!Self::is_member(&who), Error::::AlreadyMember); + // check user self or parent should has verified identity to reuse display name and + // website. + Self::has_identity(&who)?; + + let deposit = T::CandidateDeposit::get(); + T::Currency::reserve(&who, deposit) + .map_err(|_| Error::::InsufficientCandidateFunds)?; + >::insert(&who, deposit); + + let res = Self::add_candidate(&who); + debug_assert!(res.is_ok()); + + Self::deposit_event(Event::CandidateAdded(who, None, Some(deposit))); + Ok(().into()) + } + + /// Founder or fellow can nominate someone to join the alliance and become a candidate. + /// There is no deposit required to the nominator or nominee. + #[pallet::weight(0)] + pub fn nominate_candidacy( + origin: OriginFor, + who: ::Source, + ) -> DispatchResultWithPostInfo { + let nominator = ensure_signed(origin)?; + ensure!(Self::is_votable_member(&nominator), Error::::NotVotableMember); + let who = T::Lookup::lookup(who)?; + ensure!(!Self::is_account_blacklist(&who), Error::::AlreadyInBlacklist); + ensure!(!Self::is_candidate(&who), Error::::AlreadyCandidate); + ensure!(!Self::is_member(&who), Error::::AlreadyMember); + // check user self or parent should has verified identity to reuse display name and + // website. + Self::has_identity(&who)?; + + let res = Self::add_candidate(&who); + debug_assert!(res.is_ok()); + + Self::deposit_event(Event::CandidateAdded(who, Some(nominator), None)); + Ok(().into()) + } + + /// Approve a `Candidate` to become an `Ally`. + #[pallet::weight(0)] + pub fn approve_candidate( + origin: OriginFor, + candidate: ::Source, + ) -> DispatchResultWithPostInfo { + T::SuperMajorityOrigin::ensure_origin(origin)?; + let candidate = T::Lookup::lookup(candidate)?; + ensure!(Self::is_candidate(&candidate), Error::::NotCandidate); + ensure!(!Self::is_member(&candidate), Error::::AlreadyMember); + + Self::remove_candidate(&candidate)?; + Self::add_member(&candidate, MemberRole::Ally)?; + + Self::deposit_event(Event::CandidateApproved(candidate)); + Ok(().into()) + } + + /// Reject a `Candidate` back to an ordinary account. + #[pallet::weight(0)] + pub fn reject_candidate( + origin: OriginFor, + candidate: ::Source, + ) -> DispatchResultWithPostInfo { + T::SuperMajorityOrigin::ensure_origin(origin)?; + let candidate = T::Lookup::lookup(candidate)?; + ensure!(Self::is_candidate(&candidate), Error::::NotCandidate); + ensure!(!Self::is_member(&candidate), Error::::AlreadyMember); + + Self::remove_candidate(&candidate)?; + if let Some(deposit) = DepositOf::::take(&candidate) { + T::Slashed::on_unbalanced(T::Currency::slash_reserved(&candidate, deposit).0); + } + + Self::deposit_event(Event::CandidateRejected(candidate)); + Ok(().into()) + } + + /// Elevate an ally to fellow. + #[pallet::weight(0)] + pub fn elevate_ally( + origin: OriginFor, + ally: ::Source, + ) -> DispatchResultWithPostInfo { + T::SuperMajorityOrigin::ensure_origin(origin)?; + let ally = T::Lookup::lookup(ally)?; + ensure!(Self::is_ally(&ally), Error::::NotAlly); + ensure!(!Self::is_votable_member(&ally), Error::::AlreadyElevated); + + Self::remove_member(&ally, MemberRole::Ally)?; + Self::add_member(&ally, MemberRole::Fellow)?; + + Self::deposit_event(Event::AllyElevated(ally)); + Ok(().into()) + } + + /// As a member, retire and back to an ordinary account and unlock its deposit. + #[pallet::weight(0)] + pub fn retire(origin: OriginFor) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + ensure!(!Self::is_kicking(&who), Error::::KickingMember); + + let role = Self::member_role_of(&who).ok_or(Error::::NotMember)?; + Self::remove_member(&who, role)?; + let deposit = DepositOf::::take(&who); + if let Some(deposit) = deposit { + let err_amount = T::Currency::unreserve(&who, deposit); + debug_assert!(err_amount.is_zero()); + } + Self::deposit_event(Event::MemberRetired(who, deposit)); + Ok(().into()) + } + + /// Kick a member to ordinary account with its deposit slashed. + #[pallet::weight(0)] + pub fn kick_member( + origin: OriginFor, + who: ::Source, + ) -> DispatchResultWithPostInfo { + T::SuperMajorityOrigin::ensure_origin(origin)?; + let member = T::Lookup::lookup(who)?; + ensure!(Self::is_kicking(&member), Error::::NotKickingMember); + + let role = Self::member_role_of(&member).ok_or(Error::::NotMember)?; + Self::remove_member(&member, role)?; + let deposit = DepositOf::::take(member.clone()); + if let Some(deposit) = deposit { + T::Slashed::on_unbalanced(T::Currency::slash_reserved(&member, deposit).0); + } + Self::deposit_event(Event::MemberKicked(member, deposit)); + Ok(().into()) + } + + /// Add accounts or websites into blacklist. + #[pallet::weight(0)] + pub fn add_blacklist( + origin: OriginFor, + infos: Vec>, + ) -> DispatchResultWithPostInfo { + T::SuperMajorityOrigin::ensure_origin(origin)?; + let mut accounts = vec![]; + let mut webs = vec![]; + for info in infos.iter() { + ensure!(!Self::is_blacklist(info), Error::::AlreadyInBlacklist); + match info { + BlacklistItem::AccountId(who) => accounts.push(who.clone()), + BlacklistItem::Website(url) => webs.push(url.clone()), + } + } + Self::do_add_blacklist(&mut accounts, &mut webs)?; + Self::deposit_event(Event::BlacklistAdded(infos)); + Ok(().into()) + } + + /// Remove accounts or websites from blacklist. + #[pallet::weight(0)] + pub fn remove_blacklist( + origin: OriginFor, + infos: Vec>, + ) -> DispatchResultWithPostInfo { + T::SuperMajorityOrigin::ensure_origin(origin)?; + let mut accounts = vec![]; + let mut webs = vec![]; + for info in infos.iter() { + ensure!(Self::is_blacklist(info), Error::::NotInBlacklist); + match info { + BlacklistItem::AccountId(who) => accounts.push(who.clone()), + BlacklistItem::Website(url) => webs.push(url.clone()), + } + } + Self::do_remove_blacklist(&mut accounts, &mut webs)?; + Self::deposit_event(Event::BlacklistRemoved(infos)); + Ok(().into()) + } + } +} + +impl, I: 'static> Pallet { + /// Check if a user is a candidate. + pub fn is_candidate(who: &T::AccountId) -> bool { + >::get().contains(who) + } + + /// Add a candidate to the sorted candidate list. + fn add_candidate(who: &T::AccountId) -> DispatchResult { + let mut candidates = >::get(); + let pos = candidates.binary_search(who).err().ok_or(Error::::AlreadyCandidate)?; + candidates.insert(pos, who.clone()); + Candidates::::put(candidates); + Ok(()) + } + + /// Remove a candidate from the candidates list. + fn remove_candidate(who: &T::AccountId) -> DispatchResult { + let mut candidates = >::get(); + let pos = candidates.binary_search(who).ok().ok_or(Error::::NotCandidate)?; + candidates.remove(pos); + Candidates::::put(candidates); + Ok(()) + } + + fn has_member(role: MemberRole) -> bool { + !Members::::get(role).is_empty() + } + + fn member_role_of(who: &T::AccountId) -> Option { + Members::::iter() + .find_map(|(r, members)| if members.contains(who) { Some(r) } else { None }) + } + + /// Check if a user is a alliance member. + pub fn is_member(who: &T::AccountId) -> bool { + Self::member_role_of(who).is_some() + } + + pub fn is_member_of(who: &T::AccountId, role: MemberRole) -> bool { + Members::::get(role).contains(&who) + } + + fn is_founder(who: &T::AccountId) -> bool { + Self::is_member_of(who, MemberRole::Founder) + } + + fn is_fellow(who: &T::AccountId) -> bool { + Self::is_member_of(who, MemberRole::Fellow) + } + + fn is_ally(who: &T::AccountId) -> bool { + Self::is_member_of(who, MemberRole::Ally) + } + + fn is_votable_member(who: &T::AccountId) -> bool { + Self::is_founder(who) || Self::is_fellow(who) + } + + fn votable_member_count() -> u32 { + let founder_count = Members::::decode_len(MemberRole::Founder).unwrap_or_default(); + let fellow_count = Members::::decode_len(MemberRole::Fellow).unwrap_or_default(); + (founder_count + fellow_count) as u32 + } + + fn votable_member_sorted() -> Vec { + let mut founders = Members::::get(MemberRole::Founder); + let mut fellows = Members::::get(MemberRole::Fellow); + founders.append(&mut fellows); + founders.sort(); + founders + } + + fn is_kicking(who: &T::AccountId) -> bool { + >::contains_key(&who) + } + + /// Add a user to the sorted alliance member set. + fn add_member(who: &T::AccountId, role: MemberRole) -> DispatchResult { + let mut members = >::get(role); + let pos = members.binary_search(who).err().ok_or(Error::::AlreadyMember)?; + members.insert(pos, who.clone()); + Members::::insert(role, members); + + if role == MemberRole::Founder || role == MemberRole::Fellow { + let members = Self::votable_member_sorted(); + T::MembershipChanged::change_members_sorted(&[who.clone()], &[], &members[..]); + } + Ok(()) + } + + /// Remove a user from the alliance member set. + fn remove_member(who: &T::AccountId, role: MemberRole) -> DispatchResult { + let mut members = >::get(role); + let pos = members.binary_search(who).ok().ok_or(Error::::NotMember)?; + members.remove(pos); + Members::::insert(role, members); + + if role == MemberRole::Founder || role == MemberRole::Fellow { + let members = Self::votable_member_sorted(); + T::MembershipChanged::change_members_sorted(&[], &[who.clone()], &members[..]); + } + Ok(()) + } + + /// Check if a user is in blacklist. + fn is_blacklist(info: &BlacklistItem) -> bool { + match info { + BlacklistItem::Website(url) => >::get().contains(url), + BlacklistItem::AccountId(who) => >::get().contains(who), + } + } + + /// Check if a user is in account blacklist. + fn is_account_blacklist(who: &T::AccountId) -> bool { + >::get().contains(who) + } + + /// Add a identity info to the blacklist set. + fn do_add_blacklist( + new_accounts: &mut Vec, + new_webs: &mut Vec, + ) -> DispatchResult { + if !new_accounts.is_empty() { + let mut accounts = >::get(); + accounts.append(new_accounts); + accounts.sort(); + Self::maybe_warn_max_blacklist(&accounts); + AccountBlacklist::::put(accounts); + } + if !new_webs.is_empty() { + let mut webs = >::get(); + webs.append(new_webs); + webs.sort(); + Self::maybe_warn_max_blacklist(&webs); + WebsiteBlacklist::::put(webs); + } + Ok(()) + } + + /// Remove a identity info from the blacklist. + fn do_remove_blacklist( + out_accounts: &mut Vec, + out_webs: &mut Vec, + ) -> DispatchResult { + if !out_accounts.is_empty() { + let mut accounts = >::get(); + for who in out_accounts.iter() { + let pos = accounts.binary_search(who).ok().ok_or(Error::::NotInBlacklist)?; + accounts.remove(pos); + } + Self::maybe_warn_max_blacklist(&accounts); + AccountBlacklist::::put(accounts); + } + if !out_webs.is_empty() { + let mut webs = >::get(); + for web in out_webs.iter() { + let pos = webs.binary_search(web).ok().ok_or(Error::::NotInBlacklist)?; + webs.remove(pos); + } + Self::maybe_warn_max_blacklist(&webs); + WebsiteBlacklist::::put(webs); + } + Ok(()) + } + + fn maybe_warn_max_blacklist(blacklist: &[B]) { + if blacklist.len() as u32 > T::MaxBlacklistCount::get() { + log::error!( + target: "runtime::alliance", + "maximum number of blacklist used for weight is exceeded, weights can be underestimated [{} > {}].", + blacklist.len(), + T::MaxBlacklistCount::get(), + ) + } + } + + fn has_identity(who: &T::AccountId) -> DispatchResult { + let judgement = |w: &T::AccountId| -> DispatchResult { + ensure!( + T::IdentityVerifier::verify_identity(w, IDENTITY_FIELD_DISPLAY), + Error::::WithoutIdentityDisplay + ); + ensure!( + T::IdentityVerifier::verify_judgement(w), + Error::::WithoutVerifiedIdentity + ); + ensure!( + T::IdentityVerifier::verify_identity(w, IDENTITY_FIELD_WEB), + Error::::WithoutIdentityWebsite + ); + Ok(()) + }; + + let res = judgement(who); + if res.is_err() { + if let Some(parent) = T::IdentityVerifier::super_account_id(who) { + return judgement(&parent) + } + } + res + } +} diff --git a/frame/alliance/src/mock.rs b/frame/alliance/src/mock.rs new file mode 100644 index 0000000000000..49844ddd2dcba --- /dev/null +++ b/frame/alliance/src/mock.rs @@ -0,0 +1,226 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Test utilities + +pub use cid::Cid; + +pub use sp_core::H256; +pub use sp_runtime::{ + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, + BuildStorage, +}; + +pub use frame_support::{ord_parameter_types, parameter_types, traits::SortedMembers}; +pub use frame_system::EnsureSignedBy; + +pub use crate as pallet_alliance; + +use super::*; + +parameter_types! { + pub const BlockHashCount: u64 = 250; +} +impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = (); + type BlockLength = (); + 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 = Event; + type BlockHashCount = BlockHashCount; + type DbWeight = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); +} + +parameter_types! { + pub const ExistentialDeposit: u64 = 1; + pub const MaxLocks: u32 = 10; +} +impl pallet_balances::Config for Test { + type Balance = u64; + type DustRemoval = (); + type Event = Event; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type MaxLocks = MaxLocks; + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; +} + +parameter_types! { + pub const MotionDuration: u64 = 3; + pub const MaxProposals: u32 = 100; + pub const MaxMembers: u32 = 100; +} +type AllianceCollective = pallet_collective::Instance1; +impl pallet_collective::Config for Test { + type Origin = Origin; + type Proposal = Call; + type Event = Event; + type MotionDuration = MotionDuration; + type MaxProposals = MaxProposals; + type MaxMembers = MaxMembers; + type DefaultVote = pallet_collective::PrimeDefaultVote; + type WeightInfo = (); +} + +pub struct AllianceIdentityVerifier; +impl IdentityVerifier for AllianceIdentityVerifier { + fn super_account_id(_who: &u64) -> Option { + None + } + + fn verify_identity(_who: &u64, _field: u64) -> bool { + true + } + + fn verify_judgement(_who: &u64) -> bool { + true + } +} + +pub struct AllianceProposalProvider; +impl ProposalProvider for AllianceProposalProvider { + fn propose_proposal(who: u64, threshold: u32, proposal: Call) -> Result { + AllianceMotion::do_propose(who, threshold, proposal) + } + + fn vote_proposal( + who: u64, + proposal: H256, + index: ProposalIndex, + approve: bool, + ) -> Result { + AllianceMotion::do_vote(who, proposal, index, approve) + } + + fn veto_proposal(proposal_hash: H256) -> u32 { + AllianceMotion::do_disapprove_proposal(proposal_hash) + } + + fn close_proposal( + proposal_hash: H256, + proposal_index: ProposalIndex, + proposal_weight_bound: Weight, + length_bound: u32, + ) -> DispatchResultWithPostInfo { + AllianceMotion::do_close(proposal_hash, proposal_index, proposal_weight_bound, length_bound) + } + + fn proposal_of(proposal_hash: H256) -> Option { + AllianceMotion::proposal_of(proposal_hash) + } +} + +ord_parameter_types! { + pub const One: u64 = 1; + pub const Two: u64 = 2; + pub const Three: u64 = 3; + pub const Four: u64 = 4; + pub const Five: u64 = 5; +} +parameter_types! { + pub const CandidateDeposit: u64 = 25; + pub const MaxBlacklistCount: u32 = 100; +} +impl Config for Test { + type Event = Event; + type Proposal = Call; + type SuperMajorityOrigin = EnsureSignedBy; + type Currency = Balances; + type Slashed = (); + type InitializeMembers = AllianceMotion; + type MembershipChanged = AllianceMotion; + type IdentityVerifier = AllianceIdentityVerifier; + type ProposalProvider = AllianceProposalProvider; + type MaxBlacklistCount = MaxBlacklistCount; + type CandidateDeposit = CandidateDeposit; +} + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +frame_support::construct_runtime!( + pub enum Test where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Storage, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + AllianceMotion: pallet_collective::::{Pallet, Storage, Origin, Event}, + Alliance: pallet_alliance::{Pallet, Call, Storage, Event, Config}, + } +); + +pub fn new_test_ext() -> sp_io::TestExternalities { + let t = GenesisConfig { + balances: pallet_balances::GenesisConfig { + balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 20)], + }, + alliance: pallet_alliance::GenesisConfig { + founders: vec![1, 2], + fellows: vec![3], + allies: vec![], + phantom: Default::default(), + }, + } + .build_storage() + .unwrap(); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext +} + +#[cfg(feature = "runtime-benchmarks")] +pub fn new_bench_ext() -> sp_io::TestExternalities { + GenesisConfig::default().build_storage().unwrap().into() +} + +pub fn test_cid() -> Cid { + "QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n".parse().unwrap() +} + +pub fn make_proposal(value: u64) -> Call { + Call::System(frame_system::Call::remark { remark: value.encode() }) +} + +pub fn make_set_rule_proposal(rule: Cid) -> Call { + Call::Alliance(pallet_alliance::Call::set_rule { rule }) +} + +pub fn make_kick_member_proposal(who: u64) -> Call { + Call::Alliance(pallet_alliance::Call::kick_member { who }) +} diff --git a/frame/alliance/src/tests.rs b/frame/alliance/src/tests.rs new file mode 100644 index 0000000000000..3ff0296c873f4 --- /dev/null +++ b/frame/alliance/src/tests.rs @@ -0,0 +1,507 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Tests for the alliance pallet. + +use sp_runtime::traits::Hash; + +use frame_support::{assert_noop, assert_ok, Hashable}; +use frame_system::{EventRecord, Phase}; + +use super::*; +use crate::mock::*; + +type AllianceMotionEvent = pallet_collective::Event; + +#[test] +fn propose_works() { + new_test_ext().execute_with(|| { + let proposal = make_proposal(42); + let hash: H256 = proposal.blake2_256().into(); + + // only votable member can propose proposal, 4 is ally not have vote rights + assert_noop!( + Alliance::propose(Origin::signed(4), Box::new(proposal.clone())), + Error::::NotVotableMember + ); + + assert_ok!(Alliance::propose(Origin::signed(1), Box::new(proposal.clone()))); + assert_eq!(*AllianceMotion::proposals(), vec![hash]); + assert_eq!(AllianceMotion::proposal_of(&hash), Some(proposal)); + assert_eq!( + System::events(), + vec![EventRecord { + phase: Phase::Initialization, + event: mock::Event::AllianceMotion(AllianceMotionEvent::Proposed(1, 0, hash, 3)), + topics: vec![], + }] + ); + }); +} + +#[test] +fn vote_works() { + new_test_ext().execute_with(|| { + let proposal = make_proposal(42); + let hash: H256 = proposal.blake2_256().into(); + assert_ok!(Alliance::propose(Origin::signed(1), Box::new(proposal.clone()))); + assert_ok!(Alliance::vote(Origin::signed(2), hash.clone(), 0, true)); + + let record = |event| EventRecord { phase: Phase::Initialization, event, topics: vec![] }; + assert_eq!( + System::events(), + vec![ + record(mock::Event::AllianceMotion(AllianceMotionEvent::Proposed( + 1, + 0, + hash.clone(), + 3 + ))), + record(mock::Event::AllianceMotion(AllianceMotionEvent::Voted( + 2, + hash.clone(), + true, + 1, + 0 + ))), + ] + ); + }); +} + +#[test] +fn veto_works() { + new_test_ext().execute_with(|| { + let proposal = make_proposal(42); + let hash: H256 = proposal.blake2_256().into(); + assert_ok!(Alliance::propose(Origin::signed(1), Box::new(proposal.clone()))); + // only set_rule/elevate_ally can be veto + assert_noop!( + Alliance::veto(Origin::signed(1), hash.clone()), + Error::::NotVetoableProposal + ); + + let cid = test_cid(); + let vetoable_proposal = make_set_rule_proposal(cid); + let vetoable_hash: H256 = vetoable_proposal.blake2_256().into(); + assert_ok!(Alliance::propose(Origin::signed(1), Box::new(vetoable_proposal.clone()))); + + // only founder have veto rights, 3 is fellow + assert_noop!( + Alliance::veto(Origin::signed(3), vetoable_hash.clone()), + Error::::NotFounder + ); + + assert_ok!(Alliance::veto(Origin::signed(2), vetoable_hash.clone())); + let record = |event| EventRecord { phase: Phase::Initialization, event, topics: vec![] }; + assert_eq!( + System::events(), + vec![ + record(mock::Event::AllianceMotion(AllianceMotionEvent::Proposed( + 1, + 0, + hash.clone(), + 3 + ))), + record(mock::Event::AllianceMotion(AllianceMotionEvent::Proposed( + 1, + 1, + vetoable_hash.clone(), + 3 + ))), + // record(mock::Event::AllianceMotion(AllianceMotionEvent::Voted(2, hash.clone(), + // true, 2, 0))), + record(mock::Event::AllianceMotion(AllianceMotionEvent::Disapproved( + vetoable_hash.clone() + ))), + ] + ); + }) +} + +#[test] +fn close_works() { + new_test_ext().execute_with(|| { + let proposal = make_proposal(42); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); + let proposal_weight = proposal.get_dispatch_info().weight; + let hash = BlakeTwo256::hash_of(&proposal); + assert_ok!(Alliance::propose(Origin::signed(1), Box::new(proposal.clone()))); + assert_ok!(Alliance::vote(Origin::signed(1), hash.clone(), 0, true)); + assert_ok!(Alliance::vote(Origin::signed(2), hash.clone(), 0, true)); + assert_ok!(Alliance::vote(Origin::signed(3), hash.clone(), 0, true)); + assert_ok!(Alliance::close( + Origin::signed(1), + hash.clone(), + 0, + proposal_weight, + proposal_len + )); + + let record = |event| EventRecord { phase: Phase::Initialization, event, topics: vec![] }; + assert_eq!( + System::events(), + vec![ + record(mock::Event::AllianceMotion(AllianceMotionEvent::Proposed( + 1, + 0, + hash.clone(), + 3 + ))), + record(mock::Event::AllianceMotion(AllianceMotionEvent::Voted( + 1, + hash.clone(), + true, + 1, + 0 + ))), + record(mock::Event::AllianceMotion(AllianceMotionEvent::Voted( + 2, + hash.clone(), + true, + 2, + 0 + ))), + record(mock::Event::AllianceMotion(AllianceMotionEvent::Voted( + 3, + hash.clone(), + true, + 3, + 0 + ))), + record(mock::Event::AllianceMotion(AllianceMotionEvent::Closed( + hash.clone(), + 3, + 0 + ))), + record(mock::Event::AllianceMotion(AllianceMotionEvent::Approved(hash.clone()))), + record(mock::Event::AllianceMotion(AllianceMotionEvent::Executed( + hash.clone(), + Err(DispatchError::BadOrigin) + ))) + ] + ); + }); +} + +#[test] +fn set_rule_works() { + new_test_ext().execute_with(|| { + let cid = test_cid(); + assert_ok!(Alliance::set_rule(Origin::signed(1), cid)); + assert_eq!(Alliance::rule(), Some(cid)); + + System::assert_last_event(mock::Event::Alliance(crate::Event::NewRule(cid))); + }); +} + +#[test] +fn announce_works() { + new_test_ext().execute_with(|| { + let cid = test_cid(); + assert_ok!(Alliance::announce(Origin::signed(1), cid)); + assert_eq!(Alliance::announcements(), vec![cid]); + + System::assert_last_event(mock::Event::Alliance(crate::Event::NewAnnouncement(cid))); + }); +} + +#[test] +fn submit_candidacy_works() { + new_test_ext().execute_with(|| { + // check already member + assert_noop!( + Alliance::submit_candidacy(Origin::signed(1)), + Error::::AlreadyMember + ); + + // check already in blacklist + assert_ok!(Alliance::add_blacklist(Origin::signed(1), vec![BlacklistItem::AccountId(4)])); + assert_noop!( + Alliance::submit_candidacy(Origin::signed(4)), + Error::::AlreadyInBlacklist + ); + assert_ok!(Alliance::remove_blacklist( + Origin::signed(1), + vec![BlacklistItem::AccountId(4)] + )); + + // check deposit funds + assert_noop!( + Alliance::submit_candidacy(Origin::signed(5)), + Error::::InsufficientCandidateFunds + ); + + // success to submit + assert_ok!(Alliance::submit_candidacy(Origin::signed(4))); + assert_eq!(Alliance::deposit_of(4), Some(25)); + assert_eq!(Alliance::candidates(), vec![4]); + + // check already candidate + assert_noop!( + Alliance::submit_candidacy(Origin::signed(4)), + Error::::AlreadyCandidate + ); + }); +} + +#[test] +fn nominate_candidacy_works() { + new_test_ext().execute_with(|| { + // check already member + assert_noop!( + Alliance::nominate_candidacy(Origin::signed(1), 2), + Error::::AlreadyMember + ); + + // only votable member(founder/fellow) have nominate right + assert_noop!( + Alliance::nominate_candidacy(Origin::signed(5), 4), + Error::::NotVotableMember + ); + + // check already in blacklist + assert_ok!(Alliance::add_blacklist(Origin::signed(1), vec![BlacklistItem::AccountId(4)])); + assert_noop!( + Alliance::nominate_candidacy(Origin::signed(1), 4), + Error::::AlreadyInBlacklist + ); + assert_ok!(Alliance::remove_blacklist( + Origin::signed(1), + vec![BlacklistItem::AccountId(4)] + )); + + // success to nominate + assert_ok!(Alliance::nominate_candidacy(Origin::signed(1), 4)); + assert_eq!(Alliance::deposit_of(4), None); + assert_eq!(Alliance::candidates(), vec![4]); + + // check already candidate + assert_noop!( + Alliance::nominate_candidacy(Origin::signed(1), 4), + Error::::AlreadyCandidate + ); + }); +} + +#[test] +fn approve_candidate_works() { + new_test_ext().execute_with(|| { + assert_noop!( + Alliance::approve_candidate(Origin::signed(1), 4), + Error::::NotCandidate + ); + + assert_ok!(Alliance::submit_candidacy(Origin::signed(4))); + assert_eq!(Alliance::candidates(), vec![4]); + + assert_ok!(Alliance::approve_candidate(Origin::signed(1), 4)); + assert_eq!(Alliance::candidates(), Vec::::new()); + assert_eq!(Alliance::members(MemberRole::Ally), vec![4]); + }); +} + +#[test] +fn reject_candidate_works() { + new_test_ext().execute_with(|| { + assert_noop!( + Alliance::reject_candidate(Origin::signed(1), 4), + Error::::NotCandidate + ); + + assert_ok!(Alliance::submit_candidacy(Origin::signed(4))); + assert_eq!(Alliance::deposit_of(4), Some(25)); + assert_eq!(Alliance::candidates(), vec![4]); + + assert_ok!(Alliance::reject_candidate(Origin::signed(1), 4)); + assert_eq!(Alliance::deposit_of(4), None); + assert_eq!(Alliance::candidates(), Vec::::new()); + }); +} + +#[test] +fn elevate_ally_works() { + new_test_ext().execute_with(|| { + assert_noop!(Alliance::elevate_ally(Origin::signed(1), 4), Error::::NotAlly); + + assert_ok!(Alliance::submit_candidacy(Origin::signed(4))); + assert_ok!(Alliance::approve_candidate(Origin::signed(1), 4)); + assert_eq!(Alliance::members(MemberRole::Ally), vec![4]); + assert_eq!(Alliance::members(MemberRole::Fellow), vec![3]); + + assert_ok!(Alliance::elevate_ally(Origin::signed(1), 4)); + assert_eq!(Alliance::members(MemberRole::Ally), Vec::::new()); + assert_eq!(Alliance::members(MemberRole::Fellow), vec![3, 4]); + }); +} + +#[test] +fn retire_works() { + new_test_ext().execute_with(|| { + let proposal = make_kick_member_proposal(2); + assert_ok!(Alliance::propose(Origin::signed(1), Box::new(proposal.clone()))); + assert_noop!(Alliance::retire(Origin::signed(2)), Error::::KickingMember); + + assert_noop!(Alliance::retire(Origin::signed(4)), Error::::NotMember); + + assert_eq!(Alliance::members(MemberRole::Fellow), vec![3]); + assert_ok!(Alliance::retire(Origin::signed(3))); + assert_eq!(Alliance::members(MemberRole::Fellow), Vec::::new()); + }); +} + +#[test] +fn kick_member_works() { + new_test_ext().execute_with(|| { + assert_noop!( + Alliance::kick_member(Origin::signed(1), 2), + Error::::NotKickingMember + ); + + let proposal = make_kick_member_proposal(2); + assert_ok!(Alliance::propose(Origin::signed(1), Box::new(proposal.clone()))); + assert_eq!(Alliance::kicking_member(2), true); + assert_eq!(Alliance::members(MemberRole::Founder), vec![1, 2]); + + assert_ok!(Alliance::kick_member(Origin::signed(1), 2)); + assert_eq!(Alliance::members(MemberRole::Founder), vec![1]); + }); +} + +#[test] +fn add_blacklist_works() { + new_test_ext().execute_with(|| { + assert_ok!(Alliance::add_blacklist( + Origin::signed(1), + vec![BlacklistItem::AccountId(3), BlacklistItem::Website("abc".as_bytes().to_vec())] + )); + assert_eq!(Alliance::account_blacklist(), vec![3]); + assert_eq!(Alliance::website_blacklist(), vec!["abc".as_bytes().to_vec()]); + + assert_noop!( + Alliance::add_blacklist(Origin::signed(1), vec![BlacklistItem::AccountId(3)]), + Error::::AlreadyInBlacklist + ); + }); +} + +#[test] +fn remove_blacklist_works() { + new_test_ext().execute_with(|| { + assert_noop!( + Alliance::remove_blacklist(Origin::signed(1), vec![BlacklistItem::AccountId(3)]), + Error::::NotInBlacklist + ); + + assert_ok!(Alliance::add_blacklist(Origin::signed(1), vec![BlacklistItem::AccountId(3)])); + assert_eq!(Alliance::account_blacklist(), vec![3]); + assert_ok!(Alliance::remove_blacklist( + Origin::signed(1), + vec![BlacklistItem::AccountId(3)] + )); + assert_eq!(Alliance::account_blacklist(), Vec::::new()); + }); +} + +/* +mod cid_tests { + use cid::{ + multibase::Base, + multihash::{Code, MultihashDigest}, + CidGeneric, Version, + }; + use codec::{Decode, Encode}; + use hex_literal::hex; + + const RAW: u64 = 0x55; + + type Cid = CidGeneric<32>; + + #[test] + fn normal_test_for_example() { + let cid = "QmRZdc3mAMXpv6Akz9Ekp1y4vDSjazTx2dCQRkxVy1yUj6".parse::().unwrap(); + let bytes = cid.encode(); + let expect = hex!("0070000000000000001200000000000000202fe65ccc17fe180c3bf4e9b8490fcc6dc74c30bf6595795dcd1136d8d9cb3f95"); + assert_eq!(bytes, expect); + let new_cid: Cid = Decode::decode(&mut &bytes[..]).unwrap(); + assert_eq!(new_cid, cid); + } + + macro_rules! assert_cid { + ($cid:expr, $length:expr) => { + let mut digest = [0_u8; $length]; + digest.copy_from_slice($cid.hash().digest()); + let raw = + ($cid.version(), $cid.codec(), ($cid.hash().code(), $cid.hash().size(), digest)); + let raw_encode = Encode::encode(&raw); + let bytes = $cid.encode(); + assert_eq!(bytes, raw_encode); + let new_cid: Cid = Decode::decode(&mut &bytes[..]).unwrap(); + assert_eq!(new_cid, $cid); + }; + } + + // those test case is from crate cid + #[test] + fn v0_handling() { + let old = "QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n"; + let cid = old.parse::().unwrap(); + + assert_eq!(cid.version(), Version::V0); + assert_eq!(cid.to_string(), old); + + // for Cid v0 hash is 32 length + assert_cid!(cid, 32); + } + + #[test] + fn v1_handling() { + let expected_cid = "bafkreibme22gw2h7y2h7tg2fhqotaqjucnbc24deqo72b6mkl2egezxhvy"; + let cid: Cid = Cid::new_v1(RAW, Code::Sha2_256.digest(b"foo")); + assert_eq!(cid.to_string_of_base(Base::Base32Lower).unwrap(), expected_cid); + + // for sha256 hash is 32 length + assert_cid!(cid, 32); + } + + // test case from https://github.com/ipfs/go-cid/blob/master/cid_test.go#L662 + #[test] + fn v1_handling2() { + let cid1 = "k2cwueckqkibutvhkr4p2ln2pjcaxaakpd9db0e7j7ax1lxhhxy3ekpv" + .parse::() + .unwrap(); + let cid2 = "zb2rhZi1JR4eNc2jBGaRYJKYM8JEB4ovenym8L1CmFsRAytkz".parse::().unwrap(); + assert_cid!(cid1, 32); + assert_cid!(cid2, 32); + } + + #[test] + fn v1_handling3() { + let cid = Cid::new_v1(RAW, Code::Sha2_512.digest(b"foo")); + assert_cid!(cid, 64); + + let cid = Cid::new_v1(RAW, Code::Keccak384.digest(b"foo")); + assert_cid!(cid, 48); + + let cid = Cid::new_v1(RAW, Code::Sha3_224.digest(b"foo")); + assert_cid!(cid, 28); + + let cid = Cid::new_v1(RAW, Code::Blake2s128.digest(b"foo")); + assert_cid!(cid, 16); + } +} +*/ diff --git a/frame/alliance/src/types.rs b/frame/alliance/src/types.rs new file mode 100644 index 0000000000000..7d7c73004e0a9 --- /dev/null +++ b/frame/alliance/src/types.rs @@ -0,0 +1,225 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use codec::{Decode, Encode, EncodeLike, Error, Input, Output}; +use sp_runtime::RuntimeDebug; +use sp_std::{ops::Deref, vec}; + +/// A wrapped Cid for source Cid struct, to implement a valid encode/decode for Cid. +/// +/// This file will be used until this pr is merged: +/// https://github.com/multiformats/rust-multihash/pull/116 +/// For now, the source Cid use a static length `U64(H256)` for all Cid type, if we use the source +/// Cid encode/decode, it will add lots of empty zero in the result. +/// +/// e.g. +/// In the most widely used Cid type in IPFS, like: +/// QmRZdc3mAMXpv6Akz9Ekp1y4vDSjazTx2dCQRkxVy1yUj6 +/// If we use the source Cid to do encode, it will be: +/// 00-7000000000000000-1200000000000000-20-2fe65ccc17fe180c3bf4e9b8490fcc6dc74c30bf6595795dcd1136d8d9cb3f950000000000000000000000000000000000000000000000000000000000000000 +/// |Version|-|codec:u64|-|MultiHash| +/// |codec:u64| - |size:u8| - |digest| +/// We can see that ths digest part contains lots of zero for current digest in MultiHash is `[u8; +/// 64]`, However the generic hash length is 32. So the default encode/decode method wastes a lot of +/// space. +/// +/// And in pr#116 which is list above, the static length will be changed for multihash. Thus the +/// encode/decode method will be suitable for different Cid type. +/// So we consider this pr, decide to implement a encode/decode method for Cid which will be +/// **compatible** with the modification in pr#116. +/// +/// In our encode/decode, for the last part `digest`, we write the **raw value** to buffer and +/// read it from buffer **directly**, and do not add other byte like hint size or else. +/// The `code` and `size` is encoded/decoded in normal way. +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RuntimeDebug)] +pub struct Cid(cid::Cid); + +impl Cid { + pub fn new(cid: cid::Cid) -> Self { + Self(cid) + } +} + +impl Encode for Cid { + fn encode_to(&self, dest: &mut EncOut) { + // for cid + self.version().encode_to(dest); + self.codec().encode_to(dest); + // for multihash + let hash = self.hash(); + let code = hash.code(); + let size = hash.size(); + let digest = hash.digest(); + + code.encode_to(dest); + size.encode_to(dest); + // notice we write the digest directly to dest, for we have known the size. + // **IMPORTANT** + // we do not choose to encode &[u8] directly, for it will add compact length at start. + // + // in a valid cid, digest.len() must equal to `size`. Thus, in Decode, + // we can just read a raw bytes which length is equal to `size`. + dest.write(digest) + } +} + +impl EncodeLike for Cid {} + +impl Decode for Cid { + fn decode(input: &mut I) -> Result { + use cid::{ + multihash::{MultihashGeneric, U64}, + Version, + }; + + type Multihash = MultihashGeneric; + + // for cid + let version: Version = Decode::decode(input)?; + let codec: u64 = Decode::decode(input)?; + // for multihash + let code: u64 = Decode::decode(input)?; + let size: u8 = Decode::decode(input)?; + let mut buf = vec![0; size as usize]; + // In a valid Cid, the size must equal to this raw buffer. + input.read(&mut buf)?; + let hash = Multihash::wrap(code, &buf).map_err(|_| "Multihash parse error")?; + Ok(Cid::new(cid::Cid::new(version, codec, hash).map_err(|_| "Cid parse error")?)) + } +} + +impl Into for Cid { + fn into(self) -> cid::Cid { + self.0 + } +} + +impl From for Cid { + fn from(cid: cid::Cid) -> Self { + Cid::new(cid) + } +} + +impl AsRef for Cid { + fn as_ref(&self) -> &cid::Cid { + &self.0 + } +} + +impl AsMut for Cid { + fn as_mut(&mut self) -> &mut cid::Cid { + &mut self.0 + } +} + +impl Deref for Cid { + type Target = cid::Cid; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use cid::{ + multibase::Base, + multihash::{Code, MultihashDigest}, + Version, + }; + use sp_std::{convert::TryFrom, str::FromStr}; + + const RAW: u64 = 0x55; + + #[test] + fn normal_test_for_example() { + let s = "QmRZdc3mAMXpv6Akz9Ekp1y4vDSjazTx2dCQRkxVy1yUj6"; + let cid: Cid = cid::Cid::from_str(s).expect("must be valid.").into(); + let bytes = cid.encode(); + let expect = hex_literal::hex!("0070000000000000001200000000000000202fe65ccc17fe180c3bf4e9b8490fcc6dc74c30bf6595795dcd1136d8d9cb3f95"); + assert_eq!(bytes, expect); + let new_cid: Cid = Decode::decode(&mut &bytes[..]).expect("must decode well"); + assert_eq!(new_cid, cid); + } + + macro_rules! assert_cid { + ($cid:expr, $length:expr) => { + let mut digest = [0_u8; $length]; + digest.copy_from_slice($cid.hash().digest()); + let raw = + ($cid.version(), $cid.codec(), ($cid.hash().code(), $cid.hash().size(), digest)); + let raw_encode = Encode::encode(&raw); + let bytes = $cid.encode(); + assert_eq!(bytes, raw_encode); + let new_cid: Cid = Decode::decode(&mut &bytes[..]).expect("must decode well"); + assert_eq!(new_cid, $cid); + }; + } + // those test case is from crate rust-cid + #[test] + fn v0_handling() { + let old = "QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n"; + let cid: Cid = cid::Cid::try_from(old).expect("must be valid.").into(); + + assert_eq!(cid.version(), Version::V0); + assert_eq!(cid.to_string(), old); + + // for Cid v0 hash is 32 length + assert_cid!(cid, 32); + } + + #[test] + fn v1_handling() { + let expected_cid = "bafkreibme22gw2h7y2h7tg2fhqotaqjucnbc24deqo72b6mkl2egezxhvy"; + let cid: Cid = cid::Cid::new_v1(RAW, Code::Sha2_256.digest(b"foo")).into(); + assert_eq!(cid.to_string_of_base(Base::Base32Lower).unwrap(), expected_cid); + + // for sha256 hash is 32 length + assert_cid!(cid, 32); + } + + // test case from https://github.com/ipfs/go-cid/blob/master/cid_test.go#L662 + #[test] + fn v1_handling2() { + let cid1: Cid = + cid::Cid::from_str("k2cwueckqkibutvhkr4p2ln2pjcaxaakpd9db0e7j7ax1lxhhxy3ekpv") + .expect("must valid") + .into(); + let cid2: Cid = cid::Cid::from_str("zb2rhZi1JR4eNc2jBGaRYJKYM8JEB4ovenym8L1CmFsRAytkz") + .expect("must valid") + .into(); + assert_cid!(cid1, 32); + assert_cid!(cid2, 32); + } + + #[test] + fn v1_handling3() { + let cid: Cid = cid::Cid::new_v1(RAW, Code::Sha2_512.digest(b"foo")).into(); + assert_cid!(cid, 64); + + let cid: Cid = cid::Cid::new_v1(RAW, Code::Keccak384.digest(b"foo")).into(); + assert_cid!(cid, 48); + + let cid: Cid = cid::Cid::new_v1(RAW, Code::Sha3_224.digest(b"foo")).into(); + assert_cid!(cid, 28); + + let cid: Cid = cid::Cid::new_v1(RAW, Code::Blake2s128.digest(b"foo")).into(); + assert_cid!(cid, 16); + } +} diff --git a/frame/alliance/src/weights.rs b/frame/alliance/src/weights.rs new file mode 100644 index 0000000000000..8b137891791fe --- /dev/null +++ b/frame/alliance/src/weights.rs @@ -0,0 +1 @@ + diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index e876343ec33da..a1acff00d7222 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -54,7 +54,7 @@ use frame_support::{ traits::{ Backing, ChangeMembers, EnsureOrigin, Get, GetBacking, InitializeMembers, StorageVersion, }, - weights::{GetDispatchInfo, Weight}, + weights::{GetDispatchInfo, Pays, Weight}, }; #[cfg(test)] @@ -516,13 +516,14 @@ pub mod pallet { let proposal_len = proposal.using_encoded(|x| x.len()); ensure!(proposal_len <= length_bound as usize, Error::::WrongProposalLength); - let proposal_hash = T::Hashing::hash_of(&proposal); - ensure!( - !>::contains_key(proposal_hash), - Error::::DuplicateProposal - ); if threshold < 2 { + let proposal_hash = T::Hashing::hash_of(&proposal); + ensure!( + !>::contains_key(proposal_hash), + Error::::DuplicateProposal + ); + let seats = Self::members().len() as MemberCount; let result = proposal.dispatch(RawOrigin::Members(1, seats).into()); Self::deposit_event(Event::Executed { @@ -540,33 +541,12 @@ pub mod pallet { }) .into()) } else { - let active_proposals = - >::try_mutate(|proposals| -> Result { - proposals - .try_push(proposal_hash) - .map_err(|_| Error::::TooManyProposals)?; - Ok(proposals.len()) - })?; - let index = Self::proposal_count(); - >::mutate(|i| *i += 1); - >::insert(proposal_hash, *proposal); - let votes = { - let end = frame_system::Pallet::::block_number() + T::MotionDuration::get(); - Votes { index, threshold, ayes: vec![], nays: vec![], end } - }; - >::insert(proposal_hash, votes); - - Self::deposit_event(Event::Proposed { - account: who, - proposal_index: index, - proposal_hash, - threshold, - }); + let active_proposals = Self::do_propose(who, threshold, *proposal)?; Ok(Some(T::WeightInfo::propose_proposed( - proposal_len as u32, // B - members.len() as u32, // M - active_proposals as u32, // P2 + proposal_len as u32, // B + members.len() as u32, // M + active_proposals, // P2 )) .into()) } @@ -598,46 +578,8 @@ pub mod pallet { let members = Self::members(); ensure!(members.contains(&who), Error::::NotMember); - let mut voting = Self::voting(&proposal).ok_or(Error::::ProposalMissing)?; - ensure!(voting.index == index, Error::::WrongIndex); - - let position_yes = voting.ayes.iter().position(|a| a == &who); - let position_no = voting.nays.iter().position(|a| a == &who); - // Detects first vote of the member in the motion - let is_account_voting_first_time = position_yes.is_none() && position_no.is_none(); - - if approve { - if position_yes.is_none() { - voting.ayes.push(who.clone()); - } else { - return Err(Error::::DuplicateVote.into()) - } - if let Some(pos) = position_no { - voting.nays.swap_remove(pos); - } - } else { - if position_no.is_none() { - voting.nays.push(who.clone()); - } else { - return Err(Error::::DuplicateVote.into()) - } - if let Some(pos) = position_yes { - voting.ayes.swap_remove(pos); - } - } - - let yes_votes = voting.ayes.len() as MemberCount; - let no_votes = voting.nays.len() as MemberCount; - Self::deposit_event(Event::Voted { - account: who, - proposal_hash: proposal, - voted: approve, - yes: yes_votes, - no: no_votes, - }); - - Voting::::insert(&proposal, voting); + let is_account_voting_first_time = Self::do_vote(who, proposal, index, approve)?; if is_account_voting_first_time { Ok((Some(T::WeightInfo::vote(members.len() as u32)), Pays::No).into()) @@ -701,82 +643,7 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { let _ = ensure_signed(origin)?; - let voting = Self::voting(&proposal_hash).ok_or(Error::::ProposalMissing)?; - ensure!(voting.index == index, Error::::WrongIndex); - - let mut no_votes = voting.nays.len() as MemberCount; - let mut yes_votes = voting.ayes.len() as MemberCount; - let seats = Self::members().len() as MemberCount; - let approved = yes_votes >= voting.threshold; - let disapproved = seats.saturating_sub(no_votes) < voting.threshold; - // Allow (dis-)approving the proposal as soon as there are enough votes. - if approved { - let (proposal, len) = Self::validate_and_get_proposal( - &proposal_hash, - length_bound, - proposal_weight_bound, - )?; - Self::deposit_event(Event::Closed { proposal_hash, yes: yes_votes, no: no_votes }); - let (proposal_weight, proposal_count) = - Self::do_approve_proposal(seats, yes_votes, proposal_hash, proposal); - return Ok(( - Some( - T::WeightInfo::close_early_approved(len as u32, seats, proposal_count) - .saturating_add(proposal_weight), - ), - Pays::Yes, - ) - .into()) - } else if disapproved { - Self::deposit_event(Event::Closed { proposal_hash, yes: yes_votes, no: no_votes }); - let proposal_count = Self::do_disapprove_proposal(proposal_hash); - return Ok(( - Some(T::WeightInfo::close_early_disapproved(seats, proposal_count)), - Pays::No, - ) - .into()) - } - - // Only allow actual closing of the proposal after the voting period has ended. - ensure!( - frame_system::Pallet::::block_number() >= voting.end, - Error::::TooEarly - ); - - let prime_vote = Self::prime().map(|who| voting.ayes.iter().any(|a| a == &who)); - - // default voting strategy. - let default = T::DefaultVote::default_vote(prime_vote, yes_votes, no_votes, seats); - - let abstentions = seats - (yes_votes + no_votes); - match default { - true => yes_votes += abstentions, - false => no_votes += abstentions, - } - let approved = yes_votes >= voting.threshold; - - if approved { - let (proposal, len) = Self::validate_and_get_proposal( - &proposal_hash, - length_bound, - proposal_weight_bound, - )?; - Self::deposit_event(Event::Closed { proposal_hash, yes: yes_votes, no: no_votes }); - let (proposal_weight, proposal_count) = - Self::do_approve_proposal(seats, yes_votes, proposal_hash, proposal); - Ok(( - Some( - T::WeightInfo::close_approved(len as u32, seats, proposal_count) - .saturating_add(proposal_weight), - ), - Pays::Yes, - ) - .into()) - } else { - Self::deposit_event(Event::Closed { proposal_hash, yes: yes_votes, no: no_votes }); - let proposal_count = Self::do_disapprove_proposal(proposal_hash); - Ok((Some(T::WeightInfo::close_disapproved(seats, proposal_count)), Pays::No).into()) - } + Self::do_close(proposal_hash, index, proposal_weight_bound, length_bound) } /// Disapprove a proposal, close, and remove it from the system, regardless of its current @@ -823,6 +690,165 @@ impl, I: 'static> Pallet { Self::members().contains(who) } + /// Add a new proposal to be voted. + pub fn do_propose( + who: T::AccountId, + threshold: MemberCount, + proposal: >::Proposal, + ) -> Result { + let proposal_hash = T::Hashing::hash_of(&proposal); + ensure!(!>::contains_key(proposal_hash), Error::::DuplicateProposal); + + let active_proposals = + >::try_mutate(|proposals| -> Result { + proposals.try_push(proposal_hash).map_err(|_| Error::::TooManyProposals)?; + Ok(proposals.len()) + })?; + + let index = Self::proposal_count(); + >::mutate(|i| *i += 1); + >::insert(proposal_hash, proposal); + let votes = { + let end = frame_system::Pallet::::block_number() + T::MotionDuration::get(); + Votes { index, threshold, ayes: vec![], nays: vec![], end } + }; + >::insert(proposal_hash, votes); + + Self::deposit_event(Event::Proposed(who, index, proposal_hash, threshold)); + Ok(active_proposals as u32) + } + + /// Add an aye or nay vote for the member to the given proposal, returns true if it's the first + /// vote of the member in the motion + pub fn do_vote( + who: T::AccountId, + proposal: T::Hash, + index: ProposalIndex, + approve: bool, + ) -> Result { + let mut voting = Self::voting(&proposal).ok_or(Error::::ProposalMissing)?; + ensure!(voting.index == index, Error::::WrongIndex); + + let position_yes = voting.ayes.iter().position(|a| a == &who); + let position_no = voting.nays.iter().position(|a| a == &who); + + // Detects first vote of the member in the motion + let is_account_voting_first_time = position_yes.is_none() && position_no.is_none(); + + if approve { + if position_yes.is_none() { + voting.ayes.push(who.clone()); + } else { + return Err(Error::::DuplicateVote.into()) + } + if let Some(pos) = position_no { + voting.nays.swap_remove(pos); + } + } else { + if position_no.is_none() { + voting.nays.push(who.clone()); + } else { + return Err(Error::::DuplicateVote.into()) + } + if let Some(pos) = position_yes { + voting.ayes.swap_remove(pos); + } + } + + let yes_votes = voting.ayes.len() as MemberCount; + let no_votes = voting.nays.len() as MemberCount; + Self::deposit_event(Event::Voted(who, proposal, approve, yes_votes, no_votes)); + + Voting::::insert(&proposal, voting); + + Ok(is_account_voting_first_time) + } + + /// Close a vote that is either approved, disapproved or whose voting period has ended. + pub fn do_close( + proposal_hash: T::Hash, + index: ProposalIndex, + proposal_weight_bound: Weight, + length_bound: u32 + ) -> DispatchResultWithPostInfo { + let voting = Self::voting(&proposal_hash).ok_or(Error::::ProposalMissing)?; + ensure!(voting.index == index, Error::::WrongIndex); + + let mut no_votes = voting.nays.len() as MemberCount; + let mut yes_votes = voting.ayes.len() as MemberCount; + let seats = Self::members().len() as MemberCount; + let approved = yes_votes >= voting.threshold; + let disapproved = seats.saturating_sub(no_votes) < voting.threshold; + // Allow (dis-)approving the proposal as soon as there are enough votes. + if approved { + let (proposal, len) = Self::validate_and_get_proposal( + &proposal_hash, + length_bound, + proposal_weight_bound, + )?; + Self::deposit_event(Event::Closed(proposal_hash, yes_votes, no_votes)); + let (proposal_weight, proposal_count) = + Self::do_approve_proposal(seats, yes_votes, proposal_hash, proposal); + return Ok(( + Some( + T::WeightInfo::close_early_approved(len as u32, seats, proposal_count) + .saturating_add(proposal_weight), + ), + Pays::Yes, + ) + .into()) + } else if disapproved { + Self::deposit_event(Event::Closed(proposal_hash, yes_votes, no_votes)); + let proposal_count = Self::do_disapprove_proposal(proposal_hash); + return Ok(( + Some(T::WeightInfo::close_early_disapproved(seats, proposal_count)), + Pays::No, + ) + .into()) + } + + // Only allow actual closing of the proposal after the voting period has ended. + ensure!( + frame_system::Pallet::::block_number() >= voting.end, + Error::::TooEarly + ); + + let prime_vote = Self::prime().map(|who| voting.ayes.iter().any(|a| a == &who)); + + // default voting strategy. + let default = T::DefaultVote::default_vote(prime_vote, yes_votes, no_votes, seats); + + let abstentions = seats - (yes_votes + no_votes); + match default { + true => yes_votes += abstentions, + false => no_votes += abstentions, + } + let approved = yes_votes >= voting.threshold; + + if approved { + let (proposal, len) = Self::validate_and_get_proposal( + &proposal_hash, + length_bound, + proposal_weight_bound, + )?; + Self::deposit_event(Event::Closed(proposal_hash, yes_votes, no_votes)); + let (proposal_weight, proposal_count) = + Self::do_approve_proposal(seats, yes_votes, proposal_hash, proposal); + Ok(( + Some( + T::WeightInfo::close_approved(len as u32, seats, proposal_count) + .saturating_add(proposal_weight), + ), + Pays::Yes, + ) + .into()) + } else { + Self::deposit_event(Event::Closed(proposal_hash, yes_votes, no_votes)); + let proposal_count = Self::do_disapprove_proposal(proposal_hash); + Ok((Some(T::WeightInfo::close_disapproved(seats, proposal_count)), Pays::No).into()) + } + } + /// Ensure that the right proposal bounds were passed and get the proposal from storage. /// /// Checks the length in storage via `storage::read` which adds an extra `size_of::() == 4` @@ -879,7 +905,8 @@ impl, I: 'static> Pallet { (proposal_weight, proposal_count) } - fn do_disapprove_proposal(proposal_hash: T::Hash) -> u32 { + /// Removes a proposal from the pallet, and deposit the `Disapproved` event. + pub fn do_disapprove_proposal(proposal_hash: T::Hash) -> u32 { // disapproved Self::deposit_event(Event::Disapproved { proposal_hash }); Self::remove_proposal(proposal_hash) From f12601de749bf11bf6c6628b4faaed382b5a15a7 Mon Sep 17 00:00:00 2001 From: koushiro Date: Fri, 17 Sep 2021 20:08:22 +0800 Subject: [PATCH 02/72] Update multihash/cid and format Signed-off-by: koushiro --- Cargo.lock | 4 +- frame/alliance/src/tests.rs | 6 +- frame/alliance/src/types.rs | 225 ------------------------------------ frame/collective/src/lib.rs | 7 +- 4 files changed, 5 insertions(+), 237 deletions(-) delete mode 100644 frame/alliance/src/types.rs diff --git a/Cargo.lock b/Cargo.lock index f0feea0d5756d..fa449503ffb38 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4659,7 +4659,7 @@ dependencies = [ [[package]] name = "multihash" version = "0.14.0" -source = "git+https://github.com/patractlabs/rust-multihash?branch=alliance#7dc4858d2f07c9e377be05393cc5acb84368f7bb" +source = "git+https://github.com/patractlabs/rust-multihash?branch=alliance#3c581326467e65401c70a887a631f33a2db0a1d3" dependencies = [ "blake2b_simd", "blake2s_simd", @@ -4690,7 +4690,7 @@ dependencies = [ [[package]] name = "multihash-derive" version = "0.7.2" -source = "git+https://github.com/patractlabs/rust-multihash?branch=alliance#7dc4858d2f07c9e377be05393cc5acb84368f7bb" +source = "git+https://github.com/patractlabs/rust-multihash?branch=alliance#3c581326467e65401c70a887a631f33a2db0a1d3" dependencies = [ "proc-macro-crate 1.0.0", "proc-macro-error 1.0.4", diff --git a/frame/alliance/src/tests.rs b/frame/alliance/src/tests.rs index 3ff0296c873f4..885f403dee2a3 100644 --- a/frame/alliance/src/tests.rs +++ b/frame/alliance/src/tests.rs @@ -417,20 +417,17 @@ fn remove_blacklist_works() { }); } -/* mod cid_tests { use cid::{ multibase::Base, multihash::{Code, MultihashDigest}, - CidGeneric, Version, + Cid, Version, }; use codec::{Decode, Encode}; use hex_literal::hex; const RAW: u64 = 0x55; - type Cid = CidGeneric<32>; - #[test] fn normal_test_for_example() { let cid = "QmRZdc3mAMXpv6Akz9Ekp1y4vDSjazTx2dCQRkxVy1yUj6".parse::().unwrap(); @@ -504,4 +501,3 @@ mod cid_tests { assert_cid!(cid, 16); } } -*/ diff --git a/frame/alliance/src/types.rs b/frame/alliance/src/types.rs deleted file mode 100644 index 7d7c73004e0a9..0000000000000 --- a/frame/alliance/src/types.rs +++ /dev/null @@ -1,225 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use codec::{Decode, Encode, EncodeLike, Error, Input, Output}; -use sp_runtime::RuntimeDebug; -use sp_std::{ops::Deref, vec}; - -/// A wrapped Cid for source Cid struct, to implement a valid encode/decode for Cid. -/// -/// This file will be used until this pr is merged: -/// https://github.com/multiformats/rust-multihash/pull/116 -/// For now, the source Cid use a static length `U64(H256)` for all Cid type, if we use the source -/// Cid encode/decode, it will add lots of empty zero in the result. -/// -/// e.g. -/// In the most widely used Cid type in IPFS, like: -/// QmRZdc3mAMXpv6Akz9Ekp1y4vDSjazTx2dCQRkxVy1yUj6 -/// If we use the source Cid to do encode, it will be: -/// 00-7000000000000000-1200000000000000-20-2fe65ccc17fe180c3bf4e9b8490fcc6dc74c30bf6595795dcd1136d8d9cb3f950000000000000000000000000000000000000000000000000000000000000000 -/// |Version|-|codec:u64|-|MultiHash| -/// |codec:u64| - |size:u8| - |digest| -/// We can see that ths digest part contains lots of zero for current digest in MultiHash is `[u8; -/// 64]`, However the generic hash length is 32. So the default encode/decode method wastes a lot of -/// space. -/// -/// And in pr#116 which is list above, the static length will be changed for multihash. Thus the -/// encode/decode method will be suitable for different Cid type. -/// So we consider this pr, decide to implement a encode/decode method for Cid which will be -/// **compatible** with the modification in pr#116. -/// -/// In our encode/decode, for the last part `digest`, we write the **raw value** to buffer and -/// read it from buffer **directly**, and do not add other byte like hint size or else. -/// The `code` and `size` is encoded/decoded in normal way. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RuntimeDebug)] -pub struct Cid(cid::Cid); - -impl Cid { - pub fn new(cid: cid::Cid) -> Self { - Self(cid) - } -} - -impl Encode for Cid { - fn encode_to(&self, dest: &mut EncOut) { - // for cid - self.version().encode_to(dest); - self.codec().encode_to(dest); - // for multihash - let hash = self.hash(); - let code = hash.code(); - let size = hash.size(); - let digest = hash.digest(); - - code.encode_to(dest); - size.encode_to(dest); - // notice we write the digest directly to dest, for we have known the size. - // **IMPORTANT** - // we do not choose to encode &[u8] directly, for it will add compact length at start. - // - // in a valid cid, digest.len() must equal to `size`. Thus, in Decode, - // we can just read a raw bytes which length is equal to `size`. - dest.write(digest) - } -} - -impl EncodeLike for Cid {} - -impl Decode for Cid { - fn decode(input: &mut I) -> Result { - use cid::{ - multihash::{MultihashGeneric, U64}, - Version, - }; - - type Multihash = MultihashGeneric; - - // for cid - let version: Version = Decode::decode(input)?; - let codec: u64 = Decode::decode(input)?; - // for multihash - let code: u64 = Decode::decode(input)?; - let size: u8 = Decode::decode(input)?; - let mut buf = vec![0; size as usize]; - // In a valid Cid, the size must equal to this raw buffer. - input.read(&mut buf)?; - let hash = Multihash::wrap(code, &buf).map_err(|_| "Multihash parse error")?; - Ok(Cid::new(cid::Cid::new(version, codec, hash).map_err(|_| "Cid parse error")?)) - } -} - -impl Into for Cid { - fn into(self) -> cid::Cid { - self.0 - } -} - -impl From for Cid { - fn from(cid: cid::Cid) -> Self { - Cid::new(cid) - } -} - -impl AsRef for Cid { - fn as_ref(&self) -> &cid::Cid { - &self.0 - } -} - -impl AsMut for Cid { - fn as_mut(&mut self) -> &mut cid::Cid { - &mut self.0 - } -} - -impl Deref for Cid { - type Target = cid::Cid; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -#[cfg(test)] -mod tests { - use super::*; - - use cid::{ - multibase::Base, - multihash::{Code, MultihashDigest}, - Version, - }; - use sp_std::{convert::TryFrom, str::FromStr}; - - const RAW: u64 = 0x55; - - #[test] - fn normal_test_for_example() { - let s = "QmRZdc3mAMXpv6Akz9Ekp1y4vDSjazTx2dCQRkxVy1yUj6"; - let cid: Cid = cid::Cid::from_str(s).expect("must be valid.").into(); - let bytes = cid.encode(); - let expect = hex_literal::hex!("0070000000000000001200000000000000202fe65ccc17fe180c3bf4e9b8490fcc6dc74c30bf6595795dcd1136d8d9cb3f95"); - assert_eq!(bytes, expect); - let new_cid: Cid = Decode::decode(&mut &bytes[..]).expect("must decode well"); - assert_eq!(new_cid, cid); - } - - macro_rules! assert_cid { - ($cid:expr, $length:expr) => { - let mut digest = [0_u8; $length]; - digest.copy_from_slice($cid.hash().digest()); - let raw = - ($cid.version(), $cid.codec(), ($cid.hash().code(), $cid.hash().size(), digest)); - let raw_encode = Encode::encode(&raw); - let bytes = $cid.encode(); - assert_eq!(bytes, raw_encode); - let new_cid: Cid = Decode::decode(&mut &bytes[..]).expect("must decode well"); - assert_eq!(new_cid, $cid); - }; - } - // those test case is from crate rust-cid - #[test] - fn v0_handling() { - let old = "QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n"; - let cid: Cid = cid::Cid::try_from(old).expect("must be valid.").into(); - - assert_eq!(cid.version(), Version::V0); - assert_eq!(cid.to_string(), old); - - // for Cid v0 hash is 32 length - assert_cid!(cid, 32); - } - - #[test] - fn v1_handling() { - let expected_cid = "bafkreibme22gw2h7y2h7tg2fhqotaqjucnbc24deqo72b6mkl2egezxhvy"; - let cid: Cid = cid::Cid::new_v1(RAW, Code::Sha2_256.digest(b"foo")).into(); - assert_eq!(cid.to_string_of_base(Base::Base32Lower).unwrap(), expected_cid); - - // for sha256 hash is 32 length - assert_cid!(cid, 32); - } - - // test case from https://github.com/ipfs/go-cid/blob/master/cid_test.go#L662 - #[test] - fn v1_handling2() { - let cid1: Cid = - cid::Cid::from_str("k2cwueckqkibutvhkr4p2ln2pjcaxaakpd9db0e7j7ax1lxhhxy3ekpv") - .expect("must valid") - .into(); - let cid2: Cid = cid::Cid::from_str("zb2rhZi1JR4eNc2jBGaRYJKYM8JEB4ovenym8L1CmFsRAytkz") - .expect("must valid") - .into(); - assert_cid!(cid1, 32); - assert_cid!(cid2, 32); - } - - #[test] - fn v1_handling3() { - let cid: Cid = cid::Cid::new_v1(RAW, Code::Sha2_512.digest(b"foo")).into(); - assert_cid!(cid, 64); - - let cid: Cid = cid::Cid::new_v1(RAW, Code::Keccak384.digest(b"foo")).into(); - assert_cid!(cid, 48); - - let cid: Cid = cid::Cid::new_v1(RAW, Code::Sha3_224.digest(b"foo")).into(); - assert_cid!(cid, 28); - - let cid: Cid = cid::Cid::new_v1(RAW, Code::Blake2s128.digest(b"foo")).into(); - assert_cid!(cid, 16); - } -} diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index a1acff00d7222..c3ce503098165 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -769,7 +769,7 @@ impl, I: 'static> Pallet { proposal_hash: T::Hash, index: ProposalIndex, proposal_weight_bound: Weight, - length_bound: u32 + length_bound: u32, ) -> DispatchResultWithPostInfo { let voting = Self::voting(&proposal_hash).ok_or(Error::::ProposalMissing)?; ensure!(voting.index == index, Error::::WrongIndex); @@ -808,10 +808,7 @@ impl, I: 'static> Pallet { } // Only allow actual closing of the proposal after the voting period has ended. - ensure!( - frame_system::Pallet::::block_number() >= voting.end, - Error::::TooEarly - ); + ensure!(frame_system::Pallet::::block_number() >= voting.end, Error::::TooEarly); let prime_vote = Self::prime().map(|who| voting.ayes.iter().any(|a| a == &who)); From 0d93dd6bef7fa742774710150a369d932ca5d513 Mon Sep 17 00:00:00 2001 From: koushiro Date: Sat, 18 Sep 2021 10:03:44 +0800 Subject: [PATCH 03/72] Remove useless deps Signed-off-by: koushiro --- Cargo.lock | 5 ----- frame/alliance/Cargo.toml | 1 - 2 files changed, 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fa449503ffb38..d9282d8fe7273 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4645,14 +4645,10 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "752a61cd890ff691b4411423d23816d5866dd5621e4d1c5687a53b94b5a979d8" dependencies = [ - "blake2b_simd", - "blake2s_simd", - "blake3", "digest 0.9.0", "generic-array 0.14.4", "multihash-derive 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.9.3", - "sha3", "unsigned-varint 0.7.0", ] @@ -5496,7 +5492,6 @@ dependencies = [ "frame-system", "hex-literal", "log 0.4.14", - "multihash 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "pallet-balances", "pallet-collective", "parity-scale-codec", diff --git a/frame/alliance/Cargo.toml b/frame/alliance/Cargo.toml index f888fb22536b3..ac9cc273bbbb0 100644 --- a/frame/alliance/Cargo.toml +++ b/frame/alliance/Cargo.toml @@ -31,7 +31,6 @@ frame-system = { version = "4.0.0-dev", default-features = false, path = "../sys [dev-dependencies] cid = { git = "https://github.com/patractlabs/rust-cid", branch = "alliance" } hex-literal = "0.3.1" -multihash = "0.14.0" pallet-balances = { version = "4.0.0-dev", path = "../balances" } pallet-collective = { version = "4.0.0-dev", path = "../collective" } From 3bfc260f2241dc6372e75073dd384ef7efad49ae Mon Sep 17 00:00:00 2001 From: koushiro Date: Sat, 18 Sep 2021 13:48:19 +0800 Subject: [PATCH 04/72] Add pallet-alliance into node runtime Signed-off-by: koushiro --- Cargo.lock | 12 ++-- bin/node/runtime/Cargo.toml | 4 ++ bin/node/runtime/src/impls.rs | 73 ++++++++++++++++++++++-- bin/node/runtime/src/lib.rs | 101 +++++++++++++++++++++++++++++++++- frame/alliance/src/lib.rs | 39 ++++++------- frame/alliance/src/mock.rs | 10 ++-- frame/identity/src/lib.rs | 18 ++++-- frame/identity/src/types.rs | 36 +++++++++++- 8 files changed, 251 insertions(+), 42 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d9282d8fe7273..5ae5839a4a60f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1856,18 +1856,18 @@ dependencies = [ [[package]] name = "enumflags2" -version = "0.6.4" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c8d82922337cd23a15f88b70d8e4ef5f11da38dd7cdb55e84dd5de99695da0" +checksum = "a8672257d642ffdd235f6e9c723c2326ac1253c8f3c022e7cfd2e57da55b1131" dependencies = [ "enumflags2_derive", ] [[package]] name = "enumflags2_derive" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "946ee94e3dbf58fdd324f9ce245c7b238d46a66f00e86a020b71996349e46cce" +checksum = "33526f770a27828ce7c2792fdb7cb240220237e0ff12933ed6c23957fc5dd7cf" dependencies = [ "proc-macro2", "quote", @@ -5032,7 +5032,11 @@ dependencies = [ "hex-literal", "log 0.4.14", "node-primitives", +<<<<<<< HEAD "pallet-asset-tx-payment", +======= + "pallet-alliance", +>>>>>>> 4a8ad01901 (Add pallet-alliance into node runtime) "pallet-assets", "pallet-authority-discovery", "pallet-authorship", diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index 0572345fa0c89..b1256f684b33a 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -51,6 +51,7 @@ frame-system-benchmarking = { version = "4.0.0-dev", default-features = false, p frame-election-provider-support = { version = "4.0.0-dev", default-features = false, path = "../../../frame/election-provider-support" } frame-system-rpc-runtime-api = { version = "4.0.0-dev", default-features = false, path = "../../../frame/system/rpc/runtime-api/" } frame-try-runtime = { version = "0.10.0-dev", default-features = false, path = "../../../frame/try-runtime", optional = true } +pallet-alliance = { version = "4.0.0-dev", default-features = false, path = "../../../frame/alliance" } pallet-assets = { version = "4.0.0-dev", default-features = false, path = "../../../frame/assets" } pallet-authority-discovery = { version = "4.0.0-dev", default-features = false, path = "../../../frame/authority-discovery" } pallet-authorship = { version = "4.0.0-dev", default-features = false, path = "../../../frame/authorship" } @@ -181,12 +182,14 @@ std = [ "sp-npos-elections/std", "sp-io/std", "pallet-child-bounties/std", + "pallet-alliance/std", ] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "pallet-alliance/runtime-benchmarks", "pallet-assets/runtime-benchmarks", "pallet-babe/runtime-benchmarks", "pallet-bags-list/runtime-benchmarks", @@ -232,6 +235,7 @@ try-runtime = [ "frame-executive/try-runtime", "frame-try-runtime", "frame-system/try-runtime", + "pallet-alliance/try-runtime", "pallet-assets/try-runtime", "pallet-authority-discovery/try-runtime", "pallet-authorship/try-runtime", diff --git a/bin/node/runtime/src/impls.rs b/bin/node/runtime/src/impls.rs index f73443920c213..23f8c3dd8f6b6 100644 --- a/bin/node/runtime/src/impls.rs +++ b/bin/node/runtime/src/impls.rs @@ -17,11 +17,15 @@ //! Some configurable implementations as associated type for the substrate runtime. -use crate::{AccountId, Assets, Authorship, Balances, NegativeImbalance, Runtime}; -use frame_support::traits::{ - fungibles::{Balanced, CreditOf}, - Currency, OnUnbalanced, +use crate::{AllianceMotion, Authorship, Balances, Call, Identity, NegativeImbalance}; +use frame_support::{ + dispatch::{DispatchError, DispatchResultWithPostInfo}, + traits::{Currency, OnUnbalanced}, + weights::Weight, }; +use node_primitives::{AccountId, Hash}; +use pallet_alliance::{IdentityVerifier, ProposalIndex, ProposalProvider}; +use pallet_identity::Judgement; use pallet_asset_tx_payment::HandleCredit; pub struct Author; @@ -45,6 +49,67 @@ impl HandleCredit for CreditToBlockAuthor { } } +pub struct AllianceIdentityVerifier; +impl IdentityVerifier for AllianceIdentityVerifier { + fn super_account_id(who: &AccountId) -> Option { + Identity::super_of(who).map(|parent| parent.0) + } + + fn has_identity(who: &AccountId, fields: u64) -> bool { + Identity::has_identity(who, fields) + } + + fn has_good_judgement(who: &AccountId) -> bool { + if let Some(judgements) = + Identity::identity(who).map(|registration| registration.judgements) + { + judgements + .iter() + .filter(|(_, j)| Judgement::KnownGood == *j || Judgement::Reasonable == *j) + .count() > 0 + } else { + false + } + } +} + +pub struct AllianceProposalProvider; +impl ProposalProvider for AllianceProposalProvider { + fn propose_proposal( + who: AccountId, + threshold: u32, + proposal: Call, + ) -> Result { + AllianceMotion::do_propose(who, threshold, proposal) + } + + fn vote_proposal( + who: AccountId, + proposal: Hash, + index: ProposalIndex, + approve: bool, + ) -> Result { + AllianceMotion::do_vote(who, proposal, index, approve) + } + + fn veto_proposal(proposal_hash: Hash) -> u32 { + AllianceMotion::do_disapprove_proposal(proposal_hash) + } + + fn close_proposal( + proposal_hash: Hash, + proposal_index: ProposalIndex, + proposal_weight_bound: Weight, + length_bound: u32, + ) -> DispatchResultWithPostInfo { + AllianceMotion::do_close(proposal_hash, proposal_index, proposal_weight_bound, length_bound) + } + + fn proposal_of(proposal_hash: Hash) -> Option { + AllianceMotion::proposal_of(proposal_hash) + } +} + #[cfg(test)] mod multiplier_tests { use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment}; diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index f12bf8a88365f..2a0fbd1cabe36 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -85,7 +85,7 @@ pub use sp_runtime::BuildStorage; /// Implementations of some helper traits passed into runtime modules as associated types. pub mod impls; -use impls::{Author, CreditToBlockAuthor}; +use impls::{AllianceIdentityVerifier, AllianceProposalProvider, Author, CreditToBlockAuthor}; /// Constant values used within the runtime. pub mod constants; @@ -1358,6 +1358,7 @@ impl pallet_transaction_storage::Config for Runtime { type WeightInfo = pallet_transaction_storage::weights::SubstrateWeight; } +<<<<<<< HEAD impl pallet_whitelist::Config for Runtime { type Event = Event; type Call = Call; @@ -1387,6 +1388,46 @@ impl pallet_state_trie_migration::Config for Runtime { // migrations. type SignedFilter = EnsureSigned; type WeightInfo = (); +======= +parameter_types! { + pub const AllianceMotionDuration: BlockNumber = 5 * DAYS; + pub const AllianceMaxProposals: u32 = 100; + pub const AllianceMaxMembers: u32 = 100; +} + +type AllianceCollective = pallet_collective::Instance3; +impl pallet_collective::Config for Runtime { + type Origin = Origin; + type Proposal = Call; + type Event = Event; + type MotionDuration = AllianceMotionDuration; + type MaxProposals = AllianceMaxProposals; + type MaxMembers = AllianceMaxMembers; + type DefaultVote = pallet_collective::PrimeDefaultVote; + type WeightInfo = pallet_collective::weights::SubstrateWeight; +} + +parameter_types! { + pub const MaxBlacklistCount: u32 = 100; +} + +impl pallet_alliance::Config for Runtime { + type Event = Event; + type Proposal = Call; + type SuperMajorityOrigin = EnsureOneOf< + AccountId, + EnsureRoot, + pallet_collective::EnsureProportionMoreThan<_2, _3, AccountId, AllianceCollective>, + >; + type Currency = Balances; + type InitializeMembers = AllianceMotion; + type MembershipChanged = AllianceMotion; + type Slashed = Treasury; + type IdentityVerifier = AllianceIdentityVerifier; + type ProposalProvider = AllianceProposalProvider; + type MaxBlacklistCount = MaxBlacklistCount; + type CandidateDeposit = CandidateDeposit; +>>>>>>> 4a8ad01901 (Add pallet-alliance into node runtime) } construct_runtime!( @@ -1422,6 +1463,7 @@ construct_runtime!( AuthorityDiscovery: pallet_authority_discovery, Offences: pallet_offences, Historical: pallet_session_historical::{Pallet}, +<<<<<<< HEAD RandomnessCollectiveFlip: pallet_randomness_collective_flip, Identity: pallet_identity, Society: pallet_society, @@ -1445,6 +1487,26 @@ construct_runtime!( Referenda: pallet_referenda, ConvictionVoting: pallet_conviction_voting, Whitelist: pallet_whitelist, +======= + RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage}, + Identity: pallet_identity::{Pallet, Call, Storage, Event}, + Society: pallet_society::{Pallet, Call, Storage, Event, Config}, + Recovery: pallet_recovery::{Pallet, Call, Storage, Event}, + Vesting: pallet_vesting::{Pallet, Call, Storage, Event, Config}, + Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event}, + Proxy: pallet_proxy::{Pallet, Call, Storage, Event}, + Multisig: pallet_multisig::{Pallet, Call, Storage, Event}, + Bounties: pallet_bounties::{Pallet, Call, Storage, Event}, + Tips: pallet_tips::{Pallet, Call, Storage, Event}, + Assets: pallet_assets::{Pallet, Call, Storage, Event}, + Mmr: pallet_mmr::{Pallet, Storage}, + Lottery: pallet_lottery::{Pallet, Call, Storage, Event}, + Gilt: pallet_gilt::{Pallet, Call, Storage, Event, Config}, + Uniques: pallet_uniques::{Pallet, Call, Storage, Event}, + TransactionStorage: pallet_transaction_storage::{Pallet, Call, Storage, Inherent, Config, Event}, + AllianceMotion: pallet_collective::::{Pallet, Storage, Origin, Event}, + Alliance: pallet_alliance::{Pallet, Call, Storage, Event}, +>>>>>>> 4a8ad01901 (Add pallet-alliance into node runtime) } ); @@ -1884,6 +1946,43 @@ impl_runtime_apis! { let params = (&config, &whitelist); add_benchmarks!(params, batches); +<<<<<<< HEAD +======= + add_benchmark!(params, batches, pallet_assets, Assets); + add_benchmark!(params, batches, pallet_babe, Babe); + add_benchmark!(params, batches, pallet_balances, Balances); + add_benchmark!(params, batches, pallet_bounties, Bounties); + add_benchmark!(params, batches, pallet_collective, Council); + add_benchmark!(params, batches, pallet_contracts, Contracts); + add_benchmark!(params, batches, pallet_democracy, Democracy); + add_benchmark!(params, batches, pallet_election_provider_multi_phase, ElectionProviderMultiPhase); + add_benchmark!(params, batches, pallet_elections_phragmen, Elections); + add_benchmark!(params, batches, pallet_gilt, Gilt); + add_benchmark!(params, batches, pallet_grandpa, Grandpa); + add_benchmark!(params, batches, pallet_identity, Identity); + add_benchmark!(params, batches, pallet_im_online, ImOnline); + add_benchmark!(params, batches, pallet_indices, Indices); + add_benchmark!(params, batches, pallet_lottery, Lottery); + add_benchmark!(params, batches, pallet_membership, TechnicalMembership); + add_benchmark!(params, batches, pallet_mmr, Mmr); + add_benchmark!(params, batches, pallet_multisig, Multisig); + add_benchmark!(params, batches, pallet_offences, OffencesBench::); + add_benchmark!(params, batches, pallet_proxy, Proxy); + add_benchmark!(params, batches, pallet_scheduler, Scheduler); + add_benchmark!(params, batches, pallet_session, SessionBench::); + add_benchmark!(params, batches, pallet_staking, Staking); + add_benchmark!(params, batches, frame_system, SystemBench::); + add_benchmark!(params, batches, pallet_timestamp, Timestamp); + add_benchmark!(params, batches, pallet_tips, Tips); + add_benchmark!(params, batches, pallet_transaction_storage, TransactionStorage); + add_benchmark!(params, batches, pallet_treasury, Treasury); + add_benchmark!(params, batches, pallet_uniques, Uniques); + add_benchmark!(params, batches, pallet_utility, Utility); + add_benchmark!(params, batches, pallet_vesting, Vesting); + add_benchmark!(params, batches, pallet_alliance, Alliance); + + if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } +>>>>>>> 4a8ad01901 (Add pallet-alliance into node runtime) Ok(batches) } } diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index 60529836bdc52..ad58d2895d7e3 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -135,16 +135,12 @@ type NegativeImbalanceOf = <>::Currency as Currency< ::AccountId, >>::NegativeImbalance; -const IDENTITY_FIELD_DISPLAY: u64 = - 0b0000000000000000000000000000000000000000000000000000000000000001; -const IDENTITY_FIELD_WEB: u64 = 0b0000000000000000000000000000000000000000000000000000000000000100; - pub trait IdentityVerifier { - fn super_account_id(who: &AccountId) -> Option; + fn has_identity(who: &AccountId, fields: u64) -> bool; - fn verify_identity(who: &AccountId, fields: u64) -> bool; + fn has_good_judgement(who: &AccountId) -> bool; - fn verify_judgement(who: &AccountId) -> bool; + fn super_account_id(who: &AccountId) -> Option; } pub trait ProposalProvider { @@ -276,12 +272,10 @@ pub mod pallet { KickingMember, /// Balance is insufficient to be a candidate. InsufficientCandidateFunds, - /// The account's identity has not been judged. - WithoutVerifiedIdentity, - /// The account's identity has not display field. - WithoutIdentityDisplay, - /// The account' identity has not website field. - WithoutIdentityWebsite, + /// The account's identity has not display field and website field. + WithoutIdentityDisplayAndWebsite, + /// The account's identity has no good judgement. + WithoutGoodIdentityJudgement, /// The proposal hash is not found. MissingProposalHash, /// The proposal is not vetoable. @@ -934,18 +928,19 @@ impl, I: 'static> Pallet { } fn has_identity(who: &T::AccountId) -> DispatchResult { - let judgement = |w: &T::AccountId| -> DispatchResult { - ensure!( - T::IdentityVerifier::verify_identity(w, IDENTITY_FIELD_DISPLAY), - Error::::WithoutIdentityDisplay - ); + const IDENTITY_FIELD_DISPLAY: u64 = + 0b0000000000000000000000000000000000000000000000000000000000000001; + const IDENTITY_FIELD_WEB: u64 = + 0b0000000000000000000000000000000000000000000000000000000000000100; + + let judgement = |who: &T::AccountId| -> DispatchResult { ensure!( - T::IdentityVerifier::verify_judgement(w), - Error::::WithoutVerifiedIdentity + T::IdentityVerifier::has_identity(who, IDENTITY_FIELD_DISPLAY | IDENTITY_FIELD_WEB), + Error::::WithoutIdentityDisplayAndWebsite ); ensure!( - T::IdentityVerifier::verify_identity(w, IDENTITY_FIELD_WEB), - Error::::WithoutIdentityWebsite + T::IdentityVerifier::has_good_judgement(who), + Error::::WithoutGoodIdentityJudgement ); Ok(()) }; diff --git a/frame/alliance/src/mock.rs b/frame/alliance/src/mock.rs index 49844ddd2dcba..ef9d1da0435f4 100644 --- a/frame/alliance/src/mock.rs +++ b/frame/alliance/src/mock.rs @@ -97,16 +97,16 @@ impl pallet_collective::Config for Test { pub struct AllianceIdentityVerifier; impl IdentityVerifier for AllianceIdentityVerifier { - fn super_account_id(_who: &u64) -> Option { - None + fn has_identity(_who: &u64, _fields: u64) -> bool { + true } - fn verify_identity(_who: &u64, _field: u64) -> bool { + fn has_good_judgement(_who: &u64) -> bool { true } - fn verify_judgement(_who: &u64) -> bool { - true + fn super_account_id(_who: &u64) -> Option { + None } } diff --git a/frame/identity/src/lib.rs b/frame/identity/src/lib.rs index 51e63541a89b1..c4fbcca73908c 100644 --- a/frame/identity/src/lib.rs +++ b/frame/identity/src/lib.rs @@ -88,6 +88,7 @@ pub use types::{ Data, IdentityField, IdentityFields, IdentityInfo, Judgement, RegistrarIndex, RegistrarInfo, Registration, }; +pub use weights::WeightInfo; type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; @@ -159,7 +160,7 @@ pub mod pallet { /// TWOX-NOTE: OK ― `AccountId` is a secure hash. #[pallet::storage] #[pallet::getter(fn identity)] - pub(super) type IdentityOf = StorageMap< + pub type IdentityOf = StorageMap< _, Twox64Concat, T::AccountId, @@ -171,7 +172,7 @@ pub mod pallet { /// context. If the account is not some other account's sub-identity, then just `None`. #[pallet::storage] #[pallet::getter(fn super_of)] - pub(super) type SuperOf = + pub type SuperOf = StorageMap<_, Blake2_128Concat, T::AccountId, (T::AccountId, Data), OptionQuery>; /// Alternative "sub" identities of this account. @@ -181,7 +182,7 @@ pub mod pallet { /// TWOX-NOTE: OK ― `AccountId` is a secure hash. #[pallet::storage] #[pallet::getter(fn subs_of)] - pub(super) type SubsOf = StorageMap< + pub type SubsOf = StorageMap< _, Twox64Concat, T::AccountId, @@ -195,7 +196,7 @@ pub mod pallet { /// The index into this can be cast to `RegistrarIndex` to get a valid value. #[pallet::storage] #[pallet::getter(fn registrars)] - pub(super) type Registrars = StorageValue< + pub type Registrars = StorageValue< _, BoundedVec, T::AccountId>>, T::MaxRegistrars>, ValueQuery, @@ -978,4 +979,13 @@ impl Pallet { .filter_map(|a| SuperOf::::get(&a).map(|x| (a, x.1))) .collect() } + + /// Check if the account has corresponding identity information by the identity field. + pub fn has_identity(who: &T::AccountId, fields: u64) -> bool { + if let Some(info) = IdentityOf::::get(who).map(|registration| registration.info) { + (info.fields().0.bits() & fields) == 1 + } else { + false + } + } } diff --git a/frame/identity/src/types.rs b/frame/identity/src/types.rs index cb79ace98d81c..61fefa3a6b3eb 100644 --- a/frame/identity/src/types.rs +++ b/frame/identity/src/types.rs @@ -17,7 +17,7 @@ use super::*; use codec::{Decode, Encode, MaxEncodedLen}; -use enumflags2::BitFlags; +use enumflags2::{bitflags, BitFlags}; use frame_support::{ traits::{ConstU32, Get}, BoundedVec, CloneNoBound, PartialEqNoBound, RuntimeDebugNoBound, @@ -230,8 +230,9 @@ impl> { pub twitter: Data, } +impl> IdentityInfo { + pub(crate) fn fields(&self) -> IdentityFields { + let mut res = >::empty(); + if self.display != Data::None { + res.insert(IdentityField::Display); + } + if self.legal != Data::None { + res.insert(IdentityField::Legal); + } + if self.web != Data::None { + res.insert(IdentityField::Web); + } + if self.riot != Data::None { + res.insert(IdentityField::Riot); + } + if self.email != Data::None { + res.insert(IdentityField::Email); + } + if self.pgp_fingerprint.is_some() { + res.insert(IdentityField::PgpFingerprint); + } + if self.image != Data::None { + res.insert(IdentityField::Image); + } + if self.twitter != Data::None { + res.insert(IdentityField::Twitter); + } + IdentityFields(res) + } +} + /// Information concerning the identity of the controller of an account. /// /// NOTE: This is stored separately primarily to facilitate the addition of extra fields in a From 445649e5d526afb7cbd31d9614974f7932382d9e Mon Sep 17 00:00:00 2001 From: koushiro Date: Wed, 22 Sep 2021 10:26:29 +0800 Subject: [PATCH 05/72] Fix has_identity Signed-off-by: koushiro --- frame/identity/src/lib.rs | 2 +- frame/identity/src/tests.rs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/frame/identity/src/lib.rs b/frame/identity/src/lib.rs index c4fbcca73908c..a513bfcc51cb6 100644 --- a/frame/identity/src/lib.rs +++ b/frame/identity/src/lib.rs @@ -983,7 +983,7 @@ impl Pallet { /// Check if the account has corresponding identity information by the identity field. pub fn has_identity(who: &T::AccountId, fields: u64) -> bool { if let Some(info) = IdentityOf::::get(who).map(|registration| registration.info) { - (info.fields().0.bits() & fields) == 1 + (info.fields().0.bits() & fields) == fields } else { false } diff --git a/frame/identity/src/tests.rs b/frame/identity/src/tests.rs index bf41b451cbaa3..8cb0563ebeaa1 100644 --- a/frame/identity/src/tests.rs +++ b/frame/identity/src/tests.rs @@ -500,3 +500,20 @@ fn setting_account_id_should_work() { assert_ok!(Identity::set_account_id(Origin::signed(4), 0, 3)); }); } + +#[test] +fn test_has_identity() { + new_test_ext().execute_with(|| { + assert_ok!(Identity::set_identity(Origin::signed(10), Box::new(ten()))); + assert!(Identity::has_identity(&10, IdentityField::Display as u64)); + assert!(Identity::has_identity(&10, IdentityField::Legal as u64)); + assert!(Identity::has_identity( + &10, + IdentityField::Display as u64 | IdentityField::Legal as u64 + )); + assert!(!Identity::has_identity( + &10, + IdentityField::Display as u64 | IdentityField::Legal as u64 | IdentityField::Web as u64 + )); + }); +} From 0d2eaee396be912a65472da9954fcaf497f3c676 Mon Sep 17 00:00:00 2001 From: koushiro Date: Tue, 5 Oct 2021 02:00:43 +0800 Subject: [PATCH 06/72] Add TooMantBlacklist Error Signed-off-by: koushiro --- frame/alliance/src/lib.rs | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index ad58d2895d7e3..e8a98f468855f 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -268,6 +268,8 @@ pub mod pallet { AlreadyInBlacklist, /// Not be a blacklist item. NotInBlacklist, + /// Number of blacklist exceed MaxBlacklist. + TooManyBlacklist, /// The member is kicking. KickingMember, /// Balance is insufficient to be a candidate. @@ -446,7 +448,7 @@ pub mod pallet { pub fn vote( origin: OriginFor, proposal: T::Hash, - index: ProposalIndex, + #[pallet::compact] index: ProposalIndex, approve: bool, ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; @@ -483,9 +485,9 @@ pub mod pallet { pub fn close( origin: OriginFor, proposal_hash: T::Hash, - index: ProposalIndex, - proposal_weight_bound: Weight, - length_bound: u32, + #[pallet::compact] index: ProposalIndex, + #[pallet::compact] proposal_weight_bound: Weight, + #[pallet::compact] length_bound: u32, ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; ensure!(Self::is_votable_member(&who), Error::::NotVotableMember); @@ -714,6 +716,7 @@ pub mod pallet { infos: Vec>, ) -> DispatchResultWithPostInfo { T::SuperMajorityOrigin::ensure_origin(origin)?; + let mut accounts = vec![]; let mut webs = vec![]; for info in infos.iter() { @@ -723,6 +726,18 @@ pub mod pallet { BlacklistItem::Website(url) => webs.push(url.clone()), } } + + let account_blacklist_len = AccountBlacklist::::decode_len().unwrap_or_default(); + ensure!( + (account_blacklist_len + accounts.len()) as u32 <= T::MaxBlacklistCount::get(), + Error::::TooManyBlacklist + ); + let web_blacklist_len = WebsiteBlacklist::::decode_len().unwrap_or_default(); + ensure!( + (web_blacklist_len + webs.len()) as u32 <= T::MaxBlacklistCount::get(), + Error::::TooManyBlacklist + ); + Self::do_add_blacklist(&mut accounts, &mut webs)?; Self::deposit_event(Event::BlacklistAdded(infos)); Ok(().into()) @@ -877,14 +892,12 @@ impl, I: 'static> Pallet { let mut accounts = >::get(); accounts.append(new_accounts); accounts.sort(); - Self::maybe_warn_max_blacklist(&accounts); AccountBlacklist::::put(accounts); } if !new_webs.is_empty() { let mut webs = >::get(); webs.append(new_webs); webs.sort(); - Self::maybe_warn_max_blacklist(&webs); WebsiteBlacklist::::put(webs); } Ok(()) @@ -901,7 +914,6 @@ impl, I: 'static> Pallet { let pos = accounts.binary_search(who).ok().ok_or(Error::::NotInBlacklist)?; accounts.remove(pos); } - Self::maybe_warn_max_blacklist(&accounts); AccountBlacklist::::put(accounts); } if !out_webs.is_empty() { @@ -910,23 +922,11 @@ impl, I: 'static> Pallet { let pos = webs.binary_search(web).ok().ok_or(Error::::NotInBlacklist)?; webs.remove(pos); } - Self::maybe_warn_max_blacklist(&webs); WebsiteBlacklist::::put(webs); } Ok(()) } - fn maybe_warn_max_blacklist(blacklist: &[B]) { - if blacklist.len() as u32 > T::MaxBlacklistCount::get() { - log::error!( - target: "runtime::alliance", - "maximum number of blacklist used for weight is exceeded, weights can be underestimated [{} > {}].", - blacklist.len(), - T::MaxBlacklistCount::get(), - ) - } - } - fn has_identity(who: &T::AccountId) -> DispatchResult { const IDENTITY_FIELD_DISPLAY: u64 = 0b0000000000000000000000000000000000000000000000000000000000000001; From b69980d9b25d02cfa2d870c1aa8106482d963f97 Mon Sep 17 00:00:00 2001 From: koushiro Date: Tue, 5 Oct 2021 02:12:09 +0800 Subject: [PATCH 07/72] Add TooLongWebsiteUrlLength Error Signed-off-by: koushiro --- bin/node/runtime/src/lib.rs | 2 ++ frame/alliance/src/lib.rs | 21 +++++++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 2a0fbd1cabe36..a0370d483af13 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1409,6 +1409,7 @@ impl pallet_collective::Config for Runtime { parameter_types! { pub const MaxBlacklistCount: u32 = 100; + pub const MaxWebsiteUrlLength: u32 = 255; } impl pallet_alliance::Config for Runtime { @@ -1426,6 +1427,7 @@ impl pallet_alliance::Config for Runtime { type IdentityVerifier = AllianceIdentityVerifier; type ProposalProvider = AllianceProposalProvider; type MaxBlacklistCount = MaxBlacklistCount; + type MaxWebsiteUrlLength = MaxWebsiteUrlLength; type CandidateDeposit = CandidateDeposit; >>>>>>> 4a8ad01901 (Add pallet-alliance into node runtime) } diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index e8a98f468855f..686209282200f 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -230,13 +230,14 @@ pub mod pallet { /// The provider of the proposal operation. type ProposalProvider: ProposalProvider; - /// The maximum number of blacklist supported by the pallet. Used for weight estimation. - /// - /// NOTE: - /// + Benchmarks will need to be re-run and weights adjusted if this changes. - /// + This pallet assumes that dependents keep to the limit without enforcing it. + /// The maximum number of blacklist supported by the pallet. + #[pallet::constant] type MaxBlacklistCount: Get; + /// The maximum length of website url. + #[pallet::constant] + type MaxWebsiteUrlLength: Get; + /// The amount of a deposit required for submitting candidacy. #[pallet::constant] type CandidateDeposit: Get>; @@ -270,6 +271,8 @@ pub mod pallet { NotInBlacklist, /// Number of blacklist exceed MaxBlacklist. TooManyBlacklist, + /// Length of website url exceed MaxWebsiteUrlLength. + TooLongWebsiteUrl, /// The member is kicking. KickingMember, /// Balance is insufficient to be a candidate. @@ -723,7 +726,13 @@ pub mod pallet { ensure!(!Self::is_blacklist(info), Error::::AlreadyInBlacklist); match info { BlacklistItem::AccountId(who) => accounts.push(who.clone()), - BlacklistItem::Website(url) => webs.push(url.clone()), + BlacklistItem::Website(url) => { + ensure!( + url.len() as u32 <= T::MaxWebsiteUrlLength::get(), + Error::::TooLongWebsiteUrl + ); + webs.push(url.clone()); + }, } } From 9cab7156ef998953c403acdeb325b2b641433a6e Mon Sep 17 00:00:00 2001 From: koushiro Date: Tue, 5 Oct 2021 02:57:22 +0800 Subject: [PATCH 08/72] Add remove_announcement Signed-off-by: koushiro --- frame/alliance/src/benchmarking.rs | 17 +++++++++++++++++ frame/alliance/src/lib.rs | 18 ++++++++++++++++++ frame/alliance/src/mock.rs | 2 ++ frame/alliance/src/tests.rs | 16 ++++++++++++++++ 4 files changed, 53 insertions(+) diff --git a/frame/alliance/src/benchmarking.rs b/frame/alliance/src/benchmarking.rs index fe7bc7e1d077a..68abbe3580e59 100644 --- a/frame/alliance/src/benchmarking.rs +++ b/frame/alliance/src/benchmarking.rs @@ -84,6 +84,10 @@ fn ally1, I: 'static>() -> T::AccountId { funded_account::("ally", 1) } +fn set_announcement, I: 'static>(cid: Cid) { + Announcements::::put(vec![cid]); +} + fn set_candidates, I: 'static>() { let candidates = vec![funded_account::("candidate", 1)]; candidates.iter().for_each(|who| { @@ -143,6 +147,19 @@ benchmarks_instance_pallet! { assert_last_event::(Event::NewAnnouncement(announcement).into()); } + remove_announcement { + set_members::(); + let announcement = test_cid(); + set_announcement::(announcement); + + let call = Call::::remove_announcement { announcement }; + let origin = T::SuperMajorityOrigin::successful_origin(); + }: { call.dispatch_bypass_filter(origin)? } + verify { + assert!(Alliance::::announcements().is_empty()); + assert_last_event::(Event::AnnouncementRemoved(announcement).into()); + } + submit_candidacy { set_members::(); diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index 686209282200f..c69910f6f9beb 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -285,6 +285,8 @@ pub mod pallet { MissingProposalHash, /// The proposal is not vetoable. NotVetoableProposal, + /// The Announcement is not found. + MissingAnnouncement, } #[pallet::event] @@ -294,6 +296,8 @@ pub mod pallet { NewRule(Cid), /// A new announcement has been proposed. \[announcement\] NewAnnouncement(Cid), + /// A on-chain announcement has been removed. \[announcement\] + AnnouncementRemoved(Cid), /// Some accounts have been initialized to founders. \[founders\] FoundersInitialized(Vec), /// An account has been added as a candidate and lock its deposit. \[candidate, nominator, @@ -571,6 +575,20 @@ pub mod pallet { Ok(().into()) } + /// Remove the announcement. + #[pallet::weight(0)] + pub fn remove_announcement(origin: OriginFor, announcement: Cid) -> DispatchResultWithPostInfo { + T::SuperMajorityOrigin::ensure_origin(origin)?; + + let mut announcements = >::get(); + let pos = announcements.binary_search(&announcement).ok().ok_or(Error::::MissingAnnouncement)?; + announcements.remove(pos); + >::put(announcements); + + Self::deposit_event(Event::AnnouncementRemoved(announcement)); + Ok(().into()) + } + /// Submit oneself for candidacy. /// Account must have enough transferable funds in it to pay the candidate deposit. #[pallet::weight(0)] diff --git a/frame/alliance/src/mock.rs b/frame/alliance/src/mock.rs index ef9d1da0435f4..b16a2213d2081 100644 --- a/frame/alliance/src/mock.rs +++ b/frame/alliance/src/mock.rs @@ -153,6 +153,7 @@ ord_parameter_types! { parameter_types! { pub const CandidateDeposit: u64 = 25; pub const MaxBlacklistCount: u32 = 100; + pub const MaxWebsiteUrlLength: u32 = 255; } impl Config for Test { type Event = Event; @@ -165,6 +166,7 @@ impl Config for Test { type IdentityVerifier = AllianceIdentityVerifier; type ProposalProvider = AllianceProposalProvider; type MaxBlacklistCount = MaxBlacklistCount; + type MaxWebsiteUrlLength = MaxWebsiteUrlLength; type CandidateDeposit = CandidateDeposit; } diff --git a/frame/alliance/src/tests.rs b/frame/alliance/src/tests.rs index 885f403dee2a3..cefe9ab0f972c 100644 --- a/frame/alliance/src/tests.rs +++ b/frame/alliance/src/tests.rs @@ -220,6 +220,22 @@ fn announce_works() { }); } +#[test] +fn remove_announcement_works() { + new_test_ext().execute_with(|| { + let cid = test_cid(); + assert_ok!(Alliance::announce(Origin::signed(1), cid)); + assert_eq!(Alliance::announcements(), vec![cid]); + System::assert_last_event(mock::Event::Alliance(crate::Event::NewAnnouncement(cid))); + + System::set_block_number(2); + + assert_ok!(Alliance::remove_announcement(Origin::signed(1), cid)); + assert_eq!(Alliance::announcements(), vec![]); + System::assert_last_event(mock::Event::Alliance(crate::Event::AnnouncementRemoved(cid))); + }); +} + #[test] fn submit_candidacy_works() { new_test_ext().execute_with(|| { From 9241f089d9fedac23e1377116285805ce657ea81 Mon Sep 17 00:00:00 2001 From: koushiro Date: Wed, 6 Oct 2021 00:49:34 +0800 Subject: [PATCH 09/72] Derive pallet_identity::Config and Fix test/benchmarking Signed-off-by: koushiro --- Cargo.lock | 74 ++++------------- bin/node/runtime/src/lib.rs | 35 ++------ frame/alliance/Cargo.toml | 12 ++- frame/alliance/src/benchmarking.rs | 93 ++++++++++++++------- frame/alliance/src/lib.rs | 52 ++++++------ frame/alliance/src/mock.rs | 111 ++++++++++++++++++++----- frame/alliance/src/tests.rs | 125 ++++++++--------------------- frame/alliance/src/types.rs | 76 ++++++++++++++++++ 8 files changed, 319 insertions(+), 259 deletions(-) create mode 100644 frame/alliance/src/types.rs diff --git a/Cargo.lock b/Cargo.lock index 5ae5839a4a60f..85c6c92de1e95 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -959,23 +959,11 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff0e3bc0b6446b3f9663c1a6aba6ef06c5aeaa1bc92bd18077be337198ab9768" dependencies = [ - "multibase 0.8.0", + "multibase", "multihash 0.13.2", "unsigned-varint 0.5.1", ] -[[package]] -name = "cid" -version = "0.7.0" -source = "git+https://github.com/patractlabs/rust-cid?branch=alliance#d5aaa1c115b52e75b1cd513a4b866912d944a6bd" -dependencies = [ - "multibase 0.9.1", - "multihash 0.14.0 (git+https://github.com/patractlabs/rust-multihash?branch=alliance)", - "parity-scale-codec", - "scale-info", - "unsigned-varint 0.7.0", -] - [[package]] name = "cipher" version = "0.3.0" @@ -3734,7 +3722,7 @@ dependencies = [ "libsecp256k1", "log 0.4.14", "multiaddr", - "multihash 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", + "multihash 0.14.0", "multistream-select", "parking_lot 0.11.2", "pin-project 1.0.10", @@ -4586,7 +4574,7 @@ dependencies = [ "bs58", "byteorder", "data-encoding", - "multihash 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", + "multihash 0.14.0", "percent-encoding 2.1.0", "serde", "static_assertions", @@ -4605,17 +4593,6 @@ dependencies = [ "data-encoding-macro", ] -[[package]] -name = "multibase" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404" -dependencies = [ - "base-x", - "data-encoding", - "data-encoding-macro", -] - [[package]] name = "multihash" version = "0.13.2" @@ -4627,12 +4604,16 @@ dependencies = [ "blake3", "digest 0.9.0", "generic-array 0.14.4", +<<<<<<< HEAD <<<<<<< HEAD "multihash-derive", "sha2 0.9.8", "sha3 0.9.1", ======= "multihash-derive 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", +======= + "multihash-derive", +>>>>>>> 4482b77565 (Derive pallet_identity::Config and Fix test/benchmarking) "sha2 0.9.3", "sha3", >>>>>>> 2369417073 (Add pallet-alliance) @@ -4647,25 +4628,8 @@ checksum = "752a61cd890ff691b4411423d23816d5866dd5621e4d1c5687a53b94b5a979d8" dependencies = [ "digest 0.9.0", "generic-array 0.14.4", - "multihash-derive 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.9.3", - "unsigned-varint 0.7.0", -] - -[[package]] -name = "multihash" -version = "0.14.0" -source = "git+https://github.com/patractlabs/rust-multihash?branch=alliance#3c581326467e65401c70a887a631f33a2db0a1d3" -dependencies = [ - "blake2b_simd", - "blake2s_simd", - "blake3", - "digest 0.9.0", - "multihash-derive 0.7.2 (git+https://github.com/patractlabs/rust-multihash?branch=alliance)", - "parity-scale-codec", - "scale-info", + "multihash-derive", "sha2 0.9.3", - "sha3", "unsigned-varint 0.7.0", ] @@ -4683,19 +4647,6 @@ dependencies = [ "synstructure", ] -[[package]] -name = "multihash-derive" -version = "0.7.2" -source = "git+https://github.com/patractlabs/rust-multihash?branch=alliance#3c581326467e65401c70a887a631f33a2db0a1d3" -dependencies = [ - "proc-macro-crate 1.0.0", - "proc-macro-error 1.0.4", - "proc-macro2", - "quote", - "syn", - "synstructure", -] - [[package]] name = "multimap" version = "0.8.2" @@ -5490,17 +5441,22 @@ dependencies = [ name = "pallet-alliance" version = "4.0.0-dev" dependencies = [ - "cid 0.7.0", "frame-benchmarking", "frame-support", "frame-system", + "hex", "hex-literal", "log 0.4.14", "pallet-balances", "pallet-collective", + "pallet-identity", "parity-scale-codec", "scale-info", +<<<<<<< HEAD >>>>>>> 2369417073 (Add pallet-alliance) +======= + "sha2 0.9.3", +>>>>>>> 4482b77565 (Derive pallet_identity::Config and Fix test/benchmarking) "sp-core", "sp-io", "sp-runtime", @@ -8716,7 +8672,7 @@ dependencies = [ "cid", ======= "bytes 1.0.1", - "cid 0.6.1", + "cid", "derive_more", >>>>>>> 2369417073 (Add pallet-alliance) "either", diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index a0370d483af13..0fbd4ad343d3e 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1358,7 +1358,6 @@ impl pallet_transaction_storage::Config for Runtime { type WeightInfo = pallet_transaction_storage::weights::SubstrateWeight; } -<<<<<<< HEAD impl pallet_whitelist::Config for Runtime { type Event = Event; type Call = Call; @@ -1388,7 +1387,8 @@ impl pallet_state_trie_migration::Config for Runtime { // migrations. type SignedFilter = EnsureSigned; type WeightInfo = (); -======= +} + parameter_types! { pub const AllianceMotionDuration: BlockNumber = 5 * DAYS; pub const AllianceMaxProposals: u32 = 100; @@ -1420,16 +1420,13 @@ impl pallet_alliance::Config for Runtime { EnsureRoot, pallet_collective::EnsureProportionMoreThan<_2, _3, AccountId, AllianceCollective>, >; - type Currency = Balances; type InitializeMembers = AllianceMotion; type MembershipChanged = AllianceMotion; - type Slashed = Treasury; type IdentityVerifier = AllianceIdentityVerifier; type ProposalProvider = AllianceProposalProvider; type MaxBlacklistCount = MaxBlacklistCount; type MaxWebsiteUrlLength = MaxWebsiteUrlLength; type CandidateDeposit = CandidateDeposit; ->>>>>>> 4a8ad01901 (Add pallet-alliance into node runtime) } construct_runtime!( @@ -1465,7 +1462,6 @@ construct_runtime!( AuthorityDiscovery: pallet_authority_discovery, Offences: pallet_offences, Historical: pallet_session_historical::{Pallet}, -<<<<<<< HEAD RandomnessCollectiveFlip: pallet_randomness_collective_flip, Identity: pallet_identity, Society: pallet_society, @@ -1489,26 +1485,8 @@ construct_runtime!( Referenda: pallet_referenda, ConvictionVoting: pallet_conviction_voting, Whitelist: pallet_whitelist, -======= - RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage}, - Identity: pallet_identity::{Pallet, Call, Storage, Event}, - Society: pallet_society::{Pallet, Call, Storage, Event, Config}, - Recovery: pallet_recovery::{Pallet, Call, Storage, Event}, - Vesting: pallet_vesting::{Pallet, Call, Storage, Event, Config}, - Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event}, - Proxy: pallet_proxy::{Pallet, Call, Storage, Event}, - Multisig: pallet_multisig::{Pallet, Call, Storage, Event}, - Bounties: pallet_bounties::{Pallet, Call, Storage, Event}, - Tips: pallet_tips::{Pallet, Call, Storage, Event}, - Assets: pallet_assets::{Pallet, Call, Storage, Event}, - Mmr: pallet_mmr::{Pallet, Storage}, - Lottery: pallet_lottery::{Pallet, Call, Storage, Event}, - Gilt: pallet_gilt::{Pallet, Call, Storage, Event, Config}, - Uniques: pallet_uniques::{Pallet, Call, Storage, Event}, - TransactionStorage: pallet_transaction_storage::{Pallet, Call, Storage, Inherent, Config, Event}, - AllianceMotion: pallet_collective::::{Pallet, Storage, Origin, Event}, - Alliance: pallet_alliance::{Pallet, Call, Storage, Event}, ->>>>>>> 4a8ad01901 (Add pallet-alliance into node runtime) + AllianceMotion: pallet_collective::, + Alliance: pallet_alliance, } ); @@ -1948,8 +1926,12 @@ impl_runtime_apis! { let params = (&config, &whitelist); add_benchmarks!(params, batches); +<<<<<<< HEAD <<<<<<< HEAD ======= +======= + add_benchmark!(params, batches, pallet_alliance, Alliance); +>>>>>>> 4482b77565 (Derive pallet_identity::Config and Fix test/benchmarking) add_benchmark!(params, batches, pallet_assets, Assets); add_benchmark!(params, batches, pallet_babe, Babe); add_benchmark!(params, batches, pallet_balances, Balances); @@ -1981,7 +1963,6 @@ impl_runtime_apis! { add_benchmark!(params, batches, pallet_uniques, Uniques); add_benchmark!(params, batches, pallet_utility, Utility); add_benchmark!(params, batches, pallet_vesting, Vesting); - add_benchmark!(params, batches, pallet_alliance, Alliance); if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } >>>>>>> 4a8ad01901 (Add pallet-alliance into node runtime) diff --git a/frame/alliance/Cargo.toml b/frame/alliance/Cargo.toml index ac9cc273bbbb0..d295d3dae8c34 100644 --- a/frame/alliance/Cargo.toml +++ b/frame/alliance/Cargo.toml @@ -13,7 +13,7 @@ readme = "README.md" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -cid = { git = "https://github.com/patractlabs/rust-cid", branch = "alliance", default-features = false, features = ["scale-codec","scale-info"] } +hex = { version = "0.4", default-features = false, features = ["alloc"], optional = true } log = { version = "0.4.14", default-features = false } codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive"] } @@ -24,20 +24,22 @@ sp-core = { version = "4.0.0-dev", default-features = false, path = "../../primi sp-io = { version = "4.0.0-dev", default-features = false, path = "../../primitives/io" } sp-runtime = { version = "4.0.0-dev", default-features = false, path = "../../primitives/runtime" } +pallet-identity = { version = "4.0.0-dev", path = "../identity", default-features = false } + frame-benchmarking = { version = "4.0.0-dev", default-features = false, path = "../benchmarking", optional = true } frame-support = { version = "4.0.0-dev", default-features = false, path = "../support" } frame-system = { version = "4.0.0-dev", default-features = false, path = "../system" } +pallet-collective = { version = "4.0.0-dev", path = "../collective", default-features = false, optional = true } [dev-dependencies] -cid = { git = "https://github.com/patractlabs/rust-cid", branch = "alliance" } hex-literal = "0.3.1" +sha2 = "0.9" pallet-balances = { version = "4.0.0-dev", path = "../balances" } pallet-collective = { version = "4.0.0-dev", path = "../collective" } [features] default = ["std"] std = [ - "cid/std", "log/std", "codec/std", "scale-info/std", @@ -47,14 +49,16 @@ std = [ "sp-runtime/std", "frame-support/std", "frame-system/std", + "pallet-identity/std", ] runtime-benchmarks = [ + "hex", "frame-benchmarking", "sp-runtime/runtime-benchmarks", "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", - "pallet-balances/runtime-benchmarks", "pallet-collective/runtime-benchmarks", + "pallet-identity/runtime-benchmarks", ] try-runtime = [ "frame-support/try-runtime", diff --git a/frame/alliance/src/benchmarking.rs b/frame/alliance/src/benchmarking.rs index 68abbe3580e59..45c1c8321b29e 100644 --- a/frame/alliance/src/benchmarking.rs +++ b/frame/alliance/src/benchmarking.rs @@ -17,11 +17,17 @@ //! Alliance pallet benchmarking. -use sp_runtime::traits::Zero; - -use frame_benchmarking::{account, benchmarks_instance_pallet, impl_benchmark_test_suite}; -use frame_support::traits::{EnsureOrigin, Get, UnfilteredDispatchable}; +use sp_runtime::traits::{Bounded, StaticLookup}; +use sp_std::{convert::TryInto, prelude::*}; + +use frame_benchmarking::{account, benchmarks_instance_pallet}; +use frame_support::{ + assert_ok, + traits::{EnsureOrigin, Get, UnfilteredDispatchable}, + BoundedVec, +}; use frame_system::RawOrigin; +use pallet_identity::{Data, IdentityInfo, Judgement, Pallet as Identity}; use super::{Pallet as Alliance, *}; @@ -32,16 +38,53 @@ fn assert_last_event, I: 'static>(generic_event: >:: } fn test_cid() -> Cid { - "QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n".parse().unwrap() + Cid::new_v0( + hex::decode("b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9").unwrap(), + ) +} + +fn registrar_account, I: 'static>() -> T::AccountId { + account("registrar", 0, SEED) +} + +fn create_registrar_account, I: 'static>() -> T::AccountId { + let registrar: T::AccountId = registrar_account::(); + let _ = T::Currency::make_free_balance_be(®istrar, BalanceOf::::max_value()); + assert_ok!(Identity::::add_registrar(RawOrigin::Root.into(), registrar.clone())); + registrar } fn funded_account, I: 'static>(name: &'static str, index: u32) -> T::AccountId { let account: T::AccountId = account(name, index, SEED); - T::Currency::make_free_balance_be(&account, T::CandidateDeposit::get() * 2u32.into()); + T::Currency::make_free_balance_be(&account, BalanceOf::::max_value()); + + let info = IdentityInfo { + additional: BoundedVec::default(), + display: Data::Raw(b"name".to_vec().try_into().unwrap()), + legal: Data::default(), + web: Data::Raw(b"website".to_vec().try_into().unwrap()), + riot: Data::default(), + email: Data::default(), + pgp_fingerprint: None, + image: Data::default(), + twitter: Data::default(), + }; + assert_ok!(Identity::::set_identity( + RawOrigin::Signed(account.clone()).into(), + Box::new(info.clone()) + )); + assert_ok!(Identity::::provide_judgement( + RawOrigin::Signed(registrar_account::()).into(), + 0, + T::Lookup::unlookup(account.clone()), + Judgement::KnownGood + )); account } fn set_members, I: 'static>() { + create_registrar_account::(); + let founders = vec![ funded_account::("founder", 1), funded_account::("founder", 2), @@ -127,11 +170,11 @@ benchmarks_instance_pallet! { set_members::(); let rule = test_cid(); - let call = Call::::set_rule { rule }; + let call = Call::::set_rule { rule: rule.clone() }; let origin = T::SuperMajorityOrigin::successful_origin(); }: { call.dispatch_bypass_filter(origin)? } verify { - assert_eq!(Alliance::::rule(), Some(rule)); + assert_eq!(Alliance::::rule(), Some(rule.clone())); assert_last_event::(Event::NewRule(rule).into()); } @@ -139,7 +182,7 @@ benchmarks_instance_pallet! { set_members::(); let announcement = test_cid(); - let call = Call::::announce { announcement }; + let call = Call::::announce { announcement: announcement.clone() }; let origin = T::SuperMajorityOrigin::successful_origin(); }: { call.dispatch_bypass_filter(origin)? } verify { @@ -150,9 +193,9 @@ benchmarks_instance_pallet! { remove_announcement { set_members::(); let announcement = test_cid(); - set_announcement::(announcement); + set_announcement::(announcement.clone()); - let call = Call::::remove_announcement { announcement }; + let call = Call::::remove_announcement { announcement: announcement.clone() }; let origin = T::SuperMajorityOrigin::successful_origin(); }: { call.dispatch_bypass_filter(origin)? } verify { @@ -166,12 +209,12 @@ benchmarks_instance_pallet! { let outsider = create_outsider::(); assert!(!Alliance::::is_member(&outsider)); assert!(!Alliance::::is_candidate(&outsider)); - assert_eq!(T::Currency::reserved_balance(&outsider), BalanceOf::::zero()); + assert_eq!(DepositOf::::get(&outsider), None); }: _(RawOrigin::Signed(outsider.clone())) verify { assert!(!Alliance::::is_member(&outsider)); assert!(Alliance::::is_candidate(&outsider)); - assert_eq!(T::Currency::reserved_balance(&outsider), T::CandidateDeposit::get()); + assert_eq!(DepositOf::::get(&outsider), Some(T::CandidateDeposit::get())); assert_last_event::(Event::CandidateAdded(outsider, None, Some(T::CandidateDeposit::get())).into()); } @@ -184,13 +227,14 @@ benchmarks_instance_pallet! { let outsider = create_outsider::(); assert!(!Alliance::::is_member(&outsider)); assert!(!Alliance::::is_candidate(&outsider)); - assert_eq!(T::Currency::reserved_balance(&outsider), BalanceOf::::zero()); + assert_eq!(DepositOf::::get(&outsider), None); + let outsider_lookup: ::Source = T::Lookup::unlookup(outsider.clone()); }: _(RawOrigin::Signed(founder1.clone()), outsider_lookup) verify { assert!(!Alliance::::is_member(&outsider)); assert!(Alliance::::is_candidate(&outsider)); - assert_eq!(T::Currency::reserved_balance(&outsider), BalanceOf::::zero()); + assert_eq!(DepositOf::::get(&outsider), None); assert_last_event::(Event::CandidateAdded(outsider, Some(founder1), None).into()); } @@ -201,8 +245,6 @@ benchmarks_instance_pallet! { let candidate1 = candidate1::(); assert!(Alliance::::is_candidate(&candidate1)); assert!(!Alliance::::is_member(&candidate1)); - - assert_eq!(T::Currency::reserved_balance(&candidate1), T::CandidateDeposit::get()); assert_eq!(DepositOf::::get(&candidate1), Some(T::CandidateDeposit::get())); let candidate1_lookup: ::Source = T::Lookup::unlookup(candidate1.clone()); @@ -212,7 +254,6 @@ benchmarks_instance_pallet! { verify { assert!(!Alliance::::is_candidate(&candidate1)); assert!(Alliance::::is_ally(&candidate1)); - assert_eq!(T::Currency::reserved_balance(&candidate1), T::CandidateDeposit::get()); assert_eq!(DepositOf::::get(&candidate1), Some(T::CandidateDeposit::get())); assert_last_event::(Event::CandidateApproved(candidate1).into()); } @@ -224,8 +265,6 @@ benchmarks_instance_pallet! { let candidate1 = candidate1::(); assert!(Alliance::::is_candidate(&candidate1)); assert!(!Alliance::::is_member(&candidate1)); - - assert_eq!(T::Currency::reserved_balance(&candidate1), T::CandidateDeposit::get()); assert_eq!(DepositOf::::get(&candidate1), Some(T::CandidateDeposit::get())); let candidate1_lookup: ::Source = T::Lookup::unlookup(candidate1.clone()); @@ -235,7 +274,6 @@ benchmarks_instance_pallet! { verify { assert!(!Alliance::::is_candidate(&candidate1)); assert!(!Alliance::::is_member(&candidate1)); - assert_eq!(T::Currency::reserved_balance(&candidate1), BalanceOf::::zero()); assert_eq!(DepositOf::::get(&candidate1), None); assert_last_event::(Event::CandidateRejected(candidate1).into()); } @@ -263,12 +301,10 @@ benchmarks_instance_pallet! { assert!(Alliance::::is_fellow(&fellow2)); assert!(!Alliance::::is_kicking(&fellow2)); - assert_eq!(T::Currency::reserved_balance(&fellow2), T::CandidateDeposit::get()); assert_eq!(DepositOf::::get(&fellow2), Some(T::CandidateDeposit::get())); }: _(RawOrigin::Signed(fellow2.clone())) verify { assert!(!Alliance::::is_member(&fellow2)); - assert_eq!(T::Currency::reserved_balance(&fellow2), BalanceOf::::zero()); assert_eq!(DepositOf::::get(&fellow2), None); assert_last_event::(Event::MemberRetired(fellow2, Some(T::CandidateDeposit::get())).into()); } @@ -280,7 +316,6 @@ benchmarks_instance_pallet! { assert!(Alliance::::is_member_of(&fellow2, MemberRole::Fellow)); assert!(Alliance::::is_kicking(&fellow2)); - assert_eq!(T::Currency::reserved_balance(&fellow2), T::CandidateDeposit::get()); assert_eq!(DepositOf::::get(&fellow2), Some(T::CandidateDeposit::get())); let fellow2_lookup: ::Source = T::Lookup::unlookup(fellow2.clone()); @@ -289,7 +324,6 @@ benchmarks_instance_pallet! { }: { call.dispatch_bypass_filter(origin)? } verify { assert!(!Alliance::::is_member(&fellow2)); - assert_eq!(T::Currency::reserved_balance(&fellow2), BalanceOf::::zero()); assert_eq!(DepositOf::::get(&fellow2), None); assert_last_event::(Event::MemberKicked(fellow2, Some(T::CandidateDeposit::get())).into()); } @@ -297,11 +331,10 @@ benchmarks_instance_pallet! { add_blacklist { let n in 0 .. T::MaxBlacklistCount::get(); + set_members::(); let mut blacklist = (0..n).map(|i| BlacklistItem::AccountId(blacklist_account::(i))).collect::>(); blacklist.extend((0..n).map(|i| BlacklistItem::Website(vec![i as u8]))); - set_members::(); - let call = Call::::add_blacklist { infos: blacklist.clone() }; let origin = T::SuperMajorityOrigin::successful_origin(); }: { call.dispatch_bypass_filter(origin)? } @@ -312,10 +345,10 @@ benchmarks_instance_pallet! { remove_blacklist { let n in 0 .. T::MaxBlacklistCount::get(); + set_members::(); let mut blacklist = (0..n).map(|i| BlacklistItem::AccountId(blacklist_account::(i))).collect::>(); blacklist.extend((0..n).map(|i| BlacklistItem::Website(vec![i as u8]))); - set_members::(); set_blacklist::(); let call = Call::::remove_blacklist { infos: blacklist.clone() }; @@ -324,6 +357,6 @@ benchmarks_instance_pallet! { verify { assert_last_event::(Event::BlacklistRemoved(blacklist).into()); } -} -impl_benchmark_test_suite!(Alliance, crate::mock::new_bench_ext(), crate::mock::Test); + impl_benchmark_test_suite!(Alliance, crate::mock::new_bench_ext(), crate::mock::Test); +} diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index c69910f6f9beb..f8aa848902698 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -97,6 +97,7 @@ mod tests; #[cfg(feature = "runtime-benchmarks")] mod benchmarking; +mod types; pub mod weights; use sp_runtime::{ @@ -114,14 +115,14 @@ use frame_support::{ ensure, scale_info::TypeInfo, traits::{ - ChangeMembers, Currency, Get, InitializeMembers, IsSubType, LockableCurrency, OnUnbalanced, + ChangeMembers, Currency, Get, InitializeMembers, IsSubType, OnUnbalanced, ReservableCurrency, }, weights::{Pays, Weight}, }; -pub use cid::Cid; pub use pallet::*; +pub use types::*; pub use weights::*; /// Simple index type for proposal counting. @@ -129,11 +130,9 @@ pub type ProposalIndex = u32; type Url = Vec; -type BalanceOf = - <>::Currency as Currency<::AccountId>>::Balance; -type NegativeImbalanceOf = <>::Currency as Currency< +type BalanceOf = <::Currency as Currency< ::AccountId, ->>::NegativeImbalance; +>>::Balance; pub trait IdentityVerifier { fn has_identity(who: &AccountId, fields: u64) -> bool; @@ -195,7 +194,7 @@ pub mod pallet { pub struct Pallet(PhantomData<(T, I)>); #[pallet::config] - pub trait Config: frame_system::Config { + pub trait Config: frame_system::Config + pallet_identity::Config { /// The overarching event type. type Event: From> + IsType<::Event>; @@ -211,13 +210,6 @@ pub mod pallet { /// of a majority-carries referendum. type SuperMajorityOrigin: EnsureOrigin; - /// The currency used for deposits. - type Currency: LockableCurrency - + ReservableCurrency; - - /// What to do with slashed funds. - type Slashed: OnUnbalanced>; - /// What to do with genesis members type InitializeMembers: InitializeMembers; @@ -240,7 +232,7 @@ pub mod pallet { /// The amount of a deposit required for submitting candidacy. #[pallet::constant] - type CandidateDeposit: Get>; + type CandidateDeposit: Get>; } #[pallet::error] @@ -302,7 +294,7 @@ pub mod pallet { FoundersInitialized(Vec), /// An account has been added as a candidate and lock its deposit. \[candidate, nominator, /// reserved\] - CandidateAdded(T::AccountId, Option, Option>), + CandidateAdded(T::AccountId, Option, Option>), /// A proposal has been proposed to approve the candidate. \[candidate\] CandidateApproved(T::AccountId), /// A proposal has been proposed to reject the candidate. \[candidate\] @@ -311,10 +303,10 @@ pub mod pallet { AllyElevated(T::AccountId), /// A member has retired to an ordinary account with its deposit unreserved. \[member, /// unreserved\] - MemberRetired(T::AccountId, Option>), + MemberRetired(T::AccountId, Option>), /// A member has been kicked out to an ordinary account with its deposit slashed. \[member, /// slashed\] - MemberKicked(T::AccountId, Option>), + MemberKicked(T::AccountId, Option>), /// Accounts or websites have been added into blacklist. \[items\] BlacklistAdded(Vec>), /// Accounts or websites have been removed from blacklist. \[items\] @@ -344,8 +336,14 @@ pub mod pallet { #[pallet::genesis_build] impl, I: 'static> GenesisBuild for GenesisConfig { fn build(&self) { - for m in self.founders.iter().chain(self.fellows.iter()).chain(self.allies.iter()) { - assert!(Pallet::::has_identity(m).is_ok(), "Member does not set identity!"); + #[cfg(not(test))] + { + for m in self.founders.iter().chain(self.fellows.iter()).chain(self.allies.iter()) { + assert!( + Pallet::::has_identity(m).is_ok(), + "Member does not set identity!" + ); + } } if !self.founders.is_empty() { @@ -390,7 +388,7 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn deposit_of)] pub type DepositOf, I: 'static = ()> = - StorageMap<_, Blake2_128Concat, T::AccountId, BalanceOf, OptionQuery>; + StorageMap<_, Blake2_128Concat, T::AccountId, BalanceOf, OptionQuery>; /// The current set of candidates. /// If the candidacy is approved by a motion, then it will become an ally member. @@ -568,7 +566,7 @@ pub mod pallet { T::SuperMajorityOrigin::ensure_origin(origin)?; let mut announcements = >::get(); - announcements.push(announcement); + announcements.push(announcement.clone()); >::put(announcements); Self::deposit_event(Event::NewAnnouncement(announcement)); @@ -577,11 +575,17 @@ pub mod pallet { /// Remove the announcement. #[pallet::weight(0)] - pub fn remove_announcement(origin: OriginFor, announcement: Cid) -> DispatchResultWithPostInfo { + pub fn remove_announcement( + origin: OriginFor, + announcement: Cid, + ) -> DispatchResultWithPostInfo { T::SuperMajorityOrigin::ensure_origin(origin)?; let mut announcements = >::get(); - let pos = announcements.binary_search(&announcement).ok().ok_or(Error::::MissingAnnouncement)?; + let pos = announcements + .binary_search(&announcement) + .ok() + .ok_or(Error::::MissingAnnouncement)?; announcements.remove(pos); >::put(announcements); diff --git a/frame/alliance/src/mock.rs b/frame/alliance/src/mock.rs index b16a2213d2081..bd2f5fa7064b2 100644 --- a/frame/alliance/src/mock.rs +++ b/frame/alliance/src/mock.rs @@ -17,17 +17,19 @@ //! Test utilities -pub use cid::Cid; - pub use sp_core::H256; pub use sp_runtime::{ testing::Header, traits::{BlakeTwo256, IdentityLookup}, BuildStorage, }; +use sp_std::convert::TryInto; -pub use frame_support::{ord_parameter_types, parameter_types, traits::SortedMembers}; -pub use frame_system::EnsureSignedBy; +pub use frame_support::{ + assert_ok, ord_parameter_types, parameter_types, traits::SortedMembers, BoundedVec, +}; +pub use frame_system::{EnsureOneOf, EnsureRoot, EnsureSignedBy}; +use pallet_identity::{Data, IdentityInfo, Judgement}; pub use crate as pallet_alliance; @@ -95,18 +97,60 @@ impl pallet_collective::Config for Test { type WeightInfo = (); } +parameter_types! { + pub const BasicDeposit: u64 = 10; + pub const FieldDeposit: u64 = 10; + pub const SubAccountDeposit: u64 = 10; + pub const MaxSubAccounts: u32 = 2; + pub const MaxAdditionalFields: u32 = 2; + pub const MaxRegistrars: u32 = 20; +} +ord_parameter_types! { + pub const One: u64 = 1; + pub const Two: u64 = 2; + pub const Three: u64 = 3; + pub const Four: u64 = 4; + pub const Five: u64 = 5; +} +type EnsureOneOrRoot = EnsureOneOf, EnsureSignedBy>; +type EnsureTwoOrRoot = EnsureOneOf, EnsureSignedBy>; + +impl pallet_identity::Config for Test { + type Event = Event; + type Currency = Balances; + type BasicDeposit = BasicDeposit; + type FieldDeposit = FieldDeposit; + type SubAccountDeposit = SubAccountDeposit; + type MaxSubAccounts = MaxSubAccounts; + type MaxAdditionalFields = MaxAdditionalFields; + type MaxRegistrars = MaxRegistrars; + type Slashed = (); + type RegistrarOrigin = EnsureOneOrRoot; + type ForceOrigin = EnsureTwoOrRoot; + type WeightInfo = (); +} + pub struct AllianceIdentityVerifier; impl IdentityVerifier for AllianceIdentityVerifier { - fn has_identity(_who: &u64, _fields: u64) -> bool { - true + fn has_identity(who: &u64, fields: u64) -> bool { + Identity::has_identity(who, fields) } - fn has_good_judgement(_who: &u64) -> bool { - true + fn has_good_judgement(who: &u64) -> bool { + if let Some(judgements) = + Identity::identity(who).map(|registration| registration.judgements) + { + judgements + .iter() + .filter(|(_, j)| Judgement::KnownGood == *j || Judgement::Reasonable == *j) + .count() > 0 + } else { + false + } } - fn super_account_id(_who: &u64) -> Option { - None + fn super_account_id(who: &u64) -> Option { + Identity::super_of(who).map(|parent| parent.0) } } @@ -143,13 +187,6 @@ impl ProposalProvider for AllianceProposalProvider { } } -ord_parameter_types! { - pub const One: u64 = 1; - pub const Two: u64 = 2; - pub const Three: u64 = 3; - pub const Four: u64 = 4; - pub const Five: u64 = 5; -} parameter_types! { pub const CandidateDeposit: u64 = 25; pub const MaxBlacklistCount: u32 = 100; @@ -159,8 +196,6 @@ impl Config for Test { type Event = Event; type Proposal = Call; type SuperMajorityOrigin = EnsureSignedBy; - type Currency = Balances; - type Slashed = (); type InitializeMembers = AllianceMotion; type MembershipChanged = AllianceMotion; type IdentityVerifier = AllianceIdentityVerifier; @@ -181,6 +216,7 @@ frame_support::construct_runtime!( { System: frame_system::{Pallet, Call, Storage, Event}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + Identity: pallet_identity::{Pallet, Call, Storage, Event}, AllianceMotion: pallet_collective::::{Pallet, Storage, Origin, Event}, Alliance: pallet_alliance::{Pallet, Call, Storage, Event, Config}, } @@ -189,7 +225,7 @@ frame_support::construct_runtime!( pub fn new_test_ext() -> sp_io::TestExternalities { let t = GenesisConfig { balances: pallet_balances::GenesisConfig { - balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 20)], + balances: vec![(1, 50), (2, 50), (3, 50), (4, 50), (5, 30), (6, 50), (7, 50)], }, alliance: pallet_alliance::GenesisConfig { founders: vec![1, 2], @@ -202,7 +238,34 @@ pub fn new_test_ext() -> sp_io::TestExternalities { .unwrap(); let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(|| System::set_block_number(1)); + ext.execute_with(|| { + assert_ok!(Identity::add_registrar(Origin::signed(1), 1)); + + let info = IdentityInfo { + additional: BoundedVec::default(), + display: Data::Raw(b"name".to_vec().try_into().unwrap()), + legal: Data::default(), + web: Data::Raw(b"website".to_vec().try_into().unwrap()), + riot: Data::default(), + email: Data::default(), + pgp_fingerprint: None, + image: Data::default(), + twitter: Data::default(), + }; + assert_ok!(Identity::set_identity(Origin::signed(1), Box::new(info.clone()))); + assert_ok!(Identity::provide_judgement(Origin::signed(1), 0, 1, Judgement::KnownGood)); + assert_ok!(Identity::set_identity(Origin::signed(2), Box::new(info.clone()))); + assert_ok!(Identity::provide_judgement(Origin::signed(1), 0, 2, Judgement::KnownGood)); + assert_ok!(Identity::set_identity(Origin::signed(3), Box::new(info.clone()))); + assert_ok!(Identity::provide_judgement(Origin::signed(1), 0, 3, Judgement::KnownGood)); + assert_ok!(Identity::set_identity(Origin::signed(4), Box::new(info.clone()))); + assert_ok!(Identity::provide_judgement(Origin::signed(1), 0, 4, Judgement::KnownGood)); + assert_ok!(Identity::set_identity(Origin::signed(5), Box::new(info.clone()))); + assert_ok!(Identity::provide_judgement(Origin::signed(1), 0, 5, Judgement::KnownGood)); + assert_ok!(Identity::set_identity(Origin::signed(6), Box::new(info.clone()))); + + System::set_block_number(1); + }); ext } @@ -212,7 +275,11 @@ pub fn new_bench_ext() -> sp_io::TestExternalities { } pub fn test_cid() -> Cid { - "QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n".parse().unwrap() + use sha2::{Digest, Sha256}; + let mut hasher = Sha256::new(); + hasher.update(b"hello world"); + let result = hasher.finalize(); + Cid::new_v0(&*result) } pub fn make_proposal(value: u64) -> Call { diff --git a/frame/alliance/src/tests.rs b/frame/alliance/src/tests.rs index cefe9ab0f972c..d863948afc40a 100644 --- a/frame/alliance/src/tests.rs +++ b/frame/alliance/src/tests.rs @@ -202,8 +202,8 @@ fn close_works() { fn set_rule_works() { new_test_ext().execute_with(|| { let cid = test_cid(); - assert_ok!(Alliance::set_rule(Origin::signed(1), cid)); - assert_eq!(Alliance::rule(), Some(cid)); + assert_ok!(Alliance::set_rule(Origin::signed(1), cid.clone())); + assert_eq!(Alliance::rule(), Some(cid.clone())); System::assert_last_event(mock::Event::Alliance(crate::Event::NewRule(cid))); }); @@ -213,8 +213,8 @@ fn set_rule_works() { fn announce_works() { new_test_ext().execute_with(|| { let cid = test_cid(); - assert_ok!(Alliance::announce(Origin::signed(1), cid)); - assert_eq!(Alliance::announcements(), vec![cid]); + assert_ok!(Alliance::announce(Origin::signed(1), cid.clone())); + assert_eq!(Alliance::announcements(), vec![cid.clone()]); System::assert_last_event(mock::Event::Alliance(crate::Event::NewAnnouncement(cid))); }); @@ -224,13 +224,15 @@ fn announce_works() { fn remove_announcement_works() { new_test_ext().execute_with(|| { let cid = test_cid(); - assert_ok!(Alliance::announce(Origin::signed(1), cid)); - assert_eq!(Alliance::announcements(), vec![cid]); - System::assert_last_event(mock::Event::Alliance(crate::Event::NewAnnouncement(cid))); + assert_ok!(Alliance::announce(Origin::signed(1), cid.clone())); + assert_eq!(Alliance::announcements(), vec![cid.clone()]); + System::assert_last_event(mock::Event::Alliance(crate::Event::NewAnnouncement( + cid.clone(), + ))); System::set_block_number(2); - assert_ok!(Alliance::remove_announcement(Origin::signed(1), cid)); + assert_ok!(Alliance::remove_announcement(Origin::signed(1), cid.clone())); assert_eq!(Alliance::announcements(), vec![]); System::assert_last_event(mock::Event::Alliance(crate::Event::AnnouncementRemoved(cid))); }); @@ -272,6 +274,17 @@ fn submit_candidacy_works() { Alliance::submit_candidacy(Origin::signed(4)), Error::::AlreadyCandidate ); + + // check missing identity judgement + assert_noop!( + Alliance::submit_candidacy(Origin::signed(6)), + Error::::WithoutGoodIdentityJudgement + ); + // check missing identity info + assert_noop!( + Alliance::submit_candidacy(Origin::signed(7)), + Error::::WithoutIdentityDisplayAndWebsite + ); }); } @@ -311,6 +324,17 @@ fn nominate_candidacy_works() { Alliance::nominate_candidacy(Origin::signed(1), 4), Error::::AlreadyCandidate ); + + // check missing identity judgement + assert_noop!( + Alliance::submit_candidacy(Origin::signed(6)), + Error::::WithoutGoodIdentityJudgement + ); + // check missing identity info + assert_noop!( + Alliance::submit_candidacy(Origin::signed(7)), + Error::::WithoutIdentityDisplayAndWebsite + ); }); } @@ -432,88 +456,3 @@ fn remove_blacklist_works() { assert_eq!(Alliance::account_blacklist(), Vec::::new()); }); } - -mod cid_tests { - use cid::{ - multibase::Base, - multihash::{Code, MultihashDigest}, - Cid, Version, - }; - use codec::{Decode, Encode}; - use hex_literal::hex; - - const RAW: u64 = 0x55; - - #[test] - fn normal_test_for_example() { - let cid = "QmRZdc3mAMXpv6Akz9Ekp1y4vDSjazTx2dCQRkxVy1yUj6".parse::().unwrap(); - let bytes = cid.encode(); - let expect = hex!("0070000000000000001200000000000000202fe65ccc17fe180c3bf4e9b8490fcc6dc74c30bf6595795dcd1136d8d9cb3f95"); - assert_eq!(bytes, expect); - let new_cid: Cid = Decode::decode(&mut &bytes[..]).unwrap(); - assert_eq!(new_cid, cid); - } - - macro_rules! assert_cid { - ($cid:expr, $length:expr) => { - let mut digest = [0_u8; $length]; - digest.copy_from_slice($cid.hash().digest()); - let raw = - ($cid.version(), $cid.codec(), ($cid.hash().code(), $cid.hash().size(), digest)); - let raw_encode = Encode::encode(&raw); - let bytes = $cid.encode(); - assert_eq!(bytes, raw_encode); - let new_cid: Cid = Decode::decode(&mut &bytes[..]).unwrap(); - assert_eq!(new_cid, $cid); - }; - } - - // those test case is from crate cid - #[test] - fn v0_handling() { - let old = "QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n"; - let cid = old.parse::().unwrap(); - - assert_eq!(cid.version(), Version::V0); - assert_eq!(cid.to_string(), old); - - // for Cid v0 hash is 32 length - assert_cid!(cid, 32); - } - - #[test] - fn v1_handling() { - let expected_cid = "bafkreibme22gw2h7y2h7tg2fhqotaqjucnbc24deqo72b6mkl2egezxhvy"; - let cid: Cid = Cid::new_v1(RAW, Code::Sha2_256.digest(b"foo")); - assert_eq!(cid.to_string_of_base(Base::Base32Lower).unwrap(), expected_cid); - - // for sha256 hash is 32 length - assert_cid!(cid, 32); - } - - // test case from https://github.com/ipfs/go-cid/blob/master/cid_test.go#L662 - #[test] - fn v1_handling2() { - let cid1 = "k2cwueckqkibutvhkr4p2ln2pjcaxaakpd9db0e7j7ax1lxhhxy3ekpv" - .parse::() - .unwrap(); - let cid2 = "zb2rhZi1JR4eNc2jBGaRYJKYM8JEB4ovenym8L1CmFsRAytkz".parse::().unwrap(); - assert_cid!(cid1, 32); - assert_cid!(cid2, 32); - } - - #[test] - fn v1_handling3() { - let cid = Cid::new_v1(RAW, Code::Sha2_512.digest(b"foo")); - assert_cid!(cid, 64); - - let cid = Cid::new_v1(RAW, Code::Keccak384.digest(b"foo")); - assert_cid!(cid, 48); - - let cid = Cid::new_v1(RAW, Code::Sha3_224.digest(b"foo")); - assert_cid!(cid, 28); - - let cid = Cid::new_v1(RAW, Code::Blake2s128.digest(b"foo")); - assert_cid!(cid, 16); - } -} diff --git a/frame/alliance/src/types.rs b/frame/alliance/src/types.rs new file mode 100644 index 0000000000000..5ef08f31efdcf --- /dev/null +++ b/frame/alliance/src/types.rs @@ -0,0 +1,76 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use codec::{Decode, Encode}; +use scale_info::TypeInfo; +use sp_runtime::RuntimeDebug; +use sp_std::prelude::*; + +/// A Multihash instance that only supports the basic functionality and no hashing. +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RuntimeDebug, Encode, Decode, TypeInfo)] +pub struct Multihash { + /// The code of the Multihash. + pub code: u64, + /// The digest. + pub digest: Vec, +} + +impl Multihash { + /// Returns the size of the digest. + pub fn size(&self) -> usize { + self.digest.len() + } +} + +/// The version of the CID. +#[derive( + Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RuntimeDebug, Encode, Decode, TypeInfo, +)] +pub enum Version { + /// CID version 0. + V0, + /// CID version 1. + V1, +} + +/// Representation of a CID. +/// +/// The generic is about the allocated size of the multihash. +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RuntimeDebug, Encode, Decode, TypeInfo)] +pub struct Cid { + /// The version of CID. + pub version: Version, + /// The codec of CID. + pub codec: u64, + /// The multihash of CID. + pub hash: Multihash, +} + +impl Cid { + /// Create a new CIDv0. + pub fn new_v0(sha2_256_digest: impl Into>) -> Self { + /// DAG-PB multicodec code + const DAG_PB: u64 = 0x70; + /// The SHA_256 multicodec code + const SHA2_256: u64 = 0x12; + + let digest = sha2_256_digest.into(); + assert!(digest.len() == 32); + + Self { version: Version::V0, codec: DAG_PB, hash: Multihash { code: SHA2_256, digest } } + } +} From 0a715029ec116eeb1546cedb249762d003e37f40 Mon Sep 17 00:00:00 2001 From: koushiro Date: Wed, 6 Oct 2021 01:02:54 +0800 Subject: [PATCH 10/72] Add part weight for call of pallet-alliance Signed-off-by: koushiro --- bin/node/runtime/src/lib.rs | 1 + frame/alliance/src/lib.rs | 27 ++-- frame/alliance/src/mock.rs | 1 + frame/alliance/src/weights.rs | 276 ++++++++++++++++++++++++++++++++++ 4 files changed, 293 insertions(+), 12 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 0fbd4ad343d3e..dbfad59d66d2b 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1427,6 +1427,7 @@ impl pallet_alliance::Config for Runtime { type MaxBlacklistCount = MaxBlacklistCount; type MaxWebsiteUrlLength = MaxWebsiteUrlLength; type CandidateDeposit = CandidateDeposit; + type WeightInfo = pallet_alliance::weights::SubstrateWeight; } construct_runtime!( diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index f8aa848902698..ed6cbce925774 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -233,6 +233,9 @@ pub mod pallet { /// The amount of a deposit required for submitting candidacy. #[pallet::constant] type CandidateDeposit: Get>; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; } #[pallet::error] @@ -550,7 +553,7 @@ pub mod pallet { } /// Set a new IPFS cid to the alliance rule. - #[pallet::weight(0)] + #[pallet::weight(>::WeightInfo::set_rule())] pub fn set_rule(origin: OriginFor, rule: Cid) -> DispatchResultWithPostInfo { T::SuperMajorityOrigin::ensure_origin(origin)?; @@ -561,7 +564,7 @@ pub mod pallet { } /// Make a new announcement by a new IPFS cid about the alliance issues. - #[pallet::weight(0)] + #[pallet::weight(>::WeightInfo::announce())] pub fn announce(origin: OriginFor, announcement: Cid) -> DispatchResultWithPostInfo { T::SuperMajorityOrigin::ensure_origin(origin)?; @@ -574,7 +577,7 @@ pub mod pallet { } /// Remove the announcement. - #[pallet::weight(0)] + #[pallet::weight(>::WeightInfo::remove_announcement())] pub fn remove_announcement( origin: OriginFor, announcement: Cid, @@ -595,7 +598,7 @@ pub mod pallet { /// Submit oneself for candidacy. /// Account must have enough transferable funds in it to pay the candidate deposit. - #[pallet::weight(0)] + #[pallet::weight(>::WeightInfo::submit_candidacy())] pub fn submit_candidacy(origin: OriginFor) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; ensure!(!Self::is_account_blacklist(&who), Error::::AlreadyInBlacklist); @@ -619,7 +622,7 @@ pub mod pallet { /// Founder or fellow can nominate someone to join the alliance and become a candidate. /// There is no deposit required to the nominator or nominee. - #[pallet::weight(0)] + #[pallet::weight(>::WeightInfo::nominate_candidacy())] pub fn nominate_candidacy( origin: OriginFor, who: ::Source, @@ -642,7 +645,7 @@ pub mod pallet { } /// Approve a `Candidate` to become an `Ally`. - #[pallet::weight(0)] + #[pallet::weight(>::WeightInfo::approve_candidate())] pub fn approve_candidate( origin: OriginFor, candidate: ::Source, @@ -660,7 +663,7 @@ pub mod pallet { } /// Reject a `Candidate` back to an ordinary account. - #[pallet::weight(0)] + #[pallet::weight(>::WeightInfo::reject_candidate())] pub fn reject_candidate( origin: OriginFor, candidate: ::Source, @@ -680,7 +683,7 @@ pub mod pallet { } /// Elevate an ally to fellow. - #[pallet::weight(0)] + #[pallet::weight(>::WeightInfo::reject_candidate())] pub fn elevate_ally( origin: OriginFor, ally: ::Source, @@ -698,7 +701,7 @@ pub mod pallet { } /// As a member, retire and back to an ordinary account and unlock its deposit. - #[pallet::weight(0)] + #[pallet::weight(>::WeightInfo::retire())] pub fn retire(origin: OriginFor) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; ensure!(!Self::is_kicking(&who), Error::::KickingMember); @@ -715,7 +718,7 @@ pub mod pallet { } /// Kick a member to ordinary account with its deposit slashed. - #[pallet::weight(0)] + #[pallet::weight(>::WeightInfo::kick_member())] pub fn kick_member( origin: OriginFor, who: ::Source, @@ -735,7 +738,7 @@ pub mod pallet { } /// Add accounts or websites into blacklist. - #[pallet::weight(0)] + #[pallet::weight(>::WeightInfo::add_blacklist(infos.len() as u32))] pub fn add_blacklist( origin: OriginFor, infos: Vec>, @@ -775,7 +778,7 @@ pub mod pallet { } /// Remove accounts or websites from blacklist. - #[pallet::weight(0)] + #[pallet::weight(>::WeightInfo::remove_blacklist(infos.len() as u32))] pub fn remove_blacklist( origin: OriginFor, infos: Vec>, diff --git a/frame/alliance/src/mock.rs b/frame/alliance/src/mock.rs index bd2f5fa7064b2..6c3471d747a10 100644 --- a/frame/alliance/src/mock.rs +++ b/frame/alliance/src/mock.rs @@ -203,6 +203,7 @@ impl Config for Test { type MaxBlacklistCount = MaxBlacklistCount; type MaxWebsiteUrlLength = MaxWebsiteUrlLength; type CandidateDeposit = CandidateDeposit; + type WeightInfo = (); } type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; diff --git a/frame/alliance/src/weights.rs b/frame/alliance/src/weights.rs index 8b137891791fe..fd4ae27cfbfd6 100644 --- a/frame/alliance/src/weights.rs +++ b/frame/alliance/src/weights.rs @@ -1 +1,277 @@ +// This file is part of Substrate. +// Copyright (C) 2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Autogenerated weights for pallet_alliance +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2021-10-05, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 + +// Executed Command: +// ./target/release/substrate +// benchmark +// --chain=dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_alliance +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./frame/alliance/src/weights.rs +// --template=./.maintain/frame-weight-template.hbs + + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weight functions needed for pallet_alliance. +pub trait WeightInfo { + fn set_rule() -> Weight; + fn announce() -> Weight; + fn remove_announcement() -> Weight; + fn submit_candidacy() -> Weight; + fn nominate_candidacy() -> Weight; + fn approve_candidate() -> Weight; + fn reject_candidate() -> Weight; + fn elevate_ally() -> Weight; + fn retire() -> Weight; + fn kick_member() -> Weight; + fn add_blacklist(n: u32, ) -> Weight; + fn remove_blacklist(n: u32, ) -> Weight; +} + +/// Weights for pallet_alliance using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + // Storage: Alliance Rule (r:0 w:1) + fn set_rule() -> Weight { + (15_740_000 as Weight) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + // Storage: Alliance Announcements (r:1 w:1) + fn announce() -> Weight { + (17_984_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + // Storage: Alliance Announcements (r:1 w:1) + fn remove_announcement() -> Weight { + (18_094_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + // Storage: Alliance AccountBlacklist (r:1 w:0) + // Storage: Alliance Candidates (r:1 w:1) + // Storage: Alliance Members (r:4 w:0) + // Storage: Identity IdentityOf (r:1 w:0) + // Storage: System Account (r:1 w:1) + // Storage: Alliance DepositOf (r:0 w:1) + fn submit_candidacy() -> Weight { + (68_729_000 as Weight) + .saturating_add(T::DbWeight::get().reads(8 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + // Storage: Alliance Members (r:4 w:0) + // Storage: Alliance AccountBlacklist (r:1 w:0) + // Storage: Alliance Candidates (r:1 w:1) + // Storage: Identity IdentityOf (r:1 w:0) + fn nominate_candidacy() -> Weight { + (52_599_000 as Weight) + .saturating_add(T::DbWeight::get().reads(7 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + // Storage: Alliance Candidates (r:1 w:1) + // Storage: Alliance Members (r:4 w:1) + fn approve_candidate() -> Weight { + (45_466_000 as Weight) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } + // Storage: Alliance Candidates (r:1 w:1) + // Storage: Alliance Members (r:4 w:0) + // Storage: Alliance DepositOf (r:1 w:1) + // Storage: System Account (r:1 w:1) + fn reject_candidate() -> Weight { + (71_815_000 as Weight) + .saturating_add(T::DbWeight::get().reads(7 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + // Storage: Alliance Members (r:3 w:2) + // Storage: AllianceMotion Proposals (r:1 w:0) + // Storage: AllianceMotion Members (r:0 w:1) + // Storage: AllianceMotion Prime (r:0 w:1) + fn elevate_ally() -> Weight { + (44_063_000 as Weight) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + // Storage: Alliance KickingMembers (r:1 w:0) + // Storage: Alliance Members (r:3 w:1) + // Storage: AllianceMotion Proposals (r:1 w:0) + // Storage: Alliance DepositOf (r:1 w:1) + // Storage: System Account (r:1 w:1) + // Storage: AllianceMotion Members (r:0 w:1) + // Storage: AllianceMotion Prime (r:0 w:1) + fn retire() -> Weight { + (62_137_000 as Weight) + .saturating_add(T::DbWeight::get().reads(7 as Weight)) + .saturating_add(T::DbWeight::get().writes(5 as Weight)) + } + // Storage: Alliance KickingMembers (r:1 w:0) + // Storage: Alliance Members (r:3 w:1) + // Storage: AllianceMotion Proposals (r:1 w:0) + // Storage: Alliance DepositOf (r:1 w:1) + // Storage: System Account (r:1 w:1) + // Storage: AllianceMotion Members (r:0 w:1) + // Storage: AllianceMotion Prime (r:0 w:1) + fn kick_member() -> Weight { + (69_491_000 as Weight) + .saturating_add(T::DbWeight::get().reads(7 as Weight)) + .saturating_add(T::DbWeight::get().writes(5 as Weight)) + } + // Storage: Alliance AccountBlacklist (r:1 w:0) + // Storage: Alliance WebsiteBlacklist (r:1 w:0) + fn add_blacklist(n: u32, ) -> Weight { + (26_953_000 as Weight) + // Standard Error: 5_000 + .saturating_add((2_114_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } + // Storage: Alliance AccountBlacklist (r:1 w:1) + // Storage: Alliance WebsiteBlacklist (r:1 w:1) + fn remove_blacklist(n: u32, ) -> Weight { + (69_853_000 as Weight) + // Standard Error: 21_000 + .saturating_add((29_661_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + // Storage: Alliance Rule (r:0 w:1) + fn set_rule() -> Weight { + (15_740_000 as Weight) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + // Storage: Alliance Announcements (r:1 w:1) + fn announce() -> Weight { + (17_984_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + // Storage: Alliance Announcements (r:1 w:1) + fn remove_announcement() -> Weight { + (18_094_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + // Storage: Alliance AccountBlacklist (r:1 w:0) + // Storage: Alliance Candidates (r:1 w:1) + // Storage: Alliance Members (r:4 w:0) + // Storage: Identity IdentityOf (r:1 w:0) + // Storage: System Account (r:1 w:1) + // Storage: Alliance DepositOf (r:0 w:1) + fn submit_candidacy() -> Weight { + (68_729_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(8 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + // Storage: Alliance Members (r:4 w:0) + // Storage: Alliance AccountBlacklist (r:1 w:0) + // Storage: Alliance Candidates (r:1 w:1) + // Storage: Identity IdentityOf (r:1 w:0) + fn nominate_candidacy() -> Weight { + (52_599_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(7 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + // Storage: Alliance Candidates (r:1 w:1) + // Storage: Alliance Members (r:4 w:1) + fn approve_candidate() -> Weight { + (45_466_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + } + // Storage: Alliance Candidates (r:1 w:1) + // Storage: Alliance Members (r:4 w:0) + // Storage: Alliance DepositOf (r:1 w:1) + // Storage: System Account (r:1 w:1) + fn reject_candidate() -> Weight { + (71_815_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(7 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + // Storage: Alliance Members (r:3 w:2) + // Storage: AllianceMotion Proposals (r:1 w:0) + // Storage: AllianceMotion Members (r:0 w:1) + // Storage: AllianceMotion Prime (r:0 w:1) + fn elevate_ally() -> Weight { + (44_063_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + .saturating_add(RocksDbWeight::get().writes(4 as Weight)) + } + // Storage: Alliance KickingMembers (r:1 w:0) + // Storage: Alliance Members (r:3 w:1) + // Storage: AllianceMotion Proposals (r:1 w:0) + // Storage: Alliance DepositOf (r:1 w:1) + // Storage: System Account (r:1 w:1) + // Storage: AllianceMotion Members (r:0 w:1) + // Storage: AllianceMotion Prime (r:0 w:1) + fn retire() -> Weight { + (62_137_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(7 as Weight)) + .saturating_add(RocksDbWeight::get().writes(5 as Weight)) + } + // Storage: Alliance KickingMembers (r:1 w:0) + // Storage: Alliance Members (r:3 w:1) + // Storage: AllianceMotion Proposals (r:1 w:0) + // Storage: Alliance DepositOf (r:1 w:1) + // Storage: System Account (r:1 w:1) + // Storage: AllianceMotion Members (r:0 w:1) + // Storage: AllianceMotion Prime (r:0 w:1) + fn kick_member() -> Weight { + (69_491_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(7 as Weight)) + .saturating_add(RocksDbWeight::get().writes(5 as Weight)) + } + // Storage: Alliance AccountBlacklist (r:1 w:0) + // Storage: Alliance WebsiteBlacklist (r:1 w:0) + fn add_blacklist(n: u32, ) -> Weight { + (26_953_000 as Weight) + // Standard Error: 5_000 + .saturating_add((2_114_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(2 as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + } + // Storage: Alliance AccountBlacklist (r:1 w:1) + // Storage: Alliance WebsiteBlacklist (r:1 w:1) + fn remove_blacklist(n: u32, ) -> Weight { + (69_853_000 as Weight) + // Standard Error: 21_000 + .saturating_add((29_661_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(2 as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + } +} From d7aeddf662a524ac775b2ff940dc3b2c41856704 Mon Sep 17 00:00:00 2001 From: koushiro Date: Sat, 9 Oct 2021 11:42:43 +0800 Subject: [PATCH 11/72] Remove pallet_identity Config trait Signed-off-by: koushiro --- Cargo.lock | 4 ++ bin/node/runtime/src/impls.rs | 31 +++++++++--- bin/node/runtime/src/lib.rs | 4 +- frame/alliance/Cargo.toml | 5 +- frame/alliance/src/benchmarking.rs | 46 ++---------------- frame/alliance/src/lib.rs | 24 ++++++--- frame/alliance/src/mock.rs | 20 ++++++++ frame/alliance/src/tests.rs | 4 ++ frame/alliance/src/weights.rs | 78 ++++++++++++++---------------- 9 files changed, 114 insertions(+), 102 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 85c6c92de1e95..6276081e5b91b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5453,10 +5453,14 @@ dependencies = [ "parity-scale-codec", "scale-info", <<<<<<< HEAD +<<<<<<< HEAD >>>>>>> 2369417073 (Add pallet-alliance) ======= "sha2 0.9.3", >>>>>>> 4482b77565 (Derive pallet_identity::Config and Fix test/benchmarking) +======= + "sha2 0.9.5", +>>>>>>> b0f38f7b9f (Remove pallet_identity Config trait) "sp-core", "sp-io", "sp-runtime", diff --git a/bin/node/runtime/src/impls.rs b/bin/node/runtime/src/impls.rs index 23f8c3dd8f6b6..e0e8d919d89e4 100644 --- a/bin/node/runtime/src/impls.rs +++ b/bin/node/runtime/src/impls.rs @@ -17,7 +17,7 @@ //! Some configurable implementations as associated type for the substrate runtime. -use crate::{AllianceMotion, Authorship, Balances, Call, Identity, NegativeImbalance}; +use crate::{AllianceMotion, Authorship, Balances, Call, NegativeImbalance}; use frame_support::{ dispatch::{DispatchError, DispatchResultWithPostInfo}, traits::{Currency, OnUnbalanced}, @@ -51,17 +51,21 @@ impl HandleCredit for CreditToBlockAuthor { pub struct AllianceIdentityVerifier; impl IdentityVerifier for AllianceIdentityVerifier { - fn super_account_id(who: &AccountId) -> Option { - Identity::super_of(who).map(|parent| parent.0) + #[cfg(not(feature = "runtime-benchmarks"))] + fn has_identity(who: &AccountId, fields: u64) -> bool { + crate::Identity::has_identity(who, fields) } - fn has_identity(who: &AccountId, fields: u64) -> bool { - Identity::has_identity(who, fields) + #[cfg(feature = "runtime-benchmarks")] + fn has_identity(_who: &AccountId, _fields: u64) -> bool { + true } + #[cfg(not(feature = "runtime-benchmarks"))] fn has_good_judgement(who: &AccountId) -> bool { + use pallet_identity::Judgement; if let Some(judgements) = - Identity::identity(who).map(|registration| registration.judgements) + crate::Identity::identity(who).map(|registration| registration.judgements) { judgements .iter() @@ -71,6 +75,21 @@ impl IdentityVerifier for AllianceIdentityVerifier { false } } + + #[cfg(feature = "runtime-benchmarks")] + fn has_good_judgement(_who: &AccountId) -> bool { + true + } + + #[cfg(not(feature = "runtime-benchmarks"))] + fn super_account_id(who: &AccountId) -> Option { + crate::Identity::super_of(who).map(|parent| parent.0) + } + + #[cfg(feature = "runtime-benchmarks")] + fn super_account_id(_who: &AccountId) -> Option { + None + } } pub struct AllianceProposalProvider; diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index dbfad59d66d2b..721928f47d07d 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1412,7 +1412,7 @@ parameter_types! { pub const MaxWebsiteUrlLength: u32 = 255; } -impl pallet_alliance::Config for Runtime { +impl pallet_alliance::Config for Runtime { type Event = Event; type Proposal = Call; type SuperMajorityOrigin = EnsureOneOf< @@ -1420,6 +1420,8 @@ impl pallet_alliance::Config for Runtime { EnsureRoot, pallet_collective::EnsureProportionMoreThan<_2, _3, AccountId, AllianceCollective>, >; + type Currency = Balances; + type Slashed = Treasury; type InitializeMembers = AllianceMotion; type MembershipChanged = AllianceMotion; type IdentityVerifier = AllianceIdentityVerifier; diff --git a/frame/alliance/Cargo.toml b/frame/alliance/Cargo.toml index d295d3dae8c34..80a3b4ab85e55 100644 --- a/frame/alliance/Cargo.toml +++ b/frame/alliance/Cargo.toml @@ -24,18 +24,18 @@ sp-core = { version = "4.0.0-dev", default-features = false, path = "../../primi sp-io = { version = "4.0.0-dev", default-features = false, path = "../../primitives/io" } sp-runtime = { version = "4.0.0-dev", default-features = false, path = "../../primitives/runtime" } -pallet-identity = { version = "4.0.0-dev", path = "../identity", default-features = false } - frame-benchmarking = { version = "4.0.0-dev", default-features = false, path = "../benchmarking", optional = true } frame-support = { version = "4.0.0-dev", default-features = false, path = "../support" } frame-system = { version = "4.0.0-dev", default-features = false, path = "../system" } pallet-collective = { version = "4.0.0-dev", path = "../collective", default-features = false, optional = true } +pallet-identity = { version = "4.0.0-dev", path = "../identity", default-features = false, optional = true } [dev-dependencies] hex-literal = "0.3.1" sha2 = "0.9" pallet-balances = { version = "4.0.0-dev", path = "../balances" } pallet-collective = { version = "4.0.0-dev", path = "../collective" } +pallet-identity = { version = "4.0.0-dev", path = "../identity" } [features] default = ["std"] @@ -49,7 +49,6 @@ std = [ "sp-runtime/std", "frame-support/std", "frame-system/std", - "pallet-identity/std", ] runtime-benchmarks = [ "hex", diff --git a/frame/alliance/src/benchmarking.rs b/frame/alliance/src/benchmarking.rs index 45c1c8321b29e..2f900c4f0914c 100644 --- a/frame/alliance/src/benchmarking.rs +++ b/frame/alliance/src/benchmarking.rs @@ -18,16 +18,11 @@ //! Alliance pallet benchmarking. use sp_runtime::traits::{Bounded, StaticLookup}; -use sp_std::{convert::TryInto, prelude::*}; +use sp_std::prelude::*; use frame_benchmarking::{account, benchmarks_instance_pallet}; -use frame_support::{ - assert_ok, - traits::{EnsureOrigin, Get, UnfilteredDispatchable}, - BoundedVec, -}; +use frame_support::traits::{EnsureOrigin, Get, UnfilteredDispatchable}; use frame_system::RawOrigin; -use pallet_identity::{Data, IdentityInfo, Judgement, Pallet as Identity}; use super::{Pallet as Alliance, *}; @@ -43,48 +38,13 @@ fn test_cid() -> Cid { ) } -fn registrar_account, I: 'static>() -> T::AccountId { - account("registrar", 0, SEED) -} - -fn create_registrar_account, I: 'static>() -> T::AccountId { - let registrar: T::AccountId = registrar_account::(); - let _ = T::Currency::make_free_balance_be(®istrar, BalanceOf::::max_value()); - assert_ok!(Identity::::add_registrar(RawOrigin::Root.into(), registrar.clone())); - registrar -} - fn funded_account, I: 'static>(name: &'static str, index: u32) -> T::AccountId { let account: T::AccountId = account(name, index, SEED); - T::Currency::make_free_balance_be(&account, BalanceOf::::max_value()); - - let info = IdentityInfo { - additional: BoundedVec::default(), - display: Data::Raw(b"name".to_vec().try_into().unwrap()), - legal: Data::default(), - web: Data::Raw(b"website".to_vec().try_into().unwrap()), - riot: Data::default(), - email: Data::default(), - pgp_fingerprint: None, - image: Data::default(), - twitter: Data::default(), - }; - assert_ok!(Identity::::set_identity( - RawOrigin::Signed(account.clone()).into(), - Box::new(info.clone()) - )); - assert_ok!(Identity::::provide_judgement( - RawOrigin::Signed(registrar_account::()).into(), - 0, - T::Lookup::unlookup(account.clone()), - Judgement::KnownGood - )); + T::Currency::make_free_balance_be(&account, BalanceOf::::max_value()); account } fn set_members, I: 'static>() { - create_registrar_account::(); - let founders = vec![ funded_account::("founder", 1), funded_account::("founder", 2), diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index ed6cbce925774..3a2103bdcdefc 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -130,9 +130,11 @@ pub type ProposalIndex = u32; type Url = Vec; -type BalanceOf = <::Currency as Currency< +type BalanceOf = + <>::Currency as Currency<::AccountId>>::Balance; +type NegativeImbalanceOf = <>::Currency as Currency< ::AccountId, ->>::Balance; +>>::NegativeImbalance; pub trait IdentityVerifier { fn has_identity(who: &AccountId, fields: u64) -> bool; @@ -194,7 +196,7 @@ pub mod pallet { pub struct Pallet(PhantomData<(T, I)>); #[pallet::config] - pub trait Config: frame_system::Config + pallet_identity::Config { + pub trait Config: frame_system::Config { /// The overarching event type. type Event: From> + IsType<::Event>; @@ -210,6 +212,12 @@ pub mod pallet { /// of a majority-carries referendum. type SuperMajorityOrigin: EnsureOrigin; + /// The currency used for deposits. + type Currency: ReservableCurrency; + + /// What to do with slashed funds. + type Slashed: OnUnbalanced>; + /// What to do with genesis members type InitializeMembers: InitializeMembers; @@ -232,7 +240,7 @@ pub mod pallet { /// The amount of a deposit required for submitting candidacy. #[pallet::constant] - type CandidateDeposit: Get>; + type CandidateDeposit: Get>; /// Weight information for extrinsics in this pallet. type WeightInfo: WeightInfo; @@ -297,7 +305,7 @@ pub mod pallet { FoundersInitialized(Vec), /// An account has been added as a candidate and lock its deposit. \[candidate, nominator, /// reserved\] - CandidateAdded(T::AccountId, Option, Option>), + CandidateAdded(T::AccountId, Option, Option>), /// A proposal has been proposed to approve the candidate. \[candidate\] CandidateApproved(T::AccountId), /// A proposal has been proposed to reject the candidate. \[candidate\] @@ -306,10 +314,10 @@ pub mod pallet { AllyElevated(T::AccountId), /// A member has retired to an ordinary account with its deposit unreserved. \[member, /// unreserved\] - MemberRetired(T::AccountId, Option>), + MemberRetired(T::AccountId, Option>), /// A member has been kicked out to an ordinary account with its deposit slashed. \[member, /// slashed\] - MemberKicked(T::AccountId, Option>), + MemberKicked(T::AccountId, Option>), /// Accounts or websites have been added into blacklist. \[items\] BlacklistAdded(Vec>), /// Accounts or websites have been removed from blacklist. \[items\] @@ -391,7 +399,7 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn deposit_of)] pub type DepositOf, I: 'static = ()> = - StorageMap<_, Blake2_128Concat, T::AccountId, BalanceOf, OptionQuery>; + StorageMap<_, Blake2_128Concat, T::AccountId, BalanceOf, OptionQuery>; /// The current set of candidates. /// If the candidacy is approved by a motion, then it will become an ally member. diff --git a/frame/alliance/src/mock.rs b/frame/alliance/src/mock.rs index 6c3471d747a10..4f6bf00b1bdf8 100644 --- a/frame/alliance/src/mock.rs +++ b/frame/alliance/src/mock.rs @@ -132,10 +132,17 @@ impl pallet_identity::Config for Test { pub struct AllianceIdentityVerifier; impl IdentityVerifier for AllianceIdentityVerifier { + #[cfg(not(feature = "runtime-benchmarks"))] fn has_identity(who: &u64, fields: u64) -> bool { Identity::has_identity(who, fields) } + #[cfg(feature = "runtime-benchmarks")] + fn has_identity(_who: &u64, _fields: u64) -> bool { + true + } + + #[cfg(not(feature = "runtime-benchmarks"))] fn has_good_judgement(who: &u64) -> bool { if let Some(judgements) = Identity::identity(who).map(|registration| registration.judgements) @@ -149,9 +156,20 @@ impl IdentityVerifier for AllianceIdentityVerifier { } } + #[cfg(feature = "runtime-benchmarks")] + fn has_good_judgement(_who: &u64) -> bool { + true + } + + #[cfg(not(feature = "runtime-benchmarks"))] fn super_account_id(who: &u64) -> Option { Identity::super_of(who).map(|parent| parent.0) } + + #[cfg(feature = "runtime-benchmarks")] + fn super_account_id(_who: &u64) -> Option { + None + } } pub struct AllianceProposalProvider; @@ -196,6 +214,8 @@ impl Config for Test { type Event = Event; type Proposal = Call; type SuperMajorityOrigin = EnsureSignedBy; + type Currency = Balances; + type Slashed = (); type InitializeMembers = AllianceMotion; type MembershipChanged = AllianceMotion; type IdentityVerifier = AllianceIdentityVerifier; diff --git a/frame/alliance/src/tests.rs b/frame/alliance/src/tests.rs index d863948afc40a..14a163729e738 100644 --- a/frame/alliance/src/tests.rs +++ b/frame/alliance/src/tests.rs @@ -276,11 +276,13 @@ fn submit_candidacy_works() { ); // check missing identity judgement + #[cfg(not(feature = "runtime-benchmarks"))] assert_noop!( Alliance::submit_candidacy(Origin::signed(6)), Error::::WithoutGoodIdentityJudgement ); // check missing identity info + #[cfg(not(feature = "runtime-benchmarks"))] assert_noop!( Alliance::submit_candidacy(Origin::signed(7)), Error::::WithoutIdentityDisplayAndWebsite @@ -326,11 +328,13 @@ fn nominate_candidacy_works() { ); // check missing identity judgement + #[cfg(not(feature = "runtime-benchmarks"))] assert_noop!( Alliance::submit_candidacy(Origin::signed(6)), Error::::WithoutGoodIdentityJudgement ); // check missing identity info + #[cfg(not(feature = "runtime-benchmarks"))] assert_noop!( Alliance::submit_candidacy(Origin::signed(7)), Error::::WithoutIdentityDisplayAndWebsite diff --git a/frame/alliance/src/weights.rs b/frame/alliance/src/weights.rs index fd4ae27cfbfd6..34c108fc07283 100644 --- a/frame/alliance/src/weights.rs +++ b/frame/alliance/src/weights.rs @@ -18,7 +18,7 @@ //! Autogenerated weights for pallet_alliance //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2021-10-05, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2021-10-09, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: @@ -64,45 +64,43 @@ pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { // Storage: Alliance Rule (r:0 w:1) fn set_rule() -> Weight { - (15_740_000 as Weight) + (15_288_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Alliance Announcements (r:1 w:1) fn announce() -> Weight { - (17_984_000 as Weight) + (17_342_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Alliance Announcements (r:1 w:1) fn remove_announcement() -> Weight { - (18_094_000 as Weight) + (17_924_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Alliance AccountBlacklist (r:1 w:0) // Storage: Alliance Candidates (r:1 w:1) // Storage: Alliance Members (r:4 w:0) - // Storage: Identity IdentityOf (r:1 w:0) // Storage: System Account (r:1 w:1) // Storage: Alliance DepositOf (r:0 w:1) fn submit_candidacy() -> Weight { - (68_729_000 as Weight) - .saturating_add(T::DbWeight::get().reads(8 as Weight)) + (62_597_000 as Weight) + .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } // Storage: Alliance Members (r:4 w:0) // Storage: Alliance AccountBlacklist (r:1 w:0) // Storage: Alliance Candidates (r:1 w:1) - // Storage: Identity IdentityOf (r:1 w:0) fn nominate_candidacy() -> Weight { - (52_599_000 as Weight) - .saturating_add(T::DbWeight::get().reads(7 as Weight)) + (45_906_000 as Weight) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Alliance Candidates (r:1 w:1) // Storage: Alliance Members (r:4 w:1) fn approve_candidate() -> Weight { - (45_466_000 as Weight) + (45_906_000 as Weight) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } @@ -111,7 +109,7 @@ impl WeightInfo for SubstrateWeight { // Storage: Alliance DepositOf (r:1 w:1) // Storage: System Account (r:1 w:1) fn reject_candidate() -> Weight { - (71_815_000 as Weight) + (71_654_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } @@ -120,7 +118,7 @@ impl WeightInfo for SubstrateWeight { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn elevate_ally() -> Weight { - (44_063_000 as Weight) + (45_294_000 as Weight) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } @@ -132,7 +130,7 @@ impl WeightInfo for SubstrateWeight { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn retire() -> Weight { - (62_137_000 as Weight) + (61_915_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(5 as Weight)) } @@ -144,25 +142,25 @@ impl WeightInfo for SubstrateWeight { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn kick_member() -> Weight { - (69_491_000 as Weight) + (72_525_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(5 as Weight)) } // Storage: Alliance AccountBlacklist (r:1 w:0) // Storage: Alliance WebsiteBlacklist (r:1 w:0) fn add_blacklist(n: u32, ) -> Weight { - (26_953_000 as Weight) - // Standard Error: 5_000 - .saturating_add((2_114_000 as Weight).saturating_mul(n as Weight)) + (25_257_000 as Weight) + // Standard Error: 27_000 + .saturating_add((2_243_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } // Storage: Alliance AccountBlacklist (r:1 w:1) // Storage: Alliance WebsiteBlacklist (r:1 w:1) fn remove_blacklist(n: u32, ) -> Weight { - (69_853_000 as Weight) - // Standard Error: 21_000 - .saturating_add((29_661_000 as Weight).saturating_mul(n as Weight)) + (49_502_000 as Weight) + // Standard Error: 79_000 + .saturating_add((29_443_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } @@ -172,45 +170,43 @@ impl WeightInfo for SubstrateWeight { impl WeightInfo for () { // Storage: Alliance Rule (r:0 w:1) fn set_rule() -> Weight { - (15_740_000 as Weight) + (15_288_000 as Weight) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Alliance Announcements (r:1 w:1) fn announce() -> Weight { - (17_984_000 as Weight) + (17_342_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Alliance Announcements (r:1 w:1) fn remove_announcement() -> Weight { - (18_094_000 as Weight) + (17_924_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Alliance AccountBlacklist (r:1 w:0) // Storage: Alliance Candidates (r:1 w:1) // Storage: Alliance Members (r:4 w:0) - // Storage: Identity IdentityOf (r:1 w:0) // Storage: System Account (r:1 w:1) // Storage: Alliance DepositOf (r:0 w:1) fn submit_candidacy() -> Weight { - (68_729_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(8 as Weight)) + (62_597_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } // Storage: Alliance Members (r:4 w:0) // Storage: Alliance AccountBlacklist (r:1 w:0) // Storage: Alliance Candidates (r:1 w:1) - // Storage: Identity IdentityOf (r:1 w:0) fn nominate_candidacy() -> Weight { - (52_599_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(7 as Weight)) + (45_906_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(6 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Alliance Candidates (r:1 w:1) // Storage: Alliance Members (r:4 w:1) fn approve_candidate() -> Weight { - (45_466_000 as Weight) + (45_906_000 as Weight) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } @@ -219,7 +215,7 @@ impl WeightInfo for () { // Storage: Alliance DepositOf (r:1 w:1) // Storage: System Account (r:1 w:1) fn reject_candidate() -> Weight { - (71_815_000 as Weight) + (71_654_000 as Weight) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } @@ -228,7 +224,7 @@ impl WeightInfo for () { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn elevate_ally() -> Weight { - (44_063_000 as Weight) + (45_294_000 as Weight) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(4 as Weight)) } @@ -240,7 +236,7 @@ impl WeightInfo for () { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn retire() -> Weight { - (62_137_000 as Weight) + (61_915_000 as Weight) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().writes(5 as Weight)) } @@ -252,25 +248,25 @@ impl WeightInfo for () { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn kick_member() -> Weight { - (69_491_000 as Weight) + (72_525_000 as Weight) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().writes(5 as Weight)) } // Storage: Alliance AccountBlacklist (r:1 w:0) // Storage: Alliance WebsiteBlacklist (r:1 w:0) fn add_blacklist(n: u32, ) -> Weight { - (26_953_000 as Weight) - // Standard Error: 5_000 - .saturating_add((2_114_000 as Weight).saturating_mul(n as Weight)) + (25_257_000 as Weight) + // Standard Error: 27_000 + .saturating_add((2_243_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } // Storage: Alliance AccountBlacklist (r:1 w:1) // Storage: Alliance WebsiteBlacklist (r:1 w:1) fn remove_blacklist(n: u32, ) -> Weight { - (69_853_000 as Weight) - // Standard Error: 21_000 - .saturating_add((29_661_000 as Weight).saturating_mul(n as Weight)) + (49_502_000 as Weight) + // Standard Error: 79_000 + .saturating_add((29_443_000 as Weight).saturating_mul(n as Weight)) .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } From b07520eca8ee6e82a999a6e1e7b87c32a9bcfe69 Mon Sep 17 00:00:00 2001 From: koushiro Date: Mon, 11 Oct 2021 10:52:27 +0800 Subject: [PATCH 12/72] Fix propose arguments Signed-off-by: koushiro --- bin/node/runtime/src/impls.rs | 5 +++-- frame/alliance/src/lib.rs | 10 +++++++--- frame/alliance/src/mock.rs | 4 ++-- frame/alliance/src/tests.rs | 22 ++++++++++++++-------- frame/collective/src/lib.rs | 16 ++++++++++------ 5 files changed, 36 insertions(+), 21 deletions(-) diff --git a/bin/node/runtime/src/impls.rs b/bin/node/runtime/src/impls.rs index e0e8d919d89e4..002cb945f40e3 100644 --- a/bin/node/runtime/src/impls.rs +++ b/bin/node/runtime/src/impls.rs @@ -98,8 +98,9 @@ impl ProposalProvider for AllianceProposalProvider { who: AccountId, threshold: u32, proposal: Call, - ) -> Result { - AllianceMotion::do_propose(who, threshold, proposal) + length_bound: u32, + ) -> Result<(u32, u32), DispatchError> { + AllianceMotion::do_propose(who, threshold, proposal, length_bound) } fn vote_proposal( diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index 3a2103bdcdefc..c66fb3c9a31f0 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -149,7 +149,8 @@ pub trait ProposalProvider { who: AccountId, threshold: u32, proposal: Proposal, - ) -> Result; + length_bound: u32, + ) -> Result<(u32, u32), DispatchError>; fn vote_proposal( who: AccountId, @@ -442,7 +443,9 @@ pub mod pallet { #[pallet::weight(0)] pub fn propose( origin: OriginFor, + #[pallet::compact] threshold: u32, proposal: Box<>::Proposal>, + #[pallet::compact] length_bound: u32, ) -> DispatchResultWithPostInfo { let proposor = ensure_signed(origin)?; ensure!(Self::is_votable_member(&proposor), Error::::NotVotableMember); @@ -452,8 +455,7 @@ pub mod pallet { >::insert(strike, true); } - let threshold = 2 * Self::votable_member_count() / 3 + 1; - T::ProposalProvider::propose_proposal(proposor, threshold, *proposal)?; + T::ProposalProvider::propose_proposal(proposor, threshold, *proposal, length_bound)?; Ok(().into()) } @@ -866,11 +868,13 @@ impl, I: 'static> Pallet { Self::is_founder(who) || Self::is_fellow(who) } + /* fn votable_member_count() -> u32 { let founder_count = Members::::decode_len(MemberRole::Founder).unwrap_or_default(); let fellow_count = Members::::decode_len(MemberRole::Fellow).unwrap_or_default(); (founder_count + fellow_count) as u32 } + */ fn votable_member_sorted() -> Vec { let mut founders = Members::::get(MemberRole::Founder); diff --git a/frame/alliance/src/mock.rs b/frame/alliance/src/mock.rs index 4f6bf00b1bdf8..ee8befb31e80b 100644 --- a/frame/alliance/src/mock.rs +++ b/frame/alliance/src/mock.rs @@ -174,8 +174,8 @@ impl IdentityVerifier for AllianceIdentityVerifier { pub struct AllianceProposalProvider; impl ProposalProvider for AllianceProposalProvider { - fn propose_proposal(who: u64, threshold: u32, proposal: Call) -> Result { - AllianceMotion::do_propose(who, threshold, proposal) + fn propose_proposal(who: u64, threshold: u32, proposal: Call, length_bound: u32) -> Result<(u32, u32), DispatchError> { + AllianceMotion::do_propose(who, threshold, proposal, length_bound) } fn vote_proposal( diff --git a/frame/alliance/src/tests.rs b/frame/alliance/src/tests.rs index 14a163729e738..d75cf7e88135c 100644 --- a/frame/alliance/src/tests.rs +++ b/frame/alliance/src/tests.rs @@ -31,15 +31,16 @@ type AllianceMotionEvent = pallet_collective::Event::NotVotableMember ); - assert_ok!(Alliance::propose(Origin::signed(1), Box::new(proposal.clone()))); + assert_ok!(Alliance::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len)); assert_eq!(*AllianceMotion::proposals(), vec![hash]); assert_eq!(AllianceMotion::proposal_of(&hash), Some(proposal)); assert_eq!( @@ -57,8 +58,9 @@ fn propose_works() { fn vote_works() { new_test_ext().execute_with(|| { let proposal = make_proposal(42); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); let hash: H256 = proposal.blake2_256().into(); - assert_ok!(Alliance::propose(Origin::signed(1), Box::new(proposal.clone()))); + assert_ok!(Alliance::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len)); assert_ok!(Alliance::vote(Origin::signed(2), hash.clone(), 0, true)); let record = |event| EventRecord { phase: Phase::Initialization, event, topics: vec![] }; @@ -87,8 +89,9 @@ fn vote_works() { fn veto_works() { new_test_ext().execute_with(|| { let proposal = make_proposal(42); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); let hash: H256 = proposal.blake2_256().into(); - assert_ok!(Alliance::propose(Origin::signed(1), Box::new(proposal.clone()))); + assert_ok!(Alliance::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len)); // only set_rule/elevate_ally can be veto assert_noop!( Alliance::veto(Origin::signed(1), hash.clone()), @@ -97,8 +100,9 @@ fn veto_works() { let cid = test_cid(); let vetoable_proposal = make_set_rule_proposal(cid); + let vetoable_proposal_len: u32 = vetoable_proposal.using_encoded(|p| p.len() as u32); let vetoable_hash: H256 = vetoable_proposal.blake2_256().into(); - assert_ok!(Alliance::propose(Origin::signed(1), Box::new(vetoable_proposal.clone()))); + assert_ok!(Alliance::propose(Origin::signed(1), 3, Box::new(vetoable_proposal.clone()), vetoable_proposal_len)); // only founder have veto rights, 3 is fellow assert_noop!( @@ -140,7 +144,7 @@ fn close_works() { let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); let proposal_weight = proposal.get_dispatch_info().weight; let hash = BlakeTwo256::hash_of(&proposal); - assert_ok!(Alliance::propose(Origin::signed(1), Box::new(proposal.clone()))); + assert_ok!(Alliance::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len)); assert_ok!(Alliance::vote(Origin::signed(1), hash.clone(), 0, true)); assert_ok!(Alliance::vote(Origin::signed(2), hash.clone(), 0, true)); assert_ok!(Alliance::vote(Origin::signed(3), hash.clone(), 0, true)); @@ -397,7 +401,8 @@ fn elevate_ally_works() { fn retire_works() { new_test_ext().execute_with(|| { let proposal = make_kick_member_proposal(2); - assert_ok!(Alliance::propose(Origin::signed(1), Box::new(proposal.clone()))); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); + assert_ok!(Alliance::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len)); assert_noop!(Alliance::retire(Origin::signed(2)), Error::::KickingMember); assert_noop!(Alliance::retire(Origin::signed(4)), Error::::NotMember); @@ -417,7 +422,8 @@ fn kick_member_works() { ); let proposal = make_kick_member_proposal(2); - assert_ok!(Alliance::propose(Origin::signed(1), Box::new(proposal.clone()))); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); + assert_ok!(Alliance::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len)); assert_eq!(Alliance::kicking_member(2), true); assert_eq!(Alliance::members(MemberRole::Founder), vec![1, 2]); diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index c3ce503098165..1b7d4f3df0bbd 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -514,10 +514,10 @@ pub mod pallet { let members = Self::members(); ensure!(members.contains(&who), Error::::NotMember); - let proposal_len = proposal.using_encoded(|x| x.len()); - ensure!(proposal_len <= length_bound as usize, Error::::WrongProposalLength); - if threshold < 2 { + let proposal_len = proposal.using_encoded(|x| x.len()); + ensure!(proposal_len <= length_bound as usize, Error::::WrongProposalLength); + let proposal_hash = T::Hashing::hash_of(&proposal); ensure!( !>::contains_key(proposal_hash), @@ -541,7 +541,7 @@ pub mod pallet { }) .into()) } else { - let active_proposals = Self::do_propose(who, threshold, *proposal)?; + let (proposal_len, active_proposals) = Self::do_propose(who, threshold, *proposal, length_bound)?; Ok(Some(T::WeightInfo::propose_proposed( proposal_len as u32, // B @@ -695,7 +695,11 @@ impl, I: 'static> Pallet { who: T::AccountId, threshold: MemberCount, proposal: >::Proposal, - ) -> Result { + length_bound: MemberCount, + ) -> Result<(u32, u32), DispatchError> { + let proposal_len = proposal.using_encoded(|x| x.len()); + ensure!(proposal_len <= length_bound as usize, Error::::WrongProposalLength); + let proposal_hash = T::Hashing::hash_of(&proposal); ensure!(!>::contains_key(proposal_hash), Error::::DuplicateProposal); @@ -715,7 +719,7 @@ impl, I: 'static> Pallet { >::insert(proposal_hash, votes); Self::deposit_event(Event::Proposed(who, index, proposal_hash, threshold)); - Ok(active_proposals as u32) + Ok((proposal_len as u32, active_proposals as u32)) } /// Add an aye or nay vote for the member to the given proposal, returns true if it's the first From 9774055cd965ce52820be6585d3cd90f312afa3e Mon Sep 17 00:00:00 2001 From: koushiro Date: Mon, 11 Oct 2021 12:26:50 +0800 Subject: [PATCH 13/72] Some nits Signed-off-by: koushiro --- bin/node/runtime/src/impls.rs | 11 +++++---- frame/alliance/src/lib.rs | 4 ++-- frame/alliance/src/mock.rs | 4 ++-- frame/collective/src/lib.rs | 45 +++++++++++++++++++++-------------- 4 files changed, 38 insertions(+), 26 deletions(-) diff --git a/bin/node/runtime/src/impls.rs b/bin/node/runtime/src/impls.rs index 002cb945f40e3..5ce43aa88ee4c 100644 --- a/bin/node/runtime/src/impls.rs +++ b/bin/node/runtime/src/impls.rs @@ -17,17 +17,20 @@ //! Some configurable implementations as associated type for the substrate runtime. -use crate::{AllianceMotion, Authorship, Balances, Call, NegativeImbalance}; +use node_primitives::{AccountId, Hash}; +use sp_std::prelude::*; + use frame_support::{ dispatch::{DispatchError, DispatchResultWithPostInfo}, traits::{Currency, OnUnbalanced}, weights::Weight, }; -use node_primitives::{AccountId, Hash}; use pallet_alliance::{IdentityVerifier, ProposalIndex, ProposalProvider}; use pallet_identity::Judgement; use pallet_asset_tx_payment::HandleCredit; +use crate::{AllianceMotion, Authorship, Balances, Call, NegativeImbalance}; + pub struct Author; impl OnUnbalanced for Author { fn on_nonzero_unbalanced(amount: NegativeImbalance) { @@ -97,10 +100,10 @@ impl ProposalProvider for AllianceProposalProvider { fn propose_proposal( who: AccountId, threshold: u32, - proposal: Call, + proposal: Box, length_bound: u32, ) -> Result<(u32, u32), DispatchError> { - AllianceMotion::do_propose(who, threshold, proposal, length_bound) + AllianceMotion::do_propose_proposed(who, threshold, proposal, length_bound) } fn vote_proposal( diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index c66fb3c9a31f0..8ea4e818d1ad8 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -148,7 +148,7 @@ pub trait ProposalProvider { fn propose_proposal( who: AccountId, threshold: u32, - proposal: Proposal, + proposal: Box, length_bound: u32, ) -> Result<(u32, u32), DispatchError>; @@ -455,7 +455,7 @@ pub mod pallet { >::insert(strike, true); } - T::ProposalProvider::propose_proposal(proposor, threshold, *proposal, length_bound)?; + T::ProposalProvider::propose_proposal(proposor, threshold, proposal, length_bound)?; Ok(().into()) } diff --git a/frame/alliance/src/mock.rs b/frame/alliance/src/mock.rs index ee8befb31e80b..d998837ab09ce 100644 --- a/frame/alliance/src/mock.rs +++ b/frame/alliance/src/mock.rs @@ -174,8 +174,8 @@ impl IdentityVerifier for AllianceIdentityVerifier { pub struct AllianceProposalProvider; impl ProposalProvider for AllianceProposalProvider { - fn propose_proposal(who: u64, threshold: u32, proposal: Call, length_bound: u32) -> Result<(u32, u32), DispatchError> { - AllianceMotion::do_propose(who, threshold, proposal, length_bound) + fn propose_proposal(who: u64, threshold: u32, proposal: Box, length_bound: u32) -> Result<(u32, u32), DispatchError> { + AllianceMotion::do_propose_proposed(who, threshold, proposal, length_bound) } fn vote_proposal( diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index 1b7d4f3df0bbd..84708c7c69be9 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -515,21 +515,7 @@ pub mod pallet { ensure!(members.contains(&who), Error::::NotMember); if threshold < 2 { - let proposal_len = proposal.using_encoded(|x| x.len()); - ensure!(proposal_len <= length_bound as usize, Error::::WrongProposalLength); - - let proposal_hash = T::Hashing::hash_of(&proposal); - ensure!( - !>::contains_key(proposal_hash), - Error::::DuplicateProposal - ); - - let seats = Self::members().len() as MemberCount; - let result = proposal.dispatch(RawOrigin::Members(1, seats).into()); - Self::deposit_event(Event::Executed { - proposal_hash, - result: result.map(|_| ()).map_err(|e| e.error), - }); + let (proposal_len, result) = Self::do_propose_execute(proposal, length_bound)?; Ok(get_result_weight(result) .map(|w| { @@ -541,7 +527,7 @@ pub mod pallet { }) .into()) } else { - let (proposal_len, active_proposals) = Self::do_propose(who, threshold, *proposal, length_bound)?; + let (proposal_len, active_proposals) = Self::do_propose_proposed(who, threshold, proposal, length_bound)?; Ok(Some(T::WeightInfo::propose_proposed( proposal_len as u32, // B @@ -690,11 +676,34 @@ impl, I: 'static> Pallet { Self::members().contains(who) } + /// Execute immediately when adding a new proposal. + pub fn do_propose_execute( + proposal: Box<>::Proposal>, + length_bound: MemberCount, + ) -> Result<(u32, DispatchResultWithPostInfo), DispatchError> { + let proposal_len = proposal.using_encoded(|x| x.len()); + ensure!(proposal_len <= length_bound as usize, Error::::WrongProposalLength); + + let proposal_hash = T::Hashing::hash_of(&proposal); + ensure!( + !>::contains_key(proposal_hash), + Error::::DuplicateProposal + ); + + let seats = Self::members().len() as MemberCount; + let result = proposal.dispatch(RawOrigin::Members(1, seats).into()); + Self::deposit_event(Event::Executed( + proposal_hash, + result.map(|_| ()).map_err(|e| e.error), + )); + Ok((proposal_len as u32, result)) + } + /// Add a new proposal to be voted. - pub fn do_propose( + pub fn do_propose_proposed( who: T::AccountId, threshold: MemberCount, - proposal: >::Proposal, + proposal: Box<>::Proposal>, length_bound: MemberCount, ) -> Result<(u32, u32), DispatchError> { let proposal_len = proposal.using_encoded(|x| x.len()); From 0013afde074e24e988fe382ce30e80c4bc23190b Mon Sep 17 00:00:00 2001 From: koushiro Date: Mon, 11 Oct 2021 12:30:00 +0800 Subject: [PATCH 14/72] cargo fmt Signed-off-by: koushiro --- frame/alliance/src/mock.rs | 7 +++++- frame/alliance/src/tests.rs | 49 +++++++++++++++++++++++++++++++------ frame/collective/src/lib.rs | 8 +++--- 3 files changed, 51 insertions(+), 13 deletions(-) diff --git a/frame/alliance/src/mock.rs b/frame/alliance/src/mock.rs index d998837ab09ce..900f3c48ac66c 100644 --- a/frame/alliance/src/mock.rs +++ b/frame/alliance/src/mock.rs @@ -174,7 +174,12 @@ impl IdentityVerifier for AllianceIdentityVerifier { pub struct AllianceProposalProvider; impl ProposalProvider for AllianceProposalProvider { - fn propose_proposal(who: u64, threshold: u32, proposal: Box, length_bound: u32) -> Result<(u32, u32), DispatchError> { + fn propose_proposal( + who: u64, + threshold: u32, + proposal: Box, + length_bound: u32, + ) -> Result<(u32, u32), DispatchError> { AllianceMotion::do_propose_proposed(who, threshold, proposal, length_bound) } diff --git a/frame/alliance/src/tests.rs b/frame/alliance/src/tests.rs index d75cf7e88135c..7d5a6f73953eb 100644 --- a/frame/alliance/src/tests.rs +++ b/frame/alliance/src/tests.rs @@ -40,7 +40,12 @@ fn propose_works() { Error::::NotVotableMember ); - assert_ok!(Alliance::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len)); + assert_ok!(Alliance::propose( + Origin::signed(1), + 3, + Box::new(proposal.clone()), + proposal_len + )); assert_eq!(*AllianceMotion::proposals(), vec![hash]); assert_eq!(AllianceMotion::proposal_of(&hash), Some(proposal)); assert_eq!( @@ -60,7 +65,12 @@ fn vote_works() { let proposal = make_proposal(42); let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); let hash: H256 = proposal.blake2_256().into(); - assert_ok!(Alliance::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len)); + assert_ok!(Alliance::propose( + Origin::signed(1), + 3, + Box::new(proposal.clone()), + proposal_len + )); assert_ok!(Alliance::vote(Origin::signed(2), hash.clone(), 0, true)); let record = |event| EventRecord { phase: Phase::Initialization, event, topics: vec![] }; @@ -91,7 +101,12 @@ fn veto_works() { let proposal = make_proposal(42); let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); let hash: H256 = proposal.blake2_256().into(); - assert_ok!(Alliance::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len)); + assert_ok!(Alliance::propose( + Origin::signed(1), + 3, + Box::new(proposal.clone()), + proposal_len + )); // only set_rule/elevate_ally can be veto assert_noop!( Alliance::veto(Origin::signed(1), hash.clone()), @@ -102,7 +117,12 @@ fn veto_works() { let vetoable_proposal = make_set_rule_proposal(cid); let vetoable_proposal_len: u32 = vetoable_proposal.using_encoded(|p| p.len() as u32); let vetoable_hash: H256 = vetoable_proposal.blake2_256().into(); - assert_ok!(Alliance::propose(Origin::signed(1), 3, Box::new(vetoable_proposal.clone()), vetoable_proposal_len)); + assert_ok!(Alliance::propose( + Origin::signed(1), + 3, + Box::new(vetoable_proposal.clone()), + vetoable_proposal_len + )); // only founder have veto rights, 3 is fellow assert_noop!( @@ -144,7 +164,12 @@ fn close_works() { let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); let proposal_weight = proposal.get_dispatch_info().weight; let hash = BlakeTwo256::hash_of(&proposal); - assert_ok!(Alliance::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len)); + assert_ok!(Alliance::propose( + Origin::signed(1), + 3, + Box::new(proposal.clone()), + proposal_len + )); assert_ok!(Alliance::vote(Origin::signed(1), hash.clone(), 0, true)); assert_ok!(Alliance::vote(Origin::signed(2), hash.clone(), 0, true)); assert_ok!(Alliance::vote(Origin::signed(3), hash.clone(), 0, true)); @@ -402,7 +427,12 @@ fn retire_works() { new_test_ext().execute_with(|| { let proposal = make_kick_member_proposal(2); let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); - assert_ok!(Alliance::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len)); + assert_ok!(Alliance::propose( + Origin::signed(1), + 3, + Box::new(proposal.clone()), + proposal_len + )); assert_noop!(Alliance::retire(Origin::signed(2)), Error::::KickingMember); assert_noop!(Alliance::retire(Origin::signed(4)), Error::::NotMember); @@ -423,7 +453,12 @@ fn kick_member_works() { let proposal = make_kick_member_proposal(2); let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); - assert_ok!(Alliance::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len)); + assert_ok!(Alliance::propose( + Origin::signed(1), + 3, + Box::new(proposal.clone()), + proposal_len + )); assert_eq!(Alliance::kicking_member(2), true); assert_eq!(Alliance::members(MemberRole::Founder), vec![1, 2]); diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index 84708c7c69be9..8ef7480c2cdf0 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -527,7 +527,8 @@ pub mod pallet { }) .into()) } else { - let (proposal_len, active_proposals) = Self::do_propose_proposed(who, threshold, proposal, length_bound)?; + let (proposal_len, active_proposals) = + Self::do_propose_proposed(who, threshold, proposal, length_bound)?; Ok(Some(T::WeightInfo::propose_proposed( proposal_len as u32, // B @@ -685,10 +686,7 @@ impl, I: 'static> Pallet { ensure!(proposal_len <= length_bound as usize, Error::::WrongProposalLength); let proposal_hash = T::Hashing::hash_of(&proposal); - ensure!( - !>::contains_key(proposal_hash), - Error::::DuplicateProposal - ); + ensure!(!>::contains_key(proposal_hash), Error::::DuplicateProposal); let seats = Self::members().len() as MemberCount; let result = proposal.dispatch(RawOrigin::Members(1, seats).into()); From 6b2c8af90dd1aad406cadc5f6e3948c766a2e306 Mon Sep 17 00:00:00 2001 From: koushiro Date: Mon, 11 Oct 2021 13:57:20 +0800 Subject: [PATCH 15/72] Fix benchmarking of add_blacklist/remove_blacklist Signed-off-by: koushiro --- frame/alliance/src/benchmarking.rs | 120 ++++++++++++++--------------- frame/alliance/src/lib.rs | 101 ++++++++++++++++-------- frame/alliance/src/mock.rs | 13 +++- frame/alliance/src/weights.rs | 86 +++++++++++---------- 4 files changed, 186 insertions(+), 134 deletions(-) diff --git a/frame/alliance/src/benchmarking.rs b/frame/alliance/src/benchmarking.rs index 2f900c4f0914c..523ceb1e3146f 100644 --- a/frame/alliance/src/benchmarking.rs +++ b/frame/alliance/src/benchmarking.rs @@ -44,22 +44,42 @@ fn funded_account, I: 'static>(name: &'static str, index: u32) -> T account } +fn founder, I: 'static>(index: u32) -> T::AccountId { + funded_account::("founder", index) +} + +fn fellow, I: 'static>(index: u32) -> T::AccountId { + funded_account::("fellow", index) +} + +fn ally, I: 'static>(index: u32) -> T::AccountId { + funded_account::("ally", index) +} + +fn candidate, I: 'static>(index: u32) -> T::AccountId { + funded_account::("candidate", index) +} + +fn outsider, I: 'static>(index: u32) -> T::AccountId { + funded_account::("outsider", index) +} + +fn blacklist, I: 'static>(index: u32) -> T::AccountId { + funded_account::("blacklist", index) +} + fn set_members, I: 'static>() { - let founders = vec![ - funded_account::("founder", 1), - funded_account::("founder", 2), - funded_account::("founder", 3), - ]; + let founders = vec![founder::(1), founder::(2)]; Members::::insert(MemberRole::Founder, founders.clone()); - let fellows = vec![funded_account::("fellow", 1), funded_account::("fellow", 2)]; + let fellows = vec![fellow::(1), fellow::(2)]; fellows.iter().for_each(|who| { T::Currency::reserve(&who, T::CandidateDeposit::get()).unwrap(); >::insert(&who, T::CandidateDeposit::get()); }); Members::::insert(MemberRole::Fellow, fellows.clone()); - let allies = vec![funded_account::("ally", 1)]; + let allies = vec![ally::(1)]; allies.iter().for_each(|who| { T::Currency::reserve(&who, T::CandidateDeposit::get()).unwrap(); >::insert(&who, T::CandidateDeposit::get()); @@ -69,24 +89,6 @@ fn set_members, I: 'static>() { T::InitializeMembers::initialize_members(&[founders.as_slice(), fellows.as_slice()].concat()); } -fn founder1, I: 'static>() -> T::AccountId { - funded_account::("founder", 1) -} - -fn fellow2, I: 'static>() -> T::AccountId { - funded_account::("fellow", 2) -} - -fn kicking_fellow2, I: 'static>() -> T::AccountId { - let fellow2 = funded_account::("fellow", 2); - KickingMembers::::insert(&fellow2, true); - fellow2 -} - -fn ally1, I: 'static>() -> T::AccountId { - funded_account::("ally", 1) -} - fn set_announcement, I: 'static>(cid: Cid) { Announcements::::put(vec![cid]); } @@ -100,31 +102,6 @@ fn set_candidates, I: 'static>() { Candidates::::put(candidates); } -fn candidate1, I: 'static>() -> T::AccountId { - funded_account::("candidate", 1) -} - -fn create_outsider, I: 'static>() -> T::AccountId { - funded_account::("outsider", 1) -} - -fn blacklist_account, I: 'static>(index: u32) -> T::AccountId { - funded_account::("blacklist", index) -} - -fn set_blacklist, I: 'static>() { - let mut account_blacklist = (0..T::MaxBlacklistCount::get()) - .map(|i| blacklist_account::(i)) - .collect::>(); - account_blacklist.sort(); - AccountBlacklist::::put(account_blacklist); - - let mut website_blacklist = - (0..T::MaxBlacklistCount::get()).map(|i| vec![i as u8]).collect::>(); - website_blacklist.sort(); - WebsiteBlacklist::::put(website_blacklist); -} - benchmarks_instance_pallet! { set_rule { set_members::(); @@ -166,7 +143,7 @@ benchmarks_instance_pallet! { submit_candidacy { set_members::(); - let outsider = create_outsider::(); + let outsider = outsider::(1); assert!(!Alliance::::is_member(&outsider)); assert!(!Alliance::::is_candidate(&outsider)); assert_eq!(DepositOf::::get(&outsider), None); @@ -181,10 +158,10 @@ benchmarks_instance_pallet! { nominate_candidacy { set_members::(); - let founder1 = founder1::(); + let founder1 = founder::(1); assert!(Alliance::::is_member_of(&founder1, MemberRole::Founder)); - let outsider = create_outsider::(); + let outsider = outsider::(1); assert!(!Alliance::::is_member(&outsider)); assert!(!Alliance::::is_candidate(&outsider)); assert_eq!(DepositOf::::get(&outsider), None); @@ -202,7 +179,7 @@ benchmarks_instance_pallet! { set_members::(); set_candidates::(); - let candidate1 = candidate1::(); + let candidate1 = candidate::(1); assert!(Alliance::::is_candidate(&candidate1)); assert!(!Alliance::::is_member(&candidate1)); assert_eq!(DepositOf::::get(&candidate1), Some(T::CandidateDeposit::get())); @@ -222,7 +199,7 @@ benchmarks_instance_pallet! { set_members::(); set_candidates::(); - let candidate1 = candidate1::(); + let candidate1 = candidate::(1); assert!(Alliance::::is_candidate(&candidate1)); assert!(!Alliance::::is_member(&candidate1)); assert_eq!(DepositOf::::get(&candidate1), Some(T::CandidateDeposit::get())); @@ -241,7 +218,7 @@ benchmarks_instance_pallet! { elevate_ally { set_members::(); - let ally1 = ally1::(); + let ally1 = ally::(1); assert!(Alliance::::is_ally(&ally1)); let ally1_lookup: ::Source = T::Lookup::unlookup(ally1.clone()); @@ -257,7 +234,7 @@ benchmarks_instance_pallet! { retire { set_members::(); - let fellow2 = fellow2::(); + let fellow2 = fellow::(2); assert!(Alliance::::is_fellow(&fellow2)); assert!(!Alliance::::is_kicking(&fellow2)); @@ -272,7 +249,9 @@ benchmarks_instance_pallet! { kick_member { set_members::(); - let fellow2 = kicking_fellow2::(); + let fellow2 = fellow::(2); + KickingMembers::::insert(&fellow2, true); + assert!(Alliance::::is_member_of(&fellow2, MemberRole::Fellow)); assert!(Alliance::::is_kicking(&fellow2)); @@ -290,10 +269,16 @@ benchmarks_instance_pallet! { add_blacklist { let n in 0 .. T::MaxBlacklistCount::get(); + let l in 0 .. T::MaxWebsiteUrlLength::get(); set_members::(); - let mut blacklist = (0..n).map(|i| BlacklistItem::AccountId(blacklist_account::(i))).collect::>(); - blacklist.extend((0..n).map(|i| BlacklistItem::Website(vec![i as u8]))); + + let accounts = (0 .. n).map(|i| blacklist::(i)).collect::>(); + let websites = (0 .. n).map(|i| vec![i as u8; l as usize]).collect::>(); + + let mut blacklist = Vec::with_capacity(accounts.len() + websites.len()); + blacklist.extend(accounts.into_iter().map(BlacklistItem::AccountId)); + blacklist.extend(websites.into_iter().map(BlacklistItem::Website)); let call = Call::::add_blacklist { infos: blacklist.clone() }; let origin = T::SuperMajorityOrigin::successful_origin(); @@ -304,12 +289,21 @@ benchmarks_instance_pallet! { remove_blacklist { let n in 0 .. T::MaxBlacklistCount::get(); + let l in 0 .. T::MaxWebsiteUrlLength::get(); set_members::(); - let mut blacklist = (0..n).map(|i| BlacklistItem::AccountId(blacklist_account::(i))).collect::>(); - blacklist.extend((0..n).map(|i| BlacklistItem::Website(vec![i as u8]))); - set_blacklist::(); + let mut accounts = (0 .. n).map(|i| blacklist::(i)).collect::>(); + accounts.sort(); + AccountBlacklist::::put(accounts.clone()); + + let mut websites = (0 .. n).map(|i| vec![i as u8; l as usize]).collect::>(); + websites.sort(); + WebsiteBlacklist::::put(websites.clone()); + + let mut blacklist = Vec::with_capacity(accounts.len() + websites.len()); + blacklist.extend(accounts.into_iter().map(BlacklistItem::AccountId)); + blacklist.extend(websites.into_iter().map(BlacklistItem::Website)); let call = Call::::remove_blacklist { infos: blacklist.clone() }; let origin = T::SuperMajorityOrigin::successful_origin(); diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index 8ea4e818d1ad8..3fea84b75ad5c 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -219,10 +219,10 @@ pub mod pallet { /// What to do with slashed funds. type Slashed: OnUnbalanced>; - /// What to do with genesis members + /// What to do with genesis voteable members type InitializeMembers: InitializeMembers; - /// The receiver of the signal for when the members have changed. + /// The receiver of the signal for when the voteable members have changed. type MembershipChanged: ChangeMembers; /// The identity verifier of alliance member. @@ -231,6 +231,32 @@ pub mod pallet { /// The provider of the proposal operation. type ProposalProvider: ProposalProvider; + /* + /// Maximum number of proposals allowed to be active in parallel. + type MaxProposals: Get; + + /// The maximum number of founders supported by the pallet. Used for weight estimation. + /// + /// NOTE: + /// + Benchmarks will need to be re-run and weights adjusted if this changes. + /// + This pallet assumes that dependents keep to the limit without enforcing it. + type MaxFounders: Get; + + /// The maximum number of fellows supported by the pallet. Used for weight estimation. + /// + /// NOTE: + /// + Benchmarks will need to be re-run and weights adjusted if this changes. + /// + This pallet assumes that dependents keep to the limit without enforcing it. + type MaxFellows: Get; + + /// The maximum number of allies supported by the pallet. Used for weight estimation. + /// + /// NOTE: + /// + Benchmarks will need to be re-run and weights adjusted if this changes. + /// + This pallet assumes that dependents keep to the limit without enforcing it. + type MaxAllies: Get; + */ + /// The maximum number of blacklist supported by the pallet. #[pallet::constant] type MaxBlacklistCount: Get; @@ -249,8 +275,8 @@ pub mod pallet { #[pallet::error] pub enum Error { - /// The founders have already been initialized. - FoundersAlreadyInitialized, + /// The founders/fellows/allies have already been initialized. + MembersAlreadyInitialized, /// Already be a candidate. AlreadyCandidate, /// Not be a candidate. @@ -302,8 +328,9 @@ pub mod pallet { NewAnnouncement(Cid), /// A on-chain announcement has been removed. \[announcement\] AnnouncementRemoved(Cid), - /// Some accounts have been initialized to founders. \[founders\] - FoundersInitialized(Vec), + /// Some accounts have been initialized to members (founders/fellows/allies). \[founders, + /// fellows, allies\] + MembersInitialized(Vec, Vec, Vec), /// An account has been added as a candidate and lock its deposit. \[candidate, nominator, /// reserved\] CandidateAdded(T::AccountId, Option, Option>), @@ -530,40 +557,54 @@ pub mod pallet { Ok(().into()) } - /// IInitialize the founders to the given members. + /// Initialize the founders/fellows/allies. /// /// This should be called by the referendum and can only be called once. #[pallet::weight(0)] - pub fn init_founders( + pub fn init_members( origin: OriginFor, - founders: Vec, + mut founders: Vec, + mut fellows: Vec, + mut allies: Vec, ) -> DispatchResultWithPostInfo { ensure_root(origin)?; + ensure!( - !Self::has_member(MemberRole::Founder), - Error::::FoundersAlreadyInitialized + !Self::has_member(MemberRole::Founder) && + !Self::has_member(MemberRole::Fellow) && + !Self::has_member(MemberRole::Ally), + Error::::MembersAlreadyInitialized ); - for founder in &founders { - Self::has_identity(founder)?; + for member in founders.iter().chain(fellows.iter()).chain(allies.iter()) { + Self::has_identity(member)?; } - let mut founders = founders; founders.sort(); - T::InitializeMembers::initialize_members(&founders); Members::::insert(&MemberRole::Founder, founders.clone()); + fellows.sort(); + Members::::insert(&MemberRole::Fellow, fellows.clone()); + allies.sort(); + Members::::insert(&MemberRole::Ally, allies.clone()); + + let mut voteable_members = Vec::with_capacity(founders.len() + fellows.len()); + voteable_members.extend(founders.clone()); + voteable_members.extend(fellows.clone()); + voteable_members.sort(); + + T::InitializeMembers::initialize_members(&voteable_members); log::debug!( target: "runtime::alliance", - "Initialize alliance founders: {:?}", - founders, + "Initialize alliance founders: {:?}, fellows: {:?}, allies: {:?}", + founders, fellows, allies ); - Self::deposit_event(Event::FoundersInitialized(founders)); + Self::deposit_event(Event::MembersInitialized(founders, fellows, allies)); Ok(().into()) } /// Set a new IPFS cid to the alliance rule. - #[pallet::weight(>::WeightInfo::set_rule())] + #[pallet::weight(T::WeightInfo::set_rule())] pub fn set_rule(origin: OriginFor, rule: Cid) -> DispatchResultWithPostInfo { T::SuperMajorityOrigin::ensure_origin(origin)?; @@ -574,7 +615,7 @@ pub mod pallet { } /// Make a new announcement by a new IPFS cid about the alliance issues. - #[pallet::weight(>::WeightInfo::announce())] + #[pallet::weight(T::WeightInfo::announce())] pub fn announce(origin: OriginFor, announcement: Cid) -> DispatchResultWithPostInfo { T::SuperMajorityOrigin::ensure_origin(origin)?; @@ -587,7 +628,7 @@ pub mod pallet { } /// Remove the announcement. - #[pallet::weight(>::WeightInfo::remove_announcement())] + #[pallet::weight(T::WeightInfo::remove_announcement())] pub fn remove_announcement( origin: OriginFor, announcement: Cid, @@ -608,7 +649,7 @@ pub mod pallet { /// Submit oneself for candidacy. /// Account must have enough transferable funds in it to pay the candidate deposit. - #[pallet::weight(>::WeightInfo::submit_candidacy())] + #[pallet::weight(T::WeightInfo::submit_candidacy())] pub fn submit_candidacy(origin: OriginFor) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; ensure!(!Self::is_account_blacklist(&who), Error::::AlreadyInBlacklist); @@ -632,7 +673,7 @@ pub mod pallet { /// Founder or fellow can nominate someone to join the alliance and become a candidate. /// There is no deposit required to the nominator or nominee. - #[pallet::weight(>::WeightInfo::nominate_candidacy())] + #[pallet::weight(T::WeightInfo::nominate_candidacy())] pub fn nominate_candidacy( origin: OriginFor, who: ::Source, @@ -655,7 +696,7 @@ pub mod pallet { } /// Approve a `Candidate` to become an `Ally`. - #[pallet::weight(>::WeightInfo::approve_candidate())] + #[pallet::weight(T::WeightInfo::approve_candidate())] pub fn approve_candidate( origin: OriginFor, candidate: ::Source, @@ -673,7 +714,7 @@ pub mod pallet { } /// Reject a `Candidate` back to an ordinary account. - #[pallet::weight(>::WeightInfo::reject_candidate())] + #[pallet::weight(T::WeightInfo::reject_candidate())] pub fn reject_candidate( origin: OriginFor, candidate: ::Source, @@ -693,7 +734,7 @@ pub mod pallet { } /// Elevate an ally to fellow. - #[pallet::weight(>::WeightInfo::reject_candidate())] + #[pallet::weight(T::WeightInfo::reject_candidate())] pub fn elevate_ally( origin: OriginFor, ally: ::Source, @@ -711,7 +752,7 @@ pub mod pallet { } /// As a member, retire and back to an ordinary account and unlock its deposit. - #[pallet::weight(>::WeightInfo::retire())] + #[pallet::weight(T::WeightInfo::retire())] pub fn retire(origin: OriginFor) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; ensure!(!Self::is_kicking(&who), Error::::KickingMember); @@ -728,7 +769,7 @@ pub mod pallet { } /// Kick a member to ordinary account with its deposit slashed. - #[pallet::weight(>::WeightInfo::kick_member())] + #[pallet::weight(T::WeightInfo::kick_member())] pub fn kick_member( origin: OriginFor, who: ::Source, @@ -748,7 +789,7 @@ pub mod pallet { } /// Add accounts or websites into blacklist. - #[pallet::weight(>::WeightInfo::add_blacklist(infos.len() as u32))] + #[pallet::weight(T::WeightInfo::add_blacklist(infos.len() as u32, T::MaxWebsiteUrlLength::get()))] pub fn add_blacklist( origin: OriginFor, infos: Vec>, @@ -788,7 +829,7 @@ pub mod pallet { } /// Remove accounts or websites from blacklist. - #[pallet::weight(>::WeightInfo::remove_blacklist(infos.len() as u32))] + #[pallet::weight(>::WeightInfo::remove_blacklist(infos.len() as u32, T::MaxWebsiteUrlLength::get()))] pub fn remove_blacklist( origin: OriginFor, infos: Vec>, diff --git a/frame/alliance/src/mock.rs b/frame/alliance/src/mock.rs index 900f3c48ac66c..10b2b57d900e5 100644 --- a/frame/alliance/src/mock.rs +++ b/frame/alliance/src/mock.rs @@ -211,6 +211,9 @@ impl ProposalProvider for AllianceProposalProvider { } parameter_types! { + // pub const MaxFounders: u32 = 10; + // pub const MaxFellows: u32 = MaxMembers::get() - MaxFounders::get(); + // pub const MaxAllies: u32 = 100; pub const CandidateDeposit: u64 = 25; pub const MaxBlacklistCount: u32 = 100; pub const MaxWebsiteUrlLength: u32 = 255; @@ -225,6 +228,10 @@ impl Config for Test { type MembershipChanged = AllianceMotion; type IdentityVerifier = AllianceIdentityVerifier; type ProposalProvider = AllianceProposalProvider; + // type MaxProposals = MaxProposals; + // type MaxFounders = MaxMembers; + // type MaxFellows = MaxFellows; + // type MaxAllies = MaxAllies; type MaxBlacklistCount = MaxBlacklistCount; type MaxWebsiteUrlLength = MaxWebsiteUrlLength; type CandidateDeposit = CandidateDeposit; @@ -254,8 +261,8 @@ pub fn new_test_ext() -> sp_io::TestExternalities { balances: vec![(1, 50), (2, 50), (3, 50), (4, 50), (5, 30), (6, 50), (7, 50)], }, alliance: pallet_alliance::GenesisConfig { - founders: vec![1, 2], - fellows: vec![3], + founders: vec![], + fellows: vec![], allies: vec![], phantom: Default::default(), }, @@ -290,6 +297,8 @@ pub fn new_test_ext() -> sp_io::TestExternalities { assert_ok!(Identity::provide_judgement(Origin::signed(1), 0, 5, Judgement::KnownGood)); assert_ok!(Identity::set_identity(Origin::signed(6), Box::new(info.clone()))); + assert_ok!(Alliance::init_members(Origin::root(), vec![1, 2], vec![3], vec![])); + System::set_block_number(1); }); ext diff --git a/frame/alliance/src/weights.rs b/frame/alliance/src/weights.rs index 34c108fc07283..ed660d96fc428 100644 --- a/frame/alliance/src/weights.rs +++ b/frame/alliance/src/weights.rs @@ -18,7 +18,7 @@ //! Autogenerated weights for pallet_alliance //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2021-10-09, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2021-10-11, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: @@ -55,8 +55,8 @@ pub trait WeightInfo { fn elevate_ally() -> Weight; fn retire() -> Weight; fn kick_member() -> Weight; - fn add_blacklist(n: u32, ) -> Weight; - fn remove_blacklist(n: u32, ) -> Weight; + fn add_blacklist(n: u32, l: u32, ) -> Weight; + fn remove_blacklist(n: u32, l: u32, ) -> Weight; } /// Weights for pallet_alliance using the Substrate node and recommended hardware. @@ -64,18 +64,18 @@ pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { // Storage: Alliance Rule (r:0 w:1) fn set_rule() -> Weight { - (15_288_000 as Weight) + (15_168_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Alliance Announcements (r:1 w:1) fn announce() -> Weight { - (17_342_000 as Weight) + (16_982_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Alliance Announcements (r:1 w:1) fn remove_announcement() -> Weight { - (17_924_000 as Weight) + (17_312_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } @@ -85,7 +85,7 @@ impl WeightInfo for SubstrateWeight { // Storage: System Account (r:1 w:1) // Storage: Alliance DepositOf (r:0 w:1) fn submit_candidacy() -> Weight { - (62_597_000 as Weight) + (58_701_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } @@ -93,14 +93,14 @@ impl WeightInfo for SubstrateWeight { // Storage: Alliance AccountBlacklist (r:1 w:0) // Storage: Alliance Candidates (r:1 w:1) fn nominate_candidacy() -> Weight { - (45_906_000 as Weight) + (43_682_000 as Weight) .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Alliance Candidates (r:1 w:1) // Storage: Alliance Members (r:4 w:1) fn approve_candidate() -> Weight { - (45_906_000 as Weight) + (43_382_000 as Weight) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } @@ -109,7 +109,7 @@ impl WeightInfo for SubstrateWeight { // Storage: Alliance DepositOf (r:1 w:1) // Storage: System Account (r:1 w:1) fn reject_candidate() -> Weight { - (71_654_000 as Weight) + (68_389_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } @@ -118,7 +118,7 @@ impl WeightInfo for SubstrateWeight { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn elevate_ally() -> Weight { - (45_294_000 as Weight) + (42_671_000 as Weight) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } @@ -130,7 +130,7 @@ impl WeightInfo for SubstrateWeight { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn retire() -> Weight { - (61_915_000 as Weight) + (59_943_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(5 as Weight)) } @@ -142,25 +142,29 @@ impl WeightInfo for SubstrateWeight { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn kick_member() -> Weight { - (72_525_000 as Weight) + (67_326_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(5 as Weight)) } // Storage: Alliance AccountBlacklist (r:1 w:0) // Storage: Alliance WebsiteBlacklist (r:1 w:0) - fn add_blacklist(n: u32, ) -> Weight { - (25_257_000 as Weight) - // Standard Error: 27_000 - .saturating_add((2_243_000 as Weight).saturating_mul(n as Weight)) + fn add_blacklist(n: u32, l: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 14_000 + .saturating_add((2_579_000 as Weight).saturating_mul(n as Weight)) + // Standard Error: 5_000 + .saturating_add((187_000 as Weight).saturating_mul(l as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } // Storage: Alliance AccountBlacklist (r:1 w:1) // Storage: Alliance WebsiteBlacklist (r:1 w:1) - fn remove_blacklist(n: u32, ) -> Weight { - (49_502_000 as Weight) - // Standard Error: 79_000 - .saturating_add((29_443_000 as Weight).saturating_mul(n as Weight)) + fn remove_blacklist(n: u32, l: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 453_000 + .saturating_add((59_643_000 as Weight).saturating_mul(n as Weight)) + // Standard Error: 177_000 + .saturating_add((7_981_000 as Weight).saturating_mul(l as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } @@ -170,18 +174,18 @@ impl WeightInfo for SubstrateWeight { impl WeightInfo for () { // Storage: Alliance Rule (r:0 w:1) fn set_rule() -> Weight { - (15_288_000 as Weight) + (15_168_000 as Weight) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Alliance Announcements (r:1 w:1) fn announce() -> Weight { - (17_342_000 as Weight) + (16_982_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Alliance Announcements (r:1 w:1) fn remove_announcement() -> Weight { - (17_924_000 as Weight) + (17_312_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } @@ -191,7 +195,7 @@ impl WeightInfo for () { // Storage: System Account (r:1 w:1) // Storage: Alliance DepositOf (r:0 w:1) fn submit_candidacy() -> Weight { - (62_597_000 as Weight) + (58_701_000 as Weight) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } @@ -199,14 +203,14 @@ impl WeightInfo for () { // Storage: Alliance AccountBlacklist (r:1 w:0) // Storage: Alliance Candidates (r:1 w:1) fn nominate_candidacy() -> Weight { - (45_906_000 as Weight) + (43_682_000 as Weight) .saturating_add(RocksDbWeight::get().reads(6 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Alliance Candidates (r:1 w:1) // Storage: Alliance Members (r:4 w:1) fn approve_candidate() -> Weight { - (45_906_000 as Weight) + (43_382_000 as Weight) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } @@ -215,7 +219,7 @@ impl WeightInfo for () { // Storage: Alliance DepositOf (r:1 w:1) // Storage: System Account (r:1 w:1) fn reject_candidate() -> Weight { - (71_654_000 as Weight) + (68_389_000 as Weight) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } @@ -224,7 +228,7 @@ impl WeightInfo for () { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn elevate_ally() -> Weight { - (45_294_000 as Weight) + (42_671_000 as Weight) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(4 as Weight)) } @@ -236,7 +240,7 @@ impl WeightInfo for () { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn retire() -> Weight { - (61_915_000 as Weight) + (59_943_000 as Weight) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().writes(5 as Weight)) } @@ -248,25 +252,29 @@ impl WeightInfo for () { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn kick_member() -> Weight { - (72_525_000 as Weight) + (67_326_000 as Weight) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().writes(5 as Weight)) } // Storage: Alliance AccountBlacklist (r:1 w:0) // Storage: Alliance WebsiteBlacklist (r:1 w:0) - fn add_blacklist(n: u32, ) -> Weight { - (25_257_000 as Weight) - // Standard Error: 27_000 - .saturating_add((2_243_000 as Weight).saturating_mul(n as Weight)) + fn add_blacklist(n: u32, l: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 14_000 + .saturating_add((2_579_000 as Weight).saturating_mul(n as Weight)) + // Standard Error: 5_000 + .saturating_add((187_000 as Weight).saturating_mul(l as Weight)) .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } // Storage: Alliance AccountBlacklist (r:1 w:1) // Storage: Alliance WebsiteBlacklist (r:1 w:1) - fn remove_blacklist(n: u32, ) -> Weight { - (49_502_000 as Weight) - // Standard Error: 79_000 - .saturating_add((29_443_000 as Weight).saturating_mul(n as Weight)) + fn remove_blacklist(n: u32, l: u32, ) -> Weight { + (0 as Weight) + // Standard Error: 453_000 + .saturating_add((59_643_000 as Weight).saturating_mul(n as Weight)) + // Standard Error: 177_000 + .saturating_add((7_981_000 as Weight).saturating_mul(l as Weight)) .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } From 1d2bc71eda3af1b51d4ca68839b3980435ac39ef Mon Sep 17 00:00:00 2001 From: koushiro Date: Mon, 11 Oct 2021 14:21:12 +0800 Subject: [PATCH 16/72] Some nits Signed-off-by: koushiro --- frame/alliance/src/benchmarking.rs | 16 +++++++--------- frame/alliance/src/lib.rs | 5 +---- frame/alliance/src/mock.rs | 14 +++++++------- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/frame/alliance/src/benchmarking.rs b/frame/alliance/src/benchmarking.rs index 523ceb1e3146f..7438ed5d3efeb 100644 --- a/frame/alliance/src/benchmarking.rs +++ b/frame/alliance/src/benchmarking.rs @@ -89,12 +89,8 @@ fn set_members, I: 'static>() { T::InitializeMembers::initialize_members(&[founders.as_slice(), fellows.as_slice()].concat()); } -fn set_announcement, I: 'static>(cid: Cid) { - Announcements::::put(vec![cid]); -} - -fn set_candidates, I: 'static>() { - let candidates = vec![funded_account::("candidate", 1)]; +fn set_candidates, I: 'static>(indexes: Vec) { + let candidates = indexes.into_iter().map(|i| candidate::(i)).collect::>(); candidates.iter().for_each(|who| { T::Currency::reserve(&who, T::CandidateDeposit::get()).unwrap(); >::insert(&who, T::CandidateDeposit::get()); @@ -119,6 +115,7 @@ benchmarks_instance_pallet! { set_members::(); let announcement = test_cid(); + let call = Call::::announce { announcement: announcement.clone() }; let origin = T::SuperMajorityOrigin::successful_origin(); }: { call.dispatch_bypass_filter(origin)? } @@ -129,8 +126,9 @@ benchmarks_instance_pallet! { remove_announcement { set_members::(); + let announcement = test_cid(); - set_announcement::(announcement.clone()); + Announcements::::put(vec![announcement.clone()]); let call = Call::::remove_announcement { announcement: announcement.clone() }; let origin = T::SuperMajorityOrigin::successful_origin(); @@ -177,7 +175,7 @@ benchmarks_instance_pallet! { approve_candidate { set_members::(); - set_candidates::(); + set_candidates::(vec![1]); let candidate1 = candidate::(1); assert!(Alliance::::is_candidate(&candidate1)); @@ -197,7 +195,7 @@ benchmarks_instance_pallet! { reject_candidate { set_members::(); - set_candidates::(); + set_candidates::(vec![1]); let candidate1 = candidate::(1); assert!(Alliance::::is_candidate(&candidate1)); diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index 3fea84b75ad5c..b6c3595826f1c 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -231,7 +231,6 @@ pub mod pallet { /// The provider of the proposal operation. type ProposalProvider: ProposalProvider; - /* /// Maximum number of proposals allowed to be active in parallel. type MaxProposals: Get; @@ -255,7 +254,6 @@ pub mod pallet { /// + Benchmarks will need to be re-run and weights adjusted if this changes. /// + This pallet assumes that dependents keep to the limit without enforcing it. type MaxAllies: Get; - */ /// The maximum number of blacklist supported by the pallet. #[pallet::constant] @@ -647,8 +645,7 @@ pub mod pallet { Ok(().into()) } - /// Submit oneself for candidacy. - /// Account must have enough transferable funds in it to pay the candidate deposit. + /// Submit oneself for candidacy. A fixed amount of deposit is recorded. #[pallet::weight(T::WeightInfo::submit_candidacy())] pub fn submit_candidacy(origin: OriginFor) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; diff --git a/frame/alliance/src/mock.rs b/frame/alliance/src/mock.rs index 10b2b57d900e5..182f25c195b7d 100644 --- a/frame/alliance/src/mock.rs +++ b/frame/alliance/src/mock.rs @@ -211,9 +211,9 @@ impl ProposalProvider for AllianceProposalProvider { } parameter_types! { - // pub const MaxFounders: u32 = 10; - // pub const MaxFellows: u32 = MaxMembers::get() - MaxFounders::get(); - // pub const MaxAllies: u32 = 100; + pub const MaxFounders: u32 = 10; + pub const MaxFellows: u32 = MaxMembers::get() - MaxFounders::get(); + pub const MaxAllies: u32 = 100; pub const CandidateDeposit: u64 = 25; pub const MaxBlacklistCount: u32 = 100; pub const MaxWebsiteUrlLength: u32 = 255; @@ -228,10 +228,10 @@ impl Config for Test { type MembershipChanged = AllianceMotion; type IdentityVerifier = AllianceIdentityVerifier; type ProposalProvider = AllianceProposalProvider; - // type MaxProposals = MaxProposals; - // type MaxFounders = MaxMembers; - // type MaxFellows = MaxFellows; - // type MaxAllies = MaxAllies; + type MaxProposals = MaxProposals; + type MaxFounders = MaxMembers; + type MaxFellows = MaxFellows; + type MaxAllies = MaxAllies; type MaxBlacklistCount = MaxBlacklistCount; type MaxWebsiteUrlLength = MaxWebsiteUrlLength; type CandidateDeposit = CandidateDeposit; From e7f0cd3ded6c9f4c184013c21bc506ab895dbf47 Mon Sep 17 00:00:00 2001 From: koushiro Date: Mon, 11 Oct 2021 14:59:19 +0800 Subject: [PATCH 17/72] Add benchmarking for init_members Signed-off-by: koushiro --- bin/node/runtime/src/lib.rs | 7 ++ frame/alliance/src/benchmarking.rs | 28 ++++++-- frame/alliance/src/lib.rs | 8 ++- frame/alliance/src/mock.rs | 2 +- frame/alliance/src/weights.rs | 103 ++++++++++++++++++----------- 5 files changed, 101 insertions(+), 47 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 721928f47d07d..19e3864b693c4 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1408,6 +1408,9 @@ impl pallet_collective::Config for Runtime { } parameter_types! { + pub const MaxFounders: u32 = 10; + pub const MaxFellows: u32 = AllianceMaxMembers::get() - MaxFounders::get(); + pub const MaxAllies: u32 = 100; pub const MaxBlacklistCount: u32 = 100; pub const MaxWebsiteUrlLength: u32 = 255; } @@ -1426,6 +1429,10 @@ impl pallet_alliance::Config for Runtime { type MembershipChanged = AllianceMotion; type IdentityVerifier = AllianceIdentityVerifier; type ProposalProvider = AllianceProposalProvider; + type MaxProposals = AllianceMaxProposals; + type MaxFounders = MaxFounders; + type MaxFellows = MaxFellows; + type MaxAllies = MaxAllies; type MaxBlacklistCount = MaxBlacklistCount; type MaxWebsiteUrlLength = MaxWebsiteUrlLength; type CandidateDeposit = CandidateDeposit; diff --git a/frame/alliance/src/benchmarking.rs b/frame/alliance/src/benchmarking.rs index 7438ed5d3efeb..eeb6693919a8f 100644 --- a/frame/alliance/src/benchmarking.rs +++ b/frame/alliance/src/benchmarking.rs @@ -99,6 +99,26 @@ fn set_candidates, I: 'static>(indexes: Vec) { } benchmarks_instance_pallet! { + init_members { + // at least 2 founders + let a in 2 .. T::MaxFounders::get(); + let b in 0 .. T::MaxFellows::get(); + let c in 0 .. T::MaxAllies::get(); + + let mut founders = (2 .. a).map(founder::).collect::>(); + let mut fellows = (0 .. b).map(fellow::).collect::>(); + let mut allies = (0 .. c).map(ally::).collect::>(); + + }: _(RawOrigin::Root, founders.clone(), fellows.clone(), allies.clone()) + verify { + founders.sort(); + fellows.sort(); + allies.sort(); + assert_eq!(Alliance::::members(MemberRole::Founder), founders); + assert_eq!(Alliance::::members(MemberRole::Fellow), fellows); + assert_eq!(Alliance::::members(MemberRole::Ally), allies); + } + set_rule { set_members::(); @@ -266,8 +286,8 @@ benchmarks_instance_pallet! { } add_blacklist { - let n in 0 .. T::MaxBlacklistCount::get(); - let l in 0 .. T::MaxWebsiteUrlLength::get(); + let n in 1 .. T::MaxBlacklistCount::get(); + let l in 1 .. T::MaxWebsiteUrlLength::get(); set_members::(); @@ -286,8 +306,8 @@ benchmarks_instance_pallet! { } remove_blacklist { - let n in 0 .. T::MaxBlacklistCount::get(); - let l in 0 .. T::MaxWebsiteUrlLength::get(); + let n in 1 .. T::MaxBlacklistCount::get(); + let l in 1 .. T::MaxWebsiteUrlLength::get(); set_members::(); diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index b6c3595826f1c..70f3ca1ee03f8 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -557,8 +557,12 @@ pub mod pallet { /// Initialize the founders/fellows/allies. /// - /// This should be called by the referendum and can only be called once. - #[pallet::weight(0)] + /// This should only be called once. + #[pallet::weight(T::WeightInfo::init_members( + T::MaxFounders::get(), + T::MaxFellows::get(), + T::MaxAllies::get() + ))] pub fn init_members( origin: OriginFor, mut founders: Vec, diff --git a/frame/alliance/src/mock.rs b/frame/alliance/src/mock.rs index 182f25c195b7d..c71ae4d1a0ef2 100644 --- a/frame/alliance/src/mock.rs +++ b/frame/alliance/src/mock.rs @@ -229,7 +229,7 @@ impl Config for Test { type IdentityVerifier = AllianceIdentityVerifier; type ProposalProvider = AllianceProposalProvider; type MaxProposals = MaxProposals; - type MaxFounders = MaxMembers; + type MaxFounders = MaxFounders; type MaxFellows = MaxFellows; type MaxAllies = MaxAllies; type MaxBlacklistCount = MaxBlacklistCount; diff --git a/frame/alliance/src/weights.rs b/frame/alliance/src/weights.rs index ed660d96fc428..e3197cb60cd9d 100644 --- a/frame/alliance/src/weights.rs +++ b/frame/alliance/src/weights.rs @@ -45,6 +45,7 @@ use sp_std::marker::PhantomData; /// Weight functions needed for pallet_alliance. pub trait WeightInfo { + fn init_members(a: u32, b: u32, c: u32, ) -> Weight; fn set_rule() -> Weight; fn announce() -> Weight; fn remove_announcement() -> Weight; @@ -62,20 +63,31 @@ pub trait WeightInfo { /// Weights for pallet_alliance using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { + // Storage: Alliance Members (r:3 w:3) + // Storage: AllianceMotion Members (r:1 w:1) + fn init_members(_a: u32, b: u32, c: u32, ) -> Weight { + (42_518_000 as Weight) + // Standard Error: 2_000 + .saturating_add((169_000 as Weight).saturating_mul(b as Weight)) + // Standard Error: 2_000 + .saturating_add((162_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } // Storage: Alliance Rule (r:0 w:1) fn set_rule() -> Weight { - (15_168_000 as Weight) + (14_427_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Alliance Announcements (r:1 w:1) fn announce() -> Weight { - (16_982_000 as Weight) + (17_153_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Alliance Announcements (r:1 w:1) fn remove_announcement() -> Weight { - (17_312_000 as Weight) + (17_152_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } @@ -85,7 +97,7 @@ impl WeightInfo for SubstrateWeight { // Storage: System Account (r:1 w:1) // Storage: Alliance DepositOf (r:0 w:1) fn submit_candidacy() -> Weight { - (58_701_000 as Weight) + (59_542_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } @@ -93,14 +105,14 @@ impl WeightInfo for SubstrateWeight { // Storage: Alliance AccountBlacklist (r:1 w:0) // Storage: Alliance Candidates (r:1 w:1) fn nominate_candidacy() -> Weight { - (43_682_000 as Weight) + (43_241_000 as Weight) .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Alliance Candidates (r:1 w:1) // Storage: Alliance Members (r:4 w:1) fn approve_candidate() -> Weight { - (43_382_000 as Weight) + (44_303_000 as Weight) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } @@ -109,7 +121,7 @@ impl WeightInfo for SubstrateWeight { // Storage: Alliance DepositOf (r:1 w:1) // Storage: System Account (r:1 w:1) fn reject_candidate() -> Weight { - (68_389_000 as Weight) + (68_839_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } @@ -118,7 +130,7 @@ impl WeightInfo for SubstrateWeight { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn elevate_ally() -> Weight { - (42_671_000 as Weight) + (42_540_000 as Weight) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } @@ -130,7 +142,7 @@ impl WeightInfo for SubstrateWeight { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn retire() -> Weight { - (59_943_000 as Weight) + (59_933_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(5 as Weight)) } @@ -142,18 +154,18 @@ impl WeightInfo for SubstrateWeight { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn kick_member() -> Weight { - (67_326_000 as Weight) + (66_675_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(5 as Weight)) } - // Storage: Alliance AccountBlacklist (r:1 w:0) - // Storage: Alliance WebsiteBlacklist (r:1 w:0) + // Storage: Alliance AccountBlacklist (r:1 w:1) + // Storage: Alliance WebsiteBlacklist (r:1 w:1) fn add_blacklist(n: u32, l: u32, ) -> Weight { (0 as Weight) - // Standard Error: 14_000 - .saturating_add((2_579_000 as Weight).saturating_mul(n as Weight)) - // Standard Error: 5_000 - .saturating_add((187_000 as Weight).saturating_mul(l as Weight)) + // Standard Error: 6_000 + .saturating_add((2_626_000 as Weight).saturating_mul(n as Weight)) + // Standard Error: 3_000 + .saturating_add((206_000 as Weight).saturating_mul(l as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } @@ -161,10 +173,10 @@ impl WeightInfo for SubstrateWeight { // Storage: Alliance WebsiteBlacklist (r:1 w:1) fn remove_blacklist(n: u32, l: u32, ) -> Weight { (0 as Weight) - // Standard Error: 453_000 - .saturating_add((59_643_000 as Weight).saturating_mul(n as Weight)) - // Standard Error: 177_000 - .saturating_add((7_981_000 as Weight).saturating_mul(l as Weight)) + // Standard Error: 338_000 + .saturating_add((58_173_000 as Weight).saturating_mul(n as Weight)) + // Standard Error: 150_000 + .saturating_add((6_640_000 as Weight).saturating_mul(l as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } @@ -172,20 +184,31 @@ impl WeightInfo for SubstrateWeight { // For backwards compatibility and tests impl WeightInfo for () { + // Storage: Alliance Members (r:3 w:3) + // Storage: AllianceMotion Members (r:1 w:1) + fn init_members(_a: u32, b: u32, c: u32, ) -> Weight { + (42_518_000 as Weight) + // Standard Error: 2_000 + .saturating_add((169_000 as Weight).saturating_mul(b as Weight)) + // Standard Error: 2_000 + .saturating_add((162_000 as Weight).saturating_mul(c as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + .saturating_add(RocksDbWeight::get().writes(4 as Weight)) + } // Storage: Alliance Rule (r:0 w:1) fn set_rule() -> Weight { - (15_168_000 as Weight) + (14_427_000 as Weight) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Alliance Announcements (r:1 w:1) fn announce() -> Weight { - (16_982_000 as Weight) + (17_153_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Alliance Announcements (r:1 w:1) fn remove_announcement() -> Weight { - (17_312_000 as Weight) + (17_152_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } @@ -195,7 +218,7 @@ impl WeightInfo for () { // Storage: System Account (r:1 w:1) // Storage: Alliance DepositOf (r:0 w:1) fn submit_candidacy() -> Weight { - (58_701_000 as Weight) + (59_542_000 as Weight) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } @@ -203,14 +226,14 @@ impl WeightInfo for () { // Storage: Alliance AccountBlacklist (r:1 w:0) // Storage: Alliance Candidates (r:1 w:1) fn nominate_candidacy() -> Weight { - (43_682_000 as Weight) + (43_241_000 as Weight) .saturating_add(RocksDbWeight::get().reads(6 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Alliance Candidates (r:1 w:1) // Storage: Alliance Members (r:4 w:1) fn approve_candidate() -> Weight { - (43_382_000 as Weight) + (44_303_000 as Weight) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } @@ -219,7 +242,7 @@ impl WeightInfo for () { // Storage: Alliance DepositOf (r:1 w:1) // Storage: System Account (r:1 w:1) fn reject_candidate() -> Weight { - (68_389_000 as Weight) + (68_839_000 as Weight) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } @@ -228,7 +251,7 @@ impl WeightInfo for () { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn elevate_ally() -> Weight { - (42_671_000 as Weight) + (42_540_000 as Weight) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(4 as Weight)) } @@ -240,7 +263,7 @@ impl WeightInfo for () { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn retire() -> Weight { - (59_943_000 as Weight) + (59_933_000 as Weight) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().writes(5 as Weight)) } @@ -252,18 +275,18 @@ impl WeightInfo for () { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn kick_member() -> Weight { - (67_326_000 as Weight) + (66_675_000 as Weight) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().writes(5 as Weight)) } - // Storage: Alliance AccountBlacklist (r:1 w:0) - // Storage: Alliance WebsiteBlacklist (r:1 w:0) + // Storage: Alliance AccountBlacklist (r:1 w:1) + // Storage: Alliance WebsiteBlacklist (r:1 w:1) fn add_blacklist(n: u32, l: u32, ) -> Weight { (0 as Weight) - // Standard Error: 14_000 - .saturating_add((2_579_000 as Weight).saturating_mul(n as Weight)) - // Standard Error: 5_000 - .saturating_add((187_000 as Weight).saturating_mul(l as Weight)) + // Standard Error: 6_000 + .saturating_add((2_626_000 as Weight).saturating_mul(n as Weight)) + // Standard Error: 3_000 + .saturating_add((206_000 as Weight).saturating_mul(l as Weight)) .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } @@ -271,10 +294,10 @@ impl WeightInfo for () { // Storage: Alliance WebsiteBlacklist (r:1 w:1) fn remove_blacklist(n: u32, l: u32, ) -> Weight { (0 as Weight) - // Standard Error: 453_000 - .saturating_add((59_643_000 as Weight).saturating_mul(n as Weight)) - // Standard Error: 177_000 - .saturating_add((7_981_000 as Weight).saturating_mul(l as Weight)) + // Standard Error: 338_000 + .saturating_add((58_173_000 as Weight).saturating_mul(n as Weight)) + // Standard Error: 150_000 + .saturating_add((6_640_000 as Weight).saturating_mul(l as Weight)) .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } From 181738bfb5e87bf742017a5c14f6db03b8343358 Mon Sep 17 00:00:00 2001 From: koushiro Date: Mon, 11 Oct 2021 20:08:14 +0800 Subject: [PATCH 18/72] Add benchmarking for propose/vote/veto Signed-off-by: koushiro --- frame/alliance/Cargo.toml | 2 + frame/alliance/src/benchmarking.rs | 233 ++++++++++++++++++++++++++--- frame/alliance/src/lib.rs | 3 +- frame/alliance/src/types.rs | 2 +- frame/alliance/src/weights.rs | 165 ++++++++++++++------ 5 files changed, 339 insertions(+), 66 deletions(-) diff --git a/frame/alliance/Cargo.toml b/frame/alliance/Cargo.toml index 80a3b4ab85e55..b9c4ccdbd18a3 100644 --- a/frame/alliance/Cargo.toml +++ b/frame/alliance/Cargo.toml @@ -14,6 +14,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] hex = { version = "0.4", default-features = false, features = ["alloc"], optional = true } +sha2 = { version = "0.9", default-features = false, optional = true } log = { version = "0.4.14", default-features = false } codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive"] } @@ -52,6 +53,7 @@ std = [ ] runtime-benchmarks = [ "hex", + "sha2", "frame-benchmarking", "sp-runtime/runtime-benchmarks", "frame-support/runtime-benchmarks", diff --git a/frame/alliance/src/benchmarking.rs b/frame/alliance/src/benchmarking.rs index eeb6693919a8f..987d29e14d23c 100644 --- a/frame/alliance/src/benchmarking.rs +++ b/frame/alliance/src/benchmarking.rs @@ -17,25 +17,37 @@ //! Alliance pallet benchmarking. -use sp_runtime::traits::{Bounded, StaticLookup}; -use sp_std::prelude::*; +use sp_runtime::traits::{Bounded, Hash, StaticLookup}; +use sp_std::{mem::size_of, prelude::*}; use frame_benchmarking::{account, benchmarks_instance_pallet}; use frame_support::traits::{EnsureOrigin, Get, UnfilteredDispatchable}; -use frame_system::RawOrigin; +use frame_system::RawOrigin as SystemOrigin; -use super::{Pallet as Alliance, *}; +use super::{Call as AllianceCall, Pallet as Alliance, *}; const SEED: u32 = 0; +const MAX_BYTES: u32 = 1_024; + fn assert_last_event, I: 'static>(generic_event: >::Event) { frame_system::Pallet::::assert_last_event(generic_event.into()); } -fn test_cid() -> Cid { - Cid::new_v0( - hex::decode("b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9").unwrap(), - ) +fn cid(input: impl AsRef<[u8]>) -> Cid { + use sha2::{Digest, Sha256}; + let mut hasher = Sha256::new(); + hasher.update(input); + let result = hasher.finalize(); + Cid::new_v0(&*result) +} + +fn rule(input: impl AsRef<[u8]>) -> Cid { + cid(input) +} + +fn announcement(input: impl AsRef<[u8]>) -> Cid { + cid(input) } fn funded_account, I: 'static>(name: &'static str, index: u32) -> T::AccountId { @@ -99,21 +111,199 @@ fn set_candidates, I: 'static>(indexes: Vec) { } benchmarks_instance_pallet! { + // This tests when proposal is created and queued as "proposed" + propose_proposed { + let b in 1 .. MAX_BYTES; + let x in 2 .. T::MaxFounders::get(); + let y in 0 .. T::MaxFellows::get(); + let p in 1 .. T::MaxProposals::get(); + + let bytes_in_storage = size_of::() as u32 + 32; + + // Construct `members`. + let mut founders = (1 .. x - 1).map(founder::).collect::>(); + let proposer = founder::(0); + founders.push(proposer.clone()); + let fellows = (0 .. y).map(fellow::).collect::>(); + + Alliance::::init_members(SystemOrigin::Root.into(), founders, fellows, vec![])?; + + let threshold = x + y; + // Add previous proposals. + for i in 0 .. p - 1 { + // Proposals should be different so that different proposal hashes are generated + let proposal: T::Proposal = AllianceCall::::set_rule { rule: rule(vec![i as u8; b as usize]) }.into(); + Alliance::::propose( + SystemOrigin::Signed(proposer.clone()).into(), + threshold, + Box::new(proposal), + bytes_in_storage, + )?; + } + + let proposal: T::Proposal = AllianceCall::::set_rule { rule: rule(vec![p as u8; b as usize]) }.into(); + + }: propose(SystemOrigin::Signed(proposer.clone()), threshold, Box::new(proposal.clone()), bytes_in_storage) + verify { + // New proposal is recorded + let proposal_hash = T::Hashing::hash_of(&proposal); + assert_eq!(T::ProposalProvider::proposal_of(proposal_hash), Some(proposal)); + } + + vote { + // We choose 5 (3 founders + 2 fellows) as a minimum so we always trigger a vote in the voting loop (`for j in ...`) + let x in 3 .. T::MaxFounders::get(); + let y in 2 .. T::MaxFellows::get(); + + let p = T::MaxProposals::get(); + let b = MAX_BYTES; + let bytes_in_storage = size_of::() as u32 + 32; + + // Construct `members`. + let mut founders = (1 .. x - 1).map(founder::).collect::>(); + let proposer = founder::(0); + founders.push(proposer.clone()); + let mut fellows = (1 .. y - 1).map(fellow::).collect::>(); + let voter = fellow::(0); + fellows.push(voter.clone()); + + let mut members = Vec::with_capacity(founders.len() + fellows.len()); + members.extend(founders.clone()); + members.extend(fellows.clone()); + + Alliance::::init_members(SystemOrigin::Root.into(), founders, fellows, vec![])?; + + // Threshold is 1 less than the number of members so that one person can vote nay + let m = x + y; + let threshold = m - 1; + + // Add previous proposals + let mut last_hash = T::Hash::default(); + for i in 0 .. p { + // Proposals should be different so that different proposal hashes are generated + let proposal: T::Proposal = AllianceCall::::set_rule { rule: rule(vec![i as u8; b as usize]) }.into(); + Alliance::::propose( + SystemOrigin::Signed(proposer.clone()).into(), + threshold, + Box::new(proposal.clone()), + b, + )?; + last_hash = T::Hashing::hash_of(&proposal); + } + + let index = p - 1; + // Have almost everyone vote aye on last proposal, while keeping it from passing. + for j in 0 .. m - 3 { + let voter = &members[j as usize]; + let approve = true; + Alliance::::vote( + SystemOrigin::Signed(voter.clone()).into(), + last_hash.clone(), + index, + approve, + )?; + } + // Voter votes aye without resolving the vote. + let approve = true; + Alliance::::vote( + SystemOrigin::Signed(voter.clone()).into(), + last_hash.clone(), + index, + approve, + )?; + + // Voter switches vote to nay, but does not kill the vote, just updates + inserts + let approve = false; + + // Whitelist voter account from further DB operations. + let voter_key = frame_system::Account::::hashed_key_for(&voter); + frame_benchmarking::benchmarking::add_to_whitelist(voter_key.into()); + }: _(SystemOrigin::Signed(voter), last_hash.clone(), index, approve) + verify { + } + + veto { + let p in 1 .. T::MaxProposals::get(); + + let m = 3; + let b = MAX_BYTES; + let bytes_in_storage = b + size_of::() as u32 + 32; + + // Construct `members`. + let mut founders = (1 .. m).map(founder::).collect::>(); + let vetor = founder::(0); + founders.push(vetor.clone()); + + Alliance::::init_members(SystemOrigin::Root.into(), founders, vec![], vec![])?; + + // Threshold is one less than total members so that two nays will disapprove the vote + let threshold = m - 1; + + // Add proposals + let mut last_hash = T::Hash::default(); + for i in 0 .. p { + // Proposals should be different so that different proposal hashes are generated + let proposal: T::Proposal = AllianceCall::::set_rule { rule: rule(vec![i as u8; b as usize]) }.into(); + Alliance::::propose( + SystemOrigin::Signed(vetor.clone()).into(), + threshold, + Box::new(proposal.clone()), + bytes_in_storage, + )?; + last_hash = T::Hashing::hash_of(&proposal); + } + + }: _(SystemOrigin::Signed(vetor), last_hash.clone()) + verify { + // The proposal is removed + assert_eq!(T::ProposalProvider::proposal_of(last_hash), None); + } + + /* + close_early_disapproved { + + }: close(SystemOrigin::Signed(voter), last_hash.clone(), index, Weight::max_value(), bytes_in_storage) + verify { + // The last proposal is removed. + // assert_eq!(Collective::::proposals().len(), (p - 1) as usize); + // assert_last_event::(Event::Disapproved(last_hash).into()); + } + + close_early_approved { + }: close(SystemOrigin::Signed(voter), last_hash.clone(), index, Weight::max_value(), bytes_in_storage) + verify { + + } + + close_disapproved { + }: close(SystemOrigin::Signed(voter), last_hash.clone(), index, Weight::max_value(), bytes_in_storage) + verify { + + } + + close_approved { + }: close(SystemOrigin::Signed(voter), last_hash.clone(), index, Weight::max_value(), bytes_in_storage) + verify { + + } + */ + init_members { // at least 2 founders - let a in 2 .. T::MaxFounders::get(); - let b in 0 .. T::MaxFellows::get(); - let c in 0 .. T::MaxAllies::get(); + let x in 2 .. T::MaxFounders::get(); + let y in 0 .. T::MaxFellows::get(); + let z in 0 .. T::MaxAllies::get(); - let mut founders = (2 .. a).map(founder::).collect::>(); - let mut fellows = (0 .. b).map(fellow::).collect::>(); - let mut allies = (0 .. c).map(ally::).collect::>(); + let mut founders = (2 .. x).map(founder::).collect::>(); + let mut fellows = (0 .. y).map(fellow::).collect::>(); + let mut allies = (0 .. z).map(ally::).collect::>(); - }: _(RawOrigin::Root, founders.clone(), fellows.clone(), allies.clone()) + }: _(SystemOrigin::Root, founders.clone(), fellows.clone(), allies.clone()) verify { founders.sort(); fellows.sort(); allies.sort(); + assert_last_event::(Event::MembersInitialized(founders.clone(), fellows.clone(), allies.clone()).into()); assert_eq!(Alliance::::members(MemberRole::Founder), founders); assert_eq!(Alliance::::members(MemberRole::Fellow), fellows); assert_eq!(Alliance::::members(MemberRole::Ally), allies); @@ -122,7 +312,8 @@ benchmarks_instance_pallet! { set_rule { set_members::(); - let rule = test_cid(); + let rule = rule(b"hello world"); + let call = Call::::set_rule { rule: rule.clone() }; let origin = T::SuperMajorityOrigin::successful_origin(); }: { call.dispatch_bypass_filter(origin)? } @@ -134,7 +325,7 @@ benchmarks_instance_pallet! { announce { set_members::(); - let announcement = test_cid(); + let announcement = announcement(b"hello world"); let call = Call::::announce { announcement: announcement.clone() }; let origin = T::SuperMajorityOrigin::successful_origin(); @@ -147,7 +338,7 @@ benchmarks_instance_pallet! { remove_announcement { set_members::(); - let announcement = test_cid(); + let announcement = announcement(b"hello world"); Announcements::::put(vec![announcement.clone()]); let call = Call::::remove_announcement { announcement: announcement.clone() }; @@ -165,7 +356,7 @@ benchmarks_instance_pallet! { assert!(!Alliance::::is_member(&outsider)); assert!(!Alliance::::is_candidate(&outsider)); assert_eq!(DepositOf::::get(&outsider), None); - }: _(RawOrigin::Signed(outsider.clone())) + }: _(SystemOrigin::Signed(outsider.clone())) verify { assert!(!Alliance::::is_member(&outsider)); assert!(Alliance::::is_candidate(&outsider)); @@ -185,7 +376,7 @@ benchmarks_instance_pallet! { assert_eq!(DepositOf::::get(&outsider), None); let outsider_lookup: ::Source = T::Lookup::unlookup(outsider.clone()); - }: _(RawOrigin::Signed(founder1.clone()), outsider_lookup) + }: _(SystemOrigin::Signed(founder1.clone()), outsider_lookup) verify { assert!(!Alliance::::is_member(&outsider)); assert!(Alliance::::is_candidate(&outsider)); @@ -257,7 +448,7 @@ benchmarks_instance_pallet! { assert!(!Alliance::::is_kicking(&fellow2)); assert_eq!(DepositOf::::get(&fellow2), Some(T::CandidateDeposit::get())); - }: _(RawOrigin::Signed(fellow2.clone())) + }: _(SystemOrigin::Signed(fellow2.clone())) verify { assert!(!Alliance::::is_member(&fellow2)); assert_eq!(DepositOf::::get(&fellow2), None); diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index 70f3ca1ee03f8..dac58fd167580 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -204,8 +204,9 @@ pub mod pallet { /// The outer call dispatch type. type Proposal: Parameter + Dispatchable - + GetDispatchInfo + From> + + From> + + GetDispatchInfo + IsSubType> + IsType<::Call>; diff --git a/frame/alliance/src/types.rs b/frame/alliance/src/types.rs index 5ef08f31efdcf..b245482dc5368 100644 --- a/frame/alliance/src/types.rs +++ b/frame/alliance/src/types.rs @@ -61,7 +61,7 @@ pub struct Cid { } impl Cid { - /// Create a new CIDv0. + /// Creates a new CIDv0. pub fn new_v0(sha2_256_digest: impl Into>) -> Self { /// DAG-PB multicodec code const DAG_PB: u64 = 0x70; diff --git a/frame/alliance/src/weights.rs b/frame/alliance/src/weights.rs index e3197cb60cd9d..4b53a771e115f 100644 --- a/frame/alliance/src/weights.rs +++ b/frame/alliance/src/weights.rs @@ -45,7 +45,10 @@ use sp_std::marker::PhantomData; /// Weight functions needed for pallet_alliance. pub trait WeightInfo { - fn init_members(a: u32, b: u32, c: u32, ) -> Weight; + fn propose_proposed(b: u32, x: u32, y: u32, p: u32, ) -> Weight; + fn vote(x: u32, y: u32, ) -> Weight; + fn veto(p: u32, ) -> Weight; + fn init_members(x: u32, y: u32, z: u32, ) -> Weight; fn set_rule() -> Weight; fn announce() -> Weight; fn remove_announcement() -> Weight; @@ -63,31 +66,69 @@ pub trait WeightInfo { /// Weights for pallet_alliance using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { + // Storage: Alliance Members (r:1 w:0) + // Storage: AllianceMotion ProposalOf (r:1 w:1) + // Storage: AllianceMotion Proposals (r:1 w:1) + // Storage: AllianceMotion ProposalCount (r:1 w:1) + // Storage: AllianceMotion Voting (r:0 w:1) + fn propose_proposed(_b: u32, x: u32, y: u32, p: u32, ) -> Weight { + (44_806_000 as Weight) + // Standard Error: 65_000 + .saturating_add((7_000 as Weight).saturating_mul(x as Weight)) + // Standard Error: 2_000 + .saturating_add((34_000 as Weight).saturating_mul(y as Weight)) + // Standard Error: 2_000 + .saturating_add((301_000 as Weight).saturating_mul(p as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + // Storage: Alliance Members (r:2 w:0) + // Storage: AllianceMotion Voting (r:1 w:1) + fn vote(x: u32, y: u32, ) -> Weight { + (33_851_000 as Weight) + // Standard Error: 81_000 + .saturating_add((209_000 as Weight).saturating_mul(x as Weight)) + // Standard Error: 3_000 + .saturating_add((198_000 as Weight).saturating_mul(y as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + // Storage: Alliance Members (r:1 w:0) + // Storage: AllianceMotion ProposalOf (r:1 w:1) + // Storage: AllianceMotion Proposals (r:1 w:1) + // Storage: AllianceMotion Voting (r:0 w:1) + fn veto(p: u32, ) -> Weight { + (30_478_000 as Weight) + // Standard Error: 2_000 + .saturating_add((320_000 as Weight).saturating_mul(p as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } // Storage: Alliance Members (r:3 w:3) // Storage: AllianceMotion Members (r:1 w:1) - fn init_members(_a: u32, b: u32, c: u32, ) -> Weight { - (42_518_000 as Weight) + fn init_members(_x: u32, y: u32, z: u32, ) -> Weight { + (40_162_000 as Weight) // Standard Error: 2_000 - .saturating_add((169_000 as Weight).saturating_mul(b as Weight)) + .saturating_add((166_000 as Weight).saturating_mul(y as Weight)) // Standard Error: 2_000 - .saturating_add((162_000 as Weight).saturating_mul(c as Weight)) + .saturating_add((144_000 as Weight).saturating_mul(z as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } // Storage: Alliance Rule (r:0 w:1) fn set_rule() -> Weight { - (14_427_000 as Weight) + (14_337_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Alliance Announcements (r:1 w:1) fn announce() -> Weight { - (17_153_000 as Weight) + (16_721_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Alliance Announcements (r:1 w:1) fn remove_announcement() -> Weight { - (17_152_000 as Weight) + (17_663_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } @@ -97,7 +138,7 @@ impl WeightInfo for SubstrateWeight { // Storage: System Account (r:1 w:1) // Storage: Alliance DepositOf (r:0 w:1) fn submit_candidacy() -> Weight { - (59_542_000 as Weight) + (57_289_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } @@ -105,14 +146,14 @@ impl WeightInfo for SubstrateWeight { // Storage: Alliance AccountBlacklist (r:1 w:0) // Storage: Alliance Candidates (r:1 w:1) fn nominate_candidacy() -> Weight { - (43_241_000 as Weight) + (42_350_000 as Weight) .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Alliance Candidates (r:1 w:1) // Storage: Alliance Members (r:4 w:1) fn approve_candidate() -> Weight { - (44_303_000 as Weight) + (44_364_000 as Weight) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } @@ -121,7 +162,7 @@ impl WeightInfo for SubstrateWeight { // Storage: Alliance DepositOf (r:1 w:1) // Storage: System Account (r:1 w:1) fn reject_candidate() -> Weight { - (68_839_000 as Weight) + (69_210_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } @@ -130,7 +171,7 @@ impl WeightInfo for SubstrateWeight { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn elevate_ally() -> Weight { - (42_540_000 as Weight) + (41_348_000 as Weight) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } @@ -142,7 +183,7 @@ impl WeightInfo for SubstrateWeight { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn retire() -> Weight { - (59_933_000 as Weight) + (58_139_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(5 as Weight)) } @@ -154,7 +195,7 @@ impl WeightInfo for SubstrateWeight { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn kick_member() -> Weight { - (66_675_000 as Weight) + (68_409_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(5 as Weight)) } @@ -163,9 +204,9 @@ impl WeightInfo for SubstrateWeight { fn add_blacklist(n: u32, l: u32, ) -> Weight { (0 as Weight) // Standard Error: 6_000 - .saturating_add((2_626_000 as Weight).saturating_mul(n as Weight)) - // Standard Error: 3_000 - .saturating_add((206_000 as Weight).saturating_mul(l as Weight)) + .saturating_add((2_590_000 as Weight).saturating_mul(n as Weight)) + // Standard Error: 2_000 + .saturating_add((194_000 as Weight).saturating_mul(l as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } @@ -173,10 +214,10 @@ impl WeightInfo for SubstrateWeight { // Storage: Alliance WebsiteBlacklist (r:1 w:1) fn remove_blacklist(n: u32, l: u32, ) -> Weight { (0 as Weight) - // Standard Error: 338_000 - .saturating_add((58_173_000 as Weight).saturating_mul(n as Weight)) - // Standard Error: 150_000 - .saturating_add((6_640_000 as Weight).saturating_mul(l as Weight)) + // Standard Error: 332_000 + .saturating_add((57_821_000 as Weight).saturating_mul(n as Weight)) + // Standard Error: 147_000 + .saturating_add((6_544_000 as Weight).saturating_mul(l as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } @@ -184,31 +225,69 @@ impl WeightInfo for SubstrateWeight { // For backwards compatibility and tests impl WeightInfo for () { + // Storage: Alliance Members (r:1 w:0) + // Storage: AllianceMotion ProposalOf (r:1 w:1) + // Storage: AllianceMotion Proposals (r:1 w:1) + // Storage: AllianceMotion ProposalCount (r:1 w:1) + // Storage: AllianceMotion Voting (r:0 w:1) + fn propose_proposed(_b: u32, x: u32, y: u32, p: u32, ) -> Weight { + (44_806_000 as Weight) + // Standard Error: 65_000 + .saturating_add((7_000 as Weight).saturating_mul(x as Weight)) + // Standard Error: 2_000 + .saturating_add((34_000 as Weight).saturating_mul(y as Weight)) + // Standard Error: 2_000 + .saturating_add((301_000 as Weight).saturating_mul(p as Weight)) + .saturating_add(RocksDbWeight::get().reads(4 as Weight)) + .saturating_add(RocksDbWeight::get().writes(4 as Weight)) + } + // Storage: Alliance Members (r:2 w:0) + // Storage: AllianceMotion Voting (r:1 w:1) + fn vote(x: u32, y: u32, ) -> Weight { + (33_851_000 as Weight) + // Standard Error: 81_000 + .saturating_add((209_000 as Weight).saturating_mul(x as Weight)) + // Standard Error: 3_000 + .saturating_add((198_000 as Weight).saturating_mul(y as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + // Storage: Alliance Members (r:1 w:0) + // Storage: AllianceMotion ProposalOf (r:1 w:1) + // Storage: AllianceMotion Proposals (r:1 w:1) + // Storage: AllianceMotion Voting (r:0 w:1) + fn veto(p: u32, ) -> Weight { + (30_478_000 as Weight) + // Standard Error: 2_000 + .saturating_add((320_000 as Weight).saturating_mul(p as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } // Storage: Alliance Members (r:3 w:3) // Storage: AllianceMotion Members (r:1 w:1) - fn init_members(_a: u32, b: u32, c: u32, ) -> Weight { - (42_518_000 as Weight) + fn init_members(_x: u32, y: u32, z: u32, ) -> Weight { + (40_162_000 as Weight) // Standard Error: 2_000 - .saturating_add((169_000 as Weight).saturating_mul(b as Weight)) + .saturating_add((166_000 as Weight).saturating_mul(y as Weight)) // Standard Error: 2_000 - .saturating_add((162_000 as Weight).saturating_mul(c as Weight)) + .saturating_add((144_000 as Weight).saturating_mul(z as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(4 as Weight)) } // Storage: Alliance Rule (r:0 w:1) fn set_rule() -> Weight { - (14_427_000 as Weight) + (14_337_000 as Weight) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Alliance Announcements (r:1 w:1) fn announce() -> Weight { - (17_153_000 as Weight) + (16_721_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Alliance Announcements (r:1 w:1) fn remove_announcement() -> Weight { - (17_152_000 as Weight) + (17_663_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } @@ -218,7 +297,7 @@ impl WeightInfo for () { // Storage: System Account (r:1 w:1) // Storage: Alliance DepositOf (r:0 w:1) fn submit_candidacy() -> Weight { - (59_542_000 as Weight) + (57_289_000 as Weight) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } @@ -226,14 +305,14 @@ impl WeightInfo for () { // Storage: Alliance AccountBlacklist (r:1 w:0) // Storage: Alliance Candidates (r:1 w:1) fn nominate_candidacy() -> Weight { - (43_241_000 as Weight) + (42_350_000 as Weight) .saturating_add(RocksDbWeight::get().reads(6 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Alliance Candidates (r:1 w:1) // Storage: Alliance Members (r:4 w:1) fn approve_candidate() -> Weight { - (44_303_000 as Weight) + (44_364_000 as Weight) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } @@ -242,7 +321,7 @@ impl WeightInfo for () { // Storage: Alliance DepositOf (r:1 w:1) // Storage: System Account (r:1 w:1) fn reject_candidate() -> Weight { - (68_839_000 as Weight) + (69_210_000 as Weight) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } @@ -251,7 +330,7 @@ impl WeightInfo for () { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn elevate_ally() -> Weight { - (42_540_000 as Weight) + (41_348_000 as Weight) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(4 as Weight)) } @@ -263,7 +342,7 @@ impl WeightInfo for () { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn retire() -> Weight { - (59_933_000 as Weight) + (58_139_000 as Weight) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().writes(5 as Weight)) } @@ -275,7 +354,7 @@ impl WeightInfo for () { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn kick_member() -> Weight { - (66_675_000 as Weight) + (68_409_000 as Weight) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().writes(5 as Weight)) } @@ -284,9 +363,9 @@ impl WeightInfo for () { fn add_blacklist(n: u32, l: u32, ) -> Weight { (0 as Weight) // Standard Error: 6_000 - .saturating_add((2_626_000 as Weight).saturating_mul(n as Weight)) - // Standard Error: 3_000 - .saturating_add((206_000 as Weight).saturating_mul(l as Weight)) + .saturating_add((2_590_000 as Weight).saturating_mul(n as Weight)) + // Standard Error: 2_000 + .saturating_add((194_000 as Weight).saturating_mul(l as Weight)) .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } @@ -294,10 +373,10 @@ impl WeightInfo for () { // Storage: Alliance WebsiteBlacklist (r:1 w:1) fn remove_blacklist(n: u32, l: u32, ) -> Weight { (0 as Weight) - // Standard Error: 338_000 - .saturating_add((58_173_000 as Weight).saturating_mul(n as Weight)) - // Standard Error: 150_000 - .saturating_add((6_640_000 as Weight).saturating_mul(l as Weight)) + // Standard Error: 332_000 + .saturating_add((57_821_000 as Weight).saturating_mul(n as Weight)) + // Standard Error: 147_000 + .saturating_add((6_544_000 as Weight).saturating_mul(l as Weight)) .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } From a359aead65acd7e270ea188af682e9a4ef8d665a Mon Sep 17 00:00:00 2001 From: koushiro Date: Mon, 11 Oct 2021 22:39:21 +0800 Subject: [PATCH 19/72] Fix benchmarking Signed-off-by: koushiro --- frame/alliance/src/benchmarking.rs | 348 ++++++++++++++++++++++++++--- frame/alliance/src/lib.rs | 35 ++- frame/alliance/src/weights.rs | 284 +++++++++++++++++------ 3 files changed, 559 insertions(+), 108 deletions(-) diff --git a/frame/alliance/src/benchmarking.rs b/frame/alliance/src/benchmarking.rs index 987d29e14d23c..9a28ad2e591da 100644 --- a/frame/alliance/src/benchmarking.rs +++ b/frame/alliance/src/benchmarking.rs @@ -22,7 +22,7 @@ use sp_std::{mem::size_of, prelude::*}; use frame_benchmarking::{account, benchmarks_instance_pallet}; use frame_support::traits::{EnsureOrigin, Get, UnfilteredDispatchable}; -use frame_system::RawOrigin as SystemOrigin; +use frame_system::{Pallet as System, RawOrigin as SystemOrigin}; use super::{Call as AllianceCall, Pallet as Alliance, *}; @@ -118,21 +118,24 @@ benchmarks_instance_pallet! { let y in 0 .. T::MaxFellows::get(); let p in 1 .. T::MaxProposals::get(); - let bytes_in_storage = size_of::() as u32 + 32; + let m = x + y; + + let bytes_in_storage = b + size_of::() as u32 + 32; // Construct `members`. - let mut founders = (1 .. x - 1).map(founder::).collect::>(); - let proposer = founder::(0); - founders.push(proposer.clone()); + let founders = (0 .. x).map(founder::).collect::>(); + let proposer = founders[0].clone(); let fellows = (0 .. y).map(fellow::).collect::>(); Alliance::::init_members(SystemOrigin::Root.into(), founders, fellows, vec![])?; - let threshold = x + y; + let threshold = m; // Add previous proposals. for i in 0 .. p - 1 { // Proposals should be different so that different proposal hashes are generated - let proposal: T::Proposal = AllianceCall::::set_rule { rule: rule(vec![i as u8; b as usize]) }.into(); + let proposal: T::Proposal = AllianceCall::::set_rule { + rule: rule(vec![i as u8; b as usize]) + }.into(); Alliance::::propose( SystemOrigin::Signed(proposer.clone()).into(), threshold, @@ -155,17 +158,16 @@ benchmarks_instance_pallet! { let x in 3 .. T::MaxFounders::get(); let y in 2 .. T::MaxFellows::get(); + let m = x + y; + let p = T::MaxProposals::get(); let b = MAX_BYTES; - let bytes_in_storage = size_of::() as u32 + 32; + let bytes_in_storage = b + size_of::() as u32 + 32; // Construct `members`. - let mut founders = (1 .. x - 1).map(founder::).collect::>(); - let proposer = founder::(0); - founders.push(proposer.clone()); - let mut fellows = (1 .. y - 1).map(fellow::).collect::>(); - let voter = fellow::(0); - fellows.push(voter.clone()); + let founders = (0 .. x).map(founder::).collect::>(); + let proposer = founders[0].clone(); + let fellows = (0 .. y).map(fellow::).collect::>(); let mut members = Vec::with_capacity(founders.len() + fellows.len()); members.extend(founders.clone()); @@ -174,14 +176,15 @@ benchmarks_instance_pallet! { Alliance::::init_members(SystemOrigin::Root.into(), founders, fellows, vec![])?; // Threshold is 1 less than the number of members so that one person can vote nay - let m = x + y; let threshold = m - 1; // Add previous proposals let mut last_hash = T::Hash::default(); for i in 0 .. p { // Proposals should be different so that different proposal hashes are generated - let proposal: T::Proposal = AllianceCall::::set_rule { rule: rule(vec![i as u8; b as usize]) }.into(); + let proposal: T::Proposal = AllianceCall::::set_rule { + rule: rule(vec![i as u8; b as usize]) + }.into(); Alliance::::propose( SystemOrigin::Signed(proposer.clone()).into(), threshold, @@ -195,21 +198,21 @@ benchmarks_instance_pallet! { // Have almost everyone vote aye on last proposal, while keeping it from passing. for j in 0 .. m - 3 { let voter = &members[j as usize]; - let approve = true; Alliance::::vote( SystemOrigin::Signed(voter.clone()).into(), last_hash.clone(), index, - approve, + true, )?; } + + let voter = members[m as usize - 3].clone(); // Voter votes aye without resolving the vote. - let approve = true; Alliance::::vote( SystemOrigin::Signed(voter.clone()).into(), last_hash.clone(), index, - approve, + true, )?; // Voter switches vote to nay, but does not kill the vote, just updates + inserts @@ -230,9 +233,8 @@ benchmarks_instance_pallet! { let bytes_in_storage = b + size_of::() as u32 + 32; // Construct `members`. - let mut founders = (1 .. m).map(founder::).collect::>(); - let vetor = founder::(0); - founders.push(vetor.clone()); + let founders = (0 .. m).map(founder::).collect::>(); + let vetor = founders[0].clone(); Alliance::::init_members(SystemOrigin::Root.into(), founders, vec![], vec![])?; @@ -243,7 +245,9 @@ benchmarks_instance_pallet! { let mut last_hash = T::Hash::default(); for i in 0 .. p { // Proposals should be different so that different proposal hashes are generated - let proposal: T::Proposal = AllianceCall::::set_rule { rule: rule(vec![i as u8; b as usize]) }.into(); + let proposal: T::Proposal = AllianceCall::::set_rule { + rule: rule(vec![i as u8; b as usize]) + }.into(); Alliance::::propose( SystemOrigin::Signed(vetor.clone()).into(), threshold, @@ -259,34 +263,316 @@ benchmarks_instance_pallet! { assert_eq!(T::ProposalProvider::proposal_of(last_hash), None); } - /* close_early_disapproved { + // We choose 4 (2 founders + 2 fellows) as a minimum so we always trigger a vote in the voting loop (`for j in ...`) + let x in 2 .. T::MaxFounders::get(); + let y in 2 .. T::MaxFellows::get(); + let p in 1 .. T::MaxProposals::get(); + + let m = x + y; + + let bytes = 100; + let bytes_in_storage = bytes + size_of::() as u32 + 32; + // Construct `members`. + let founders = (0 .. x).map(founder::).collect::>(); + let fellows = (0 .. y).map(fellow::).collect::>(); + + let mut members = Vec::with_capacity(founders.len() + fellows.len()); + members.extend(founders.clone()); + members.extend(fellows.clone()); + + Alliance::::init_members(SystemOrigin::Root.into(), founders, fellows, vec![])?; + + let proposer = members[0].clone(); + let voter = members[1].clone(); + + // Threshold is total members so that one nay will disapprove the vote + let threshold = m; + + // Add previous proposals + let mut last_hash = T::Hash::default(); + for i in 0 .. p { + // Proposals should be different so that different proposal hashes are generated + let proposal: T::Proposal = AllianceCall::::set_rule { + rule: rule(vec![i as u8; bytes as usize]) + }.into(); + Alliance::::propose( + SystemOrigin::Signed(proposer.clone()).into(), + threshold, + Box::new(proposal.clone()), + bytes_in_storage, + )?; + last_hash = T::Hashing::hash_of(&proposal); + assert_eq!(T::ProposalProvider::proposal_of(last_hash), Some(proposal)); + } + + let index = p - 1; + // Have most everyone vote aye on last proposal, while keeping it from passing. + for j in 2 .. m - 1 { + let voter = &members[j as usize]; + Alliance::::vote( + SystemOrigin::Signed(voter.clone()).into(), + last_hash.clone(), + index, + true, + )?; + } + + // Voter votes aye without resolving the vote. + Alliance::::vote( + SystemOrigin::Signed(voter.clone()).into(), + last_hash.clone(), + index, + true, + )?; + + // Voter switches vote to nay, which kills the vote + Alliance::::vote( + SystemOrigin::Signed(voter.clone()).into(), + last_hash.clone(), + index, + false, + )?; + + // Whitelist voter account from further DB operations. + let voter_key = frame_system::Account::::hashed_key_for(&voter); + frame_benchmarking::benchmarking::add_to_whitelist(voter_key.into()); }: close(SystemOrigin::Signed(voter), last_hash.clone(), index, Weight::max_value(), bytes_in_storage) verify { // The last proposal is removed. - // assert_eq!(Collective::::proposals().len(), (p - 1) as usize); - // assert_last_event::(Event::Disapproved(last_hash).into()); + assert_eq!(T::ProposalProvider::proposal_of(last_hash), None); } close_early_approved { + let b in 1 .. MAX_BYTES; + // We choose 4 (2 founders + 2 fellows) as a minimum so we always trigger a vote in the voting loop (`for j in ...`) + let x in 2 .. T::MaxFounders::get(); + let y in 2 .. T::MaxFellows::get(); + let p in 1 .. T::MaxProposals::get(); + + let m = x + y; + let bytes_in_storage = b + size_of::() as u32 + 32; + + // Construct `members`. + let founders = (0 .. x).map(founder::).collect::>(); + let fellows = (0 .. y).map(fellow::).collect::>(); + + let mut members = Vec::with_capacity(founders.len() + fellows.len()); + members.extend(founders.clone()); + members.extend(fellows.clone()); + + Alliance::::init_members(SystemOrigin::Root.into(), founders, fellows, vec![])?; + + let proposer = members[0].clone(); + let voter = members[1].clone(); + + // Threshold is 2 so any two ayes will approve the vote + let threshold = 2; + + // Add previous proposals + let mut last_hash = T::Hash::default(); + for i in 0 .. p { + // Proposals should be different so that different proposal hashes are generated + let proposal: T::Proposal = AllianceCall::::set_rule { + rule: rule(vec![i as u8; b as usize]) + }.into(); + Alliance::::propose( + SystemOrigin::Signed(proposer.clone()).into(), + threshold, + Box::new(proposal.clone()), + bytes_in_storage, + )?; + last_hash = T::Hashing::hash_of(&proposal); + assert_eq!(T::ProposalProvider::proposal_of(last_hash), Some(proposal)); + } + + let index = p - 1; + // Caller switches vote to nay on their own proposal, allowing them to be the deciding approval vote + Alliance::::vote( + SystemOrigin::Signed(proposer.clone()).into(), + last_hash.clone(), + index, + false, + )?; + + // Have almost everyone vote nay on last proposal, while keeping it from failing. + for j in 2 .. m - 1 { + let voter = &members[j as usize]; + Alliance::::vote( + SystemOrigin::Signed(voter.clone()).into(), + last_hash.clone(), + index, + false, + )?; + } + + // Member zero is the first aye + Alliance::::vote( + SystemOrigin::Signed(members[0].clone()).into(), + last_hash.clone(), + index, + true, + )?; + + let voter = members[1].clone(); + // Caller switches vote to aye, which passes the vote + Alliance::::vote( + SystemOrigin::Signed(voter.clone()).into(), + last_hash.clone(), + index, + true, + )?; }: close(SystemOrigin::Signed(voter), last_hash.clone(), index, Weight::max_value(), bytes_in_storage) verify { - + // The last proposal is removed. + assert_eq!(T::ProposalProvider::proposal_of(last_hash), None); } close_disapproved { + // We choose 2 (2 founders / 2 fellows) as a minimum so we always trigger a vote in the voting loop (`for j in ...`) + let x in 2 .. T::MaxFounders::get(); + let y in 2 .. T::MaxFellows::get(); + let p in 1 .. T::MaxProposals::get(); + + let m = x + y; + + let bytes = 100; + let bytes_in_storage = bytes + size_of::() as u32 + 32; + + // Construct `members`. + let founders = (0 .. x).map(founder::).collect::>(); + let fellows = (0 .. y).map(fellow::).collect::>(); + + let mut members = Vec::with_capacity(founders.len() + fellows.len()); + members.extend(founders.clone()); + members.extend(fellows.clone()); + + Alliance::::init_members(SystemOrigin::Root.into(), founders, fellows, vec![])?; + + let proposer = members[0].clone(); + let voter = members[1].clone(); + + // Threshold is one less than total members so that two nays will disapprove the vote + let threshold = m - 1; + + // Add proposals + let mut last_hash = T::Hash::default(); + for i in 0 .. p { + // Proposals should be different so that different proposal hashes are generated + let proposal: T::Proposal = AllianceCall::::set_rule { + rule: rule(vec![i as u8; bytes as usize]) + }.into(); + Alliance::::propose( + SystemOrigin::Signed(proposer.clone()).into(), + threshold, + Box::new(proposal.clone()), + bytes_in_storage, + )?; + last_hash = T::Hashing::hash_of(&proposal); + assert_eq!(T::ProposalProvider::proposal_of(last_hash), Some(proposal)); + } + + let index = p - 1; + // Have almost everyone vote aye on last proposal, while keeping it from passing. + // A few abstainers will be the nay votes needed to fail the vote. + for j in 2 .. m - 1 { + let voter = &members[j as usize]; + Alliance::::vote( + SystemOrigin::Signed(voter.clone()).into(), + last_hash.clone(), + index, + true, + )?; + } + + Alliance::::vote( + SystemOrigin::Signed(voter.clone()).into(), + last_hash.clone(), + index, + false, + )?; + + System::::set_block_number(T::BlockNumber::max_value()); + }: close(SystemOrigin::Signed(voter), last_hash.clone(), index, Weight::max_value(), bytes_in_storage) verify { - + // The last proposal is removed. + assert_eq!(T::ProposalProvider::proposal_of(last_hash), None); } close_approved { + let b in 1 .. MAX_BYTES; + // We choose 4 (2 founders + 2 fellows) as a minimum so we always trigger a vote in the voting loop (`for j in ...`) + let x in 2 .. T::MaxFounders::get(); + let y in 2 .. T::MaxFellows::get(); + let p in 1 .. T::MaxProposals::get(); + + let m = x + y; + let bytes_in_storage = b + size_of::() as u32 + 32; + + // Construct `members`. + let founders = (0 .. x).map(founder::).collect::>(); + let fellows = (0 .. y).map(fellow::).collect::>(); + + let mut members = Vec::with_capacity(founders.len() + fellows.len()); + members.extend(founders.clone()); + members.extend(fellows.clone()); + + Alliance::::init_members(SystemOrigin::Root.into(), founders, fellows, vec![])?; + + let proposer = members[0].clone(); + let voter = members[1].clone(); + + // Threshold is two, so any two ayes will pass the vote + let threshold = 2; + + // Add proposals + let mut last_hash = T::Hash::default(); + for i in 0 .. p { + // Proposals should be different so that different proposal hashes are generated + let proposal: T::Proposal = AllianceCall::::set_rule { + rule: rule(vec![i as u8; b as usize]) + }.into(); + Alliance::::propose( + SystemOrigin::Signed(proposer.clone()).into(), + threshold, + Box::new(proposal.clone()), + bytes_in_storage, + )?; + last_hash = T::Hashing::hash_of(&proposal); + assert_eq!(T::ProposalProvider::proposal_of(last_hash), Some(proposal)); + } + + // The prime member votes aye, so abstentions default to aye. + Alliance::::vote( + SystemOrigin::Signed(proposer.clone()).into(), + last_hash.clone(), + p - 1, + true // Vote aye. + )?; + + let index = p - 1; + // Have almost everyone vote nay on last proposal, while keeping it from failing. + // A few abstainers will be the aye votes needed to pass the vote. + for j in 2 .. m - 1 { + let voter = &members[j as usize]; + Alliance::::vote( + SystemOrigin::Signed(voter.clone()).into(), + last_hash.clone(), + index, + false + )?; + } + + // caller is prime, prime already votes aye by creating the proposal + System::::set_block_number(T::BlockNumber::max_value()); + }: close(SystemOrigin::Signed(voter), last_hash.clone(), index, Weight::max_value(), bytes_in_storage) verify { - + // The last proposal is removed. + assert_eq!(T::ProposalProvider::proposal_of(last_hash), None); } - */ init_members { // at least 2 founders diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index dac58fd167580..15ae5a76ca24d 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -466,7 +466,15 @@ pub mod pallet { /// Add a new proposal to be voted on. /// /// Requires the sender to be founder or fellow. - #[pallet::weight(0)] + #[pallet::weight(( + T::WeightInfo::propose_proposed( + *length_bound, // B + T::MaxFounders::get(), // X + T::MaxFellows::get(), // Y + T::MaxProposals::get(), // P2 + ), + DispatchClass::Operational + ))] pub fn propose( origin: OriginFor, #[pallet::compact] threshold: u32, @@ -488,7 +496,10 @@ pub mod pallet { /// Add an aye or nay vote for the sender to the given proposal. /// /// Requires the sender to be founder or fellow. - #[pallet::weight(0)] + #[pallet::weight(( + T::WeightInfo::vote(T::MaxFounders::get(), T::MaxFellows::get()), + DispatchClass::Operational + ))] pub fn vote( origin: OriginFor, proposal: T::Hash, @@ -506,7 +517,7 @@ pub mod pallet { /// the system, regardless of its current state. /// /// Must be called by a founder. - #[pallet::weight(0)] + #[pallet::weight(T::WeightInfo::veto(T::MaxProposals::get()))] pub fn veto(origin: OriginFor, proposal_hash: T::Hash) -> DispatchResultWithPostInfo { let proposor = ensure_signed(origin)?; ensure!(Self::is_founder(&proposor), Error::::NotFounder); @@ -525,7 +536,21 @@ pub mod pallet { /// Close a vote that is either approved, disapproved or whose voting period has ended. /// /// Requires the sender to be founder or fellow. - #[pallet::weight(0)] + #[pallet::weight(( + { + let b = *length_bound; + let x = T::MaxFounders::get(); + let y = T::MaxFellows::get(); + let p1 = *proposal_weight_bound; + let p2 = T::MaxProposals::get(); + T::WeightInfo::close_early_approved(b, x, y, p2) + .max(T::WeightInfo::close_early_disapproved(x, y, p2)) + .max(T::WeightInfo::close_approved(b, x, y, p2)) + .max(T::WeightInfo::close_disapproved(x, y, p2)) + .saturating_add(p1) + }, + DispatchClass::Operational + ))] pub fn close( origin: OriginFor, proposal_hash: T::Hash, @@ -553,7 +578,7 @@ pub mod pallet { >::remove(strike); } } - Ok(().into()) + Ok(info.into()) } /// Initialize the founders/fellows/allies. diff --git a/frame/alliance/src/weights.rs b/frame/alliance/src/weights.rs index 4b53a771e115f..45cca8c980051 100644 --- a/frame/alliance/src/weights.rs +++ b/frame/alliance/src/weights.rs @@ -48,6 +48,10 @@ pub trait WeightInfo { fn propose_proposed(b: u32, x: u32, y: u32, p: u32, ) -> Weight; fn vote(x: u32, y: u32, ) -> Weight; fn veto(p: u32, ) -> Weight; + fn close_early_disapproved(x: u32, y: u32, p: u32, ) -> Weight; + fn close_early_approved(b: u32, x: u32, y: u32, p: u32, ) -> Weight; + fn close_disapproved(x: u32, y: u32, p: u32, ) -> Weight; + fn close_approved(b: u32, x: u32, y: u32, p: u32, ) -> Weight; fn init_members(x: u32, y: u32, z: u32, ) -> Weight; fn set_rule() -> Weight; fn announce() -> Weight; @@ -71,25 +75,23 @@ impl WeightInfo for SubstrateWeight { // Storage: AllianceMotion Proposals (r:1 w:1) // Storage: AllianceMotion ProposalCount (r:1 w:1) // Storage: AllianceMotion Voting (r:0 w:1) - fn propose_proposed(_b: u32, x: u32, y: u32, p: u32, ) -> Weight { - (44_806_000 as Weight) - // Standard Error: 65_000 - .saturating_add((7_000 as Weight).saturating_mul(x as Weight)) + fn propose_proposed(_b: u32, _x: u32, y: u32, p: u32, ) -> Weight { + (39_992_000 as Weight) // Standard Error: 2_000 - .saturating_add((34_000 as Weight).saturating_mul(y as Weight)) + .saturating_add((44_000 as Weight).saturating_mul(y as Weight)) // Standard Error: 2_000 - .saturating_add((301_000 as Weight).saturating_mul(p as Weight)) + .saturating_add((323_000 as Weight).saturating_mul(p as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } // Storage: Alliance Members (r:2 w:0) // Storage: AllianceMotion Voting (r:1 w:1) fn vote(x: u32, y: u32, ) -> Weight { - (33_851_000 as Weight) - // Standard Error: 81_000 - .saturating_add((209_000 as Weight).saturating_mul(x as Weight)) + (36_649_000 as Weight) + // Standard Error: 90_000 + .saturating_add((42_000 as Weight).saturating_mul(x as Weight)) // Standard Error: 3_000 - .saturating_add((198_000 as Weight).saturating_mul(y as Weight)) + .saturating_add((195_000 as Weight).saturating_mul(y as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } @@ -98,37 +100,107 @@ impl WeightInfo for SubstrateWeight { // Storage: AllianceMotion Proposals (r:1 w:1) // Storage: AllianceMotion Voting (r:0 w:1) fn veto(p: u32, ) -> Weight { - (30_478_000 as Weight) - // Standard Error: 2_000 - .saturating_add((320_000 as Weight).saturating_mul(p as Weight)) + (30_301_000 as Weight) + // Standard Error: 1_000 + .saturating_add((330_000 as Weight).saturating_mul(p as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } + // Storage: Alliance Members (r:1 w:0) + // Storage: AllianceMotion ProposalOf (r:1 w:1) + // Storage: AllianceMotion Voting (r:1 w:1) + // Storage: AllianceMotion Members (r:1 w:0) + // Storage: AllianceMotion Proposals (r:1 w:1) + fn close_early_disapproved(x: u32, y: u32, p: u32, ) -> Weight { + (40_472_000 as Weight) + // Standard Error: 69_000 + .saturating_add((485_000 as Weight).saturating_mul(x as Weight)) + // Standard Error: 2_000 + .saturating_add((192_000 as Weight).saturating_mul(y as Weight)) + // Standard Error: 2_000 + .saturating_add((330_000 as Weight).saturating_mul(p as Weight)) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + // Storage: Alliance Members (r:1 w:0) + // Storage: AllianceMotion ProposalOf (r:1 w:1) + // Storage: AllianceMotion Voting (r:1 w:1) + // Storage: AllianceMotion Members (r:1 w:0) + // Storage: AllianceMotion Proposals (r:1 w:1) + fn close_early_approved(b: u32, x: u32, y: u32, p: u32, ) -> Weight { + (52_076_000 as Weight) + // Standard Error: 0 + .saturating_add((4_000 as Weight).saturating_mul(b as Weight)) + // Standard Error: 77_000 + .saturating_add((194_000 as Weight).saturating_mul(x as Weight)) + // Standard Error: 3_000 + .saturating_add((188_000 as Weight).saturating_mul(y as Weight)) + // Standard Error: 2_000 + .saturating_add((329_000 as Weight).saturating_mul(p as Weight)) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + // Storage: Alliance Members (r:1 w:0) + // Storage: AllianceMotion ProposalOf (r:1 w:1) + // Storage: AllianceMotion Voting (r:1 w:1) + // Storage: AllianceMotion Members (r:1 w:0) + // Storage: AllianceMotion Prime (r:1 w:0) + // Storage: AllianceMotion Proposals (r:1 w:1) + fn close_disapproved(x: u32, y: u32, p: u32, ) -> Weight { + (47_009_000 as Weight) + // Standard Error: 66_000 + .saturating_add((256_000 as Weight).saturating_mul(x as Weight)) + // Standard Error: 2_000 + .saturating_add((176_000 as Weight).saturating_mul(y as Weight)) + // Standard Error: 2_000 + .saturating_add((327_000 as Weight).saturating_mul(p as Weight)) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + // Storage: Alliance Members (r:1 w:0) + // Storage: AllianceMotion ProposalOf (r:1 w:1) + // Storage: AllianceMotion Voting (r:1 w:1) + // Storage: AllianceMotion Members (r:1 w:0) + // Storage: AllianceMotion Prime (r:1 w:0) + // Storage: AllianceMotion Proposals (r:1 w:1) + fn close_approved(b: u32, x: u32, y: u32, p: u32, ) -> Weight { + (43_650_000 as Weight) + // Standard Error: 0 + .saturating_add((3_000 as Weight).saturating_mul(b as Weight)) + // Standard Error: 85_000 + .saturating_add((124_000 as Weight).saturating_mul(x as Weight)) + // Standard Error: 3_000 + .saturating_add((199_000 as Weight).saturating_mul(y as Weight)) + // Standard Error: 3_000 + .saturating_add((326_000 as Weight).saturating_mul(p as Weight)) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } // Storage: Alliance Members (r:3 w:3) // Storage: AllianceMotion Members (r:1 w:1) fn init_members(_x: u32, y: u32, z: u32, ) -> Weight { - (40_162_000 as Weight) - // Standard Error: 2_000 - .saturating_add((166_000 as Weight).saturating_mul(y as Weight)) - // Standard Error: 2_000 - .saturating_add((144_000 as Weight).saturating_mul(z as Weight)) + (45_100_000 as Weight) + // Standard Error: 4_000 + .saturating_add((162_000 as Weight).saturating_mul(y as Weight)) + // Standard Error: 4_000 + .saturating_add((151_000 as Weight).saturating_mul(z as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } // Storage: Alliance Rule (r:0 w:1) fn set_rule() -> Weight { - (14_337_000 as Weight) + (14_517_000 as Weight) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Alliance Announcements (r:1 w:1) fn announce() -> Weight { - (16_721_000 as Weight) + (16_801_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Alliance Announcements (r:1 w:1) fn remove_announcement() -> Weight { - (17_663_000 as Weight) + (17_133_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } @@ -138,7 +210,7 @@ impl WeightInfo for SubstrateWeight { // Storage: System Account (r:1 w:1) // Storage: Alliance DepositOf (r:0 w:1) fn submit_candidacy() -> Weight { - (57_289_000 as Weight) + (95_370_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } @@ -146,14 +218,14 @@ impl WeightInfo for SubstrateWeight { // Storage: Alliance AccountBlacklist (r:1 w:0) // Storage: Alliance Candidates (r:1 w:1) fn nominate_candidacy() -> Weight { - (42_350_000 as Weight) + (44_764_000 as Weight) .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Alliance Candidates (r:1 w:1) // Storage: Alliance Members (r:4 w:1) fn approve_candidate() -> Weight { - (44_364_000 as Weight) + (71_876_000 as Weight) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } @@ -162,7 +234,7 @@ impl WeightInfo for SubstrateWeight { // Storage: Alliance DepositOf (r:1 w:1) // Storage: System Account (r:1 w:1) fn reject_candidate() -> Weight { - (69_210_000 as Weight) + (69_732_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } @@ -171,7 +243,7 @@ impl WeightInfo for SubstrateWeight { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn elevate_ally() -> Weight { - (41_348_000 as Weight) + (44_013_000 as Weight) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } @@ -183,7 +255,7 @@ impl WeightInfo for SubstrateWeight { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn retire() -> Weight { - (58_139_000 as Weight) + (60_183_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(5 as Weight)) } @@ -195,7 +267,7 @@ impl WeightInfo for SubstrateWeight { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn kick_member() -> Weight { - (68_409_000 as Weight) + (67_467_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(5 as Weight)) } @@ -203,10 +275,10 @@ impl WeightInfo for SubstrateWeight { // Storage: Alliance WebsiteBlacklist (r:1 w:1) fn add_blacklist(n: u32, l: u32, ) -> Weight { (0 as Weight) - // Standard Error: 6_000 - .saturating_add((2_590_000 as Weight).saturating_mul(n as Weight)) - // Standard Error: 2_000 - .saturating_add((194_000 as Weight).saturating_mul(l as Weight)) + // Standard Error: 16_000 + .saturating_add((2_673_000 as Weight).saturating_mul(n as Weight)) + // Standard Error: 7_000 + .saturating_add((224_000 as Weight).saturating_mul(l as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } @@ -214,10 +286,10 @@ impl WeightInfo for SubstrateWeight { // Storage: Alliance WebsiteBlacklist (r:1 w:1) fn remove_blacklist(n: u32, l: u32, ) -> Weight { (0 as Weight) - // Standard Error: 332_000 - .saturating_add((57_821_000 as Weight).saturating_mul(n as Weight)) - // Standard Error: 147_000 - .saturating_add((6_544_000 as Weight).saturating_mul(l as Weight)) + // Standard Error: 343_000 + .saturating_add((59_025_000 as Weight).saturating_mul(n as Weight)) + // Standard Error: 153_000 + .saturating_add((6_725_000 as Weight).saturating_mul(l as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } @@ -230,25 +302,23 @@ impl WeightInfo for () { // Storage: AllianceMotion Proposals (r:1 w:1) // Storage: AllianceMotion ProposalCount (r:1 w:1) // Storage: AllianceMotion Voting (r:0 w:1) - fn propose_proposed(_b: u32, x: u32, y: u32, p: u32, ) -> Weight { - (44_806_000 as Weight) - // Standard Error: 65_000 - .saturating_add((7_000 as Weight).saturating_mul(x as Weight)) + fn propose_proposed(_b: u32, _x: u32, y: u32, p: u32, ) -> Weight { + (39_992_000 as Weight) // Standard Error: 2_000 - .saturating_add((34_000 as Weight).saturating_mul(y as Weight)) + .saturating_add((44_000 as Weight).saturating_mul(y as Weight)) // Standard Error: 2_000 - .saturating_add((301_000 as Weight).saturating_mul(p as Weight)) + .saturating_add((323_000 as Weight).saturating_mul(p as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(4 as Weight)) } // Storage: Alliance Members (r:2 w:0) // Storage: AllianceMotion Voting (r:1 w:1) fn vote(x: u32, y: u32, ) -> Weight { - (33_851_000 as Weight) - // Standard Error: 81_000 - .saturating_add((209_000 as Weight).saturating_mul(x as Weight)) + (36_649_000 as Weight) + // Standard Error: 90_000 + .saturating_add((42_000 as Weight).saturating_mul(x as Weight)) // Standard Error: 3_000 - .saturating_add((198_000 as Weight).saturating_mul(y as Weight)) + .saturating_add((195_000 as Weight).saturating_mul(y as Weight)) .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } @@ -257,37 +327,107 @@ impl WeightInfo for () { // Storage: AllianceMotion Proposals (r:1 w:1) // Storage: AllianceMotion Voting (r:0 w:1) fn veto(p: u32, ) -> Weight { - (30_478_000 as Weight) - // Standard Error: 2_000 - .saturating_add((320_000 as Weight).saturating_mul(p as Weight)) + (30_301_000 as Weight) + // Standard Error: 1_000 + .saturating_add((330_000 as Weight).saturating_mul(p as Weight)) .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } + // Storage: Alliance Members (r:1 w:0) + // Storage: AllianceMotion ProposalOf (r:1 w:1) + // Storage: AllianceMotion Voting (r:1 w:1) + // Storage: AllianceMotion Members (r:1 w:0) + // Storage: AllianceMotion Proposals (r:1 w:1) + fn close_early_disapproved(x: u32, y: u32, p: u32, ) -> Weight { + (40_472_000 as Weight) + // Standard Error: 69_000 + .saturating_add((485_000 as Weight).saturating_mul(x as Weight)) + // Standard Error: 2_000 + .saturating_add((192_000 as Weight).saturating_mul(y as Weight)) + // Standard Error: 2_000 + .saturating_add((330_000 as Weight).saturating_mul(p as Weight)) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + // Storage: Alliance Members (r:1 w:0) + // Storage: AllianceMotion ProposalOf (r:1 w:1) + // Storage: AllianceMotion Voting (r:1 w:1) + // Storage: AllianceMotion Members (r:1 w:0) + // Storage: AllianceMotion Proposals (r:1 w:1) + fn close_early_approved(b: u32, x: u32, y: u32, p: u32, ) -> Weight { + (52_076_000 as Weight) + // Standard Error: 0 + .saturating_add((4_000 as Weight).saturating_mul(b as Weight)) + // Standard Error: 77_000 + .saturating_add((194_000 as Weight).saturating_mul(x as Weight)) + // Standard Error: 3_000 + .saturating_add((188_000 as Weight).saturating_mul(y as Weight)) + // Standard Error: 2_000 + .saturating_add((329_000 as Weight).saturating_mul(p as Weight)) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + // Storage: Alliance Members (r:1 w:0) + // Storage: AllianceMotion ProposalOf (r:1 w:1) + // Storage: AllianceMotion Voting (r:1 w:1) + // Storage: AllianceMotion Members (r:1 w:0) + // Storage: AllianceMotion Prime (r:1 w:0) + // Storage: AllianceMotion Proposals (r:1 w:1) + fn close_disapproved(x: u32, y: u32, p: u32, ) -> Weight { + (47_009_000 as Weight) + // Standard Error: 66_000 + .saturating_add((256_000 as Weight).saturating_mul(x as Weight)) + // Standard Error: 2_000 + .saturating_add((176_000 as Weight).saturating_mul(y as Weight)) + // Standard Error: 2_000 + .saturating_add((327_000 as Weight).saturating_mul(p as Weight)) + .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + // Storage: Alliance Members (r:1 w:0) + // Storage: AllianceMotion ProposalOf (r:1 w:1) + // Storage: AllianceMotion Voting (r:1 w:1) + // Storage: AllianceMotion Members (r:1 w:0) + // Storage: AllianceMotion Prime (r:1 w:0) + // Storage: AllianceMotion Proposals (r:1 w:1) + fn close_approved(b: u32, x: u32, y: u32, p: u32, ) -> Weight { + (43_650_000 as Weight) + // Standard Error: 0 + .saturating_add((3_000 as Weight).saturating_mul(b as Weight)) + // Standard Error: 85_000 + .saturating_add((124_000 as Weight).saturating_mul(x as Weight)) + // Standard Error: 3_000 + .saturating_add((199_000 as Weight).saturating_mul(y as Weight)) + // Standard Error: 3_000 + .saturating_add((326_000 as Weight).saturating_mul(p as Weight)) + .saturating_add(RocksDbWeight::get().reads(6 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } // Storage: Alliance Members (r:3 w:3) // Storage: AllianceMotion Members (r:1 w:1) fn init_members(_x: u32, y: u32, z: u32, ) -> Weight { - (40_162_000 as Weight) - // Standard Error: 2_000 - .saturating_add((166_000 as Weight).saturating_mul(y as Weight)) - // Standard Error: 2_000 - .saturating_add((144_000 as Weight).saturating_mul(z as Weight)) + (45_100_000 as Weight) + // Standard Error: 4_000 + .saturating_add((162_000 as Weight).saturating_mul(y as Weight)) + // Standard Error: 4_000 + .saturating_add((151_000 as Weight).saturating_mul(z as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(4 as Weight)) } // Storage: Alliance Rule (r:0 w:1) fn set_rule() -> Weight { - (14_337_000 as Weight) + (14_517_000 as Weight) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Alliance Announcements (r:1 w:1) fn announce() -> Weight { - (16_721_000 as Weight) + (16_801_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Alliance Announcements (r:1 w:1) fn remove_announcement() -> Weight { - (17_663_000 as Weight) + (17_133_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } @@ -297,7 +437,7 @@ impl WeightInfo for () { // Storage: System Account (r:1 w:1) // Storage: Alliance DepositOf (r:0 w:1) fn submit_candidacy() -> Weight { - (57_289_000 as Weight) + (95_370_000 as Weight) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } @@ -305,14 +445,14 @@ impl WeightInfo for () { // Storage: Alliance AccountBlacklist (r:1 w:0) // Storage: Alliance Candidates (r:1 w:1) fn nominate_candidacy() -> Weight { - (42_350_000 as Weight) + (44_764_000 as Weight) .saturating_add(RocksDbWeight::get().reads(6 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Alliance Candidates (r:1 w:1) // Storage: Alliance Members (r:4 w:1) fn approve_candidate() -> Weight { - (44_364_000 as Weight) + (71_876_000 as Weight) .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } @@ -321,7 +461,7 @@ impl WeightInfo for () { // Storage: Alliance DepositOf (r:1 w:1) // Storage: System Account (r:1 w:1) fn reject_candidate() -> Weight { - (69_210_000 as Weight) + (69_732_000 as Weight) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } @@ -330,7 +470,7 @@ impl WeightInfo for () { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn elevate_ally() -> Weight { - (41_348_000 as Weight) + (44_013_000 as Weight) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(4 as Weight)) } @@ -342,7 +482,7 @@ impl WeightInfo for () { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn retire() -> Weight { - (58_139_000 as Weight) + (60_183_000 as Weight) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().writes(5 as Weight)) } @@ -354,7 +494,7 @@ impl WeightInfo for () { // Storage: AllianceMotion Members (r:0 w:1) // Storage: AllianceMotion Prime (r:0 w:1) fn kick_member() -> Weight { - (68_409_000 as Weight) + (67_467_000 as Weight) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().writes(5 as Weight)) } @@ -362,10 +502,10 @@ impl WeightInfo for () { // Storage: Alliance WebsiteBlacklist (r:1 w:1) fn add_blacklist(n: u32, l: u32, ) -> Weight { (0 as Weight) - // Standard Error: 6_000 - .saturating_add((2_590_000 as Weight).saturating_mul(n as Weight)) - // Standard Error: 2_000 - .saturating_add((194_000 as Weight).saturating_mul(l as Weight)) + // Standard Error: 16_000 + .saturating_add((2_673_000 as Weight).saturating_mul(n as Weight)) + // Standard Error: 7_000 + .saturating_add((224_000 as Weight).saturating_mul(l as Weight)) .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } @@ -373,10 +513,10 @@ impl WeightInfo for () { // Storage: Alliance WebsiteBlacklist (r:1 w:1) fn remove_blacklist(n: u32, l: u32, ) -> Weight { (0 as Weight) - // Standard Error: 332_000 - .saturating_add((57_821_000 as Weight).saturating_mul(n as Weight)) - // Standard Error: 147_000 - .saturating_add((6_544_000 as Weight).saturating_mul(l as Weight)) + // Standard Error: 343_000 + .saturating_add((59_025_000 as Weight).saturating_mul(n as Weight)) + // Standard Error: 153_000 + .saturating_add((6_725_000 as Weight).saturating_mul(l as Weight)) .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } From d1bb18d5ed75b4640b3a99d1259c373ae1749aaf Mon Sep 17 00:00:00 2001 From: koushiro Date: Mon, 11 Oct 2021 22:45:44 +0800 Subject: [PATCH 20/72] Remove some useless Signed-off-by: koushiro --- frame/alliance/src/lib.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index 15ae5a76ca24d..458e00c097c0b 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -936,14 +936,6 @@ impl, I: 'static> Pallet { Self::is_founder(who) || Self::is_fellow(who) } - /* - fn votable_member_count() -> u32 { - let founder_count = Members::::decode_len(MemberRole::Founder).unwrap_or_default(); - let fellow_count = Members::::decode_len(MemberRole::Fellow).unwrap_or_default(); - (founder_count + fellow_count) as u32 - } - */ - fn votable_member_sorted() -> Vec { let mut founders = Members::::get(MemberRole::Founder); let mut fellows = Members::::get(MemberRole::Fellow); From a2f986f44f08a6d123c4fd8c95488b310651a03d Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Sat, 12 Mar 2022 21:48:47 +1300 Subject: [PATCH 21/72] fix some compile issue --- Cargo.lock | 81 +++++++++++++------------------------ frame/alliance/Cargo.toml | 16 ++++---- frame/collective/src/lib.rs | 45 ++++++++++++++++----- frame/identity/src/lib.rs | 1 - frame/identity/src/types.rs | 5 +-- 5 files changed, 74 insertions(+), 74 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6276081e5b91b..1bfba14798fe4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1844,18 +1844,18 @@ dependencies = [ [[package]] name = "enumflags2" -version = "0.7.1" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8672257d642ffdd235f6e9c723c2326ac1253c8f3c022e7cfd2e57da55b1131" +checksum = "83c8d82922337cd23a15f88b70d8e4ef5f11da38dd7cdb55e84dd5de99695da0" dependencies = [ "enumflags2_derive", ] [[package]] name = "enumflags2_derive" -version = "0.7.0" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33526f770a27828ce7c2792fdb7cb240220237e0ff12933ed6c23957fc5dd7cf" +checksum = "946ee94e3dbf58fdd324f9ce245c7b238d46a66f00e86a020b71996349e46cce" dependencies = [ "proc-macro2", "quote", @@ -4604,19 +4604,9 @@ dependencies = [ "blake3", "digest 0.9.0", "generic-array 0.14.4", -<<<<<<< HEAD -<<<<<<< HEAD "multihash-derive", "sha2 0.9.8", "sha3 0.9.1", -======= - "multihash-derive 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", -======= - "multihash-derive", ->>>>>>> 4482b77565 (Derive pallet_identity::Config and Fix test/benchmarking) - "sha2 0.9.3", - "sha3", ->>>>>>> 2369417073 (Add pallet-alliance) "unsigned-varint 0.5.1", ] @@ -4629,7 +4619,7 @@ dependencies = [ "digest 0.9.0", "generic-array 0.14.4", "multihash-derive", - "sha2 0.9.3", + "sha2 0.9.8", "unsigned-varint 0.7.0", ] @@ -4983,11 +4973,8 @@ dependencies = [ "hex-literal", "log 0.4.14", "node-primitives", -<<<<<<< HEAD - "pallet-asset-tx-payment", -======= "pallet-alliance", ->>>>>>> 4a8ad01901 (Add pallet-alliance into node runtime) + "pallet-asset-tx-payment", "pallet-assets", "pallet-authority-discovery", "pallet-authorship", @@ -5422,22 +5409,6 @@ dependencies = [ ] [[package]] -<<<<<<< HEAD -name = "pallet-asset-tx-payment" -version = "4.0.0-dev" -dependencies = [ - "frame-support", - "frame-system", - "pallet-assets", - "pallet-authorship", - "pallet-balances", - "pallet-transaction-payment", - "parity-scale-codec", - "scale-info", - "serde", - "serde_json", - "smallvec 1.8.0", -======= name = "pallet-alliance" version = "4.0.0-dev" dependencies = [ @@ -5452,23 +5423,33 @@ dependencies = [ "pallet-identity", "parity-scale-codec", "scale-info", -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> 2369417073 (Add pallet-alliance) -======= - "sha2 0.9.3", ->>>>>>> 4482b77565 (Derive pallet_identity::Config and Fix test/benchmarking) -======= - "sha2 0.9.5", ->>>>>>> b0f38f7b9f (Remove pallet_identity Config trait) + "sha2 0.10.1", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-asset-tx-payment" +version = "4.0.0-dev" +dependencies = [ + "frame-support", + "frame-system", + "pallet-assets", + "pallet-authorship", + "pallet-balances", + "pallet-transaction-payment", + "parity-scale-codec", + "scale-info", + "serde", + "serde_json", + "smallvec 1.8.0", "sp-core", "sp-io", "sp-runtime", "sp-std", -<<<<<<< HEAD "sp-storage", -======= ->>>>>>> 2369417073 (Add pallet-alliance) ] [[package]] @@ -8671,14 +8652,8 @@ dependencies = [ "async-trait", "asynchronous-codec 0.5.0", "bitflags", -<<<<<<< HEAD "bytes 1.1.0", "cid", -======= - "bytes 1.0.1", - "cid", - "derive_more", ->>>>>>> 2369417073 (Add pallet-alliance) "either", "fnv", "fork-tree", diff --git a/frame/alliance/Cargo.toml b/frame/alliance/Cargo.toml index b9c4ccdbd18a3..771ec867569f3 100644 --- a/frame/alliance/Cargo.toml +++ b/frame/alliance/Cargo.toml @@ -14,16 +14,16 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] hex = { version = "0.4", default-features = false, features = ["alloc"], optional = true } -sha2 = { version = "0.9", default-features = false, optional = true } +sha2 = { version = "0.10.1", default-features = false, optional = true } log = { version = "0.4.14", default-features = false } -codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive"] } -scale-info = { version = "1.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] } +scale-info = { version = "2.0.1", default-features = false, features = ["derive"] } -sp-std = { version = "4.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-core = { version = "4.0.0-dev", default-features = false, path = "../../primitives/core" } -sp-io = { version = "4.0.0-dev", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "4.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "4.0.0", default-features = false, path = "../../primitives/std" } +sp-core = { version = "6.0.0", default-features = false, path = "../../primitives/core" } +sp-io = { version = "6.0.0", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "6.0.0", default-features = false, path = "../../primitives/runtime" } frame-benchmarking = { version = "4.0.0-dev", default-features = false, path = "../benchmarking", optional = true } frame-support = { version = "4.0.0-dev", default-features = false, path = "../support" } @@ -33,7 +33,7 @@ pallet-identity = { version = "4.0.0-dev", path = "../identity", default-feature [dev-dependencies] hex-literal = "0.3.1" -sha2 = "0.9" +sha2 = "0.10.1" pallet-balances = { version = "4.0.0-dev", path = "../balances" } pallet-collective = { version = "4.0.0-dev", path = "../collective" } pallet-identity = { version = "4.0.0-dev", path = "../identity" } diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index 8ef7480c2cdf0..f00a71b268b68 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -690,10 +690,10 @@ impl, I: 'static> Pallet { let seats = Self::members().len() as MemberCount; let result = proposal.dispatch(RawOrigin::Members(1, seats).into()); - Self::deposit_event(Event::Executed( + Self::deposit_event(Event::Executed { proposal_hash, - result.map(|_| ()).map_err(|e| e.error), - )); + result: result.map(|_| ()).map_err(|e| e.error), + }); Ok((proposal_len as u32, result)) } @@ -725,7 +725,12 @@ impl, I: 'static> Pallet { }; >::insert(proposal_hash, votes); - Self::deposit_event(Event::Proposed(who, index, proposal_hash, threshold)); + Self::deposit_event(Event::Proposed { + account: who, + proposal_index: index, + proposal_hash, + threshold + }); Ok((proposal_len as u32, active_proposals as u32)) } @@ -768,7 +773,13 @@ impl, I: 'static> Pallet { let yes_votes = voting.ayes.len() as MemberCount; let no_votes = voting.nays.len() as MemberCount; - Self::deposit_event(Event::Voted(who, proposal, approve, yes_votes, no_votes)); + Self::deposit_event(Event::Voted { + account: who, + proposal_hash: proposal, + voted: approve, + yes: yes_votes, + no: no_votes, + }); Voting::::insert(&proposal, voting); @@ -797,7 +808,11 @@ impl, I: 'static> Pallet { length_bound, proposal_weight_bound, )?; - Self::deposit_event(Event::Closed(proposal_hash, yes_votes, no_votes)); + Self::deposit_event(Event::Closed { + proposal_hash, + yes: yes_votes, + no: no_votes, + }); let (proposal_weight, proposal_count) = Self::do_approve_proposal(seats, yes_votes, proposal_hash, proposal); return Ok(( @@ -809,7 +824,11 @@ impl, I: 'static> Pallet { ) .into()) } else if disapproved { - Self::deposit_event(Event::Closed(proposal_hash, yes_votes, no_votes)); + Self::deposit_event(Event::Closed { + proposal_hash, + yes: yes_votes, + no: no_votes, + }); let proposal_count = Self::do_disapprove_proposal(proposal_hash); return Ok(( Some(T::WeightInfo::close_early_disapproved(seats, proposal_count)), @@ -839,7 +858,11 @@ impl, I: 'static> Pallet { length_bound, proposal_weight_bound, )?; - Self::deposit_event(Event::Closed(proposal_hash, yes_votes, no_votes)); + Self::deposit_event(Event::Closed { + proposal_hash, + yes: yes_votes, + no: no_votes, + }); let (proposal_weight, proposal_count) = Self::do_approve_proposal(seats, yes_votes, proposal_hash, proposal); Ok(( @@ -851,7 +874,11 @@ impl, I: 'static> Pallet { ) .into()) } else { - Self::deposit_event(Event::Closed(proposal_hash, yes_votes, no_votes)); + Self::deposit_event(Event::Closed { + proposal_hash, + yes: yes_votes, + no: no_votes, + }); let proposal_count = Self::do_disapprove_proposal(proposal_hash); Ok((Some(T::WeightInfo::close_disapproved(seats, proposal_count)), Pays::No).into()) } diff --git a/frame/identity/src/lib.rs b/frame/identity/src/lib.rs index a513bfcc51cb6..da6b311768a5b 100644 --- a/frame/identity/src/lib.rs +++ b/frame/identity/src/lib.rs @@ -88,7 +88,6 @@ pub use types::{ Data, IdentityField, IdentityFields, IdentityInfo, Judgement, RegistrarIndex, RegistrarInfo, Registration, }; -pub use weights::WeightInfo; type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; diff --git a/frame/identity/src/types.rs b/frame/identity/src/types.rs index 61fefa3a6b3eb..860c21485eb97 100644 --- a/frame/identity/src/types.rs +++ b/frame/identity/src/types.rs @@ -17,7 +17,7 @@ use super::*; use codec::{Decode, Encode, MaxEncodedLen}; -use enumflags2::{bitflags, BitFlags}; +use enumflags2::BitFlags; use frame_support::{ traits::{ConstU32, Get}, BoundedVec, CloneNoBound, PartialEqNoBound, RuntimeDebugNoBound, @@ -230,9 +230,8 @@ impl Date: Sat, 12 Mar 2022 23:19:50 +1300 Subject: [PATCH 22/72] more fix --- bin/node/runtime/src/impls.rs | 2 +- frame/alliance/src/lib.rs | 1 + frame/alliance/src/mock.rs | 40 ++++++---- frame/alliance/src/tests.rs | 141 ++++++++++++++++++---------------- frame/alliance/src/types.rs | 31 ++++++-- frame/collective/src/lib.rs | 26 ++----- 6 files changed, 129 insertions(+), 112 deletions(-) diff --git a/bin/node/runtime/src/impls.rs b/bin/node/runtime/src/impls.rs index 5ce43aa88ee4c..ad1da7ff712ad 100644 --- a/bin/node/runtime/src/impls.rs +++ b/bin/node/runtime/src/impls.rs @@ -26,8 +26,8 @@ use frame_support::{ weights::Weight, }; use pallet_alliance::{IdentityVerifier, ProposalIndex, ProposalProvider}; -use pallet_identity::Judgement; use pallet_asset_tx_payment::HandleCredit; +use pallet_identity::Judgement; use crate::{AllianceMotion, Authorship, Balances, Call, NegativeImbalance}; diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index 458e00c097c0b..345e5c247a157 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -194,6 +194,7 @@ pub mod pallet { #[pallet::pallet] #[pallet::generate_store(pub (super) trait Store)] + #[pallet::without_storage_info] pub struct Pallet(PhantomData<(T, I)>); #[pallet::config] diff --git a/frame/alliance/src/mock.rs b/frame/alliance/src/mock.rs index c71ae4d1a0ef2..7c1427677b73e 100644 --- a/frame/alliance/src/mock.rs +++ b/frame/alliance/src/mock.rs @@ -26,9 +26,11 @@ pub use sp_runtime::{ use sp_std::convert::TryInto; pub use frame_support::{ - assert_ok, ord_parameter_types, parameter_types, traits::SortedMembers, BoundedVec, + assert_ok, ord_parameter_types, parameter_types, + traits::{EnsureOneOf, GenesisBuild, SortedMembers}, + BoundedVec, }; -pub use frame_system::{EnsureOneOf, EnsureRoot, EnsureSignedBy}; +use frame_system::{EnsureRoot, EnsureSignedBy}; use pallet_identity::{Data, IdentityInfo, Judgement}; pub use crate as pallet_alliance; @@ -62,6 +64,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { @@ -112,8 +115,8 @@ ord_parameter_types! { pub const Four: u64 = 4; pub const Five: u64 = 5; } -type EnsureOneOrRoot = EnsureOneOf, EnsureSignedBy>; -type EnsureTwoOrRoot = EnsureOneOf, EnsureSignedBy>; +type EnsureOneOrRoot = EnsureOneOf, EnsureSignedBy>; +type EnsureTwoOrRoot = EnsureOneOf, EnsureSignedBy>; impl pallet_identity::Config for Test { type Event = Event; @@ -247,27 +250,32 @@ frame_support::construct_runtime!( NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic, { - System: frame_system::{Pallet, Call, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Identity: pallet_identity::{Pallet, Call, Storage, Event}, - AllianceMotion: pallet_collective::::{Pallet, Storage, Origin, Event}, - Alliance: pallet_alliance::{Pallet, Call, Storage, Event, Config}, + System: frame_system, + Balances: pallet_balances, + Identity: pallet_identity, + AllianceMotion: pallet_collective::, + Alliance: pallet_alliance, } ); pub fn new_test_ext() -> sp_io::TestExternalities { - let t = GenesisConfig { - balances: pallet_balances::GenesisConfig { - balances: vec![(1, 50), (2, 50), (3, 50), (4, 50), (5, 30), (6, 50), (7, 50)], - }, - alliance: pallet_alliance::GenesisConfig { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + + pallet_balances::GenesisConfig:: { + balances: vec![(1, 50), (2, 50), (3, 50), (4, 50), (5, 30), (6, 50), (7, 50)], + } + .assimilate_storage(&mut t) + .unwrap(); + + GenesisBuild::::assimilate_storage( + &pallet_alliance::GenesisConfig { founders: vec![], fellows: vec![], allies: vec![], phantom: Default::default(), }, - } - .build_storage() + &mut t, + ) .unwrap(); let mut ext = sp_io::TestExternalities::new(t); diff --git a/frame/alliance/src/tests.rs b/frame/alliance/src/tests.rs index 7d5a6f73953eb..2e026d26d1062 100644 --- a/frame/alliance/src/tests.rs +++ b/frame/alliance/src/tests.rs @@ -52,7 +52,12 @@ fn propose_works() { System::events(), vec![EventRecord { phase: Phase::Initialization, - event: mock::Event::AllianceMotion(AllianceMotionEvent::Proposed(1, 0, hash, 3)), + event: mock::Event::AllianceMotion(AllianceMotionEvent::Proposed { + account: 1, + proposal_index: 0, + proposal_hash: hash, + threshold: 3, + }), topics: vec![], }] ); @@ -77,19 +82,19 @@ fn vote_works() { assert_eq!( System::events(), vec![ - record(mock::Event::AllianceMotion(AllianceMotionEvent::Proposed( - 1, - 0, - hash.clone(), - 3 - ))), - record(mock::Event::AllianceMotion(AllianceMotionEvent::Voted( - 2, - hash.clone(), - true, - 1, - 0 - ))), + record(mock::Event::AllianceMotion(AllianceMotionEvent::Proposed { + account: 1, + proposal_index: 0, + proposal_hash: hash.clone(), + threshold: 3 + })), + record(mock::Event::AllianceMotion(AllianceMotionEvent::Voted { + account: 2, + proposal_hash: hash.clone(), + voted: true, + yes: 1, + no: 0, + })), ] ); }); @@ -135,23 +140,21 @@ fn veto_works() { assert_eq!( System::events(), vec![ - record(mock::Event::AllianceMotion(AllianceMotionEvent::Proposed( - 1, - 0, - hash.clone(), - 3 - ))), - record(mock::Event::AllianceMotion(AllianceMotionEvent::Proposed( - 1, - 1, - vetoable_hash.clone(), - 3 - ))), - // record(mock::Event::AllianceMotion(AllianceMotionEvent::Voted(2, hash.clone(), - // true, 2, 0))), - record(mock::Event::AllianceMotion(AllianceMotionEvent::Disapproved( - vetoable_hash.clone() - ))), + record(mock::Event::AllianceMotion(AllianceMotionEvent::Proposed { + account: 1, + proposal_index: 0, + proposal_hash: hash.clone(), + threshold: 3 + })), + record(mock::Event::AllianceMotion(AllianceMotionEvent::Proposed { + account: 1, + proposal_index: 1, + proposal_hash: vetoable_hash.clone(), + threshold: 3 + })), + record(mock::Event::AllianceMotion(AllianceMotionEvent::Disapproved { + proposal_hash: vetoable_hash.clone() + })), ] ); }) @@ -185,43 +188,45 @@ fn close_works() { assert_eq!( System::events(), vec![ - record(mock::Event::AllianceMotion(AllianceMotionEvent::Proposed( - 1, - 0, - hash.clone(), - 3 - ))), - record(mock::Event::AllianceMotion(AllianceMotionEvent::Voted( - 1, - hash.clone(), - true, - 1, - 0 - ))), - record(mock::Event::AllianceMotion(AllianceMotionEvent::Voted( - 2, - hash.clone(), - true, - 2, - 0 - ))), - record(mock::Event::AllianceMotion(AllianceMotionEvent::Voted( - 3, - hash.clone(), - true, - 3, - 0 - ))), - record(mock::Event::AllianceMotion(AllianceMotionEvent::Closed( - hash.clone(), - 3, - 0 - ))), - record(mock::Event::AllianceMotion(AllianceMotionEvent::Approved(hash.clone()))), - record(mock::Event::AllianceMotion(AllianceMotionEvent::Executed( - hash.clone(), - Err(DispatchError::BadOrigin) - ))) + record(mock::Event::AllianceMotion(AllianceMotionEvent::Proposed { + account: 1, + proposal_index: 0, + proposal_hash: hash.clone(), + threshold: 3 + })), + record(mock::Event::AllianceMotion(AllianceMotionEvent::Voted { + account: 1, + proposal_hash: hash.clone(), + voted: true, + yes: 1, + no: 0, + })), + record(mock::Event::AllianceMotion(AllianceMotionEvent::Voted { + account: 2, + proposal_hash: hash.clone(), + voted: true, + yes: 2, + no: 0, + })), + record(mock::Event::AllianceMotion(AllianceMotionEvent::Voted { + account: 3, + proposal_hash: hash.clone(), + voted: true, + yes: 3, + no: 0, + })), + record(mock::Event::AllianceMotion(AllianceMotionEvent::Closed { + proposal_hash: hash.clone(), + yes: 3, + no: 0, + })), + record(mock::Event::AllianceMotion(AllianceMotionEvent::Approved { + proposal_hash: hash.clone() + })), + record(mock::Event::AllianceMotion(AllianceMotionEvent::Executed { + proposal_hash: hash.clone(), + result: Err(DispatchError::BadOrigin), + })) ] ); }); diff --git a/frame/alliance/src/types.rs b/frame/alliance/src/types.rs index b245482dc5368..35f112507b3a6 100644 --- a/frame/alliance/src/types.rs +++ b/frame/alliance/src/types.rs @@ -15,18 +15,21 @@ // See the License for the specific language governing permissions and // limitations under the License. -use codec::{Decode, Encode}; +use codec::{Decode, Encode, MaxEncodedLen}; +use frame_support::{traits::ConstU32, BoundedVec}; use scale_info::TypeInfo; use sp_runtime::RuntimeDebug; use sp_std::prelude::*; /// A Multihash instance that only supports the basic functionality and no hashing. -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RuntimeDebug, Encode, Decode, TypeInfo)] +#[derive( + Clone, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen, +)] pub struct Multihash { /// The code of the Multihash. pub code: u64, /// The digest. - pub digest: Vec, + pub digest: BoundedVec>, // 4 byte dig size + 64 bytes hash digest } impl Multihash { @@ -38,7 +41,17 @@ impl Multihash { /// The version of the CID. #[derive( - Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RuntimeDebug, Encode, Decode, TypeInfo, + Clone, + Copy, + PartialEq, + Eq, + PartialOrd, + Ord, + RuntimeDebug, + Encode, + Decode, + TypeInfo, + MaxEncodedLen, )] pub enum Version { /// CID version 0. @@ -50,7 +63,9 @@ pub enum Version { /// Representation of a CID. /// /// The generic is about the allocated size of the multihash. -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RuntimeDebug, Encode, Decode, TypeInfo)] +#[derive( + Clone, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen, +)] pub struct Cid { /// The version of CID. pub version: Version, @@ -71,6 +86,10 @@ impl Cid { let digest = sha2_256_digest.into(); assert!(digest.len() == 32); - Self { version: Version::V0, codec: DAG_PB, hash: Multihash { code: SHA2_256, digest } } + Self { + version: Version::V0, + codec: DAG_PB, + hash: Multihash { code: SHA2_256, digest: digest.try_into().expect("msg") }, + } } } diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index f00a71b268b68..6ad51e80cc5ed 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -729,7 +729,7 @@ impl, I: 'static> Pallet { account: who, proposal_index: index, proposal_hash, - threshold + threshold, }); Ok((proposal_len as u32, active_proposals as u32)) } @@ -808,11 +808,7 @@ impl, I: 'static> Pallet { length_bound, proposal_weight_bound, )?; - Self::deposit_event(Event::Closed { - proposal_hash, - yes: yes_votes, - no: no_votes, - }); + Self::deposit_event(Event::Closed { proposal_hash, yes: yes_votes, no: no_votes }); let (proposal_weight, proposal_count) = Self::do_approve_proposal(seats, yes_votes, proposal_hash, proposal); return Ok(( @@ -824,11 +820,7 @@ impl, I: 'static> Pallet { ) .into()) } else if disapproved { - Self::deposit_event(Event::Closed { - proposal_hash, - yes: yes_votes, - no: no_votes, - }); + Self::deposit_event(Event::Closed { proposal_hash, yes: yes_votes, no: no_votes }); let proposal_count = Self::do_disapprove_proposal(proposal_hash); return Ok(( Some(T::WeightInfo::close_early_disapproved(seats, proposal_count)), @@ -858,11 +850,7 @@ impl, I: 'static> Pallet { length_bound, proposal_weight_bound, )?; - Self::deposit_event(Event::Closed { - proposal_hash, - yes: yes_votes, - no: no_votes, - }); + Self::deposit_event(Event::Closed { proposal_hash, yes: yes_votes, no: no_votes }); let (proposal_weight, proposal_count) = Self::do_approve_proposal(seats, yes_votes, proposal_hash, proposal); Ok(( @@ -874,11 +862,7 @@ impl, I: 'static> Pallet { ) .into()) } else { - Self::deposit_event(Event::Closed { - proposal_hash, - yes: yes_votes, - no: no_votes, - }); + Self::deposit_event(Event::Closed { proposal_hash, yes: yes_votes, no: no_votes }); let proposal_count = Self::do_disapprove_proposal(proposal_hash); Ok((Some(T::WeightInfo::close_disapproved(seats, proposal_count)), Pays::No).into()) } From a04c5b869b35b061d81f8c8a62b8161a992459c8 Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Sat, 12 Mar 2022 23:34:10 +1300 Subject: [PATCH 23/72] all checks --- bin/node/cli/src/chain_spec.rs | 2 ++ bin/node/runtime/src/impls.rs | 18 +++++-------- bin/node/runtime/src/lib.rs | 46 ++------------------------------- bin/node/testing/src/genesis.rs | 2 ++ 4 files changed, 13 insertions(+), 55 deletions(-) diff --git a/bin/node/cli/src/chain_spec.rs b/bin/node/cli/src/chain_spec.rs index 11516f964903a..70ef08879311c 100644 --- a/bin/node/cli/src/chain_spec.rs +++ b/bin/node/cli/src/chain_spec.rs @@ -363,6 +363,8 @@ pub fn testnet_genesis( gilt: Default::default(), transaction_storage: Default::default(), transaction_payment: Default::default(), + alliance: Default::default(), + alliance_motion: Default::default(), } } diff --git a/bin/node/runtime/src/impls.rs b/bin/node/runtime/src/impls.rs index ad1da7ff712ad..4ce44b5992f58 100644 --- a/bin/node/runtime/src/impls.rs +++ b/bin/node/runtime/src/impls.rs @@ -17,19 +17,15 @@ //! Some configurable implementations as associated type for the substrate runtime. -use node_primitives::{AccountId, Hash}; -use sp_std::prelude::*; - -use frame_support::{ - dispatch::{DispatchError, DispatchResultWithPostInfo}, - traits::{Currency, OnUnbalanced}, - weights::Weight, +use crate::{AccountId, Assets, AllianceMotion, Authorship, Balances, NegativeImbalance, Runtime, Hash, Call}; +use frame_support::traits::{ + fungibles::{Balanced, CreditOf}, + Currency, OnUnbalanced, }; -use pallet_alliance::{IdentityVerifier, ProposalIndex, ProposalProvider}; use pallet_asset_tx_payment::HandleCredit; -use pallet_identity::Judgement; - -use crate::{AllianceMotion, Authorship, Balances, Call, NegativeImbalance}; +use pallet_alliance::{IdentityVerifier, ProposalIndex, ProposalProvider}; +use sp_std::prelude::*; +use frame_support::pallet_prelude::*; pub struct Author; impl OnUnbalanced for Author { diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 19e3864b693c4..2df18626565e1 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1415,13 +1415,12 @@ parameter_types! { pub const MaxWebsiteUrlLength: u32 = 255; } -impl pallet_alliance::Config for Runtime { +impl pallet_alliance::Config for Runtime { type Event = Event; type Proposal = Call; type SuperMajorityOrigin = EnsureOneOf< - AccountId, EnsureRoot, - pallet_collective::EnsureProportionMoreThan<_2, _3, AccountId, AllianceCollective>, + pallet_collective::EnsureProportionMoreThan, >; type Currency = Balances; type Slashed = Treasury; @@ -1935,47 +1934,6 @@ impl_runtime_apis! { let mut batches = Vec::::new(); let params = (&config, &whitelist); add_benchmarks!(params, batches); - -<<<<<<< HEAD -<<<<<<< HEAD -======= -======= - add_benchmark!(params, batches, pallet_alliance, Alliance); ->>>>>>> 4482b77565 (Derive pallet_identity::Config and Fix test/benchmarking) - add_benchmark!(params, batches, pallet_assets, Assets); - add_benchmark!(params, batches, pallet_babe, Babe); - add_benchmark!(params, batches, pallet_balances, Balances); - add_benchmark!(params, batches, pallet_bounties, Bounties); - add_benchmark!(params, batches, pallet_collective, Council); - add_benchmark!(params, batches, pallet_contracts, Contracts); - add_benchmark!(params, batches, pallet_democracy, Democracy); - add_benchmark!(params, batches, pallet_election_provider_multi_phase, ElectionProviderMultiPhase); - add_benchmark!(params, batches, pallet_elections_phragmen, Elections); - add_benchmark!(params, batches, pallet_gilt, Gilt); - add_benchmark!(params, batches, pallet_grandpa, Grandpa); - add_benchmark!(params, batches, pallet_identity, Identity); - add_benchmark!(params, batches, pallet_im_online, ImOnline); - add_benchmark!(params, batches, pallet_indices, Indices); - add_benchmark!(params, batches, pallet_lottery, Lottery); - add_benchmark!(params, batches, pallet_membership, TechnicalMembership); - add_benchmark!(params, batches, pallet_mmr, Mmr); - add_benchmark!(params, batches, pallet_multisig, Multisig); - add_benchmark!(params, batches, pallet_offences, OffencesBench::); - add_benchmark!(params, batches, pallet_proxy, Proxy); - add_benchmark!(params, batches, pallet_scheduler, Scheduler); - add_benchmark!(params, batches, pallet_session, SessionBench::); - add_benchmark!(params, batches, pallet_staking, Staking); - add_benchmark!(params, batches, frame_system, SystemBench::); - add_benchmark!(params, batches, pallet_timestamp, Timestamp); - add_benchmark!(params, batches, pallet_tips, Tips); - add_benchmark!(params, batches, pallet_transaction_storage, TransactionStorage); - add_benchmark!(params, batches, pallet_treasury, Treasury); - add_benchmark!(params, batches, pallet_uniques, Uniques); - add_benchmark!(params, batches, pallet_utility, Utility); - add_benchmark!(params, batches, pallet_vesting, Vesting); - - if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } ->>>>>>> 4a8ad01901 (Add pallet-alliance into node runtime) Ok(batches) } } diff --git a/bin/node/testing/src/genesis.rs b/bin/node/testing/src/genesis.rs index 8d2b53b0b7210..6c02c3a7c4779 100644 --- a/bin/node/testing/src/genesis.rs +++ b/bin/node/testing/src/genesis.rs @@ -92,5 +92,7 @@ pub fn config_endowed(code: Option<&[u8]>, extra_endowed: Vec) -> Gen gilt: Default::default(), transaction_storage: Default::default(), transaction_payment: Default::default(), + alliance: Default::default(), + alliance_motion: Default::default(), } } From fde2562533830243bcad3b9fd1ca224eccd05991 Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Sun, 13 Mar 2022 00:04:53 +1300 Subject: [PATCH 24/72] refactor --- bin/node/runtime/src/impls.rs | 18 ------------------ bin/node/runtime/src/lib.rs | 3 +++ frame/alliance/src/lib.rs | 16 +++++++++++++++- frame/alliance/src/mock.rs | 21 +++------------------ 4 files changed, 21 insertions(+), 37 deletions(-) diff --git a/bin/node/runtime/src/impls.rs b/bin/node/runtime/src/impls.rs index 4ce44b5992f58..a8bb7a4ec8c0f 100644 --- a/bin/node/runtime/src/impls.rs +++ b/bin/node/runtime/src/impls.rs @@ -50,17 +50,10 @@ impl HandleCredit for CreditToBlockAuthor { pub struct AllianceIdentityVerifier; impl IdentityVerifier for AllianceIdentityVerifier { - #[cfg(not(feature = "runtime-benchmarks"))] fn has_identity(who: &AccountId, fields: u64) -> bool { crate::Identity::has_identity(who, fields) } - #[cfg(feature = "runtime-benchmarks")] - fn has_identity(_who: &AccountId, _fields: u64) -> bool { - true - } - - #[cfg(not(feature = "runtime-benchmarks"))] fn has_good_judgement(who: &AccountId) -> bool { use pallet_identity::Judgement; if let Some(judgements) = @@ -75,20 +68,9 @@ impl IdentityVerifier for AllianceIdentityVerifier { } } - #[cfg(feature = "runtime-benchmarks")] - fn has_good_judgement(_who: &AccountId) -> bool { - true - } - - #[cfg(not(feature = "runtime-benchmarks"))] fn super_account_id(who: &AccountId) -> Option { crate::Identity::super_of(who).map(|parent| parent.0) } - - #[cfg(feature = "runtime-benchmarks")] - fn super_account_id(_who: &AccountId) -> Option { - None - } } pub struct AllianceProposalProvider; diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 2df18626565e1..1a37d5da9c988 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1426,7 +1426,10 @@ impl pallet_alliance::Config for Runtime { type Slashed = Treasury; type InitializeMembers = AllianceMotion; type MembershipChanged = AllianceMotion; + #[cfg(not(feature = "runtime-benchmarks"))] type IdentityVerifier = AllianceIdentityVerifier; + #[cfg(feature = "runtime-benchmarks")] + type IdentityVerifier = (); type ProposalProvider = AllianceProposalProvider; type MaxProposals = AllianceMaxProposals; type MaxFounders = MaxFounders; diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index 345e5c247a157..61e17faa302bb 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -136,7 +136,7 @@ type NegativeImbalanceOf = <>::Currency as Currency< ::AccountId, >>::NegativeImbalance; -pub trait IdentityVerifier { +pub trait IdentityVerifier { fn has_identity(who: &AccountId, fields: u64) -> bool; fn has_good_judgement(who: &AccountId) -> bool; @@ -144,6 +144,20 @@ pub trait IdentityVerifier { fn super_account_id(who: &AccountId) -> Option; } +impl IdentityVerifier for () { + fn has_identity(_who: &AccountId, _fields: u64) -> bool { + true + } + + fn has_good_judgement(_who: &AccountId) -> bool { + true + } + + fn super_account_id(_who: &AccountId) -> Option { + None + } +} + pub trait ProposalProvider { fn propose_proposal( who: AccountId, diff --git a/frame/alliance/src/mock.rs b/frame/alliance/src/mock.rs index 7c1427677b73e..ffc67b16c1d1a 100644 --- a/frame/alliance/src/mock.rs +++ b/frame/alliance/src/mock.rs @@ -135,17 +135,10 @@ impl pallet_identity::Config for Test { pub struct AllianceIdentityVerifier; impl IdentityVerifier for AllianceIdentityVerifier { - #[cfg(not(feature = "runtime-benchmarks"))] fn has_identity(who: &u64, fields: u64) -> bool { Identity::has_identity(who, fields) } - #[cfg(feature = "runtime-benchmarks")] - fn has_identity(_who: &u64, _fields: u64) -> bool { - true - } - - #[cfg(not(feature = "runtime-benchmarks"))] fn has_good_judgement(who: &u64) -> bool { if let Some(judgements) = Identity::identity(who).map(|registration| registration.judgements) @@ -159,20 +152,9 @@ impl IdentityVerifier for AllianceIdentityVerifier { } } - #[cfg(feature = "runtime-benchmarks")] - fn has_good_judgement(_who: &u64) -> bool { - true - } - - #[cfg(not(feature = "runtime-benchmarks"))] fn super_account_id(who: &u64) -> Option { Identity::super_of(who).map(|parent| parent.0) } - - #[cfg(feature = "runtime-benchmarks")] - fn super_account_id(_who: &u64) -> Option { - None - } } pub struct AllianceProposalProvider; @@ -229,7 +211,10 @@ impl Config for Test { type Slashed = (); type InitializeMembers = AllianceMotion; type MembershipChanged = AllianceMotion; + #[cfg(not(feature = "runtime-benchmarks"))] type IdentityVerifier = AllianceIdentityVerifier; + #[cfg(feature = "runtime-benchmarks")] + type IdentityVerifier = (); type ProposalProvider = AllianceProposalProvider; type MaxProposals = MaxProposals; type MaxFounders = MaxFounders; From 1757810e9edd6977c2512fbf2f7545c44b4d28c5 Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Sun, 13 Mar 2022 00:25:06 +1300 Subject: [PATCH 25/72] refactor event --- bin/node/runtime/src/impls.rs | 16 +++--- frame/alliance/src/lib.rs | 94 ++++++++++++++++++++--------------- frame/alliance/src/tests.rs | 16 +++--- 3 files changed, 73 insertions(+), 53 deletions(-) diff --git a/bin/node/runtime/src/impls.rs b/bin/node/runtime/src/impls.rs index a8bb7a4ec8c0f..26fdef2b6c384 100644 --- a/bin/node/runtime/src/impls.rs +++ b/bin/node/runtime/src/impls.rs @@ -17,15 +17,19 @@ //! Some configurable implementations as associated type for the substrate runtime. -use crate::{AccountId, Assets, AllianceMotion, Authorship, Balances, NegativeImbalance, Runtime, Hash, Call}; -use frame_support::traits::{ - fungibles::{Balanced, CreditOf}, - Currency, OnUnbalanced, +use crate::{ + AccountId, AllianceMotion, Assets, Authorship, Balances, Call, Hash, NegativeImbalance, Runtime, +}; +use frame_support::{ + pallet_prelude::*, + traits::{ + fungibles::{Balanced, CreditOf}, + Currency, OnUnbalanced, + }, }; -use pallet_asset_tx_payment::HandleCredit; use pallet_alliance::{IdentityVerifier, ProposalIndex, ProposalProvider}; +use pallet_asset_tx_payment::HandleCredit; use sp_std::prelude::*; -use frame_support::pallet_prelude::*; pub struct Author; impl OnUnbalanced for Author { diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index 61e17faa302bb..7b42b189ba290 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -336,34 +336,38 @@ pub mod pallet { #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event, I: 'static = ()> { - /// A new rule has been set. \[rule\] - NewRule(Cid), - /// A new announcement has been proposed. \[announcement\] - NewAnnouncement(Cid), - /// A on-chain announcement has been removed. \[announcement\] - AnnouncementRemoved(Cid), - /// Some accounts have been initialized to members (founders/fellows/allies). \[founders, - /// fellows, allies\] - MembersInitialized(Vec, Vec, Vec), - /// An account has been added as a candidate and lock its deposit. \[candidate, nominator, - /// reserved\] - CandidateAdded(T::AccountId, Option, Option>), - /// A proposal has been proposed to approve the candidate. \[candidate\] - CandidateApproved(T::AccountId), - /// A proposal has been proposed to reject the candidate. \[candidate\] - CandidateRejected(T::AccountId), - /// As an active member, an ally has been elevated to fellow. \[ally\] - AllyElevated(T::AccountId), - /// A member has retired to an ordinary account with its deposit unreserved. \[member, - /// unreserved\] - MemberRetired(T::AccountId, Option>), - /// A member has been kicked out to an ordinary account with its deposit slashed. \[member, - /// slashed\] - MemberKicked(T::AccountId, Option>), - /// Accounts or websites have been added into blacklist. \[items\] - BlacklistAdded(Vec>), - /// Accounts or websites have been removed from blacklist. \[items\] - BlacklistRemoved(Vec>), + /// A new rule has been set. + NewRule { rule: Cid }, + /// A new announcement has been proposed. + NewAnnouncement { announcement: Cid }, + /// A on-chain announcement has been removed. + AnnouncementRemoved { announcement: Cid }, + /// Some accounts have been initialized to members (founders/fellows/allies). + MembersInitialized { + founders: Vec, + fellows: Vec, + allies: Vec, + }, + /// An account has been added as a candidate and lock its deposit. + CandidateAdded { + candidate: T::AccountId, + nominator: Option, + reserved: Option>, + }, + /// A proposal has been proposed to approve the candidate. + CandidateApproved { candidate: T::AccountId }, + /// A proposal has been proposed to reject the candidate. + CandidateRejected { candidate: T::AccountId }, + /// As an active member, an ally has been elevated to fellow. + AllyElevated { ally: T::AccountId }, + /// A member has retired to an ordinary account with its deposit unreserved. + MemberRetired { member: T::AccountId, unreserved: Option> }, + /// A member has been kicked out to an ordinary account with its deposit slashed. + MemberKicked { member: T::AccountId, slashed: Option> }, + /// Accounts or websites have been added into blacklist. + BlacklistAdded { items: Vec> }, + /// Accounts or websites have been removed from blacklist. + BlacklistRemoved { items: Vec> }, } #[pallet::genesis_config] @@ -642,7 +646,7 @@ pub mod pallet { founders, fellows, allies ); - Self::deposit_event(Event::MembersInitialized(founders, fellows, allies)); + Self::deposit_event(Event::MembersInitialized { founders, fellows, allies }); Ok(().into()) } @@ -653,7 +657,7 @@ pub mod pallet { Rule::::put(&rule); - Self::deposit_event(Event::NewRule(rule)); + Self::deposit_event(Event::NewRule { rule }); Ok(().into()) } @@ -666,7 +670,7 @@ pub mod pallet { announcements.push(announcement.clone()); >::put(announcements); - Self::deposit_event(Event::NewAnnouncement(announcement)); + Self::deposit_event(Event::NewAnnouncement { announcement }); Ok(().into()) } @@ -686,7 +690,7 @@ pub mod pallet { announcements.remove(pos); >::put(announcements); - Self::deposit_event(Event::AnnouncementRemoved(announcement)); + Self::deposit_event(Event::AnnouncementRemoved { announcement }); Ok(().into()) } @@ -709,7 +713,11 @@ pub mod pallet { let res = Self::add_candidate(&who); debug_assert!(res.is_ok()); - Self::deposit_event(Event::CandidateAdded(who, None, Some(deposit))); + Self::deposit_event(Event::CandidateAdded { + candidate: who, + nominator: None, + reserved: Some(deposit), + }); Ok(().into()) } @@ -733,7 +741,11 @@ pub mod pallet { let res = Self::add_candidate(&who); debug_assert!(res.is_ok()); - Self::deposit_event(Event::CandidateAdded(who, Some(nominator), None)); + Self::deposit_event(Event::CandidateAdded { + candidate: who, + nominator: Some(nominator), + reserved: None, + }); Ok(().into()) } @@ -751,7 +763,7 @@ pub mod pallet { Self::remove_candidate(&candidate)?; Self::add_member(&candidate, MemberRole::Ally)?; - Self::deposit_event(Event::CandidateApproved(candidate)); + Self::deposit_event(Event::CandidateApproved { candidate }); Ok(().into()) } @@ -771,7 +783,7 @@ pub mod pallet { T::Slashed::on_unbalanced(T::Currency::slash_reserved(&candidate, deposit).0); } - Self::deposit_event(Event::CandidateRejected(candidate)); + Self::deposit_event(Event::CandidateRejected { candidate }); Ok(().into()) } @@ -789,7 +801,7 @@ pub mod pallet { Self::remove_member(&ally, MemberRole::Ally)?; Self::add_member(&ally, MemberRole::Fellow)?; - Self::deposit_event(Event::AllyElevated(ally)); + Self::deposit_event(Event::AllyElevated { ally }); Ok(().into()) } @@ -806,7 +818,7 @@ pub mod pallet { let err_amount = T::Currency::unreserve(&who, deposit); debug_assert!(err_amount.is_zero()); } - Self::deposit_event(Event::MemberRetired(who, deposit)); + Self::deposit_event(Event::MemberRetired { member: who, unreserved: deposit }); Ok(().into()) } @@ -826,7 +838,7 @@ pub mod pallet { if let Some(deposit) = deposit { T::Slashed::on_unbalanced(T::Currency::slash_reserved(&member, deposit).0); } - Self::deposit_event(Event::MemberKicked(member, deposit)); + Self::deposit_event(Event::MemberKicked { member, slashed: deposit }); Ok(().into()) } @@ -866,7 +878,7 @@ pub mod pallet { ); Self::do_add_blacklist(&mut accounts, &mut webs)?; - Self::deposit_event(Event::BlacklistAdded(infos)); + Self::deposit_event(Event::BlacklistAdded { items: infos }); Ok(().into()) } @@ -887,7 +899,7 @@ pub mod pallet { } } Self::do_remove_blacklist(&mut accounts, &mut webs)?; - Self::deposit_event(Event::BlacklistRemoved(infos)); + Self::deposit_event(Event::BlacklistRemoved { items: infos }); Ok(().into()) } } diff --git a/frame/alliance/src/tests.rs b/frame/alliance/src/tests.rs index 2e026d26d1062..3e012443959f4 100644 --- a/frame/alliance/src/tests.rs +++ b/frame/alliance/src/tests.rs @@ -239,7 +239,7 @@ fn set_rule_works() { assert_ok!(Alliance::set_rule(Origin::signed(1), cid.clone())); assert_eq!(Alliance::rule(), Some(cid.clone())); - System::assert_last_event(mock::Event::Alliance(crate::Event::NewRule(cid))); + System::assert_last_event(mock::Event::Alliance(crate::Event::NewRule { rule: cid })); }); } @@ -250,7 +250,9 @@ fn announce_works() { assert_ok!(Alliance::announce(Origin::signed(1), cid.clone())); assert_eq!(Alliance::announcements(), vec![cid.clone()]); - System::assert_last_event(mock::Event::Alliance(crate::Event::NewAnnouncement(cid))); + System::assert_last_event(mock::Event::Alliance(crate::Event::NewAnnouncement { + announcement: cid, + })); }); } @@ -260,15 +262,17 @@ fn remove_announcement_works() { let cid = test_cid(); assert_ok!(Alliance::announce(Origin::signed(1), cid.clone())); assert_eq!(Alliance::announcements(), vec![cid.clone()]); - System::assert_last_event(mock::Event::Alliance(crate::Event::NewAnnouncement( - cid.clone(), - ))); + System::assert_last_event(mock::Event::Alliance(crate::Event::NewAnnouncement { + announcement: cid.clone(), + })); System::set_block_number(2); assert_ok!(Alliance::remove_announcement(Origin::signed(1), cid.clone())); assert_eq!(Alliance::announcements(), vec![]); - System::assert_last_event(mock::Event::Alliance(crate::Event::AnnouncementRemoved(cid))); + System::assert_last_event(mock::Event::Alliance(crate::Event::AnnouncementRemoved { + announcement: cid, + })); }); } From 03a6be5dc562ded543bcc1483ee456a67291b5ef Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Sun, 13 Mar 2022 00:35:44 +1300 Subject: [PATCH 26/72] refactor --- frame/alliance/src/lib.rs | 66 +++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index 7b42b189ba290..d36cda7831ab3 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -499,7 +499,7 @@ pub mod pallet { #[pallet::compact] threshold: u32, proposal: Box<>::Proposal>, #[pallet::compact] length_bound: u32, - ) -> DispatchResultWithPostInfo { + ) -> DispatchResult { let proposor = ensure_signed(origin)?; ensure!(Self::is_votable_member(&proposor), Error::::NotVotableMember); @@ -509,7 +509,7 @@ pub mod pallet { } T::ProposalProvider::propose_proposal(proposor, threshold, proposal, length_bound)?; - Ok(().into()) + Ok(()) } /// Add an aye or nay vote for the sender to the given proposal. @@ -524,12 +524,12 @@ pub mod pallet { proposal: T::Hash, #[pallet::compact] index: ProposalIndex, approve: bool, - ) -> DispatchResultWithPostInfo { + ) -> DispatchResult { let who = ensure_signed(origin)?; ensure!(Self::is_votable_member(&who), Error::::NotVotableMember); T::ProposalProvider::vote_proposal(who, proposal, index, approve)?; - Ok(().into()) + Ok(()) } /// Disapprove a proposal about set_rule and elevate_ally, close, and remove it from @@ -537,7 +537,7 @@ pub mod pallet { /// /// Must be called by a founder. #[pallet::weight(T::WeightInfo::veto(T::MaxProposals::get()))] - pub fn veto(origin: OriginFor, proposal_hash: T::Hash) -> DispatchResultWithPostInfo { + pub fn veto(origin: OriginFor, proposal_hash: T::Hash) -> DispatchResult { let proposor = ensure_signed(origin)?; ensure!(Self::is_founder(&proposor), Error::::NotFounder); @@ -546,7 +546,7 @@ pub mod pallet { match proposal.expect("proposal must be exist; qed").is_sub_type() { Some(Call::set_rule { .. }) | Some(Call::elevate_ally { .. }) => { T::ProposalProvider::veto_proposal(proposal_hash); - Ok(().into()) + Ok(()) }, _ => Err(Error::::NotVetoableProposal.into()), } @@ -613,7 +613,7 @@ pub mod pallet { mut founders: Vec, mut fellows: Vec, mut allies: Vec, - ) -> DispatchResultWithPostInfo { + ) -> DispatchResult { ensure_root(origin)?; ensure!( @@ -647,23 +647,23 @@ pub mod pallet { ); Self::deposit_event(Event::MembersInitialized { founders, fellows, allies }); - Ok(().into()) + Ok(()) } /// Set a new IPFS cid to the alliance rule. #[pallet::weight(T::WeightInfo::set_rule())] - pub fn set_rule(origin: OriginFor, rule: Cid) -> DispatchResultWithPostInfo { + pub fn set_rule(origin: OriginFor, rule: Cid) -> DispatchResult { T::SuperMajorityOrigin::ensure_origin(origin)?; Rule::::put(&rule); Self::deposit_event(Event::NewRule { rule }); - Ok(().into()) + Ok(()) } /// Make a new announcement by a new IPFS cid about the alliance issues. #[pallet::weight(T::WeightInfo::announce())] - pub fn announce(origin: OriginFor, announcement: Cid) -> DispatchResultWithPostInfo { + pub fn announce(origin: OriginFor, announcement: Cid) -> DispatchResult { T::SuperMajorityOrigin::ensure_origin(origin)?; let mut announcements = >::get(); @@ -671,7 +671,7 @@ pub mod pallet { >::put(announcements); Self::deposit_event(Event::NewAnnouncement { announcement }); - Ok(().into()) + Ok(()) } /// Remove the announcement. @@ -679,7 +679,7 @@ pub mod pallet { pub fn remove_announcement( origin: OriginFor, announcement: Cid, - ) -> DispatchResultWithPostInfo { + ) -> DispatchResult { T::SuperMajorityOrigin::ensure_origin(origin)?; let mut announcements = >::get(); @@ -691,12 +691,12 @@ pub mod pallet { >::put(announcements); Self::deposit_event(Event::AnnouncementRemoved { announcement }); - Ok(().into()) + Ok(()) } /// Submit oneself for candidacy. A fixed amount of deposit is recorded. #[pallet::weight(T::WeightInfo::submit_candidacy())] - pub fn submit_candidacy(origin: OriginFor) -> DispatchResultWithPostInfo { + pub fn submit_candidacy(origin: OriginFor) -> DispatchResult { let who = ensure_signed(origin)?; ensure!(!Self::is_account_blacklist(&who), Error::::AlreadyInBlacklist); ensure!(!Self::is_candidate(&who), Error::::AlreadyCandidate); @@ -718,7 +718,7 @@ pub mod pallet { nominator: None, reserved: Some(deposit), }); - Ok(().into()) + Ok(()) } /// Founder or fellow can nominate someone to join the alliance and become a candidate. @@ -727,7 +727,7 @@ pub mod pallet { pub fn nominate_candidacy( origin: OriginFor, who: ::Source, - ) -> DispatchResultWithPostInfo { + ) -> DispatchResult { let nominator = ensure_signed(origin)?; ensure!(Self::is_votable_member(&nominator), Error::::NotVotableMember); let who = T::Lookup::lookup(who)?; @@ -746,7 +746,7 @@ pub mod pallet { nominator: Some(nominator), reserved: None, }); - Ok(().into()) + Ok(()) } /// Approve a `Candidate` to become an `Ally`. @@ -754,7 +754,7 @@ pub mod pallet { pub fn approve_candidate( origin: OriginFor, candidate: ::Source, - ) -> DispatchResultWithPostInfo { + ) -> DispatchResult { T::SuperMajorityOrigin::ensure_origin(origin)?; let candidate = T::Lookup::lookup(candidate)?; ensure!(Self::is_candidate(&candidate), Error::::NotCandidate); @@ -764,7 +764,7 @@ pub mod pallet { Self::add_member(&candidate, MemberRole::Ally)?; Self::deposit_event(Event::CandidateApproved { candidate }); - Ok(().into()) + Ok(()) } /// Reject a `Candidate` back to an ordinary account. @@ -772,7 +772,7 @@ pub mod pallet { pub fn reject_candidate( origin: OriginFor, candidate: ::Source, - ) -> DispatchResultWithPostInfo { + ) -> DispatchResult { T::SuperMajorityOrigin::ensure_origin(origin)?; let candidate = T::Lookup::lookup(candidate)?; ensure!(Self::is_candidate(&candidate), Error::::NotCandidate); @@ -784,7 +784,7 @@ pub mod pallet { } Self::deposit_event(Event::CandidateRejected { candidate }); - Ok(().into()) + Ok(()) } /// Elevate an ally to fellow. @@ -792,7 +792,7 @@ pub mod pallet { pub fn elevate_ally( origin: OriginFor, ally: ::Source, - ) -> DispatchResultWithPostInfo { + ) -> DispatchResult { T::SuperMajorityOrigin::ensure_origin(origin)?; let ally = T::Lookup::lookup(ally)?; ensure!(Self::is_ally(&ally), Error::::NotAlly); @@ -802,12 +802,12 @@ pub mod pallet { Self::add_member(&ally, MemberRole::Fellow)?; Self::deposit_event(Event::AllyElevated { ally }); - Ok(().into()) + Ok(()) } /// As a member, retire and back to an ordinary account and unlock its deposit. #[pallet::weight(T::WeightInfo::retire())] - pub fn retire(origin: OriginFor) -> DispatchResultWithPostInfo { + pub fn retire(origin: OriginFor) -> DispatchResult { let who = ensure_signed(origin)?; ensure!(!Self::is_kicking(&who), Error::::KickingMember); @@ -819,7 +819,7 @@ pub mod pallet { debug_assert!(err_amount.is_zero()); } Self::deposit_event(Event::MemberRetired { member: who, unreserved: deposit }); - Ok(().into()) + Ok(()) } /// Kick a member to ordinary account with its deposit slashed. @@ -827,7 +827,7 @@ pub mod pallet { pub fn kick_member( origin: OriginFor, who: ::Source, - ) -> DispatchResultWithPostInfo { + ) -> DispatchResult { T::SuperMajorityOrigin::ensure_origin(origin)?; let member = T::Lookup::lookup(who)?; ensure!(Self::is_kicking(&member), Error::::NotKickingMember); @@ -839,7 +839,7 @@ pub mod pallet { T::Slashed::on_unbalanced(T::Currency::slash_reserved(&member, deposit).0); } Self::deposit_event(Event::MemberKicked { member, slashed: deposit }); - Ok(().into()) + Ok(()) } /// Add accounts or websites into blacklist. @@ -847,7 +847,7 @@ pub mod pallet { pub fn add_blacklist( origin: OriginFor, infos: Vec>, - ) -> DispatchResultWithPostInfo { + ) -> DispatchResult { T::SuperMajorityOrigin::ensure_origin(origin)?; let mut accounts = vec![]; @@ -879,7 +879,7 @@ pub mod pallet { Self::do_add_blacklist(&mut accounts, &mut webs)?; Self::deposit_event(Event::BlacklistAdded { items: infos }); - Ok(().into()) + Ok(()) } /// Remove accounts or websites from blacklist. @@ -887,7 +887,7 @@ pub mod pallet { pub fn remove_blacklist( origin: OriginFor, infos: Vec>, - ) -> DispatchResultWithPostInfo { + ) -> DispatchResult { T::SuperMajorityOrigin::ensure_origin(origin)?; let mut accounts = vec![]; let mut webs = vec![]; @@ -900,7 +900,7 @@ pub mod pallet { } Self::do_remove_blacklist(&mut accounts, &mut webs)?; Self::deposit_event(Event::BlacklistRemoved { items: infos }); - Ok(().into()) + Ok(()) } } } @@ -930,7 +930,7 @@ impl, I: 'static> Pallet { } fn has_member(role: MemberRole) -> bool { - !Members::::get(role).is_empty() + Members::::decode_len(role).unwrap_or_default() > 0 } fn member_role_of(who: &T::AccountId) -> Option { From 3e4e7f466c23c5c0917476b3afc0705ac0410695 Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Sun, 13 Mar 2022 00:37:15 +1300 Subject: [PATCH 27/72] cleanup --- frame/alliance/src/lib.rs | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index d36cda7831ab3..a3fbd4c444200 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -541,9 +541,9 @@ pub mod pallet { let proposor = ensure_signed(origin)?; ensure!(Self::is_founder(&proposor), Error::::NotFounder); - let proposal = T::ProposalProvider::proposal_of(proposal_hash); - ensure!(proposal.is_some(), Error::::MissingProposalHash); - match proposal.expect("proposal must be exist; qed").is_sub_type() { + let proposal = T::ProposalProvider::proposal_of(proposal_hash) + .ok_or(Error::::MissingProposalHash)?; + match proposal.is_sub_type() { Some(Call::set_rule { .. }) | Some(Call::elevate_ally { .. }) => { T::ProposalProvider::veto_proposal(proposal_hash); Ok(()) @@ -580,8 +580,8 @@ pub mod pallet { let who = ensure_signed(origin)?; ensure!(Self::is_votable_member(&who), Error::::NotVotableMember); - let proposal = T::ProposalProvider::proposal_of(proposal_hash); - ensure!(proposal.is_some(), Error::::MissingProposalHash); + let proposal = T::ProposalProvider::proposal_of(proposal_hash) + .ok_or(Error::::MissingProposalHash)?; let info = T::ProposalProvider::close_proposal( proposal_hash, @@ -590,9 +590,7 @@ pub mod pallet { length_bound, )?; if Pays::No == info.pays_fee { - if let Some(Call::kick_member { who }) = - proposal.expect("proposal must be exist; qed").is_sub_type() - { + if let Some(Call::kick_member { who }) = proposal.is_sub_type() { let strike = T::Lookup::lookup(who.clone())?; >::remove(strike); } @@ -676,10 +674,7 @@ pub mod pallet { /// Remove the announcement. #[pallet::weight(T::WeightInfo::remove_announcement())] - pub fn remove_announcement( - origin: OriginFor, - announcement: Cid, - ) -> DispatchResult { + pub fn remove_announcement(origin: OriginFor, announcement: Cid) -> DispatchResult { T::SuperMajorityOrigin::ensure_origin(origin)?; let mut announcements = >::get(); From 73331485ca08d8f1ebc0160974721036a62b2fbd Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Sun, 13 Mar 2022 00:47:48 +1300 Subject: [PATCH 28/72] cleanup --- frame/alliance/src/lib.rs | 81 +++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 38 deletions(-) diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index a3fbd4c444200..a25c77d21b5c0 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -908,20 +908,20 @@ impl, I: 'static> Pallet { /// Add a candidate to the sorted candidate list. fn add_candidate(who: &T::AccountId) -> DispatchResult { - let mut candidates = >::get(); - let pos = candidates.binary_search(who).err().ok_or(Error::::AlreadyCandidate)?; - candidates.insert(pos, who.clone()); - Candidates::::put(candidates); - Ok(()) + >::try_mutate(|candidates| { + let pos = candidates.binary_search(who).err().ok_or(Error::::AlreadyCandidate)?; + candidates.insert(pos, who.clone()); + Ok(()) + }) } /// Remove a candidate from the candidates list. fn remove_candidate(who: &T::AccountId) -> DispatchResult { - let mut candidates = >::get(); - let pos = candidates.binary_search(who).ok().ok_or(Error::::NotCandidate)?; - candidates.remove(pos); - Candidates::::put(candidates); - Ok(()) + >::try_mutate(|candidates| { + let pos = candidates.binary_search(who).ok().ok_or(Error::::NotCandidate)?; + candidates.remove(pos); + Ok(()) + }) } fn has_member(role: MemberRole) -> bool { @@ -972,10 +972,11 @@ impl, I: 'static> Pallet { /// Add a user to the sorted alliance member set. fn add_member(who: &T::AccountId, role: MemberRole) -> DispatchResult { - let mut members = >::get(role); - let pos = members.binary_search(who).err().ok_or(Error::::AlreadyMember)?; - members.insert(pos, who.clone()); - Members::::insert(role, members); + >::try_mutate(role, |members| -> DispatchResult { + let pos = members.binary_search(who).err().ok_or(Error::::AlreadyMember)?; + members.insert(pos, who.clone()); + Ok(()) + })?; if role == MemberRole::Founder || role == MemberRole::Fellow { let members = Self::votable_member_sorted(); @@ -986,10 +987,11 @@ impl, I: 'static> Pallet { /// Remove a user from the alliance member set. fn remove_member(who: &T::AccountId, role: MemberRole) -> DispatchResult { - let mut members = >::get(role); - let pos = members.binary_search(who).ok().ok_or(Error::::NotMember)?; - members.remove(pos); - Members::::insert(role, members); + >::try_mutate(role, |members| -> DispatchResult { + let pos = members.binary_search(who).ok().ok_or(Error::::NotMember)?; + members.remove(pos); + Ok(()) + })?; if role == MemberRole::Founder || role == MemberRole::Fellow { let members = Self::votable_member_sorted(); @@ -1017,16 +1019,16 @@ impl, I: 'static> Pallet { new_webs: &mut Vec, ) -> DispatchResult { if !new_accounts.is_empty() { - let mut accounts = >::get(); - accounts.append(new_accounts); - accounts.sort(); - AccountBlacklist::::put(accounts); + >::mutate(|accounts| { + accounts.append(new_accounts); + accounts.sort(); + }); } if !new_webs.is_empty() { - let mut webs = >::get(); - webs.append(new_webs); - webs.sort(); - WebsiteBlacklist::::put(webs); + >::mutate(|webs| { + webs.append(new_webs); + webs.sort(); + }); } Ok(()) } @@ -1037,20 +1039,23 @@ impl, I: 'static> Pallet { out_webs: &mut Vec, ) -> DispatchResult { if !out_accounts.is_empty() { - let mut accounts = >::get(); - for who in out_accounts.iter() { - let pos = accounts.binary_search(who).ok().ok_or(Error::::NotInBlacklist)?; - accounts.remove(pos); - } - AccountBlacklist::::put(accounts); + >::try_mutate(|accounts| -> DispatchResult { + for who in out_accounts.iter() { + let pos = + accounts.binary_search(who).ok().ok_or(Error::::NotInBlacklist)?; + accounts.remove(pos); + } + Ok(()) + })?; } if !out_webs.is_empty() { - let mut webs = >::get(); - for web in out_webs.iter() { - let pos = webs.binary_search(web).ok().ok_or(Error::::NotInBlacklist)?; - webs.remove(pos); - } - WebsiteBlacklist::::put(webs); + >::try_mutate(|webs| -> DispatchResult { + for web in out_webs.iter() { + let pos = webs.binary_search(web).ok().ok_or(Error::::NotInBlacklist)?; + webs.remove(pos); + } + Ok(()) + })?; } Ok(()) } From c49b6339fd7e60527d5a8a5fdb7dbc37cbd0f415 Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Fri, 25 Mar 2022 10:41:30 +1300 Subject: [PATCH 29/72] fix benchmarking --- frame/alliance/src/benchmarking.rs | 44 +++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/frame/alliance/src/benchmarking.rs b/frame/alliance/src/benchmarking.rs index 9a28ad2e591da..e8fa84b822258 100644 --- a/frame/alliance/src/benchmarking.rs +++ b/frame/alliance/src/benchmarking.rs @@ -589,7 +589,11 @@ benchmarks_instance_pallet! { founders.sort(); fellows.sort(); allies.sort(); - assert_last_event::(Event::MembersInitialized(founders.clone(), fellows.clone(), allies.clone()).into()); + assert_last_event::(Event::MembersInitialized { + founders: founders.clone(), + fellows: fellows.clone(), + allies: allies.clone(), + }.into()); assert_eq!(Alliance::::members(MemberRole::Founder), founders); assert_eq!(Alliance::::members(MemberRole::Fellow), fellows); assert_eq!(Alliance::::members(MemberRole::Ally), allies); @@ -605,7 +609,7 @@ benchmarks_instance_pallet! { }: { call.dispatch_bypass_filter(origin)? } verify { assert_eq!(Alliance::::rule(), Some(rule.clone())); - assert_last_event::(Event::NewRule(rule).into()); + assert_last_event::(Event::NewRule { rule }.into()); } announce { @@ -618,7 +622,7 @@ benchmarks_instance_pallet! { }: { call.dispatch_bypass_filter(origin)? } verify { assert!(Alliance::::announcements().contains(&announcement)); - assert_last_event::(Event::NewAnnouncement(announcement).into()); + assert_last_event::(Event::NewAnnouncement { announcement }.into()); } remove_announcement { @@ -632,7 +636,7 @@ benchmarks_instance_pallet! { }: { call.dispatch_bypass_filter(origin)? } verify { assert!(Alliance::::announcements().is_empty()); - assert_last_event::(Event::AnnouncementRemoved(announcement).into()); + assert_last_event::(Event::AnnouncementRemoved { announcement }.into()); } submit_candidacy { @@ -647,7 +651,11 @@ benchmarks_instance_pallet! { assert!(!Alliance::::is_member(&outsider)); assert!(Alliance::::is_candidate(&outsider)); assert_eq!(DepositOf::::get(&outsider), Some(T::CandidateDeposit::get())); - assert_last_event::(Event::CandidateAdded(outsider, None, Some(T::CandidateDeposit::get())).into()); + assert_last_event::(Event::CandidateAdded { + candidate: outsider, + nominator: None, + reserved: Some(T::CandidateDeposit::get()) + }.into()); } nominate_candidacy { @@ -667,7 +675,11 @@ benchmarks_instance_pallet! { assert!(!Alliance::::is_member(&outsider)); assert!(Alliance::::is_candidate(&outsider)); assert_eq!(DepositOf::::get(&outsider), None); - assert_last_event::(Event::CandidateAdded(outsider, Some(founder1), None).into()); + assert_last_event::(Event::CandidateAdded { + candidate: outsider, + nominator: Some(founder1), + reserved: None + }.into()); } approve_candidate { @@ -687,7 +699,7 @@ benchmarks_instance_pallet! { assert!(!Alliance::::is_candidate(&candidate1)); assert!(Alliance::::is_ally(&candidate1)); assert_eq!(DepositOf::::get(&candidate1), Some(T::CandidateDeposit::get())); - assert_last_event::(Event::CandidateApproved(candidate1).into()); + assert_last_event::(Event::CandidateApproved { candidate: candidate1 }.into()); } reject_candidate { @@ -707,7 +719,7 @@ benchmarks_instance_pallet! { assert!(!Alliance::::is_candidate(&candidate1)); assert!(!Alliance::::is_member(&candidate1)); assert_eq!(DepositOf::::get(&candidate1), None); - assert_last_event::(Event::CandidateRejected(candidate1).into()); + assert_last_event::(Event::CandidateRejected { candidate: candidate1 }.into()); } elevate_ally { @@ -723,7 +735,7 @@ benchmarks_instance_pallet! { verify { assert!(!Alliance::::is_ally(&ally1)); assert!(Alliance::::is_fellow(&ally1)); - assert_last_event::(Event::AllyElevated(ally1).into()); + assert_last_event::(Event::AllyElevated { ally: ally1 }.into()); } retire { @@ -738,7 +750,10 @@ benchmarks_instance_pallet! { verify { assert!(!Alliance::::is_member(&fellow2)); assert_eq!(DepositOf::::get(&fellow2), None); - assert_last_event::(Event::MemberRetired(fellow2, Some(T::CandidateDeposit::get())).into()); + assert_last_event::(Event::MemberRetired { + member: fellow2, + unreserved: Some(T::CandidateDeposit::get()) + }.into()); } kick_member { @@ -759,7 +774,10 @@ benchmarks_instance_pallet! { verify { assert!(!Alliance::::is_member(&fellow2)); assert_eq!(DepositOf::::get(&fellow2), None); - assert_last_event::(Event::MemberKicked(fellow2, Some(T::CandidateDeposit::get())).into()); + assert_last_event::(Event::MemberKicked { + member: fellow2, + slashed: Some(T::CandidateDeposit::get()) + }.into()); } add_blacklist { @@ -779,7 +797,7 @@ benchmarks_instance_pallet! { let origin = T::SuperMajorityOrigin::successful_origin(); }: { call.dispatch_bypass_filter(origin)? } verify { - assert_last_event::(Event::BlacklistAdded(blacklist).into()); + assert_last_event::(Event::BlacklistAdded { items: blacklist }.into()); } remove_blacklist { @@ -804,7 +822,7 @@ benchmarks_instance_pallet! { let origin = T::SuperMajorityOrigin::successful_origin(); }: { call.dispatch_bypass_filter(origin)? } verify { - assert_last_event::(Event::BlacklistRemoved(blacklist).into()); + assert_last_event::(Event::BlacklistRemoved { items: blacklist }.into()); } impl_benchmark_test_suite!(Alliance, crate::mock::new_bench_ext(), crate::mock::Test); From bbd087b759761b9ba0de1de5df6bc762f9eb2de2 Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Fri, 25 Mar 2022 11:07:42 +1300 Subject: [PATCH 30/72] fix warning --- bin/node/runtime/src/lib.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index f6557e39f8996..81672053ac73b 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -88,7 +88,9 @@ pub use sp_runtime::BuildStorage; /// Implementations of some helper traits passed into runtime modules as associated types. pub mod impls; -use impls::{AllianceIdentityVerifier, AllianceProposalProvider, Author, CreditToBlockAuthor}; +use impls::{AllianceProposalProvider, Author, CreditToBlockAuthor}; +#[cfg(not(feature = "runtime-benchmarks"))] +use impls::AllianceIdentityVerifier; /// Constant values used within the runtime. pub mod constants; From 062bad8da8d465afc278d25d84f288c82cdc57b8 Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Fri, 25 Mar 2022 11:11:57 +1300 Subject: [PATCH 31/72] fmt --- bin/node/runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 81672053ac73b..fb50e3d6dabbe 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -88,9 +88,9 @@ pub use sp_runtime::BuildStorage; /// Implementations of some helper traits passed into runtime modules as associated types. pub mod impls; -use impls::{AllianceProposalProvider, Author, CreditToBlockAuthor}; #[cfg(not(feature = "runtime-benchmarks"))] use impls::AllianceIdentityVerifier; +use impls::{AllianceProposalProvider, Author, CreditToBlockAuthor}; /// Constant values used within the runtime. pub mod constants; From 8ab53a8304a3ac8eb4c23577aaf80489eec30f76 Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Fri, 25 Mar 2022 14:24:35 +1300 Subject: [PATCH 32/72] fix benchmarks --- frame/alliance/src/benchmarking.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/alliance/src/benchmarking.rs b/frame/alliance/src/benchmarking.rs index e8fa84b822258..c8ad4cc37e936 100644 --- a/frame/alliance/src/benchmarking.rs +++ b/frame/alliance/src/benchmarking.rs @@ -52,7 +52,7 @@ fn announcement(input: impl AsRef<[u8]>) -> Cid { fn funded_account, I: 'static>(name: &'static str, index: u32) -> T::AccountId { let account: T::AccountId = account(name, index, SEED); - T::Currency::make_free_balance_be(&account, BalanceOf::::max_value()); + T::Currency::make_free_balance_be(&account, BalanceOf::::max_value() / 100u8.into()); account } From c16c2a779751ae87e1efba1ed614aa4506115d7e Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Thu, 31 Mar 2022 20:38:15 +1300 Subject: [PATCH 33/72] with storage info --- frame/alliance/src/lib.rs | 143 ++++++++++++++--------- frame/support/src/storage/bounded_vec.rs | 24 ++++ 2 files changed, 115 insertions(+), 52 deletions(-) diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index a25c77d21b5c0..0ec048599cfa4 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -100,6 +100,8 @@ mod benchmarking; mod types; pub mod weights; +use frame_support::pallet_prelude::*; +use frame_system::pallet_prelude::*; use sp_runtime::{ traits::{StaticLookup, Zero}, RuntimeDebug, @@ -107,7 +109,7 @@ use sp_runtime::{ use sp_std::prelude::*; use frame_support::{ - codec::{Decode, Encode}, + codec::{Decode, Encode, MaxEncodedLen}, dispatch::{ DispatchError, DispatchResult, DispatchResultWithPostInfo, Dispatchable, GetDispatchInfo, PostDispatchInfo, @@ -128,7 +130,7 @@ pub use weights::*; /// Simple index type for proposal counting. pub type ProposalIndex = u32; -type Url = Vec; +type UrlOf = BoundedVec>::MaxWebsiteUrlLength>; type BalanceOf = <>::Currency as Currency<::AccountId>>::Balance; @@ -157,7 +159,6 @@ impl IdentityVerifier for () { None } } - pub trait ProposalProvider { fn propose_proposal( who: AccountId, @@ -186,7 +187,7 @@ pub trait ProposalProvider { } /// The role of members. -#[derive(Copy, Clone, PartialEq, Eq, RuntimeDebug, Encode, Decode, TypeInfo)] +#[derive(Copy, Clone, PartialEq, Eq, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)] pub enum MemberRole { Founder, Fellow, @@ -194,21 +195,20 @@ pub enum MemberRole { } /// The item type of blacklist. -#[derive(Clone, PartialEq, Eq, RuntimeDebug, Encode, Decode, TypeInfo)] -pub enum BlacklistItem { +#[derive(Clone, PartialEq, Eq, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)] +pub enum BlacklistItem { AccountId(AccountId), Website(Url), } +type BlacklistItemOf = BlacklistItem<::AccountId, UrlOf>; + #[frame_support::pallet] pub mod pallet { use super::*; - use frame_support::pallet_prelude::*; - use frame_system::pallet_prelude::*; #[pallet::pallet] #[pallet::generate_store(pub (super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(PhantomData<(T, I)>); #[pallet::config] @@ -283,6 +283,18 @@ pub mod pallet { #[pallet::constant] type CandidateDeposit: Get>; + /// The maximum numbers of announcements. + #[pallet::constant] + type MaxAnnouncementsCount: Get; + + /// The maximum numbers of members per member role. + #[pallet::constant] + type MaxMembersCount: Get; + + /// The maximum numbers of candidates. + #[pallet::constant] + type MaxCandidatesCount: Get; + /// Weight information for extrinsics in this pallet. type WeightInfo: WeightInfo; } @@ -331,6 +343,12 @@ pub mod pallet { NotVetoableProposal, /// The Announcement is not found. MissingAnnouncement, + /// Number of members exceed MaxMembersCount. + TooManyMembers, + /// Number of candidates exceed MaxCandidatesCount. + TooManyCandidates, + /// Number of Announcements exceed MaxAnnouncementsCount. + TooManyAnnouncements, } #[pallet::event] @@ -365,9 +383,9 @@ pub mod pallet { /// A member has been kicked out to an ordinary account with its deposit slashed. MemberKicked { member: T::AccountId, slashed: Option> }, /// Accounts or websites have been added into blacklist. - BlacklistAdded { items: Vec> }, + BlacklistAdded { items: Vec> }, /// Accounts or websites have been removed from blacklist. - BlacklistRemoved { items: Vec> }, + BlacklistRemoved { items: Vec> }, } #[pallet::genesis_config] @@ -408,17 +426,23 @@ pub mod pallet { !Pallet::::has_member(MemberRole::Founder), "Founders are already initialized!" ); - Members::::insert(MemberRole::Founder, self.founders.clone()); + let members: BoundedVec = + self.founders.clone().try_into().expect("Too many genesis founders"); + Members::::insert(MemberRole::Founder, members); } if !self.fellows.is_empty() { assert!( !Pallet::::has_member(MemberRole::Fellow), "Fellows are already initialized!" ); - Members::::insert(MemberRole::Fellow, self.fellows.clone()); + let members: BoundedVec = + self.fellows.clone().try_into().expect("Too many genesis fellows"); + Members::::insert(MemberRole::Fellow, members); } if !self.allies.is_empty() { - Members::::insert(MemberRole::Ally, self.allies.clone()) + let members: BoundedVec = + self.allies.clone().try_into().expect("Too many genesis allies"); + Members::::insert(MemberRole::Ally, members); } T::InitializeMembers::initialize_members( @@ -439,7 +463,8 @@ pub mod pallet { /// The current IPFS cids of the announcements. #[pallet::storage] #[pallet::getter(fn announcements)] - pub type Announcements, I: 'static = ()> = StorageValue<_, Vec, ValueQuery>; + pub type Announcements, I: 'static = ()> = + StorageValue<_, BoundedVec, ValueQuery>; /// Maps member and their candidate deposit. #[pallet::storage] @@ -452,15 +477,20 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn candidates)] pub type Candidates, I: 'static = ()> = - StorageValue<_, Vec, ValueQuery>; + StorageValue<_, BoundedVec, ValueQuery>; /// Maps member type to alliance members, including founder, fellow and ally. /// Founders and fellows can propose and vote on alliance motions, /// and ally can only wait to be elevated to fellow. #[pallet::storage] #[pallet::getter(fn members)] - pub type Members, I: 'static = ()> = - StorageMap<_, Twox64Concat, MemberRole, Vec, ValueQuery>; + pub type Members, I: 'static = ()> = StorageMap< + _, + Twox64Concat, + MemberRole, + BoundedVec, + ValueQuery, + >; /// The members are being kicked out. They can't retire during the motion. #[pallet::storage] @@ -472,13 +502,13 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn account_blacklist)] pub type AccountBlacklist, I: 'static = ()> = - StorageValue<_, Vec, ValueQuery>; + StorageValue<_, BoundedVec, ValueQuery>; /// The current blacklist of websites. #[pallet::storage] #[pallet::getter(fn website_blacklist)] pub type WebsiteBlacklist, I: 'static = ()> = - StorageValue<_, Vec, ValueQuery>; + StorageValue<_, BoundedVec, T::MaxBlacklistCount>, ValueQuery>; #[pallet::call] impl, I: 'static> Pallet { @@ -608,12 +638,19 @@ pub mod pallet { ))] pub fn init_members( origin: OriginFor, - mut founders: Vec, - mut fellows: Vec, - mut allies: Vec, + founders: Vec, + fellows: Vec, + allies: Vec, ) -> DispatchResult { ensure_root(origin)?; + let mut founders: BoundedVec = + founders.try_into().map_err(|_| Error::::TooManyMembers)?; + let mut fellows: BoundedVec = + fellows.try_into().map_err(|_| Error::::TooManyMembers)?; + let mut allies: BoundedVec = + allies.try_into().map_err(|_| Error::::TooManyMembers)?; + ensure!( !Self::has_member(MemberRole::Founder) && !Self::has_member(MemberRole::Fellow) && @@ -644,7 +681,11 @@ pub mod pallet { founders, fellows, allies ); - Self::deposit_event(Event::MembersInitialized { founders, fellows, allies }); + Self::deposit_event(Event::MembersInitialized { + founders: founders.into(), + fellows: fellows.into(), + allies: allies.into(), + }); Ok(()) } @@ -665,7 +706,7 @@ pub mod pallet { T::SuperMajorityOrigin::ensure_origin(origin)?; let mut announcements = >::get(); - announcements.push(announcement.clone()); + announcements.try_push(announcement.clone()).map_err(|_| Error::::TooManyAnnouncements)?; >::put(announcements); Self::deposit_event(Event::NewAnnouncement { announcement }); @@ -841,7 +882,7 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::add_blacklist(infos.len() as u32, T::MaxWebsiteUrlLength::get()))] pub fn add_blacklist( origin: OriginFor, - infos: Vec>, + infos: Vec>, ) -> DispatchResult { T::SuperMajorityOrigin::ensure_origin(origin)?; @@ -861,17 +902,6 @@ pub mod pallet { } } - let account_blacklist_len = AccountBlacklist::::decode_len().unwrap_or_default(); - ensure!( - (account_blacklist_len + accounts.len()) as u32 <= T::MaxBlacklistCount::get(), - Error::::TooManyBlacklist - ); - let web_blacklist_len = WebsiteBlacklist::::decode_len().unwrap_or_default(); - ensure!( - (web_blacklist_len + webs.len()) as u32 <= T::MaxBlacklistCount::get(), - Error::::TooManyBlacklist - ); - Self::do_add_blacklist(&mut accounts, &mut webs)?; Self::deposit_event(Event::BlacklistAdded { items: infos }); Ok(()) @@ -881,7 +911,7 @@ pub mod pallet { #[pallet::weight(>::WeightInfo::remove_blacklist(infos.len() as u32, T::MaxWebsiteUrlLength::get()))] pub fn remove_blacklist( origin: OriginFor, - infos: Vec>, + infos: Vec>, ) -> DispatchResult { T::SuperMajorityOrigin::ensure_origin(origin)?; let mut accounts = vec![]; @@ -910,7 +940,9 @@ impl, I: 'static> Pallet { fn add_candidate(who: &T::AccountId) -> DispatchResult { >::try_mutate(|candidates| { let pos = candidates.binary_search(who).err().ok_or(Error::::AlreadyCandidate)?; - candidates.insert(pos, who.clone()); + candidates + .try_insert(pos, who.clone()) + .map_err(|_| Error::::TooManyCandidates)?; Ok(()) }) } @@ -959,11 +991,11 @@ impl, I: 'static> Pallet { } fn votable_member_sorted() -> Vec { - let mut founders = Members::::get(MemberRole::Founder); - let mut fellows = Members::::get(MemberRole::Fellow); + let mut founders = Members::::get(MemberRole::Founder).into_inner(); + let mut fellows = Members::::get(MemberRole::Fellow).into_inner(); founders.append(&mut fellows); founders.sort(); - founders + founders.into() } fn is_kicking(who: &T::AccountId) -> bool { @@ -974,7 +1006,9 @@ impl, I: 'static> Pallet { fn add_member(who: &T::AccountId, role: MemberRole) -> DispatchResult { >::try_mutate(role, |members| -> DispatchResult { let pos = members.binary_search(who).err().ok_or(Error::::AlreadyMember)?; - members.insert(pos, who.clone()); + members + .try_insert(pos, who.clone()) + .map_err(|_| Error::::TooManyMembers)?; Ok(()) })?; @@ -1001,7 +1035,7 @@ impl, I: 'static> Pallet { } /// Check if a user is in blacklist. - fn is_blacklist(info: &BlacklistItem) -> bool { + fn is_blacklist(info: &BlacklistItemOf) -> bool { match info { BlacklistItem::Website(url) => >::get().contains(url), BlacklistItem::AccountId(who) => >::get().contains(who), @@ -1016,27 +1050,32 @@ impl, I: 'static> Pallet { /// Add a identity info to the blacklist set. fn do_add_blacklist( new_accounts: &mut Vec, - new_webs: &mut Vec, + new_webs: &mut Vec>, ) -> DispatchResult { if !new_accounts.is_empty() { - >::mutate(|accounts| { - accounts.append(new_accounts); + >::try_mutate(|accounts| -> DispatchResult { + accounts.try_append(new_accounts).map_err(|_| Error::::TooManyBlacklist)?; accounts.sort(); - }); + + Ok(()) + })?; } if !new_webs.is_empty() { - >::mutate(|webs| { - webs.append(new_webs); + >::try_mutate(|webs| -> DispatchResult { + webs.try_append(new_webs).map_err(|_| Error::::TooManyBlacklist)?; webs.sort(); - }); + + Ok(()) + })?; } + Ok(()) } /// Remove a identity info from the blacklist. fn do_remove_blacklist( out_accounts: &mut Vec, - out_webs: &mut Vec, + out_webs: &mut Vec>, ) -> DispatchResult { if !out_accounts.is_empty() { >::try_mutate(|accounts| -> DispatchResult { diff --git a/frame/support/src/storage/bounded_vec.rs b/frame/support/src/storage/bounded_vec.rs index cf585af395587..fa10cf0677497 100644 --- a/frame/support/src/storage/bounded_vec.rs +++ b/frame/support/src/storage/bounded_vec.rs @@ -129,6 +129,16 @@ impl BoundedVec { self.0.sort_by(compare) } + /// Exactly the same semantics as [`slice::sort`]. + /// + /// This is safe since sorting cannot change the number of elements in the vector. + pub fn sort(&mut self) + where + T: sp_std::cmp::Ord, + { + self.0.sort() + } + /// Exactly the same semantics as `Vec::remove`. /// /// # Panics @@ -374,6 +384,20 @@ impl> BoundedVec { } } + /// Exactly the same semantics as [`Vec::append`], but returns an error and does nothing if the + /// length of the outcome is larger than the bound. + pub fn try_append( + &mut self, + other: &mut Vec, + ) -> Result<(), ()> { + if other.len().saturating_add(self.len()) <= Self::bound() { + self.0.append(other); + Ok(()) + } else { + Err(()) + } + } + /// Consumes self and mutates self via the given `mutate` function. /// /// If the outcome of mutation is within bounds, `Some(Self)` is returned. Else, `None` is From 58ca07dc6840e2ddf3d5c651cd113c72fc445765 Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Thu, 31 Mar 2022 20:40:21 +1300 Subject: [PATCH 34/72] fmt --- frame/alliance/src/lib.rs | 4 +++- frame/support/src/storage/bounded_vec.rs | 5 +---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index 0ec048599cfa4..2b35c5a450df0 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -706,7 +706,9 @@ pub mod pallet { T::SuperMajorityOrigin::ensure_origin(origin)?; let mut announcements = >::get(); - announcements.try_push(announcement.clone()).map_err(|_| Error::::TooManyAnnouncements)?; + announcements + .try_push(announcement.clone()) + .map_err(|_| Error::::TooManyAnnouncements)?; >::put(announcements); Self::deposit_event(Event::NewAnnouncement { announcement }); diff --git a/frame/support/src/storage/bounded_vec.rs b/frame/support/src/storage/bounded_vec.rs index fa10cf0677497..81b958c840b71 100644 --- a/frame/support/src/storage/bounded_vec.rs +++ b/frame/support/src/storage/bounded_vec.rs @@ -386,10 +386,7 @@ impl> BoundedVec { /// Exactly the same semantics as [`Vec::append`], but returns an error and does nothing if the /// length of the outcome is larger than the bound. - pub fn try_append( - &mut self, - other: &mut Vec, - ) -> Result<(), ()> { + pub fn try_append(&mut self, other: &mut Vec) -> Result<(), ()> { if other.len().saturating_add(self.len()) <= Self::bound() { self.0.append(other); Ok(()) From 4013d84a38cd30fc4e78e8b17b89929cd2144fb5 Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Sat, 2 Apr 2022 13:52:56 +1300 Subject: [PATCH 35/72] add new config --- bin/node/runtime/src/lib.rs | 9 +++++---- frame/alliance/src/mock.rs | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index e576d78651fbb..5f2ffd6928f5f 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1426,8 +1426,6 @@ parameter_types! { pub const MaxFounders: u32 = 10; pub const MaxFellows: u32 = AllianceMaxMembers::get() - MaxFounders::get(); pub const MaxAllies: u32 = 100; - pub const MaxBlacklistCount: u32 = 100; - pub const MaxWebsiteUrlLength: u32 = 255; } impl pallet_alliance::Config for Runtime { @@ -1450,8 +1448,11 @@ impl pallet_alliance::Config for Runtime { type MaxFounders = MaxFounders; type MaxFellows = MaxFellows; type MaxAllies = MaxAllies; - type MaxBlacklistCount = MaxBlacklistCount; - type MaxWebsiteUrlLength = MaxWebsiteUrlLength; + type MaxBlacklistCount = ConstU32<100>; + type MaxWebsiteUrlLength = ConstU32<255>; + type MaxAnnouncementsCount = ConstU32<100>; + type MaxMembersCount = AllianceMaxMembers; + type MaxCandidatesCount = ConstU32<100>; type CandidateDeposit = CandidateDeposit; type WeightInfo = pallet_alliance::weights::SubstrateWeight; } diff --git a/frame/alliance/src/mock.rs b/frame/alliance/src/mock.rs index ffc67b16c1d1a..abdcedc9906a9 100644 --- a/frame/alliance/src/mock.rs +++ b/frame/alliance/src/mock.rs @@ -200,8 +200,6 @@ parameter_types! { pub const MaxFellows: u32 = MaxMembers::get() - MaxFounders::get(); pub const MaxAllies: u32 = 100; pub const CandidateDeposit: u64 = 25; - pub const MaxBlacklistCount: u32 = 100; - pub const MaxWebsiteUrlLength: u32 = 255; } impl Config for Test { type Event = Event; @@ -220,8 +218,11 @@ impl Config for Test { type MaxFounders = MaxFounders; type MaxFellows = MaxFellows; type MaxAllies = MaxAllies; - type MaxBlacklistCount = MaxBlacklistCount; - type MaxWebsiteUrlLength = MaxWebsiteUrlLength; + type MaxBlacklistCount = ConstU32<100>; + type MaxWebsiteUrlLength = ConstU32<255>; + type MaxAnnouncementsCount = ConstU32<100>; + type MaxMembersCount = AllianceMaxMembers; + type MaxCandidatesCount = ConstU32<100>; type CandidateDeposit = CandidateDeposit; type WeightInfo = (); } From a0c097154f8c5777375a2fee35a6fae71551bb79 Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Sat, 2 Apr 2022 20:22:43 +1300 Subject: [PATCH 36/72] fix benchmarks --- frame/alliance/src/benchmarking.rs | 26 +++++++++++++++++++------- frame/alliance/src/mock.rs | 2 +- frame/alliance/src/tests.rs | 9 ++++++--- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/frame/alliance/src/benchmarking.rs b/frame/alliance/src/benchmarking.rs index c8ad4cc37e936..83b7b250bb933 100644 --- a/frame/alliance/src/benchmarking.rs +++ b/frame/alliance/src/benchmarking.rs @@ -21,7 +21,10 @@ use sp_runtime::traits::{Bounded, Hash, StaticLookup}; use sp_std::{mem::size_of, prelude::*}; use frame_benchmarking::{account, benchmarks_instance_pallet}; -use frame_support::traits::{EnsureOrigin, Get, UnfilteredDispatchable}; +use frame_support::{ + bounded_vec, + traits::{EnsureOrigin, Get, UnfilteredDispatchable}, +}; use frame_system::{Pallet as System, RawOrigin as SystemOrigin}; use super::{Call as AllianceCall, Pallet as Alliance, *}; @@ -81,17 +84,19 @@ fn blacklist, I: 'static>(index: u32) -> T::AccountId { } fn set_members, I: 'static>() { - let founders = vec![founder::(1), founder::(2)]; + let founders: BoundedVec<_, T::MaxMembersCount> = + bounded_vec![founder::(1), founder::(2)]; Members::::insert(MemberRole::Founder, founders.clone()); - let fellows = vec![fellow::(1), fellow::(2)]; + let fellows: BoundedVec<_, T::MaxMembersCount> = + bounded_vec![fellow::(1), fellow::(2)]; fellows.iter().for_each(|who| { T::Currency::reserve(&who, T::CandidateDeposit::get()).unwrap(); >::insert(&who, T::CandidateDeposit::get()); }); Members::::insert(MemberRole::Fellow, fellows.clone()); - let allies = vec![ally::(1)]; + let allies: BoundedVec<_, T::MaxMembersCount> = bounded_vec![ally::(1)]; allies.iter().for_each(|who| { T::Currency::reserve(&who, T::CandidateDeposit::get()).unwrap(); >::insert(&who, T::CandidateDeposit::get()); @@ -107,6 +112,7 @@ fn set_candidates, I: 'static>(indexes: Vec) { T::Currency::reserve(&who, T::CandidateDeposit::get()).unwrap(); >::insert(&who, T::CandidateDeposit::get()); }); + let candidates: BoundedVec<_, T::MaxCandidatesCount> = candidates.try_into().unwrap(); Candidates::::put(candidates); } @@ -629,7 +635,8 @@ benchmarks_instance_pallet! { set_members::(); let announcement = announcement(b"hello world"); - Announcements::::put(vec![announcement.clone()]); + let announcements: BoundedVec<_, T::MaxAnnouncementsCount> = bounded_vec![announcement.clone()]; + Announcements::::put(announcements); let call = Call::::remove_announcement { announcement: announcement.clone() }; let origin = T::SuperMajorityOrigin::successful_origin(); @@ -787,7 +794,9 @@ benchmarks_instance_pallet! { set_members::(); let accounts = (0 .. n).map(|i| blacklist::(i)).collect::>(); - let websites = (0 .. n).map(|i| vec![i as u8; l as usize]).collect::>(); + let websites = (0 .. n).map(|i| -> BoundedVec { + bounded_vec![i as u8; l as usize] + }).collect::>(); let mut blacklist = Vec::with_capacity(accounts.len() + websites.len()); blacklist.extend(accounts.into_iter().map(BlacklistItem::AccountId)); @@ -808,10 +817,13 @@ benchmarks_instance_pallet! { let mut accounts = (0 .. n).map(|i| blacklist::(i)).collect::>(); accounts.sort(); + let accounts: BoundedVec<_, T::MaxBlacklistCount> = accounts.try_into().unwrap(); AccountBlacklist::::put(accounts.clone()); - let mut websites = (0 .. n).map(|i| vec![i as u8; l as usize]).collect::>(); + let mut websites = (0 .. n).map(|i| -> BoundedVec<_, T::MaxWebsiteUrlLength> + { bounded_vec![i as u8; l as usize] }).collect::>(); websites.sort(); + let websites: BoundedVec<_, T::MaxBlacklistCount> = websites.try_into().unwrap(); WebsiteBlacklist::::put(websites.clone()); let mut blacklist = Vec::with_capacity(accounts.len() + websites.len()); diff --git a/frame/alliance/src/mock.rs b/frame/alliance/src/mock.rs index abdcedc9906a9..0b741e1afde9c 100644 --- a/frame/alliance/src/mock.rs +++ b/frame/alliance/src/mock.rs @@ -221,7 +221,7 @@ impl Config for Test { type MaxBlacklistCount = ConstU32<100>; type MaxWebsiteUrlLength = ConstU32<255>; type MaxAnnouncementsCount = ConstU32<100>; - type MaxMembersCount = AllianceMaxMembers; + type MaxMembersCount = MaxMembers; type MaxCandidatesCount = ConstU32<100>; type CandidateDeposit = CandidateDeposit; type WeightInfo = (); diff --git a/frame/alliance/src/tests.rs b/frame/alliance/src/tests.rs index 3e012443959f4..dfa5efe040bff 100644 --- a/frame/alliance/src/tests.rs +++ b/frame/alliance/src/tests.rs @@ -481,10 +481,13 @@ fn add_blacklist_works() { new_test_ext().execute_with(|| { assert_ok!(Alliance::add_blacklist( Origin::signed(1), - vec![BlacklistItem::AccountId(3), BlacklistItem::Website("abc".as_bytes().to_vec())] + vec![ + BlacklistItem::AccountId(3), + BlacklistItem::Website("abc".as_bytes().to_vec().try_into().unwrap()) + ] )); - assert_eq!(Alliance::account_blacklist(), vec![3]); - assert_eq!(Alliance::website_blacklist(), vec!["abc".as_bytes().to_vec()]); + assert_eq!(Alliance::account_blacklist().into_inner(), vec![3]); + assert_eq!(Alliance::website_blacklist().into_inner(), vec!["abc".as_bytes().to_vec()]); assert_noop!( Alliance::add_blacklist(Origin::signed(1), vec![BlacklistItem::AccountId(3)]), From 31f846bd677e3d2eaab1075d6fe530a586e466d1 Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Sun, 3 Apr 2022 20:25:53 +1200 Subject: [PATCH 37/72] fix --- frame/alliance/src/benchmarking.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/frame/alliance/src/benchmarking.rs b/frame/alliance/src/benchmarking.rs index 83b7b250bb933..edd7853638cc7 100644 --- a/frame/alliance/src/benchmarking.rs +++ b/frame/alliance/src/benchmarking.rs @@ -22,7 +22,6 @@ use sp_std::{mem::size_of, prelude::*}; use frame_benchmarking::{account, benchmarks_instance_pallet}; use frame_support::{ - bounded_vec, traits::{EnsureOrigin, Get, UnfilteredDispatchable}, }; use frame_system::{Pallet as System, RawOrigin as SystemOrigin}; @@ -85,18 +84,18 @@ fn blacklist, I: 'static>(index: u32) -> T::AccountId { fn set_members, I: 'static>() { let founders: BoundedVec<_, T::MaxMembersCount> = - bounded_vec![founder::(1), founder::(2)]; + BoundedVec::try_from(vec![founder::(1), founder::(2)]).unwrap(); Members::::insert(MemberRole::Founder, founders.clone()); let fellows: BoundedVec<_, T::MaxMembersCount> = - bounded_vec![fellow::(1), fellow::(2)]; + BoundedVec::try_from(vec![fellow::(1), fellow::(2)]).unwrap(); fellows.iter().for_each(|who| { T::Currency::reserve(&who, T::CandidateDeposit::get()).unwrap(); >::insert(&who, T::CandidateDeposit::get()); }); Members::::insert(MemberRole::Fellow, fellows.clone()); - let allies: BoundedVec<_, T::MaxMembersCount> = bounded_vec![ally::(1)]; + let allies: BoundedVec<_, T::MaxMembersCount> = BoundedVec::try_from(vec![ally::(1)]).unwrap(); allies.iter().for_each(|who| { T::Currency::reserve(&who, T::CandidateDeposit::get()).unwrap(); >::insert(&who, T::CandidateDeposit::get()); @@ -635,7 +634,7 @@ benchmarks_instance_pallet! { set_members::(); let announcement = announcement(b"hello world"); - let announcements: BoundedVec<_, T::MaxAnnouncementsCount> = bounded_vec![announcement.clone()]; + let announcements: BoundedVec<_, T::MaxAnnouncementsCount> = BoundedVec::try_from(vec![announcement.clone()]).unwrap(); Announcements::::put(announcements); let call = Call::::remove_announcement { announcement: announcement.clone() }; @@ -795,7 +794,7 @@ benchmarks_instance_pallet! { let accounts = (0 .. n).map(|i| blacklist::(i)).collect::>(); let websites = (0 .. n).map(|i| -> BoundedVec { - bounded_vec![i as u8; l as usize] + BoundedVec::try_from(vec![i as u8; l as usize]).unwrap() }).collect::>(); let mut blacklist = Vec::with_capacity(accounts.len() + websites.len()); @@ -821,7 +820,7 @@ benchmarks_instance_pallet! { AccountBlacklist::::put(accounts.clone()); let mut websites = (0 .. n).map(|i| -> BoundedVec<_, T::MaxWebsiteUrlLength> - { bounded_vec![i as u8; l as usize] }).collect::>(); + { BoundedVec::try_from(vec![i as u8; l as usize]).unwrap() }).collect::>(); websites.sort(); let websites: BoundedVec<_, T::MaxBlacklistCount> = websites.try_into().unwrap(); WebsiteBlacklist::::put(websites.clone()); From 616646beeaa97932610704ccf4e372bb41657953 Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Sun, 3 Apr 2022 20:33:45 +1200 Subject: [PATCH 38/72] fmt --- frame/alliance/src/benchmarking.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/frame/alliance/src/benchmarking.rs b/frame/alliance/src/benchmarking.rs index edd7853638cc7..de6cc98479d9a 100644 --- a/frame/alliance/src/benchmarking.rs +++ b/frame/alliance/src/benchmarking.rs @@ -21,9 +21,7 @@ use sp_runtime::traits::{Bounded, Hash, StaticLookup}; use sp_std::{mem::size_of, prelude::*}; use frame_benchmarking::{account, benchmarks_instance_pallet}; -use frame_support::{ - traits::{EnsureOrigin, Get, UnfilteredDispatchable}, -}; +use frame_support::traits::{EnsureOrigin, Get, UnfilteredDispatchable}; use frame_system::{Pallet as System, RawOrigin as SystemOrigin}; use super::{Call as AllianceCall, Pallet as Alliance, *}; @@ -95,7 +93,8 @@ fn set_members, I: 'static>() { }); Members::::insert(MemberRole::Fellow, fellows.clone()); - let allies: BoundedVec<_, T::MaxMembersCount> = BoundedVec::try_from(vec![ally::(1)]).unwrap(); + let allies: BoundedVec<_, T::MaxMembersCount> = + BoundedVec::try_from(vec![ally::(1)]).unwrap(); allies.iter().for_each(|who| { T::Currency::reserve(&who, T::CandidateDeposit::get()).unwrap(); >::insert(&who, T::CandidateDeposit::get()); From 02aaf4ea4b01009fa83cd7a9861dfb8f7da7d6cb Mon Sep 17 00:00:00 2001 From: Xiliang Chen Date: Tue, 5 Apr 2022 10:44:45 +1200 Subject: [PATCH 39/72] Apply suggestions from code review Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- frame/alliance/src/lib.rs | 5 +++-- frame/alliance/src/types.rs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index 2b35c5a450df0..2138037daba62 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. +// Copyright (C) 2022 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); @@ -159,6 +159,7 @@ impl IdentityVerifier for () { None } } + pub trait ProposalProvider { fn propose_proposal( who: AccountId, @@ -522,7 +523,7 @@ pub mod pallet { T::MaxFellows::get(), // Y T::MaxProposals::get(), // P2 ), - DispatchClass::Operational + DispatchClass::Normal ))] pub fn propose( origin: OriginFor, diff --git a/frame/alliance/src/types.rs b/frame/alliance/src/types.rs index 35f112507b3a6..0bb8cc73613ad 100644 --- a/frame/alliance/src/types.rs +++ b/frame/alliance/src/types.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd. +// Copyright (C) 2022 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); From 82f84d15d1acf85d3adb5a7e3bdfa2c685635f46 Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Fri, 8 Apr 2022 14:01:20 +1200 Subject: [PATCH 40/72] improvements --- frame/alliance/Cargo.toml | 2 +- frame/alliance/src/lib.rs | 20 ++++++-------------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/frame/alliance/Cargo.toml b/frame/alliance/Cargo.toml index 771ec867569f3..cbb60dbd35064 100644 --- a/frame/alliance/Cargo.toml +++ b/frame/alliance/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" -description = "Collective system: Members of a set of account IDs can make their collective feelings known through dispatched calls from one of two specialized origins." +description = "The Alliance Pallet provides a DAO to form an industry group." readme = "README.md" [package.metadata.docs.rs] diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index 2138037daba62..a86cb64c24325 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -132,9 +132,9 @@ pub type ProposalIndex = u32; type UrlOf = BoundedVec>::MaxWebsiteUrlLength>; -type BalanceOf = +type BalanceOf = <>::Currency as Currency<::AccountId>>::Balance; -type NegativeImbalanceOf = <>::Currency as Currency< +type NegativeImbalanceOf = <>::Currency as Currency< ::AccountId, >>::NegativeImbalance; @@ -412,14 +412,8 @@ pub mod pallet { #[pallet::genesis_build] impl, I: 'static> GenesisBuild for GenesisConfig { fn build(&self) { - #[cfg(not(test))] - { - for m in self.founders.iter().chain(self.fellows.iter()).chain(self.allies.iter()) { - assert!( - Pallet::::has_identity(m).is_ok(), - "Member does not set identity!" - ); - } + for m in self.founders.iter().chain(self.fellows.iter()).chain(self.allies.iter()) { + assert!(Pallet::::has_identity(m).is_ok(), "Member does not set identity!"); } if !self.founders.is_empty() { @@ -1103,10 +1097,8 @@ impl, I: 'static> Pallet { } fn has_identity(who: &T::AccountId) -> DispatchResult { - const IDENTITY_FIELD_DISPLAY: u64 = - 0b0000000000000000000000000000000000000000000000000000000000000001; - const IDENTITY_FIELD_WEB: u64 = - 0b0000000000000000000000000000000000000000000000000000000000000100; + const IDENTITY_FIELD_DISPLAY: u64 = IdentityField::Display as u64; + const IDENTITY_FIELD_WEB: u64 = IdentityField::Web as u64; let judgement = |who: &T::AccountId| -> DispatchResult { ensure!( From 551e830cb6a654e78406fb810c9fbbada6e56d4c Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Fri, 8 Apr 2022 15:15:41 +1200 Subject: [PATCH 41/72] fix --- frame/alliance/Cargo.toml | 6 +++--- frame/alliance/src/lib.rs | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/frame/alliance/Cargo.toml b/frame/alliance/Cargo.toml index cbb60dbd35064..468bd11736438 100644 --- a/frame/alliance/Cargo.toml +++ b/frame/alliance/Cargo.toml @@ -28,15 +28,14 @@ sp-runtime = { version = "6.0.0", default-features = false, path = "../../primit frame-benchmarking = { version = "4.0.0-dev", default-features = false, path = "../benchmarking", optional = true } frame-support = { version = "4.0.0-dev", default-features = false, path = "../support" } frame-system = { version = "4.0.0-dev", default-features = false, path = "../system" } -pallet-collective = { version = "4.0.0-dev", path = "../collective", default-features = false, optional = true } -pallet-identity = { version = "4.0.0-dev", path = "../identity", default-features = false, optional = true } + +pallet-identity = { version = "4.0.0-dev", path = "../identity", default-features = false } [dev-dependencies] hex-literal = "0.3.1" sha2 = "0.10.1" pallet-balances = { version = "4.0.0-dev", path = "../balances" } pallet-collective = { version = "4.0.0-dev", path = "../collective" } -pallet-identity = { version = "4.0.0-dev", path = "../identity" } [features] default = ["std"] @@ -50,6 +49,7 @@ std = [ "sp-runtime/std", "frame-support/std", "frame-system/std", + "pallet-identity/std", ] runtime-benchmarks = [ "hex", diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index a86cb64c24325..c04871eee7b53 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -122,6 +122,7 @@ use frame_support::{ }, weights::{Pays, Weight}, }; +use pallet_identity::IdentityField; pub use pallet::*; pub use types::*; From 451396e5edc645e0ca3c68643817ca948f1b7ebe Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Sat, 9 Apr 2022 08:44:15 +0200 Subject: [PATCH 42/72] update docs --- frame/alliance/src/lib.rs | 218 +++++++++++++++++++------------------- 1 file changed, 111 insertions(+), 107 deletions(-) diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index c04871eee7b53..847634551e099 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -17,44 +17,39 @@ //! # Alliance Pallet //! -//! The Alliance Pallet provides a DAO to form an industry group that does two main things: +//! The Alliance Pallet provides a collective that curates a blacklist of accounts and URLs, +//! presumably agreed by the voting members to be bad actors. The alliance //! -//! - provide a set of ethics against bad behaviors. -//! - provide recognition and influence for those teams that contribute something back to the +//! - provides a set of ethics against bad behavior, and +//! - provides recognition and influence for those teams that contribute something back to the //! ecosystem. //! //! ## Overview //! -//! The Alliance first needs to initialize the Founders with sudo permissions. +//! The network initializes the Alliance via a Root call. //! After that, anyone with an approved identity and website can apply to become a Candidate. //! Members will initiate a motion to determine whether a Candidate can join the Alliance or not. -//! The motion requires the approval of over 2/3 majority. -//! The Alliance can also maintain a blacklist list about accounts and websites. -//! Members can also vote to update the alliance's rule and make announcements. +//! The motion requires the approval of the `SuperMajorityOrigin`. +//! The Alliance can also maintain a blacklist of accounts and websites. +//! Members can also vote to update the Alliance's rule and make announcements. //! //! ### Terminology //! -//! - Rule: The IPFS Hash of the Alliance Rule for the community to read and the alliance members to -//! enforce for the management. -//! -//! - Announcement: An IPFS hash of some content that the Alliance want to announce. -//! -//! - Member: An account which is already in the group of the Alliance, including three types: -//! Founder, Fellow, Ally. Member can also be kicked by super majority motion or retire by itself. -//! -//! - Founder: An account who is initiated by sudo with normal voting rights for basic motions and +//! - Rule: The IPFS CID (hash) of the Alliance rules for the community to read and the Alliance +//! members to enforce. Similar to a Code of Conduct. +//! - Announcement: An IPFS CID of some content that the Alliance want to announce. +//! - Member: An account that is already in the group of the Alliance, including three types: +//! Founder, Fellow, or Ally. A member can also be kicked by `SuperMajorityOrigin` or retire by +//! itself. +//! - Founder: An account who is initiated by Root with normal voting rights for basic motions and //! special veto rights for rule change and ally elevation motions. -//! -//! - Fellow: An account who is elevated from Ally by Founders and other Fellows from Ally. -//! +//! - Fellow: An account who is elevated from Ally by Founders and other Fellows. //! - Ally: An account who is approved by Founders and Fellows from Candidate. An Ally doesn't have //! voting rights. -//! //! - Candidate: An account who is trying to become a member. The applicant should already have an //! approved identity with website. The application should be submitted by the account itself with -//! some token as deposit, or be nominated by an existing Founder or Fellow for free. -//! -//! - Blacklist: A list of bad websites and addresses, and can be added or removed items by Founders +//! some deposit, or be nominated by an existing Founder or Fellow for free. +//! - Blacklist: A list of bad websites and addresses, items can be added or removed by Founders //! and Fellows. //! //! ## Interface @@ -62,30 +57,34 @@ //! ### Dispatchable Functions //! //! #### For General Users +//! //! - `submit_candidacy` - Submit the application to become a candidate with deposit. //! //! #### For Members (All) -//! - `retire` - Member retire to out of the Alliance and release its deposit. +//! +//! - `retire` - Retire from the Alliance and release the caller's deposit. //! //! #### For Members (Founders/Fellows) //! //! - `propose` - Propose a motion. //! - `vote` - Vote on a motion. -//! - `close` - Close a motion with enough votes or expired. -//! - `set_rule` - Initialize or update the alliance's rule by IPFS hash. -//! - `announce` - Make announcement by IPFS hash. +//! - `close` - Close a motion with enough votes or that has expired. +//! - `set_rule` - Initialize or update the Alliance's rule by IPFS CID. +//! - `announce` - Make announcement by IPFS CID. //! - `nominate_candidacy` - Nominate a non-member to become a Candidate for free. //! - `approve_candidate` - Approve a candidate to become an Ally. //! - `reject_candidate` - Reject a candidate and slash its deposit. //! - `elevate_ally` - Approve an ally to become a Fellow. //! - `kick_member` - Kick a member and slash its deposit. -//! - `add_blacklist` - Add some items of account and website in the blacklist. -//! - `remove_blacklist` - Remove some items of account and website from the blacklist. +//! - `add_blacklist` - Add some items, either accounts or websites, to the blacklist. +//! - `remove_blacklist` - Remove some items from the blacklist. //! //! #### For Members (Only Founders) +//! //! - `veto` - Veto on a motion about `set_rule` and `elevate_ally`. //! -//! #### For Super Users +//! #### Root Calls +//! //! - `init_founders` - Initialize the founding members. #![cfg_attr(not(feature = "std"), no_std)] @@ -188,7 +187,7 @@ pub trait ProposalProvider { fn proposal_of(proposal_hash: Hash) -> Option; } -/// The role of members. +/// The various roles that a member can hold. #[derive(Copy, Clone, PartialEq, Eq, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)] pub enum MemberRole { Founder, @@ -196,7 +195,7 @@ pub enum MemberRole { Ally, } -/// The item type of blacklist. +/// The type of item within the blacklist. #[derive(Clone, PartialEq, Eq, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)] pub enum BlacklistItem { AccountId(AccountId), @@ -227,8 +226,7 @@ pub mod pallet { + IsSubType> + IsType<::Call>; - /// Origin from which the next tabled referendum may be forced; this allows for the tabling - /// of a majority-carries referendum. + /// TO RENAME type SuperMajorityOrigin: EnsureOrigin; /// The currency used for deposits. @@ -237,13 +235,13 @@ pub mod pallet { /// What to do with slashed funds. type Slashed: OnUnbalanced>; - /// What to do with genesis voteable members + /// What to do with initial voting members of the Alliance. type InitializeMembers: InitializeMembers; - /// The receiver of the signal for when the voteable members have changed. + /// What to do when a member has been added or removed. type MembershipChanged: ChangeMembers; - /// The identity verifier of alliance member. + /// The identity verifier of an Alliance member. type IdentityVerifier: IdentityVerifier; /// The provider of the proposal operation. @@ -256,44 +254,44 @@ pub mod pallet { /// /// NOTE: /// + Benchmarks will need to be re-run and weights adjusted if this changes. - /// + This pallet assumes that dependents keep to the limit without enforcing it. + /// + This pallet assumes that dependencies keep to the limit without enforcing it. type MaxFounders: Get; /// The maximum number of fellows supported by the pallet. Used for weight estimation. /// /// NOTE: /// + Benchmarks will need to be re-run and weights adjusted if this changes. - /// + This pallet assumes that dependents keep to the limit without enforcing it. + /// + This pallet assumes that dependencies keep to the limit without enforcing it. type MaxFellows: Get; /// The maximum number of allies supported by the pallet. Used for weight estimation. /// /// NOTE: /// + Benchmarks will need to be re-run and weights adjusted if this changes. - /// + This pallet assumes that dependents keep to the limit without enforcing it. + /// + This pallet assumes that dependencies keep to the limit without enforcing it. type MaxAllies: Get; - /// The maximum number of blacklist supported by the pallet. + /// The maximum length of the blacklist supported by the pallet. #[pallet::constant] type MaxBlacklistCount: Get; - /// The maximum length of website url. + /// The maximum length of a website URL. #[pallet::constant] type MaxWebsiteUrlLength: Get; - /// The amount of a deposit required for submitting candidacy. + /// The deposit required for submitting candidacy. #[pallet::constant] type CandidateDeposit: Get>; - /// The maximum numbers of announcements. + /// The maximum number of announcements. #[pallet::constant] type MaxAnnouncementsCount: Get; - /// The maximum numbers of members per member role. + /// The maximum number of members per member role. #[pallet::constant] type MaxMembersCount: Get; - /// The maximum numbers of candidates. + /// The maximum number of candidates. #[pallet::constant] type MaxCandidatesCount: Get; @@ -305,37 +303,37 @@ pub mod pallet { pub enum Error { /// The founders/fellows/allies have already been initialized. MembersAlreadyInitialized, - /// Already be a candidate. + /// Account is already a candidate. AlreadyCandidate, - /// Not be a candidate. + /// Account is not a candidate. NotCandidate, - /// Already be a member. + /// Account is already a member. AlreadyMember, - /// Not be a member. + /// Account is not a member. NotMember, - /// Not be an ally member. + /// Account is not an ally. NotAlly, - /// Not be a founder member. + /// Account is not a founder. NotFounder, - /// Not be a kicking member. + /// TO RENAME NotKickingMember, - /// Not be a votable (founder or fellow) member. + /// Account does not have voting rights. NotVotableMember, - /// Already be an elevated (fellow) member. + /// Account is already an elevated (fellow) member. AlreadyElevated, - /// Already be a blacklist item. + /// Item is already in the blacklist. AlreadyInBlacklist, - /// Not be a blacklist item. + /// Item is not blacklisted. NotInBlacklist, - /// Number of blacklist exceed MaxBlacklist. + /// Length of blacklist exceeds `MaxBlacklist`. TooManyBlacklist, - /// Length of website url exceed MaxWebsiteUrlLength. + /// Length of website URL exceeds `MaxWebsiteUrlLength`. TooLongWebsiteUrl, - /// The member is kicking. + /// TO RENAME KickingMember, /// Balance is insufficient to be a candidate. InsufficientCandidateFunds, - /// The account's identity has not display field and website field. + /// The account's identity does not have display field and website field. WithoutIdentityDisplayAndWebsite, /// The account's identity has no good judgement. WithoutGoodIdentityJudgement, @@ -343,50 +341,50 @@ pub mod pallet { MissingProposalHash, /// The proposal is not vetoable. NotVetoableProposal, - /// The Announcement is not found. + /// The announcement is not found. MissingAnnouncement, - /// Number of members exceed MaxMembersCount. + /// Number of members exceeds `MaxMembersCount`. TooManyMembers, - /// Number of candidates exceed MaxCandidatesCount. + /// Number of candidates exceeds `MaxCandidatesCount`. TooManyCandidates, - /// Number of Announcements exceed MaxAnnouncementsCount. + /// Number of announcements exceeds `MaxAnnouncementsCount`. TooManyAnnouncements, } #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event, I: 'static = ()> { - /// A new rule has been set. + /// A new rule has been set. // TO RENAME NewRule { rule: Cid }, /// A new announcement has been proposed. NewAnnouncement { announcement: Cid }, - /// A on-chain announcement has been removed. + /// An on-chain announcement has been removed. AnnouncementRemoved { announcement: Cid }, - /// Some accounts have been initialized to members (founders/fellows/allies). + /// Some accounts have been initialized as members (founders/fellows/allies). MembersInitialized { founders: Vec, fellows: Vec, allies: Vec, }, - /// An account has been added as a candidate and lock its deposit. + /// An account has been added as a candidate and reserved its deposit. CandidateAdded { candidate: T::AccountId, nominator: Option, reserved: Option>, }, - /// A proposal has been proposed to approve the candidate. + /// A candidate has been approved as an ally. CandidateApproved { candidate: T::AccountId }, - /// A proposal has been proposed to reject the candidate. + /// A candidate has been rejected and its deposit slashed. CandidateRejected { candidate: T::AccountId }, - /// As an active member, an ally has been elevated to fellow. + /// An ally has been elevated to fellow. AllyElevated { ally: T::AccountId }, /// A member has retired to an ordinary account with its deposit unreserved. MemberRetired { member: T::AccountId, unreserved: Option> }, /// A member has been kicked out to an ordinary account with its deposit slashed. MemberKicked { member: T::AccountId, slashed: Option> }, - /// Accounts or websites have been added into blacklist. + /// Accounts or websites have been added into the blacklist. // TO RENAME BlacklistAdded { items: Vec> }, - /// Accounts or websites have been removed from blacklist. + /// Accounts or websites have been removed from the blacklist. // TO RENAME BlacklistRemoved { items: Vec> }, } @@ -447,37 +445,34 @@ pub mod pallet { } } - /// The IPFS cid of the alliance rule. - /// Founders and fellows can propose a new rule, other founders and fellows make a traditional - /// super-majority votes, vote to determine if the rules take effect. + /// The IPFS CID of the alliance rule. + /// Founders and fellows can propose a new rule with a super-majority. /// /// Any founder has a special one-vote veto right to the rule setting. #[pallet::storage] #[pallet::getter(fn rule)] pub type Rule, I: 'static = ()> = StorageValue<_, Cid, OptionQuery>; - /// The current IPFS cids of the announcements. + /// The current IPFS CIDs of any announcements. #[pallet::storage] #[pallet::getter(fn announcements)] pub type Announcements, I: 'static = ()> = StorageValue<_, BoundedVec, ValueQuery>; - /// Maps member and their candidate deposit. + /// Maps members to their candidacy deposit. #[pallet::storage] #[pallet::getter(fn deposit_of)] pub type DepositOf, I: 'static = ()> = StorageMap<_, Blake2_128Concat, T::AccountId, BalanceOf, OptionQuery>; /// The current set of candidates. - /// If the candidacy is approved by a motion, then it will become an ally member. + /// If a candidate is approved by a motion, then it will become an ally. #[pallet::storage] #[pallet::getter(fn candidates)] pub type Candidates, I: 'static = ()> = StorageValue<_, BoundedVec, ValueQuery>; - /// Maps member type to alliance members, including founder, fellow and ally. - /// Founders and fellows can propose and vote on alliance motions, - /// and ally can only wait to be elevated to fellow. + /// Maps member type to members of each type. #[pallet::storage] #[pallet::getter(fn members)] pub type Members, I: 'static = ()> = StorageMap< @@ -488,13 +483,13 @@ pub mod pallet { ValueQuery, >; - /// The members are being kicked out. They can't retire during the motion. + /// A set of members that are (potentially) being kicked out. They cannot retire until settled. #[pallet::storage] #[pallet::getter(fn kicking_member)] pub type KickingMembers, I: 'static = ()> = StorageMap<_, Blake2_128Concat, T::AccountId, bool, ValueQuery>; - /// The current blacklist of accounts. The accounts can't submit candidacy. + /// The current blacklist of accounts. These accounts cannot submit candidacy. #[pallet::storage] #[pallet::getter(fn account_blacklist)] pub type AccountBlacklist, I: 'static = ()> = @@ -510,7 +505,7 @@ pub mod pallet { impl, I: 'static> Pallet { /// Add a new proposal to be voted on. /// - /// Requires the sender to be founder or fellow. + /// Requires the sender to be a founder or fellow. #[pallet::weight(( T::WeightInfo::propose_proposed( *length_bound, // B @@ -540,7 +535,7 @@ pub mod pallet { /// Add an aye or nay vote for the sender to the given proposal. /// - /// Requires the sender to be founder or fellow. + /// Requires the sender to be a founder or fellow. #[pallet::weight(( T::WeightInfo::vote(T::MaxFounders::get(), T::MaxFellows::get()), DispatchClass::Operational @@ -558,8 +553,8 @@ pub mod pallet { Ok(()) } - /// Disapprove a proposal about set_rule and elevate_ally, close, and remove it from - /// the system, regardless of its current state. + /// Veto a proposal about `set_rule` and `elevate_ally`, close, and remove it from the + /// system, regardless of its current state. /// /// Must be called by a founder. #[pallet::weight(T::WeightInfo::veto(T::MaxProposals::get()))] @@ -578,9 +573,9 @@ pub mod pallet { } } - /// Close a vote that is either approved, disapproved or whose voting period has ended. + /// Close a vote that is either approved, disapproved, or whose voting period has ended. /// - /// Requires the sender to be founder or fellow. + /// Requires the sender to be a founder or fellow. #[pallet::weight(( { let b = *length_bound; @@ -624,9 +619,9 @@ pub mod pallet { Ok(info.into()) } - /// Initialize the founders/fellows/allies. + /// Initialize the founders, fellows, and allies. /// - /// This should only be called once. + /// This should only be called once, and must be called by the Root origin. #[pallet::weight(T::WeightInfo::init_members( T::MaxFounders::get(), T::MaxFellows::get(), @@ -685,7 +680,7 @@ pub mod pallet { Ok(()) } - /// Set a new IPFS cid to the alliance rule. + /// Set a new IPFS CID to the alliance rule. #[pallet::weight(T::WeightInfo::set_rule())] pub fn set_rule(origin: OriginFor, rule: Cid) -> DispatchResult { T::SuperMajorityOrigin::ensure_origin(origin)?; @@ -696,7 +691,7 @@ pub mod pallet { Ok(()) } - /// Make a new announcement by a new IPFS cid about the alliance issues. + /// Make an announcement of a new IPFS CID about alliance issues. #[pallet::weight(T::WeightInfo::announce())] pub fn announce(origin: OriginFor, announcement: Cid) -> DispatchResult { T::SuperMajorityOrigin::ensure_origin(origin)?; @@ -711,7 +706,7 @@ pub mod pallet { Ok(()) } - /// Remove the announcement. + /// Remove an announcement. #[pallet::weight(T::WeightInfo::remove_announcement())] pub fn remove_announcement(origin: OriginFor, announcement: Cid) -> DispatchResult { T::SuperMajorityOrigin::ensure_origin(origin)?; @@ -728,7 +723,7 @@ pub mod pallet { Ok(()) } - /// Submit oneself for candidacy. A fixed amount of deposit is recorded. + /// Submit oneself for candidacy. A fixed deposit is reserved. #[pallet::weight(T::WeightInfo::submit_candidacy())] pub fn submit_candidacy(origin: OriginFor) -> DispatchResult { let who = ensure_signed(origin)?; @@ -755,7 +750,7 @@ pub mod pallet { Ok(()) } - /// Founder or fellow can nominate someone to join the alliance and become a candidate. + /// A founder or fellow can nominate someone to join the alliance and become a candidate. /// There is no deposit required to the nominator or nominee. #[pallet::weight(T::WeightInfo::nominate_candidacy())] pub fn nominate_candidacy( @@ -801,7 +796,7 @@ pub mod pallet { Ok(()) } - /// Reject a `Candidate` back to an ordinary account. + /// Reject a `Candidate`. This results in a slash of the candidate's deposit. #[pallet::weight(T::WeightInfo::reject_candidate())] pub fn reject_candidate( origin: OriginFor, @@ -839,7 +834,7 @@ pub mod pallet { Ok(()) } - /// As a member, retire and back to an ordinary account and unlock its deposit. + /// As a member, retire from the alliance and unreserve the deposit. #[pallet::weight(T::WeightInfo::retire())] pub fn retire(origin: OriginFor) -> DispatchResult { let who = ensure_signed(origin)?; @@ -856,7 +851,7 @@ pub mod pallet { Ok(()) } - /// Kick a member to ordinary account with its deposit slashed. + /// Kick a member from the alliance and slash its deposit. #[pallet::weight(T::WeightInfo::kick_member())] pub fn kick_member( origin: OriginFor, @@ -876,7 +871,7 @@ pub mod pallet { Ok(()) } - /// Add accounts or websites into blacklist. + /// Add accounts or websites to the blacklist. #[pallet::weight(T::WeightInfo::add_blacklist(infos.len() as u32, T::MaxWebsiteUrlLength::get()))] pub fn add_blacklist( origin: OriginFor, @@ -905,7 +900,7 @@ pub mod pallet { Ok(()) } - /// Remove accounts or websites from blacklist. + /// Remove accounts or websites from the blacklist. #[pallet::weight(>::WeightInfo::remove_blacklist(infos.len() as u32, T::MaxWebsiteUrlLength::get()))] pub fn remove_blacklist( origin: OriginFor, @@ -954,10 +949,12 @@ impl, I: 'static> Pallet { }) } + /// Check if a given role has any members. fn has_member(role: MemberRole) -> bool { Members::::decode_len(role).unwrap_or_default() > 0 } + /// Look up the role, if any, of an account. fn member_role_of(who: &T::AccountId) -> Option { Members::::iter() .find_map(|(r, members)| if members.contains(who) { Some(r) } else { None }) @@ -968,26 +965,32 @@ impl, I: 'static> Pallet { Self::member_role_of(who).is_some() } + /// Check if an account has a given role. pub fn is_member_of(who: &T::AccountId, role: MemberRole) -> bool { Members::::get(role).contains(&who) } + /// Check if an account is a founder. fn is_founder(who: &T::AccountId) -> bool { Self::is_member_of(who, MemberRole::Founder) } + /// Check if an account is a fellow. fn is_fellow(who: &T::AccountId) -> bool { Self::is_member_of(who, MemberRole::Fellow) } + /// Check if an account is an ally. fn is_ally(who: &T::AccountId) -> bool { Self::is_member_of(who, MemberRole::Ally) } + /// Check if a member has voting rights. fn is_votable_member(who: &T::AccountId) -> bool { Self::is_founder(who) || Self::is_fellow(who) } + /// Collect all members who have voting rights into one list. fn votable_member_sorted() -> Vec { let mut founders = Members::::get(MemberRole::Founder).into_inner(); let mut fellows = Members::::get(MemberRole::Fellow).into_inner(); @@ -996,6 +999,7 @@ impl, I: 'static> Pallet { founders.into() } + /// Check if an account's membership is up for consideration. fn is_kicking(who: &T::AccountId) -> bool { >::contains_key(&who) } @@ -1032,7 +1036,7 @@ impl, I: 'static> Pallet { Ok(()) } - /// Check if a user is in blacklist. + /// Check if an item is blacklisted. fn is_blacklist(info: &BlacklistItemOf) -> bool { match info { BlacklistItem::Website(url) => >::get().contains(url), @@ -1040,12 +1044,12 @@ impl, I: 'static> Pallet { } } - /// Check if a user is in account blacklist. + /// Check if a user is blacklisted. fn is_account_blacklist(who: &T::AccountId) -> bool { >::get().contains(who) } - /// Add a identity info to the blacklist set. + /// Add identity info to the blacklist set. fn do_add_blacklist( new_accounts: &mut Vec, new_webs: &mut Vec>, @@ -1070,7 +1074,7 @@ impl, I: 'static> Pallet { Ok(()) } - /// Remove a identity info from the blacklist. + /// Remove identity info from the blacklist. fn do_remove_blacklist( out_accounts: &mut Vec, out_webs: &mut Vec>, From 814d5206dd55a2d04a06710ef8ba6973d5666a75 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Sat, 9 Apr 2022 09:29:12 +0200 Subject: [PATCH 43/72] rename events, errors, and functions --- frame/alliance/README.md | 86 ++++++++--------- frame/alliance/src/benchmarking.rs | 10 +- frame/alliance/src/lib.rs | 149 +++++++++++++++-------------- frame/alliance/src/tests.rs | 34 +++---- frame/alliance/src/weights.rs | 18 ++-- 5 files changed, 150 insertions(+), 147 deletions(-) diff --git a/frame/alliance/README.md b/frame/alliance/README.md index fb74b07201370..7fabd1df18577 100644 --- a/frame/alliance/README.md +++ b/frame/alliance/README.md @@ -1,74 +1,70 @@ # Alliance Pallet -The Alliance Pallet provides a DAO to form an industry group that does two main things: +The Alliance Pallet provides a collective that curates a blacklist of accounts and URLs, +presumably agreed by the voting members to be bad actors. The alliance -- provide a set of ethics against bad behaviors. -- provide recognition and influence for those teams that contribute something back to the ecosystem. +- provides a set of ethics against bad behavior, and +- provides recognition and influence for those teams that contribute something back to the + ecosystem. ## Overview -The Alliance first needs to initialize the Founders with sudo permissions. -After that, anyone with an approved identity and website can apply to become a Candidate. -Members will initiate a motion to determine whether a Candidate can join the Alliance or not. -The motion requires the approval of over 2/3 majority. -The Alliance can also maintain a blacklist list about accounts and websites. -Members can also vote to update the alliance's rule and make announcements. +The network initializes the Alliance via a Root call. After that, anyone with an approved +identity and website can apply to become a Candidate. Members will initiate a motion to +determine whether a Candidate can join the Alliance or not. The motion requires the approval of +the `MembershipManager` origin. The Alliance can also maintain a blacklist of accounts and +websites. Members can also vote to update the Alliance's rule and make announcements. ### Terminology -- Rule: The IPFS Hash of the Alliance Rule for the community to read - and the alliance members to enforce for the management. - -- Announcement: An IPFS hash of some content that the Alliance want to announce. - -- Member: An account which is already in the group of the Alliance, - including three types: Founder, Fellow, Ally. - Member can also be kicked by super majority motion or retire by itself. - -- Founder: An account who is initiated by sudo with normal voting rights for basic motions - and special veto rights for rule change and ally elevation motions. - -- Fellow: An account who is elevated from Ally by Founders and other Fellows from Ally. - -- Ally: An account who is approved by Founders and Fellows from Candidate. - An Ally doesn't have voting rights. - -- Candidate: An account who is trying to become a member. - The applicant should already have an approved identity with website. - The application should be submitted by the account itself with some token as deposit, - or be nominated by an existing Founder or Fellow for free. - -- Blacklist: A list of bad websites and addresses, and can be added or removed items by Founders and Fellows. +- Rule: The IPFS CID (hash) of the Alliance rules for the community to read and the Alliance + members to enforce. Similar to a Code of Conduct. +- Announcement: An IPFS CID of some content that the Alliance want to announce. +- Member: An account that is already in the group of the Alliance, including three types: + Founder, Fellow, or Ally. A member can also be kicked by the `MembershipManager` origin or + retire by itself. +- Founder: An account who is initiated by Root with normal voting rights for basic motions and + special veto rights for rule change and ally elevation motions. +- Fellow: An account who is elevated from Ally by Founders and other Fellows. +- Ally: An account who is approved by Founders and Fellows from Candidate. An Ally doesn't have + voting rights. +- Candidate: An account who is trying to become a member. The applicant should already have an + approved identity with website. The application should be submitted by the account itself with + some deposit, or be nominated by an existing Founder or Fellow for free. +- Blacklist: A list of bad websites and addresses, items can be added or removed by Founders + and Fellows. ## Interface ### Dispatchable Functions #### For General Users + - `submit_candidacy` - Submit the application to become a candidate with deposit. #### For Members (All) -- `retire` - Member retire to out of the Alliance and release its deposit. -#### For Members (Founders/Fellows) +- `retire` - Retire from the Alliance and release the caller's deposit. + +#### For Members (Founders/Fellows) - `propose` - Propose a motion. -- `vote` - Vote on a motion. -- `close` - Close a motion with enough votes or expired. -- `set_rule` - Initialize or update the alliance's rule by IPFS hash. -- `announce` - Make announcement by IPFS hash. -- `nominate_candidacy` - Nominate a non-member to become a Candidate for free. +- `vote` - Vote on a motion. +- `close` - Close a motion with enough votes or that has expired. +- `set_rule` - Initialize or update the Alliance's rule by IPFS CID. +- `announce` - Make announcement by IPFS CID. +- `nominate_candidate` - Nominate a non-member to become a Candidate for free. - `approve_candidate` - Approve a candidate to become an Ally. - `reject_candidate` - Reject a candidate and slash its deposit. - `elevate_ally` - Approve an ally to become a Fellow. -- `kick_member` - Kick a member and slash its deposit. -- `add_blacklist` - Add some items of account and website in the blacklist. -- `remove_blacklist` - Remove some items of account and website from the blacklist. +- `kick_member` - Kick a member and slash its deposit. +- `add_blacklist_items` - Add some items, either accounts or websites, to the blacklist. +- `remove_blacklist_items` - Remove some items from the blacklist. #### For Members (Only Founders) + - `veto` - Veto on a motion about `set_rule` and `elevate_ally`. -#### For Super Users -- `init_founders` - Initialize the founding members. +#### Root Calls -License: Apache-2.0 +- `init_founders` - Initialize the founding members. diff --git a/frame/alliance/src/benchmarking.rs b/frame/alliance/src/benchmarking.rs index de6cc98479d9a..e60e6427f111a 100644 --- a/frame/alliance/src/benchmarking.rs +++ b/frame/alliance/src/benchmarking.rs @@ -663,7 +663,7 @@ benchmarks_instance_pallet! { }.into()); } - nominate_candidacy { + nominate_candidate { set_members::(); let founder1 = founder::(1); @@ -785,7 +785,7 @@ benchmarks_instance_pallet! { }.into()); } - add_blacklist { + add_blacklist_items { let n in 1 .. T::MaxBlacklistCount::get(); let l in 1 .. T::MaxWebsiteUrlLength::get(); @@ -800,14 +800,14 @@ benchmarks_instance_pallet! { blacklist.extend(accounts.into_iter().map(BlacklistItem::AccountId)); blacklist.extend(websites.into_iter().map(BlacklistItem::Website)); - let call = Call::::add_blacklist { infos: blacklist.clone() }; + let call = Call::::add_blacklist_items { infos: blacklist.clone() }; let origin = T::SuperMajorityOrigin::successful_origin(); }: { call.dispatch_bypass_filter(origin)? } verify { assert_last_event::(Event::BlacklistAdded { items: blacklist }.into()); } - remove_blacklist { + remove_blacklist_items { let n in 1 .. T::MaxBlacklistCount::get(); let l in 1 .. T::MaxWebsiteUrlLength::get(); @@ -828,7 +828,7 @@ benchmarks_instance_pallet! { blacklist.extend(accounts.into_iter().map(BlacklistItem::AccountId)); blacklist.extend(websites.into_iter().map(BlacklistItem::Website)); - let call = Call::::remove_blacklist { infos: blacklist.clone() }; + let call = Call::::remove_blacklist_items { infos: blacklist.clone() }; let origin = T::SuperMajorityOrigin::successful_origin(); }: { call.dispatch_bypass_filter(origin)? } verify { diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index 847634551e099..fadd237c915f0 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -26,12 +26,11 @@ //! //! ## Overview //! -//! The network initializes the Alliance via a Root call. -//! After that, anyone with an approved identity and website can apply to become a Candidate. -//! Members will initiate a motion to determine whether a Candidate can join the Alliance or not. -//! The motion requires the approval of the `SuperMajorityOrigin`. -//! The Alliance can also maintain a blacklist of accounts and websites. -//! Members can also vote to update the Alliance's rule and make announcements. +//! The network initializes the Alliance via a Root call. After that, anyone with an approved +//! identity and website can apply to become a Candidate. Members will initiate a motion to +//! determine whether a Candidate can join the Alliance or not. The motion requires the approval of +//! the `MembershipManager` origin. The Alliance can also maintain a blacklist of accounts and +//! websites. Members can also vote to update the Alliance's rule and make announcements. //! //! ### Terminology //! @@ -39,8 +38,8 @@ //! members to enforce. Similar to a Code of Conduct. //! - Announcement: An IPFS CID of some content that the Alliance want to announce. //! - Member: An account that is already in the group of the Alliance, including three types: -//! Founder, Fellow, or Ally. A member can also be kicked by `SuperMajorityOrigin` or retire by -//! itself. +//! Founder, Fellow, or Ally. A member can also be kicked by the `MembershipManager` origin or +//! retire by itself. //! - Founder: An account who is initiated by Root with normal voting rights for basic motions and //! special veto rights for rule change and ally elevation motions. //! - Fellow: An account who is elevated from Ally by Founders and other Fellows. @@ -71,13 +70,13 @@ //! - `close` - Close a motion with enough votes or that has expired. //! - `set_rule` - Initialize or update the Alliance's rule by IPFS CID. //! - `announce` - Make announcement by IPFS CID. -//! - `nominate_candidacy` - Nominate a non-member to become a Candidate for free. +//! - `nominate_candidate` - Nominate a non-member to become a Candidate for free. //! - `approve_candidate` - Approve a candidate to become an Ally. //! - `reject_candidate` - Reject a candidate and slash its deposit. //! - `elevate_ally` - Approve an ally to become a Fellow. //! - `kick_member` - Kick a member and slash its deposit. -//! - `add_blacklist` - Add some items, either accounts or websites, to the blacklist. -//! - `remove_blacklist` - Remove some items from the blacklist. +//! - `add_blacklist_items` - Add some items, either accounts or websites, to the blacklist. +//! - `remove_blacklist_items` - Remove some items from the blacklist. //! //! #### For Members (Only Founders) //! @@ -226,8 +225,14 @@ pub mod pallet { + IsSubType> + IsType<::Call>; - /// TO RENAME - type SuperMajorityOrigin: EnsureOrigin; + /// Origin for admin-level operations, like setting the Alliance's rules. + type AdminOrigin: EnsureOrigin; + + /// Origin that manages entry and forcible discharge from the Alliance. + type MembershipManager: EnsureOrigin; + + /// Origin for making announcements and adding/removing items from the blacklist. + type AnnouncementOrigin: EnsureOrigin; /// The currency used for deposits. type Currency: ReservableCurrency; @@ -315,10 +320,10 @@ pub mod pallet { NotAlly, /// Account is not a founder. NotFounder, - /// TO RENAME + /// Member is not up for consideration of being kicked. NotKickingMember, /// Account does not have voting rights. - NotVotableMember, + NoVotingRights, /// Account is already an elevated (fellow) member. AlreadyElevated, /// Item is already in the blacklist. @@ -329,8 +334,8 @@ pub mod pallet { TooManyBlacklist, /// Length of website URL exceeds `MaxWebsiteUrlLength`. TooLongWebsiteUrl, - /// TO RENAME - KickingMember, + /// This member is up for being kicked from the Alliance and cannot perform this operation. + MemberBeingKicked, /// Balance is insufficient to be a candidate. InsufficientCandidateFunds, /// The account's identity does not have display field and website field. @@ -354,10 +359,10 @@ pub mod pallet { #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event, I: 'static = ()> { - /// A new rule has been set. // TO RENAME - NewRule { rule: Cid }, + /// A new rule has been set. + NewRuleSet { rule: Cid }, /// A new announcement has been proposed. - NewAnnouncement { announcement: Cid }, + Announced { announcement: Cid }, /// An on-chain announcement has been removed. AnnouncementRemoved { announcement: Cid }, /// Some accounts have been initialized as members (founders/fellows/allies). @@ -382,10 +387,10 @@ pub mod pallet { MemberRetired { member: T::AccountId, unreserved: Option> }, /// A member has been kicked out to an ordinary account with its deposit slashed. MemberKicked { member: T::AccountId, slashed: Option> }, - /// Accounts or websites have been added into the blacklist. // TO RENAME - BlacklistAdded { items: Vec> }, - /// Accounts or websites have been removed from the blacklist. // TO RENAME - BlacklistRemoved { items: Vec> }, + /// Accounts or websites have been added into the blacklist. + BlacklistItemAdded { items: Vec> }, + /// Accounts or websites have been removed from the blacklist. + BlacklistItemRemoved { items: Vec> }, } #[pallet::genesis_config] @@ -483,7 +488,8 @@ pub mod pallet { ValueQuery, >; - /// A set of members that are (potentially) being kicked out. They cannot retire until settled. + /// A set of members that are (potentially) being kicked out. They cannot retire until the + /// motion is settled. #[pallet::storage] #[pallet::getter(fn kicking_member)] pub type KickingMembers, I: 'static = ()> = @@ -522,7 +528,7 @@ pub mod pallet { #[pallet::compact] length_bound: u32, ) -> DispatchResult { let proposor = ensure_signed(origin)?; - ensure!(Self::is_votable_member(&proposor), Error::::NotVotableMember); + ensure!(Self::has_voting_rights(&proposor), Error::::NoVotingRights); if let Some(Call::kick_member { who }) = proposal.is_sub_type() { let strike = T::Lookup::lookup(who.clone())?; @@ -547,7 +553,7 @@ pub mod pallet { approve: bool, ) -> DispatchResult { let who = ensure_signed(origin)?; - ensure!(Self::is_votable_member(&who), Error::::NotVotableMember); + ensure!(Self::has_voting_rights(&who), Error::::NoVotingRights); T::ProposalProvider::vote_proposal(who, proposal, index, approve)?; Ok(()) @@ -599,7 +605,7 @@ pub mod pallet { #[pallet::compact] length_bound: u32, ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; - ensure!(Self::is_votable_member(&who), Error::::NotVotableMember); + ensure!(Self::has_voting_rights(&who), Error::::NoVotingRights); let proposal = T::ProposalProvider::proposal_of(proposal_hash) .ok_or(Error::::MissingProposalHash)?; @@ -683,18 +689,18 @@ pub mod pallet { /// Set a new IPFS CID to the alliance rule. #[pallet::weight(T::WeightInfo::set_rule())] pub fn set_rule(origin: OriginFor, rule: Cid) -> DispatchResult { - T::SuperMajorityOrigin::ensure_origin(origin)?; + T::AdminOrigin::ensure_origin(origin)?; Rule::::put(&rule); - Self::deposit_event(Event::NewRule { rule }); + Self::deposit_event(Event::NewRuleSet { rule }); Ok(()) } /// Make an announcement of a new IPFS CID about alliance issues. #[pallet::weight(T::WeightInfo::announce())] pub fn announce(origin: OriginFor, announcement: Cid) -> DispatchResult { - T::SuperMajorityOrigin::ensure_origin(origin)?; + T::AnnouncementOrigin::ensure_origin(origin)?; let mut announcements = >::get(); announcements @@ -702,14 +708,14 @@ pub mod pallet { .map_err(|_| Error::::TooManyAnnouncements)?; >::put(announcements); - Self::deposit_event(Event::NewAnnouncement { announcement }); + Self::deposit_event(Event::Announced { announcement }); Ok(()) } /// Remove an announcement. #[pallet::weight(T::WeightInfo::remove_announcement())] pub fn remove_announcement(origin: OriginFor, announcement: Cid) -> DispatchResult { - T::SuperMajorityOrigin::ensure_origin(origin)?; + T::AnnouncementOrigin::ensure_origin(origin)?; let mut announcements = >::get(); let pos = announcements @@ -727,7 +733,7 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::submit_candidacy())] pub fn submit_candidacy(origin: OriginFor) -> DispatchResult { let who = ensure_signed(origin)?; - ensure!(!Self::is_account_blacklist(&who), Error::::AlreadyInBlacklist); + ensure!(!Self::account_blacklisted(&who), Error::::AlreadyInBlacklist); ensure!(!Self::is_candidate(&who), Error::::AlreadyCandidate); ensure!(!Self::is_member(&who), Error::::AlreadyMember); // check user self or parent should has verified identity to reuse display name and @@ -752,15 +758,15 @@ pub mod pallet { /// A founder or fellow can nominate someone to join the alliance and become a candidate. /// There is no deposit required to the nominator or nominee. - #[pallet::weight(T::WeightInfo::nominate_candidacy())] - pub fn nominate_candidacy( + #[pallet::weight(T::WeightInfo::nominate_candidate())] + pub fn nominate_candidate( origin: OriginFor, who: ::Source, ) -> DispatchResult { let nominator = ensure_signed(origin)?; - ensure!(Self::is_votable_member(&nominator), Error::::NotVotableMember); + ensure!(Self::has_voting_rights(&nominator), Error::::NoVotingRights); let who = T::Lookup::lookup(who)?; - ensure!(!Self::is_account_blacklist(&who), Error::::AlreadyInBlacklist); + ensure!(!Self::account_blacklisted(&who), Error::::AlreadyInBlacklist); ensure!(!Self::is_candidate(&who), Error::::AlreadyCandidate); ensure!(!Self::is_member(&who), Error::::AlreadyMember); // check user self or parent should has verified identity to reuse display name and @@ -784,7 +790,7 @@ pub mod pallet { origin: OriginFor, candidate: ::Source, ) -> DispatchResult { - T::SuperMajorityOrigin::ensure_origin(origin)?; + T::MembershipManager::ensure_origin(origin)?; let candidate = T::Lookup::lookup(candidate)?; ensure!(Self::is_candidate(&candidate), Error::::NotCandidate); ensure!(!Self::is_member(&candidate), Error::::AlreadyMember); @@ -802,7 +808,7 @@ pub mod pallet { origin: OriginFor, candidate: ::Source, ) -> DispatchResult { - T::SuperMajorityOrigin::ensure_origin(origin)?; + T::MembershipManager::ensure_origin(origin)?; let candidate = T::Lookup::lookup(candidate)?; ensure!(Self::is_candidate(&candidate), Error::::NotCandidate); ensure!(!Self::is_member(&candidate), Error::::AlreadyMember); @@ -822,10 +828,10 @@ pub mod pallet { origin: OriginFor, ally: ::Source, ) -> DispatchResult { - T::SuperMajorityOrigin::ensure_origin(origin)?; + T::MembershipManager::ensure_origin(origin)?; let ally = T::Lookup::lookup(ally)?; ensure!(Self::is_ally(&ally), Error::::NotAlly); - ensure!(!Self::is_votable_member(&ally), Error::::AlreadyElevated); + ensure!(!Self::has_voting_rights(&ally), Error::::AlreadyElevated); Self::remove_member(&ally, MemberRole::Ally)?; Self::add_member(&ally, MemberRole::Fellow)?; @@ -838,7 +844,8 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::retire())] pub fn retire(origin: OriginFor) -> DispatchResult { let who = ensure_signed(origin)?; - ensure!(!Self::is_kicking(&who), Error::::KickingMember); + // A member up for kicking cannot retire. + ensure!(!Self::is_being_kicked(&who), Error::::MemberBeingKicked); let role = Self::member_role_of(&who).ok_or(Error::::NotMember)?; Self::remove_member(&who, role)?; @@ -857,9 +864,9 @@ pub mod pallet { origin: OriginFor, who: ::Source, ) -> DispatchResult { - T::SuperMajorityOrigin::ensure_origin(origin)?; + T::MembershipManager::ensure_origin(origin)?; let member = T::Lookup::lookup(who)?; - ensure!(Self::is_kicking(&member), Error::::NotKickingMember); + ensure!(Self::is_being_kicked(&member), Error::::NotKickingMember); let role = Self::member_role_of(&member).ok_or(Error::::NotMember)?; Self::remove_member(&member, role)?; @@ -872,17 +879,17 @@ pub mod pallet { } /// Add accounts or websites to the blacklist. - #[pallet::weight(T::WeightInfo::add_blacklist(infos.len() as u32, T::MaxWebsiteUrlLength::get()))] - pub fn add_blacklist( + #[pallet::weight(T::WeightInfo::add_blacklist_items(items.len() as u32, T::MaxWebsiteUrlLength::get()))] + pub fn add_blacklist_items( origin: OriginFor, - infos: Vec>, + items: Vec>, ) -> DispatchResult { - T::SuperMajorityOrigin::ensure_origin(origin)?; + T::AnnouncementOrigin::ensure_origin(origin)?; let mut accounts = vec![]; let mut webs = vec![]; - for info in infos.iter() { - ensure!(!Self::is_blacklist(info), Error::::AlreadyInBlacklist); + for info in items.iter() { + ensure!(!Self::is_in_blacklist(info), Error::::AlreadyInBlacklist); match info { BlacklistItem::AccountId(who) => accounts.push(who.clone()), BlacklistItem::Website(url) => { @@ -895,29 +902,29 @@ pub mod pallet { } } - Self::do_add_blacklist(&mut accounts, &mut webs)?; - Self::deposit_event(Event::BlacklistAdded { items: infos }); + Self::do_add_blacklist_items(&mut accounts, &mut webs)?; + Self::deposit_event(Event::BlacklistItemsAdded { items }); Ok(()) } /// Remove accounts or websites from the blacklist. - #[pallet::weight(>::WeightInfo::remove_blacklist(infos.len() as u32, T::MaxWebsiteUrlLength::get()))] - pub fn remove_blacklist( + #[pallet::weight(>::WeightInfo::remove_blacklist_items(items.len() as u32, T::MaxWebsiteUrlLength::get()))] + pub fn remove_blacklist_items( origin: OriginFor, - infos: Vec>, + items: Vec>, ) -> DispatchResult { - T::SuperMajorityOrigin::ensure_origin(origin)?; + T::AnnouncementOrigin::ensure_origin(origin)?; let mut accounts = vec![]; let mut webs = vec![]; - for info in infos.iter() { - ensure!(Self::is_blacklist(info), Error::::NotInBlacklist); + for info in items.iter() { + ensure!(Self::is_in_blacklist(info), Error::::NotInBlacklist); match info { BlacklistItem::AccountId(who) => accounts.push(who.clone()), BlacklistItem::Website(url) => webs.push(url.clone()), } } - Self::do_remove_blacklist(&mut accounts, &mut webs)?; - Self::deposit_event(Event::BlacklistRemoved { items: infos }); + Self::do_remove_blacklist_items(&mut accounts, &mut webs)?; + Self::deposit_event(Event::BlacklistItemsRemoved { items }); Ok(()) } } @@ -986,12 +993,12 @@ impl, I: 'static> Pallet { } /// Check if a member has voting rights. - fn is_votable_member(who: &T::AccountId) -> bool { + fn has_voting_rights(who: &T::AccountId) -> bool { Self::is_founder(who) || Self::is_fellow(who) } /// Collect all members who have voting rights into one list. - fn votable_member_sorted() -> Vec { + fn votable_members_sorted() -> Vec { let mut founders = Members::::get(MemberRole::Founder).into_inner(); let mut fellows = Members::::get(MemberRole::Fellow).into_inner(); founders.append(&mut fellows); @@ -999,8 +1006,8 @@ impl, I: 'static> Pallet { founders.into() } - /// Check if an account's membership is up for consideration. - fn is_kicking(who: &T::AccountId) -> bool { + /// Check if an account's forced removal is up for consideration. + fn is_being_kicked(who: &T::AccountId) -> bool { >::contains_key(&who) } @@ -1015,7 +1022,7 @@ impl, I: 'static> Pallet { })?; if role == MemberRole::Founder || role == MemberRole::Fellow { - let members = Self::votable_member_sorted(); + let members = Self::votable_members_sorted(); T::MembershipChanged::change_members_sorted(&[who.clone()], &[], &members[..]); } Ok(()) @@ -1030,14 +1037,14 @@ impl, I: 'static> Pallet { })?; if role == MemberRole::Founder || role == MemberRole::Fellow { - let members = Self::votable_member_sorted(); + let members = Self::votable_members_sorted(); T::MembershipChanged::change_members_sorted(&[], &[who.clone()], &members[..]); } Ok(()) } /// Check if an item is blacklisted. - fn is_blacklist(info: &BlacklistItemOf) -> bool { + fn is_in_blacklist(info: &BlacklistItemOf) -> bool { match info { BlacklistItem::Website(url) => >::get().contains(url), BlacklistItem::AccountId(who) => >::get().contains(who), @@ -1045,12 +1052,12 @@ impl, I: 'static> Pallet { } /// Check if a user is blacklisted. - fn is_account_blacklist(who: &T::AccountId) -> bool { + fn account_blacklisted(who: &T::AccountId) -> bool { >::get().contains(who) } /// Add identity info to the blacklist set. - fn do_add_blacklist( + fn do_add_blacklist_items( new_accounts: &mut Vec, new_webs: &mut Vec>, ) -> DispatchResult { @@ -1075,7 +1082,7 @@ impl, I: 'static> Pallet { } /// Remove identity info from the blacklist. - fn do_remove_blacklist( + fn do_remove_blacklist_items( out_accounts: &mut Vec, out_webs: &mut Vec>, ) -> DispatchResult { diff --git a/frame/alliance/src/tests.rs b/frame/alliance/src/tests.rs index dfa5efe040bff..b226abe8836a6 100644 --- a/frame/alliance/src/tests.rs +++ b/frame/alliance/src/tests.rs @@ -286,12 +286,12 @@ fn submit_candidacy_works() { ); // check already in blacklist - assert_ok!(Alliance::add_blacklist(Origin::signed(1), vec![BlacklistItem::AccountId(4)])); + assert_ok!(Alliance::add_blacklist_items(Origin::signed(1), vec![BlacklistItem::AccountId(4)])); assert_noop!( Alliance::submit_candidacy(Origin::signed(4)), Error::::AlreadyInBlacklist ); - assert_ok!(Alliance::remove_blacklist( + assert_ok!(Alliance::remove_blacklist_items( Origin::signed(1), vec![BlacklistItem::AccountId(4)] )); @@ -329,39 +329,39 @@ fn submit_candidacy_works() { } #[test] -fn nominate_candidacy_works() { +fn nominate_candidate_works() { new_test_ext().execute_with(|| { // check already member assert_noop!( - Alliance::nominate_candidacy(Origin::signed(1), 2), + Alliance::nominate_candidate(Origin::signed(1), 2), Error::::AlreadyMember ); // only votable member(founder/fellow) have nominate right assert_noop!( - Alliance::nominate_candidacy(Origin::signed(5), 4), + Alliance::nominate_candidate(Origin::signed(5), 4), Error::::NotVotableMember ); // check already in blacklist - assert_ok!(Alliance::add_blacklist(Origin::signed(1), vec![BlacklistItem::AccountId(4)])); + assert_ok!(Alliance::add_blacklist_items(Origin::signed(1), vec![BlacklistItem::AccountId(4)])); assert_noop!( - Alliance::nominate_candidacy(Origin::signed(1), 4), + Alliance::nominate_candidate(Origin::signed(1), 4), Error::::AlreadyInBlacklist ); - assert_ok!(Alliance::remove_blacklist( + assert_ok!(Alliance::remove_blacklist_items( Origin::signed(1), vec![BlacklistItem::AccountId(4)] )); // success to nominate - assert_ok!(Alliance::nominate_candidacy(Origin::signed(1), 4)); + assert_ok!(Alliance::nominate_candidate(Origin::signed(1), 4)); assert_eq!(Alliance::deposit_of(4), None); assert_eq!(Alliance::candidates(), vec![4]); // check already candidate assert_noop!( - Alliance::nominate_candidacy(Origin::signed(1), 4), + Alliance::nominate_candidate(Origin::signed(1), 4), Error::::AlreadyCandidate ); @@ -477,9 +477,9 @@ fn kick_member_works() { } #[test] -fn add_blacklist_works() { +fn add_blacklist_items_works() { new_test_ext().execute_with(|| { - assert_ok!(Alliance::add_blacklist( + assert_ok!(Alliance::add_blacklist_items( Origin::signed(1), vec![ BlacklistItem::AccountId(3), @@ -490,23 +490,23 @@ fn add_blacklist_works() { assert_eq!(Alliance::website_blacklist().into_inner(), vec!["abc".as_bytes().to_vec()]); assert_noop!( - Alliance::add_blacklist(Origin::signed(1), vec![BlacklistItem::AccountId(3)]), + Alliance::add_blacklist_items(Origin::signed(1), vec![BlacklistItem::AccountId(3)]), Error::::AlreadyInBlacklist ); }); } #[test] -fn remove_blacklist_works() { +fn remove_blacklist_items_works() { new_test_ext().execute_with(|| { assert_noop!( - Alliance::remove_blacklist(Origin::signed(1), vec![BlacklistItem::AccountId(3)]), + Alliance::remove_blacklist_items(Origin::signed(1), vec![BlacklistItem::AccountId(3)]), Error::::NotInBlacklist ); - assert_ok!(Alliance::add_blacklist(Origin::signed(1), vec![BlacklistItem::AccountId(3)])); + assert_ok!(Alliance::add_blacklist_items(Origin::signed(1), vec![BlacklistItem::AccountId(3)])); assert_eq!(Alliance::account_blacklist(), vec![3]); - assert_ok!(Alliance::remove_blacklist( + assert_ok!(Alliance::remove_blacklist_items( Origin::signed(1), vec![BlacklistItem::AccountId(3)] )); diff --git a/frame/alliance/src/weights.rs b/frame/alliance/src/weights.rs index 45cca8c980051..dfb497bb9fe1e 100644 --- a/frame/alliance/src/weights.rs +++ b/frame/alliance/src/weights.rs @@ -57,14 +57,14 @@ pub trait WeightInfo { fn announce() -> Weight; fn remove_announcement() -> Weight; fn submit_candidacy() -> Weight; - fn nominate_candidacy() -> Weight; + fn nominate_candidate() -> Weight; fn approve_candidate() -> Weight; fn reject_candidate() -> Weight; fn elevate_ally() -> Weight; fn retire() -> Weight; fn kick_member() -> Weight; - fn add_blacklist(n: u32, l: u32, ) -> Weight; - fn remove_blacklist(n: u32, l: u32, ) -> Weight; + fn add_blacklist_items(n: u32, l: u32, ) -> Weight; + fn remove_blacklist_items(n: u32, l: u32, ) -> Weight; } /// Weights for pallet_alliance using the Substrate node and recommended hardware. @@ -217,7 +217,7 @@ impl WeightInfo for SubstrateWeight { // Storage: Alliance Members (r:4 w:0) // Storage: Alliance AccountBlacklist (r:1 w:0) // Storage: Alliance Candidates (r:1 w:1) - fn nominate_candidacy() -> Weight { + fn nominate_candidate() -> Weight { (44_764_000 as Weight) .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) @@ -273,7 +273,7 @@ impl WeightInfo for SubstrateWeight { } // Storage: Alliance AccountBlacklist (r:1 w:1) // Storage: Alliance WebsiteBlacklist (r:1 w:1) - fn add_blacklist(n: u32, l: u32, ) -> Weight { + fn add_blacklist_items(n: u32, l: u32, ) -> Weight { (0 as Weight) // Standard Error: 16_000 .saturating_add((2_673_000 as Weight).saturating_mul(n as Weight)) @@ -284,7 +284,7 @@ impl WeightInfo for SubstrateWeight { } // Storage: Alliance AccountBlacklist (r:1 w:1) // Storage: Alliance WebsiteBlacklist (r:1 w:1) - fn remove_blacklist(n: u32, l: u32, ) -> Weight { + fn remove_blacklist_items(n: u32, l: u32, ) -> Weight { (0 as Weight) // Standard Error: 343_000 .saturating_add((59_025_000 as Weight).saturating_mul(n as Weight)) @@ -444,7 +444,7 @@ impl WeightInfo for () { // Storage: Alliance Members (r:4 w:0) // Storage: Alliance AccountBlacklist (r:1 w:0) // Storage: Alliance Candidates (r:1 w:1) - fn nominate_candidacy() -> Weight { + fn nominate_candidate() -> Weight { (44_764_000 as Weight) .saturating_add(RocksDbWeight::get().reads(6 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) @@ -500,7 +500,7 @@ impl WeightInfo for () { } // Storage: Alliance AccountBlacklist (r:1 w:1) // Storage: Alliance WebsiteBlacklist (r:1 w:1) - fn add_blacklist(n: u32, l: u32, ) -> Weight { + fn add_blacklist_items(n: u32, l: u32, ) -> Weight { (0 as Weight) // Standard Error: 16_000 .saturating_add((2_673_000 as Weight).saturating_mul(n as Weight)) @@ -511,7 +511,7 @@ impl WeightInfo for () { } // Storage: Alliance AccountBlacklist (r:1 w:1) // Storage: Alliance WebsiteBlacklist (r:1 w:1) - fn remove_blacklist(n: u32, l: u32, ) -> Weight { + fn remove_blacklist_items(n: u32, l: u32, ) -> Weight { (0 as Weight) // Standard Error: 343_000 .saturating_add((59_025_000 as Weight).saturating_mul(n as Weight)) From f90df9e60564ca89ec54eb3112a82c419450c62a Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Sat, 9 Apr 2022 13:20:17 +0200 Subject: [PATCH 44/72] make kicking events clearer --- frame/alliance/src/lib.rs | 22 +++++++++++----------- frame/alliance/src/tests.rs | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index fadd237c915f0..7e8ad73d97392 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -320,8 +320,10 @@ pub mod pallet { NotAlly, /// Account is not a founder. NotFounder, + /// This member is up for being kicked from the Alliance and cannot perform this operation. + UpForKicking, /// Member is not up for consideration of being kicked. - NotKickingMember, + NotUpForKicking, /// Account does not have voting rights. NoVotingRights, /// Account is already an elevated (fellow) member. @@ -334,8 +336,6 @@ pub mod pallet { TooManyBlacklist, /// Length of website URL exceeds `MaxWebsiteUrlLength`. TooLongWebsiteUrl, - /// This member is up for being kicked from the Alliance and cannot perform this operation. - MemberBeingKicked, /// Balance is insufficient to be a candidate. InsufficientCandidateFunds, /// The account's identity does not have display field and website field. @@ -491,8 +491,8 @@ pub mod pallet { /// A set of members that are (potentially) being kicked out. They cannot retire until the /// motion is settled. #[pallet::storage] - #[pallet::getter(fn kicking_member)] - pub type KickingMembers, I: 'static = ()> = + #[pallet::getter(fn up_for_kicking)] + pub type UpForKicking, I: 'static = ()> = StorageMap<_, Blake2_128Concat, T::AccountId, bool, ValueQuery>; /// The current blacklist of accounts. These accounts cannot submit candidacy. @@ -532,7 +532,7 @@ pub mod pallet { if let Some(Call::kick_member { who }) = proposal.is_sub_type() { let strike = T::Lookup::lookup(who.clone())?; - >::insert(strike, true); + >::insert(strike, true); } T::ProposalProvider::propose_proposal(proposor, threshold, proposal, length_bound)?; @@ -619,7 +619,7 @@ pub mod pallet { if Pays::No == info.pays_fee { if let Some(Call::kick_member { who }) = proposal.is_sub_type() { let strike = T::Lookup::lookup(who.clone())?; - >::remove(strike); + >::remove(strike); } } Ok(info.into()) @@ -845,7 +845,7 @@ pub mod pallet { pub fn retire(origin: OriginFor) -> DispatchResult { let who = ensure_signed(origin)?; // A member up for kicking cannot retire. - ensure!(!Self::is_being_kicked(&who), Error::::MemberBeingKicked); + ensure!(!Self::is_up_for_kicking(&who), Error::::UpForKicking); let role = Self::member_role_of(&who).ok_or(Error::::NotMember)?; Self::remove_member(&who, role)?; @@ -866,7 +866,7 @@ pub mod pallet { ) -> DispatchResult { T::MembershipManager::ensure_origin(origin)?; let member = T::Lookup::lookup(who)?; - ensure!(Self::is_being_kicked(&member), Error::::NotKickingMember); + ensure!(Self::is_up_for_kicking(&member), Error::::NotUpForKicking); let role = Self::member_role_of(&member).ok_or(Error::::NotMember)?; Self::remove_member(&member, role)?; @@ -1007,8 +1007,8 @@ impl, I: 'static> Pallet { } /// Check if an account's forced removal is up for consideration. - fn is_being_kicked(who: &T::AccountId) -> bool { - >::contains_key(&who) + fn is_up_for_kicking(who: &T::AccountId) -> bool { + >::contains_key(&who) } /// Add a user to the sorted alliance member set. diff --git a/frame/alliance/src/tests.rs b/frame/alliance/src/tests.rs index b226abe8836a6..73c41dc1e5f34 100644 --- a/frame/alliance/src/tests.rs +++ b/frame/alliance/src/tests.rs @@ -457,7 +457,7 @@ fn kick_member_works() { new_test_ext().execute_with(|| { assert_noop!( Alliance::kick_member(Origin::signed(1), 2), - Error::::NotKickingMember + Error::::NotUpForKicking ); let proposal = make_kick_member_proposal(2); @@ -468,7 +468,7 @@ fn kick_member_works() { Box::new(proposal.clone()), proposal_len )); - assert_eq!(Alliance::kicking_member(2), true); + assert_eq!(Alliance::up_for_kicking(2), true); assert_eq!(Alliance::members(MemberRole::Founder), vec![1, 2]); assert_ok!(Alliance::kick_member(Origin::signed(1), 2)); From 35d50b9b8b902e2d2a9d6a439f6940dd89dbb02a Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Sun, 10 Apr 2022 17:41:59 +1200 Subject: [PATCH 45/72] fix --- frame/alliance/src/lib.rs | 25 ++++++++----------------- frame/alliance/src/tests.rs | 15 ++++++++++++--- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index 7e8ad73d97392..ffd59a6977985 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -48,8 +48,8 @@ //! - Candidate: An account who is trying to become a member. The applicant should already have an //! approved identity with website. The application should be submitted by the account itself with //! some deposit, or be nominated by an existing Founder or Fellow for free. -//! - Blacklist: A list of bad websites and addresses, items can be added or removed by Founders -//! and Fellows. +//! - Blacklist: A list of bad websites and addresses, items can be added or removed by Founders and +//! Fellows. //! //! ## Interface //! @@ -118,7 +118,7 @@ use frame_support::{ ChangeMembers, Currency, Get, InitializeMembers, IsSubType, OnUnbalanced, ReservableCurrency, }, - weights::{Pays, Weight}, + weights::Weight, }; use pallet_identity::IdentityField; @@ -322,8 +322,6 @@ pub mod pallet { NotFounder, /// This member is up for being kicked from the Alliance and cannot perform this operation. UpForKicking, - /// Member is not up for consideration of being kicked. - NotUpForKicking, /// Account does not have voting rights. NoVotingRights, /// Account is already an elevated (fellow) member. @@ -388,9 +386,9 @@ pub mod pallet { /// A member has been kicked out to an ordinary account with its deposit slashed. MemberKicked { member: T::AccountId, slashed: Option> }, /// Accounts or websites have been added into the blacklist. - BlacklistItemAdded { items: Vec> }, + BlacklistItemsAdded { items: Vec> }, /// Accounts or websites have been removed from the blacklist. - BlacklistItemRemoved { items: Vec> }, + BlacklistItemsRemoved { items: Vec> }, } #[pallet::genesis_config] @@ -607,21 +605,12 @@ pub mod pallet { let who = ensure_signed(origin)?; ensure!(Self::has_voting_rights(&who), Error::::NoVotingRights); - let proposal = T::ProposalProvider::proposal_of(proposal_hash) - .ok_or(Error::::MissingProposalHash)?; - let info = T::ProposalProvider::close_proposal( proposal_hash, index, proposal_weight_bound, length_bound, )?; - if Pays::No == info.pays_fee { - if let Some(Call::kick_member { who }) = proposal.is_sub_type() { - let strike = T::Lookup::lookup(who.clone())?; - >::remove(strike); - } - } Ok(info.into()) } @@ -866,7 +855,6 @@ pub mod pallet { ) -> DispatchResult { T::MembershipManager::ensure_origin(origin)?; let member = T::Lookup::lookup(who)?; - ensure!(Self::is_up_for_kicking(&member), Error::::NotUpForKicking); let role = Self::member_role_of(&member).ok_or(Error::::NotMember)?; Self::remove_member(&member, role)?; @@ -874,6 +862,9 @@ pub mod pallet { if let Some(deposit) = deposit { T::Slashed::on_unbalanced(T::Currency::slash_reserved(&member, deposit).0); } + + >::remove(&member); + Self::deposit_event(Event::MemberKicked { member, slashed: deposit }); Ok(()) } diff --git a/frame/alliance/src/tests.rs b/frame/alliance/src/tests.rs index 73c41dc1e5f34..b5e65a4eca5a4 100644 --- a/frame/alliance/src/tests.rs +++ b/frame/alliance/src/tests.rs @@ -286,7 +286,10 @@ fn submit_candidacy_works() { ); // check already in blacklist - assert_ok!(Alliance::add_blacklist_items(Origin::signed(1), vec![BlacklistItem::AccountId(4)])); + assert_ok!(Alliance::add_blacklist_items( + Origin::signed(1), + vec![BlacklistItem::AccountId(4)] + )); assert_noop!( Alliance::submit_candidacy(Origin::signed(4)), Error::::AlreadyInBlacklist @@ -344,7 +347,10 @@ fn nominate_candidate_works() { ); // check already in blacklist - assert_ok!(Alliance::add_blacklist_items(Origin::signed(1), vec![BlacklistItem::AccountId(4)])); + assert_ok!(Alliance::add_blacklist_items( + Origin::signed(1), + vec![BlacklistItem::AccountId(4)] + )); assert_noop!( Alliance::nominate_candidate(Origin::signed(1), 4), Error::::AlreadyInBlacklist @@ -504,7 +510,10 @@ fn remove_blacklist_items_works() { Error::::NotInBlacklist ); - assert_ok!(Alliance::add_blacklist_items(Origin::signed(1), vec![BlacklistItem::AccountId(3)])); + assert_ok!(Alliance::add_blacklist_items( + Origin::signed(1), + vec![BlacklistItem::AccountId(3)] + )); assert_eq!(Alliance::account_blacklist(), vec![3]); assert_ok!(Alliance::remove_blacklist_items( Origin::signed(1), From e024c73af70996a0bce45c4edd312e179825028b Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Sun, 10 Apr 2022 18:23:16 +1200 Subject: [PATCH 46/72] fix tests --- frame/alliance/src/mock.rs | 4 +++- frame/alliance/src/tests.rs | 17 ++++++----------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/frame/alliance/src/mock.rs b/frame/alliance/src/mock.rs index 0b741e1afde9c..ec09f00ba784f 100644 --- a/frame/alliance/src/mock.rs +++ b/frame/alliance/src/mock.rs @@ -204,7 +204,9 @@ parameter_types! { impl Config for Test { type Event = Event; type Proposal = Call; - type SuperMajorityOrigin = EnsureSignedBy; + type AdminOrigin = EnsureSignedBy; + type MembershipManager = EnsureSignedBy; + type AnnouncementOrigin = EnsureSignedBy; type Currency = Balances; type Slashed = (); type InitializeMembers = AllianceMotion; diff --git a/frame/alliance/src/tests.rs b/frame/alliance/src/tests.rs index b5e65a4eca5a4..830d8142235d6 100644 --- a/frame/alliance/src/tests.rs +++ b/frame/alliance/src/tests.rs @@ -37,7 +37,7 @@ fn propose_works() { // only votable member can propose proposal, 4 is ally not have vote rights assert_noop!( Alliance::propose(Origin::signed(4), 3, Box::new(proposal.clone()), proposal_len), - Error::::NotVotableMember + Error::::NoVotingRights ); assert_ok!(Alliance::propose( @@ -239,7 +239,7 @@ fn set_rule_works() { assert_ok!(Alliance::set_rule(Origin::signed(1), cid.clone())); assert_eq!(Alliance::rule(), Some(cid.clone())); - System::assert_last_event(mock::Event::Alliance(crate::Event::NewRule { rule: cid })); + System::assert_last_event(mock::Event::Alliance(crate::Event::NewRuleSet { rule: cid })); }); } @@ -250,7 +250,7 @@ fn announce_works() { assert_ok!(Alliance::announce(Origin::signed(1), cid.clone())); assert_eq!(Alliance::announcements(), vec![cid.clone()]); - System::assert_last_event(mock::Event::Alliance(crate::Event::NewAnnouncement { + System::assert_last_event(mock::Event::Alliance(crate::Event::Announced { announcement: cid, })); }); @@ -262,7 +262,7 @@ fn remove_announcement_works() { let cid = test_cid(); assert_ok!(Alliance::announce(Origin::signed(1), cid.clone())); assert_eq!(Alliance::announcements(), vec![cid.clone()]); - System::assert_last_event(mock::Event::Alliance(crate::Event::NewAnnouncement { + System::assert_last_event(mock::Event::Alliance(crate::Event::Announced { announcement: cid.clone(), })); @@ -343,7 +343,7 @@ fn nominate_candidate_works() { // only votable member(founder/fellow) have nominate right assert_noop!( Alliance::nominate_candidate(Origin::signed(5), 4), - Error::::NotVotableMember + Error::::NoVotingRights ); // check already in blacklist @@ -448,7 +448,7 @@ fn retire_works() { Box::new(proposal.clone()), proposal_len )); - assert_noop!(Alliance::retire(Origin::signed(2)), Error::::KickingMember); + assert_noop!(Alliance::retire(Origin::signed(2)), Error::::UpForKicking); assert_noop!(Alliance::retire(Origin::signed(4)), Error::::NotMember); @@ -461,11 +461,6 @@ fn retire_works() { #[test] fn kick_member_works() { new_test_ext().execute_with(|| { - assert_noop!( - Alliance::kick_member(Origin::signed(1), 2), - Error::::NotUpForKicking - ); - let proposal = make_kick_member_proposal(2); let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); assert_ok!(Alliance::propose( From 1d0eef4502edc4155ea81d8c3020dd8fb6c627e8 Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Sun, 10 Apr 2022 18:32:28 +1200 Subject: [PATCH 47/72] fix tests --- frame/alliance/src/benchmarking.rs | 36 +++++++++++++-------------- frame/alliance/src/tests.rs | 40 +++++++++++++++--------------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/frame/alliance/src/benchmarking.rs b/frame/alliance/src/benchmarking.rs index e60e6427f111a..638a2e7643fbc 100644 --- a/frame/alliance/src/benchmarking.rs +++ b/frame/alliance/src/benchmarking.rs @@ -609,11 +609,11 @@ benchmarks_instance_pallet! { let rule = rule(b"hello world"); let call = Call::::set_rule { rule: rule.clone() }; - let origin = T::SuperMajorityOrigin::successful_origin(); + let origin = T::AdminOrigin::successful_origin(); }: { call.dispatch_bypass_filter(origin)? } verify { assert_eq!(Alliance::::rule(), Some(rule.clone())); - assert_last_event::(Event::NewRule { rule }.into()); + assert_last_event::(Event::NewRuleSet { rule }.into()); } announce { @@ -622,11 +622,11 @@ benchmarks_instance_pallet! { let announcement = announcement(b"hello world"); let call = Call::::announce { announcement: announcement.clone() }; - let origin = T::SuperMajorityOrigin::successful_origin(); + let origin = T::AnnouncementOrigin::successful_origin(); }: { call.dispatch_bypass_filter(origin)? } verify { assert!(Alliance::::announcements().contains(&announcement)); - assert_last_event::(Event::NewAnnouncement { announcement }.into()); + assert_last_event::(Event::Announced { announcement }.into()); } remove_announcement { @@ -637,7 +637,7 @@ benchmarks_instance_pallet! { Announcements::::put(announcements); let call = Call::::remove_announcement { announcement: announcement.clone() }; - let origin = T::SuperMajorityOrigin::successful_origin(); + let origin = T::AnnouncementOrigin::successful_origin(); }: { call.dispatch_bypass_filter(origin)? } verify { assert!(Alliance::::announcements().is_empty()); @@ -698,7 +698,7 @@ benchmarks_instance_pallet! { let candidate1_lookup: ::Source = T::Lookup::unlookup(candidate1.clone()); let call = Call::::approve_candidate { candidate: candidate1_lookup }; - let origin = T::SuperMajorityOrigin::successful_origin(); + let origin = T::MembershipManager::successful_origin(); }: { call.dispatch_bypass_filter(origin)? } verify { assert!(!Alliance::::is_candidate(&candidate1)); @@ -718,7 +718,7 @@ benchmarks_instance_pallet! { let candidate1_lookup: ::Source = T::Lookup::unlookup(candidate1.clone()); let call = Call::::reject_candidate { candidate: candidate1_lookup }; - let origin = T::SuperMajorityOrigin::successful_origin(); + let origin = T::MembershipManager::successful_origin(); }: { call.dispatch_bypass_filter(origin)? } verify { assert!(!Alliance::::is_candidate(&candidate1)); @@ -735,7 +735,7 @@ benchmarks_instance_pallet! { let ally1_lookup: ::Source = T::Lookup::unlookup(ally1.clone()); let call = Call::::elevate_ally { ally: ally1_lookup }; - let origin = T::SuperMajorityOrigin::successful_origin(); + let origin = T::MembershipManager::successful_origin(); }: { call.dispatch_bypass_filter(origin)? } verify { assert!(!Alliance::::is_ally(&ally1)); @@ -748,7 +748,7 @@ benchmarks_instance_pallet! { let fellow2 = fellow::(2); assert!(Alliance::::is_fellow(&fellow2)); - assert!(!Alliance::::is_kicking(&fellow2)); + assert!(!Alliance::::is_up_for_kicking(&fellow2)); assert_eq!(DepositOf::::get(&fellow2), Some(T::CandidateDeposit::get())); }: _(SystemOrigin::Signed(fellow2.clone())) @@ -765,16 +765,16 @@ benchmarks_instance_pallet! { set_members::(); let fellow2 = fellow::(2); - KickingMembers::::insert(&fellow2, true); + UpForKicking::::insert(&fellow2, true); assert!(Alliance::::is_member_of(&fellow2, MemberRole::Fellow)); - assert!(Alliance::::is_kicking(&fellow2)); + assert!(Alliance::::is_up_for_kicking(&fellow2)); assert_eq!(DepositOf::::get(&fellow2), Some(T::CandidateDeposit::get())); let fellow2_lookup: ::Source = T::Lookup::unlookup(fellow2.clone()); let call = Call::::kick_member { who: fellow2_lookup }; - let origin = T::SuperMajorityOrigin::successful_origin(); + let origin = T::MembershipManager::successful_origin(); }: { call.dispatch_bypass_filter(origin)? } verify { assert!(!Alliance::::is_member(&fellow2)); @@ -800,11 +800,11 @@ benchmarks_instance_pallet! { blacklist.extend(accounts.into_iter().map(BlacklistItem::AccountId)); blacklist.extend(websites.into_iter().map(BlacklistItem::Website)); - let call = Call::::add_blacklist_items { infos: blacklist.clone() }; - let origin = T::SuperMajorityOrigin::successful_origin(); + let call = Call::::add_blacklist_items { items: blacklist.clone() }; + let origin = T::AnnouncementOrigin::successful_origin(); }: { call.dispatch_bypass_filter(origin)? } verify { - assert_last_event::(Event::BlacklistAdded { items: blacklist }.into()); + assert_last_event::(Event::BlacklistItemsAdded { items: blacklist }.into()); } remove_blacklist_items { @@ -828,11 +828,11 @@ benchmarks_instance_pallet! { blacklist.extend(accounts.into_iter().map(BlacklistItem::AccountId)); blacklist.extend(websites.into_iter().map(BlacklistItem::Website)); - let call = Call::::remove_blacklist_items { infos: blacklist.clone() }; - let origin = T::SuperMajorityOrigin::successful_origin(); + let call = Call::::remove_blacklist_items { items: blacklist.clone() }; + let origin = T::AnnouncementOrigin::successful_origin(); }: { call.dispatch_bypass_filter(origin)? } verify { - assert_last_event::(Event::BlacklistRemoved { items: blacklist }.into()); + assert_last_event::(Event::BlacklistItemsRemoved { items: blacklist }.into()); } impl_benchmark_test_suite!(Alliance, crate::mock::new_bench_ext(), crate::mock::Test); diff --git a/frame/alliance/src/tests.rs b/frame/alliance/src/tests.rs index 830d8142235d6..01c88bf1ce4bb 100644 --- a/frame/alliance/src/tests.rs +++ b/frame/alliance/src/tests.rs @@ -247,7 +247,7 @@ fn set_rule_works() { fn announce_works() { new_test_ext().execute_with(|| { let cid = test_cid(); - assert_ok!(Alliance::announce(Origin::signed(1), cid.clone())); + assert_ok!(Alliance::announce(Origin::signed(3), cid.clone())); assert_eq!(Alliance::announcements(), vec![cid.clone()]); System::assert_last_event(mock::Event::Alliance(crate::Event::Announced { @@ -260,7 +260,7 @@ fn announce_works() { fn remove_announcement_works() { new_test_ext().execute_with(|| { let cid = test_cid(); - assert_ok!(Alliance::announce(Origin::signed(1), cid.clone())); + assert_ok!(Alliance::announce(Origin::signed(3), cid.clone())); assert_eq!(Alliance::announcements(), vec![cid.clone()]); System::assert_last_event(mock::Event::Alliance(crate::Event::Announced { announcement: cid.clone(), @@ -268,7 +268,7 @@ fn remove_announcement_works() { System::set_block_number(2); - assert_ok!(Alliance::remove_announcement(Origin::signed(1), cid.clone())); + assert_ok!(Alliance::remove_announcement(Origin::signed(3), cid.clone())); assert_eq!(Alliance::announcements(), vec![]); System::assert_last_event(mock::Event::Alliance(crate::Event::AnnouncementRemoved { announcement: cid, @@ -287,7 +287,7 @@ fn submit_candidacy_works() { // check already in blacklist assert_ok!(Alliance::add_blacklist_items( - Origin::signed(1), + Origin::signed(3), vec![BlacklistItem::AccountId(4)] )); assert_noop!( @@ -295,7 +295,7 @@ fn submit_candidacy_works() { Error::::AlreadyInBlacklist ); assert_ok!(Alliance::remove_blacklist_items( - Origin::signed(1), + Origin::signed(3), vec![BlacklistItem::AccountId(4)] )); @@ -348,7 +348,7 @@ fn nominate_candidate_works() { // check already in blacklist assert_ok!(Alliance::add_blacklist_items( - Origin::signed(1), + Origin::signed(3), vec![BlacklistItem::AccountId(4)] )); assert_noop!( @@ -356,7 +356,7 @@ fn nominate_candidate_works() { Error::::AlreadyInBlacklist ); assert_ok!(Alliance::remove_blacklist_items( - Origin::signed(1), + Origin::signed(3), vec![BlacklistItem::AccountId(4)] )); @@ -390,14 +390,14 @@ fn nominate_candidate_works() { fn approve_candidate_works() { new_test_ext().execute_with(|| { assert_noop!( - Alliance::approve_candidate(Origin::signed(1), 4), + Alliance::approve_candidate(Origin::signed(2), 4), Error::::NotCandidate ); assert_ok!(Alliance::submit_candidacy(Origin::signed(4))); assert_eq!(Alliance::candidates(), vec![4]); - assert_ok!(Alliance::approve_candidate(Origin::signed(1), 4)); + assert_ok!(Alliance::approve_candidate(Origin::signed(2), 4)); assert_eq!(Alliance::candidates(), Vec::::new()); assert_eq!(Alliance::members(MemberRole::Ally), vec![4]); }); @@ -407,7 +407,7 @@ fn approve_candidate_works() { fn reject_candidate_works() { new_test_ext().execute_with(|| { assert_noop!( - Alliance::reject_candidate(Origin::signed(1), 4), + Alliance::reject_candidate(Origin::signed(2), 4), Error::::NotCandidate ); @@ -415,7 +415,7 @@ fn reject_candidate_works() { assert_eq!(Alliance::deposit_of(4), Some(25)); assert_eq!(Alliance::candidates(), vec![4]); - assert_ok!(Alliance::reject_candidate(Origin::signed(1), 4)); + assert_ok!(Alliance::reject_candidate(Origin::signed(2), 4)); assert_eq!(Alliance::deposit_of(4), None); assert_eq!(Alliance::candidates(), Vec::::new()); }); @@ -424,14 +424,14 @@ fn reject_candidate_works() { #[test] fn elevate_ally_works() { new_test_ext().execute_with(|| { - assert_noop!(Alliance::elevate_ally(Origin::signed(1), 4), Error::::NotAlly); + assert_noop!(Alliance::elevate_ally(Origin::signed(2), 4), Error::::NotAlly); assert_ok!(Alliance::submit_candidacy(Origin::signed(4))); - assert_ok!(Alliance::approve_candidate(Origin::signed(1), 4)); + assert_ok!(Alliance::approve_candidate(Origin::signed(2), 4)); assert_eq!(Alliance::members(MemberRole::Ally), vec![4]); assert_eq!(Alliance::members(MemberRole::Fellow), vec![3]); - assert_ok!(Alliance::elevate_ally(Origin::signed(1), 4)); + assert_ok!(Alliance::elevate_ally(Origin::signed(2), 4)); assert_eq!(Alliance::members(MemberRole::Ally), Vec::::new()); assert_eq!(Alliance::members(MemberRole::Fellow), vec![3, 4]); }); @@ -472,7 +472,7 @@ fn kick_member_works() { assert_eq!(Alliance::up_for_kicking(2), true); assert_eq!(Alliance::members(MemberRole::Founder), vec![1, 2]); - assert_ok!(Alliance::kick_member(Origin::signed(1), 2)); + assert_ok!(Alliance::kick_member(Origin::signed(2), 2)); assert_eq!(Alliance::members(MemberRole::Founder), vec![1]); }); } @@ -481,7 +481,7 @@ fn kick_member_works() { fn add_blacklist_items_works() { new_test_ext().execute_with(|| { assert_ok!(Alliance::add_blacklist_items( - Origin::signed(1), + Origin::signed(3), vec![ BlacklistItem::AccountId(3), BlacklistItem::Website("abc".as_bytes().to_vec().try_into().unwrap()) @@ -491,7 +491,7 @@ fn add_blacklist_items_works() { assert_eq!(Alliance::website_blacklist().into_inner(), vec!["abc".as_bytes().to_vec()]); assert_noop!( - Alliance::add_blacklist_items(Origin::signed(1), vec![BlacklistItem::AccountId(3)]), + Alliance::add_blacklist_items(Origin::signed(3), vec![BlacklistItem::AccountId(3)]), Error::::AlreadyInBlacklist ); }); @@ -501,17 +501,17 @@ fn add_blacklist_items_works() { fn remove_blacklist_items_works() { new_test_ext().execute_with(|| { assert_noop!( - Alliance::remove_blacklist_items(Origin::signed(1), vec![BlacklistItem::AccountId(3)]), + Alliance::remove_blacklist_items(Origin::signed(3), vec![BlacklistItem::AccountId(3)]), Error::::NotInBlacklist ); assert_ok!(Alliance::add_blacklist_items( - Origin::signed(1), + Origin::signed(3), vec![BlacklistItem::AccountId(3)] )); assert_eq!(Alliance::account_blacklist(), vec![3]); assert_ok!(Alliance::remove_blacklist_items( - Origin::signed(1), + Origin::signed(3), vec![BlacklistItem::AccountId(3)] )); assert_eq!(Alliance::account_blacklist(), Vec::::new()); From 4f2a0bdb26de68eb9ff176a87dda79134265d404 Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Sun, 10 Apr 2022 18:37:10 +1200 Subject: [PATCH 48/72] fix runtime --- bin/node/runtime/src/lib.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 5f2ffd6928f5f..5ec7eebe5629a 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1431,7 +1431,15 @@ parameter_types! { impl pallet_alliance::Config for Runtime { type Event = Event; type Proposal = Call; - type SuperMajorityOrigin = EnsureOneOf< + type AdminOrigin = EnsureOneOf< + EnsureRoot, + pallet_collective::EnsureProportionMoreThan, + >; + type MembershipManager = EnsureOneOf< + EnsureRoot, + pallet_collective::EnsureProportionMoreThan, + >; + type AnnouncementOrigin = EnsureOneOf< EnsureRoot, pallet_collective::EnsureProportionMoreThan, >; From 3c8b8783f5e090da55ae0629af42d0162f57b49a Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Sun, 10 Apr 2022 18:58:40 +1200 Subject: [PATCH 49/72] fix build --- frame/alliance/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/frame/alliance/Cargo.toml b/frame/alliance/Cargo.toml index 468bd11736438..1e6823234b487 100644 --- a/frame/alliance/Cargo.toml +++ b/frame/alliance/Cargo.toml @@ -30,6 +30,7 @@ frame-support = { version = "4.0.0-dev", default-features = false, path = "../su frame-system = { version = "4.0.0-dev", default-features = false, path = "../system" } pallet-identity = { version = "4.0.0-dev", path = "../identity", default-features = false } +pallet-collective = { version = "4.0.0-dev", path = "../collective", default-features = false, optional = true } [dev-dependencies] hex-literal = "0.3.1" From 0f12ed48060f17b2e34e0c0da780fc934370f4a2 Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Mon, 11 Apr 2022 11:14:33 +1200 Subject: [PATCH 50/72] remove unneeded change --- frame/identity/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/frame/identity/src/lib.rs b/frame/identity/src/lib.rs index da6b311768a5b..155ebafef81f4 100644 --- a/frame/identity/src/lib.rs +++ b/frame/identity/src/lib.rs @@ -159,7 +159,7 @@ pub mod pallet { /// TWOX-NOTE: OK ― `AccountId` is a secure hash. #[pallet::storage] #[pallet::getter(fn identity)] - pub type IdentityOf = StorageMap< + pub(super) type IdentityOf = StorageMap< _, Twox64Concat, T::AccountId, @@ -171,7 +171,7 @@ pub mod pallet { /// context. If the account is not some other account's sub-identity, then just `None`. #[pallet::storage] #[pallet::getter(fn super_of)] - pub type SuperOf = + pub(super) type SuperOf = StorageMap<_, Blake2_128Concat, T::AccountId, (T::AccountId, Data), OptionQuery>; /// Alternative "sub" identities of this account. @@ -181,7 +181,7 @@ pub mod pallet { /// TWOX-NOTE: OK ― `AccountId` is a secure hash. #[pallet::storage] #[pallet::getter(fn subs_of)] - pub type SubsOf = StorageMap< + pub(super) type SubsOf = StorageMap< _, Twox64Concat, T::AccountId, @@ -195,7 +195,7 @@ pub mod pallet { /// The index into this can be cast to `RegistrarIndex` to get a valid value. #[pallet::storage] #[pallet::getter(fn registrars)] - pub type Registrars = StorageValue< + pub(super) type Registrars = StorageValue< _, BoundedVec, T::AccountId>>, T::MaxRegistrars>, ValueQuery, From 5b6b3362e47adce3cadcc874e51326c4d1a20872 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Sat, 30 Apr 2022 16:44:21 +0200 Subject: [PATCH 51/72] remove Candidate role from Alliance --- bin/node/runtime/src/lib.rs | 4 +- frame/alliance/README.md | 31 +++--- frame/alliance/src/benchmarking.rs | 4 +- frame/alliance/src/lib.rs | 173 ++++++++--------------------- frame/alliance/src/mock.rs | 7 +- frame/alliance/src/tests.rs | 84 ++++---------- frame/alliance/src/types.rs | 1 + frame/alliance/src/weights.rs | 50 +-------- 8 files changed, 96 insertions(+), 258 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 492bcfce0e2e1..ba64daf4633e4 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1426,6 +1426,7 @@ parameter_types! { pub const MaxFounders: u32 = 10; pub const MaxFellows: u32 = AllianceMaxMembers::get() - MaxFounders::get(); pub const MaxAllies: u32 = 100; + pub const AllyDeposit: Balance = 10 * DOLLARS; } impl pallet_alliance::Config for Runtime { @@ -1460,8 +1461,7 @@ impl pallet_alliance::Config for Runtime { type MaxWebsiteUrlLength = ConstU32<255>; type MaxAnnouncementsCount = ConstU32<100>; type MaxMembersCount = AllianceMaxMembers; - type MaxCandidatesCount = ConstU32<100>; - type CandidateDeposit = CandidateDeposit; + type AllyDeposit = AllyDeposit; type WeightInfo = pallet_alliance::weights::SubstrateWeight; } diff --git a/frame/alliance/README.md b/frame/alliance/README.md index 7fabd1df18577..f9d2199980d46 100644 --- a/frame/alliance/README.md +++ b/frame/alliance/README.md @@ -10,10 +10,11 @@ presumably agreed by the voting members to be bad actors. The alliance ## Overview The network initializes the Alliance via a Root call. After that, anyone with an approved -identity and website can apply to become a Candidate. Members will initiate a motion to -determine whether a Candidate can join the Alliance or not. The motion requires the approval of -the `MembershipManager` origin. The Alliance can also maintain a blacklist of accounts and -websites. Members can also vote to update the Alliance's rule and make announcements. +identity and website can join as an Ally. The `MembershipManager` origin can elevate Allies to +Fellows, giving them voting rights within the Alliance. + +Voting members of the Alliance maintain a blacklist of accounts and websites. Members can also +vote to update the Alliance's rule and make announcements. ### Terminology @@ -24,15 +25,13 @@ websites. Members can also vote to update the Alliance's rule and make announcem Founder, Fellow, or Ally. A member can also be kicked by the `MembershipManager` origin or retire by itself. - Founder: An account who is initiated by Root with normal voting rights for basic motions and - special veto rights for rule change and ally elevation motions. + special veto rights for rule change and Ally elevation motions. - Fellow: An account who is elevated from Ally by Founders and other Fellows. -- Ally: An account who is approved by Founders and Fellows from Candidate. An Ally doesn't have - voting rights. -- Candidate: An account who is trying to become a member. The applicant should already have an - approved identity with website. The application should be submitted by the account itself with - some deposit, or be nominated by an existing Founder or Fellow for free. -- Blacklist: A list of bad websites and addresses, items can be added or removed by Founders - and Fellows. +- Ally: An account who would like to join the alliance. To become a voting member, Fellow or + Founder, it will need approval from the `MembershipManager` origin. Any account can join as an + Ally either by placing a deposit or by nomination from a voting member. +- Blacklist: A list of bad websites and addresses, items can be added or removed by Founders and + Fellows. ## Interface @@ -40,7 +39,7 @@ websites. Members can also vote to update the Alliance's rule and make announcem #### For General Users -- `submit_candidacy` - Submit the application to become a candidate with deposit. +- `join_alliance` - Join the Alliance as an Ally. This requires a slashable deposit. #### For Members (All) @@ -53,9 +52,7 @@ websites. Members can also vote to update the Alliance's rule and make announcem - `close` - Close a motion with enough votes or that has expired. - `set_rule` - Initialize or update the Alliance's rule by IPFS CID. - `announce` - Make announcement by IPFS CID. -- `nominate_candidate` - Nominate a non-member to become a Candidate for free. -- `approve_candidate` - Approve a candidate to become an Ally. -- `reject_candidate` - Reject a candidate and slash its deposit. +- `nominate_ally` - Nominate a non-member to become an Ally, without deposit. - `elevate_ally` - Approve an ally to become a Fellow. - `kick_member` - Kick a member and slash its deposit. - `add_blacklist_items` - Add some items, either accounts or websites, to the blacklist. @@ -67,4 +64,4 @@ websites. Members can also vote to update the Alliance's rule and make announcem #### Root Calls -- `init_founders` - Initialize the founding members. +- `init_founders` - Initialize the founding members. \ No newline at end of file diff --git a/frame/alliance/src/benchmarking.rs b/frame/alliance/src/benchmarking.rs index 638a2e7643fbc..ba39108ba3d1f 100644 --- a/frame/alliance/src/benchmarking.rs +++ b/frame/alliance/src/benchmarking.rs @@ -644,7 +644,7 @@ benchmarks_instance_pallet! { assert_last_event::(Event::AnnouncementRemoved { announcement }.into()); } - submit_candidacy { + join_alliance { set_members::(); let outsider = outsider::(1); @@ -663,7 +663,7 @@ benchmarks_instance_pallet! { }.into()); } - nominate_candidate { + nominate_ally { set_members::(); let founder1 = founder::(1); diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index ffd59a6977985..da495fae05244 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -27,10 +27,11 @@ //! ## Overview //! //! The network initializes the Alliance via a Root call. After that, anyone with an approved -//! identity and website can apply to become a Candidate. Members will initiate a motion to -//! determine whether a Candidate can join the Alliance or not. The motion requires the approval of -//! the `MembershipManager` origin. The Alliance can also maintain a blacklist of accounts and -//! websites. Members can also vote to update the Alliance's rule and make announcements. +//! identity and website can join as an Ally. The `MembershipManager` origin can elevate Allies to +//! Fellows, giving them voting rights within the Alliance. +//! +//! Voting members of the Alliance maintain a blacklist of accounts and websites. Members can also +//! vote to update the Alliance's rule and make announcements. //! //! ### Terminology //! @@ -41,13 +42,11 @@ //! Founder, Fellow, or Ally. A member can also be kicked by the `MembershipManager` origin or //! retire by itself. //! - Founder: An account who is initiated by Root with normal voting rights for basic motions and -//! special veto rights for rule change and ally elevation motions. +//! special veto rights for rule change and Ally elevation motions. //! - Fellow: An account who is elevated from Ally by Founders and other Fellows. -//! - Ally: An account who is approved by Founders and Fellows from Candidate. An Ally doesn't have -//! voting rights. -//! - Candidate: An account who is trying to become a member. The applicant should already have an -//! approved identity with website. The application should be submitted by the account itself with -//! some deposit, or be nominated by an existing Founder or Fellow for free. +//! - Ally: An account who would like to join the alliance. To become a voting member, Fellow or +//! Founder, it will need approval from the `MembershipManager` origin. Any account can join as an +//! Ally either by placing a deposit or by nomination from a voting member. //! - Blacklist: A list of bad websites and addresses, items can be added or removed by Founders and //! Fellows. //! @@ -57,7 +56,7 @@ //! //! #### For General Users //! -//! - `submit_candidacy` - Submit the application to become a candidate with deposit. +//! - `join_alliance` - Join the Alliance as an Ally. This requires a slashable deposit. //! //! #### For Members (All) //! @@ -70,9 +69,7 @@ //! - `close` - Close a motion with enough votes or that has expired. //! - `set_rule` - Initialize or update the Alliance's rule by IPFS CID. //! - `announce` - Make announcement by IPFS CID. -//! - `nominate_candidate` - Nominate a non-member to become a Candidate for free. -//! - `approve_candidate` - Approve a candidate to become an Ally. -//! - `reject_candidate` - Reject a candidate and slash its deposit. +//! - `nominate_ally` - Nominate a non-member to become an Ally, without deposit. //! - `elevate_ally` - Approve an ally to become a Fellow. //! - `kick_member` - Kick a member and slash its deposit. //! - `add_blacklist_items` - Add some items, either accounts or websites, to the blacklist. @@ -105,6 +102,7 @@ use sp_runtime::{ RuntimeDebug, }; use sp_std::prelude::*; +use sp_std::convert::TryInto; use frame_support::{ codec::{Decode, Encode, MaxEncodedLen}, @@ -286,20 +284,17 @@ pub mod pallet { /// The deposit required for submitting candidacy. #[pallet::constant] - type CandidateDeposit: Get>; + type AllyDeposit: Get>; /// The maximum number of announcements. #[pallet::constant] type MaxAnnouncementsCount: Get; - /// The maximum number of members per member role. + /// The maximum number of members per member role. Should not exceed the sum of + /// `MaxFounders` and `MaxFellows`. #[pallet::constant] type MaxMembersCount: Get; - /// The maximum number of candidates. - #[pallet::constant] - type MaxCandidatesCount: Get; - /// Weight information for extrinsics in this pallet. type WeightInfo: WeightInfo; } @@ -308,10 +303,6 @@ pub mod pallet { pub enum Error { /// The founders/fellows/allies have already been initialized. MembersAlreadyInitialized, - /// Account is already a candidate. - AlreadyCandidate, - /// Account is not a candidate. - NotCandidate, /// Account is already a member. AlreadyMember, /// Account is not a member. @@ -331,11 +322,11 @@ pub mod pallet { /// Item is not blacklisted. NotInBlacklist, /// Length of blacklist exceeds `MaxBlacklist`. - TooManyBlacklist, + TooManyItemsInBlacklist, /// Length of website URL exceeds `MaxWebsiteUrlLength`. TooLongWebsiteUrl, - /// Balance is insufficient to be a candidate. - InsufficientCandidateFunds, + /// Balance is insufficient for the required deposit. + InsufficientFunds, /// The account's identity does not have display field and website field. WithoutIdentityDisplayAndWebsite, /// The account's identity has no good judgement. @@ -348,8 +339,6 @@ pub mod pallet { MissingAnnouncement, /// Number of members exceeds `MaxMembersCount`. TooManyMembers, - /// Number of candidates exceeds `MaxCandidatesCount`. - TooManyCandidates, /// Number of announcements exceeds `MaxAnnouncementsCount`. TooManyAnnouncements, } @@ -369,21 +358,17 @@ pub mod pallet { fellows: Vec, allies: Vec, }, - /// An account has been added as a candidate and reserved its deposit. - CandidateAdded { - candidate: T::AccountId, + /// An account has been added as an Ally and reserved its deposit. + NewAllyJoined { + ally: T::AccountId, nominator: Option, reserved: Option>, }, - /// A candidate has been approved as an ally. - CandidateApproved { candidate: T::AccountId }, - /// A candidate has been rejected and its deposit slashed. - CandidateRejected { candidate: T::AccountId }, - /// An ally has been elevated to fellow. + /// An ally has been elevated to Fellow. AllyElevated { ally: T::AccountId }, - /// A member has retired to an ordinary account with its deposit unreserved. + /// A member has retired with its deposit unreserved. MemberRetired { member: T::AccountId, unreserved: Option> }, - /// A member has been kicked out to an ordinary account with its deposit slashed. + /// A member has been kicked out with its deposit slashed. MemberKicked { member: T::AccountId, slashed: Option> }, /// Accounts or websites have been added into the blacklist. BlacklistItemsAdded { items: Vec> }, @@ -468,13 +453,6 @@ pub mod pallet { pub type DepositOf, I: 'static = ()> = StorageMap<_, Blake2_128Concat, T::AccountId, BalanceOf, OptionQuery>; - /// The current set of candidates. - /// If a candidate is approved by a motion, then it will become an ally. - #[pallet::storage] - #[pallet::getter(fn candidates)] - pub type Candidates, I: 'static = ()> = - StorageValue<_, BoundedVec, ValueQuery>; - /// Maps member type to members of each type. #[pallet::storage] #[pallet::getter(fn members)] @@ -719,100 +697,62 @@ pub mod pallet { } /// Submit oneself for candidacy. A fixed deposit is reserved. - #[pallet::weight(T::WeightInfo::submit_candidacy())] - pub fn submit_candidacy(origin: OriginFor) -> DispatchResult { + #[pallet::weight(T::WeightInfo::join_alliance())] + pub fn join_alliance(origin: OriginFor) -> DispatchResult { let who = ensure_signed(origin)?; + + // Blacklisted accounts cannot join. ensure!(!Self::account_blacklisted(&who), Error::::AlreadyInBlacklist); - ensure!(!Self::is_candidate(&who), Error::::AlreadyCandidate); ensure!(!Self::is_member(&who), Error::::AlreadyMember); // check user self or parent should has verified identity to reuse display name and // website. Self::has_identity(&who)?; - let deposit = T::CandidateDeposit::get(); + let deposit = T::AllyDeposit::get(); T::Currency::reserve(&who, deposit) - .map_err(|_| Error::::InsufficientCandidateFunds)?; + .map_err(|_| Error::::InsufficientFunds)?; >::insert(&who, deposit); - let res = Self::add_candidate(&who); - debug_assert!(res.is_ok()); + Self::add_member(&who, MemberRole::Ally)?; - Self::deposit_event(Event::CandidateAdded { - candidate: who, + Self::deposit_event(Event::NewAllyJoined { + ally: who, nominator: None, reserved: Some(deposit), }); Ok(()) } - /// A founder or fellow can nominate someone to join the alliance and become a candidate. + /// A founder or fellow can nominate someone to join the alliance as an Ally. /// There is no deposit required to the nominator or nominee. - #[pallet::weight(T::WeightInfo::nominate_candidate())] - pub fn nominate_candidate( + #[pallet::weight(T::WeightInfo::nominate_ally())] + pub fn nominate_ally( origin: OriginFor, who: ::Source, ) -> DispatchResult { let nominator = ensure_signed(origin)?; ensure!(Self::has_voting_rights(&nominator), Error::::NoVotingRights); let who = T::Lookup::lookup(who)?; + + // Individual voting members cannot nominate blacklisted accounts. ensure!(!Self::account_blacklisted(&who), Error::::AlreadyInBlacklist); - ensure!(!Self::is_candidate(&who), Error::::AlreadyCandidate); ensure!(!Self::is_member(&who), Error::::AlreadyMember); // check user self or parent should has verified identity to reuse display name and // website. Self::has_identity(&who)?; - let res = Self::add_candidate(&who); - debug_assert!(res.is_ok()); + Self::add_member(&who, MemberRole::Ally)?; - Self::deposit_event(Event::CandidateAdded { - candidate: who, + Self::deposit_event(Event::NewAllyJoined { + ally: who, nominator: Some(nominator), reserved: None, }); Ok(()) } - /// Approve a `Candidate` to become an `Ally`. - #[pallet::weight(T::WeightInfo::approve_candidate())] - pub fn approve_candidate( - origin: OriginFor, - candidate: ::Source, - ) -> DispatchResult { - T::MembershipManager::ensure_origin(origin)?; - let candidate = T::Lookup::lookup(candidate)?; - ensure!(Self::is_candidate(&candidate), Error::::NotCandidate); - ensure!(!Self::is_member(&candidate), Error::::AlreadyMember); - - Self::remove_candidate(&candidate)?; - Self::add_member(&candidate, MemberRole::Ally)?; - - Self::deposit_event(Event::CandidateApproved { candidate }); - Ok(()) - } - - /// Reject a `Candidate`. This results in a slash of the candidate's deposit. - #[pallet::weight(T::WeightInfo::reject_candidate())] - pub fn reject_candidate( - origin: OriginFor, - candidate: ::Source, - ) -> DispatchResult { - T::MembershipManager::ensure_origin(origin)?; - let candidate = T::Lookup::lookup(candidate)?; - ensure!(Self::is_candidate(&candidate), Error::::NotCandidate); - ensure!(!Self::is_member(&candidate), Error::::AlreadyMember); - - Self::remove_candidate(&candidate)?; - if let Some(deposit) = DepositOf::::take(&candidate) { - T::Slashed::on_unbalanced(T::Currency::slash_reserved(&candidate, deposit).0); - } - - Self::deposit_event(Event::CandidateRejected { candidate }); - Ok(()) - } - /// Elevate an ally to fellow. - #[pallet::weight(T::WeightInfo::reject_candidate())] + #[pallet::weight(T::WeightInfo::elevate_ally())] pub fn elevate_ally( origin: OriginFor, ally: ::Source, @@ -922,31 +862,6 @@ pub mod pallet { } impl, I: 'static> Pallet { - /// Check if a user is a candidate. - pub fn is_candidate(who: &T::AccountId) -> bool { - >::get().contains(who) - } - - /// Add a candidate to the sorted candidate list. - fn add_candidate(who: &T::AccountId) -> DispatchResult { - >::try_mutate(|candidates| { - let pos = candidates.binary_search(who).err().ok_or(Error::::AlreadyCandidate)?; - candidates - .try_insert(pos, who.clone()) - .map_err(|_| Error::::TooManyCandidates)?; - Ok(()) - }) - } - - /// Remove a candidate from the candidates list. - fn remove_candidate(who: &T::AccountId) -> DispatchResult { - >::try_mutate(|candidates| { - let pos = candidates.binary_search(who).ok().ok_or(Error::::NotCandidate)?; - candidates.remove(pos); - Ok(()) - }) - } - /// Check if a given role has any members. fn has_member(role: MemberRole) -> bool { Members::::decode_len(role).unwrap_or_default() > 0 @@ -1054,7 +969,7 @@ impl, I: 'static> Pallet { ) -> DispatchResult { if !new_accounts.is_empty() { >::try_mutate(|accounts| -> DispatchResult { - accounts.try_append(new_accounts).map_err(|_| Error::::TooManyBlacklist)?; + accounts.try_append(new_accounts).map_err(|_| Error::::TooManyItemsInBlacklist)?; accounts.sort(); Ok(()) @@ -1062,7 +977,7 @@ impl, I: 'static> Pallet { } if !new_webs.is_empty() { >::try_mutate(|webs| -> DispatchResult { - webs.try_append(new_webs).map_err(|_| Error::::TooManyBlacklist)?; + webs.try_append(new_webs).map_err(|_| Error::::TooManyItemsInBlacklist)?; webs.sort(); Ok(()) diff --git a/frame/alliance/src/mock.rs b/frame/alliance/src/mock.rs index ec09f00ba784f..a346eb48fe6e4 100644 --- a/frame/alliance/src/mock.rs +++ b/frame/alliance/src/mock.rs @@ -23,7 +23,7 @@ pub use sp_runtime::{ traits::{BlakeTwo256, IdentityLookup}, BuildStorage, }; -use sp_std::convert::TryInto; +use sp_std::convert::{TryFrom, TryInto}; pub use frame_support::{ assert_ok, ord_parameter_types, parameter_types, @@ -199,7 +199,7 @@ parameter_types! { pub const MaxFounders: u32 = 10; pub const MaxFellows: u32 = MaxMembers::get() - MaxFounders::get(); pub const MaxAllies: u32 = 100; - pub const CandidateDeposit: u64 = 25; + pub const AllyDeposit: u64 = 25; } impl Config for Test { type Event = Event; @@ -224,8 +224,7 @@ impl Config for Test { type MaxWebsiteUrlLength = ConstU32<255>; type MaxAnnouncementsCount = ConstU32<100>; type MaxMembersCount = MaxMembers; - type MaxCandidatesCount = ConstU32<100>; - type CandidateDeposit = CandidateDeposit; + type AllyDeposit = AllyDeposit; type WeightInfo = (); } diff --git a/frame/alliance/src/tests.rs b/frame/alliance/src/tests.rs index 01c88bf1ce4bb..ea45f93f2f94d 100644 --- a/frame/alliance/src/tests.rs +++ b/frame/alliance/src/tests.rs @@ -277,11 +277,11 @@ fn remove_announcement_works() { } #[test] -fn submit_candidacy_works() { +fn join_alliance_works() { new_test_ext().execute_with(|| { // check already member assert_noop!( - Alliance::submit_candidacy(Origin::signed(1)), + Alliance::join_alliance(Origin::signed(1)), Error::::AlreadyMember ); @@ -291,7 +291,7 @@ fn submit_candidacy_works() { vec![BlacklistItem::AccountId(4)] )); assert_noop!( - Alliance::submit_candidacy(Origin::signed(4)), + Alliance::join_alliance(Origin::signed(4)), Error::::AlreadyInBlacklist ); assert_ok!(Alliance::remove_blacklist_items( @@ -301,48 +301,48 @@ fn submit_candidacy_works() { // check deposit funds assert_noop!( - Alliance::submit_candidacy(Origin::signed(5)), - Error::::InsufficientCandidateFunds + Alliance::join_alliance(Origin::signed(5)), + Error::::InsufficientFunds ); // success to submit - assert_ok!(Alliance::submit_candidacy(Origin::signed(4))); + assert_ok!(Alliance::join_alliance(Origin::signed(4))); assert_eq!(Alliance::deposit_of(4), Some(25)); - assert_eq!(Alliance::candidates(), vec![4]); + assert_eq!(Alliance::members(MemberRole::Ally), vec![4]); - // check already candidate + // check already member assert_noop!( - Alliance::submit_candidacy(Origin::signed(4)), - Error::::AlreadyCandidate + Alliance::join_alliance(Origin::signed(4)), + Error::::AlreadyMember ); // check missing identity judgement #[cfg(not(feature = "runtime-benchmarks"))] assert_noop!( - Alliance::submit_candidacy(Origin::signed(6)), + Alliance::join_alliance(Origin::signed(6)), Error::::WithoutGoodIdentityJudgement ); // check missing identity info #[cfg(not(feature = "runtime-benchmarks"))] assert_noop!( - Alliance::submit_candidacy(Origin::signed(7)), + Alliance::join_alliance(Origin::signed(7)), Error::::WithoutIdentityDisplayAndWebsite ); }); } #[test] -fn nominate_candidate_works() { +fn nominate_ally_works() { new_test_ext().execute_with(|| { // check already member assert_noop!( - Alliance::nominate_candidate(Origin::signed(1), 2), + Alliance::nominate_ally(Origin::signed(1), 2), Error::::AlreadyMember ); // only votable member(founder/fellow) have nominate right assert_noop!( - Alliance::nominate_candidate(Origin::signed(5), 4), + Alliance::nominate_ally(Origin::signed(5), 4), Error::::NoVotingRights ); @@ -352,7 +352,7 @@ fn nominate_candidate_works() { vec![BlacklistItem::AccountId(4)] )); assert_noop!( - Alliance::nominate_candidate(Origin::signed(1), 4), + Alliance::nominate_ally(Origin::signed(1), 4), Error::::AlreadyInBlacklist ); assert_ok!(Alliance::remove_blacklist_items( @@ -361,73 +361,37 @@ fn nominate_candidate_works() { )); // success to nominate - assert_ok!(Alliance::nominate_candidate(Origin::signed(1), 4)); + assert_ok!(Alliance::nominate_ally(Origin::signed(1), 4)); assert_eq!(Alliance::deposit_of(4), None); - assert_eq!(Alliance::candidates(), vec![4]); + assert_eq!(Alliance::members(MemberRole::Ally), vec![4]); - // check already candidate + // check already member assert_noop!( - Alliance::nominate_candidate(Origin::signed(1), 4), - Error::::AlreadyCandidate + Alliance::nominate_ally(Origin::signed(1), 4), + Error::::AlreadyMember ); // check missing identity judgement #[cfg(not(feature = "runtime-benchmarks"))] assert_noop!( - Alliance::submit_candidacy(Origin::signed(6)), + Alliance::join_alliance(Origin::signed(6)), Error::::WithoutGoodIdentityJudgement ); // check missing identity info #[cfg(not(feature = "runtime-benchmarks"))] assert_noop!( - Alliance::submit_candidacy(Origin::signed(7)), + Alliance::join_alliance(Origin::signed(7)), Error::::WithoutIdentityDisplayAndWebsite ); }); } -#[test] -fn approve_candidate_works() { - new_test_ext().execute_with(|| { - assert_noop!( - Alliance::approve_candidate(Origin::signed(2), 4), - Error::::NotCandidate - ); - - assert_ok!(Alliance::submit_candidacy(Origin::signed(4))); - assert_eq!(Alliance::candidates(), vec![4]); - - assert_ok!(Alliance::approve_candidate(Origin::signed(2), 4)); - assert_eq!(Alliance::candidates(), Vec::::new()); - assert_eq!(Alliance::members(MemberRole::Ally), vec![4]); - }); -} - -#[test] -fn reject_candidate_works() { - new_test_ext().execute_with(|| { - assert_noop!( - Alliance::reject_candidate(Origin::signed(2), 4), - Error::::NotCandidate - ); - - assert_ok!(Alliance::submit_candidacy(Origin::signed(4))); - assert_eq!(Alliance::deposit_of(4), Some(25)); - assert_eq!(Alliance::candidates(), vec![4]); - - assert_ok!(Alliance::reject_candidate(Origin::signed(2), 4)); - assert_eq!(Alliance::deposit_of(4), None); - assert_eq!(Alliance::candidates(), Vec::::new()); - }); -} - #[test] fn elevate_ally_works() { new_test_ext().execute_with(|| { assert_noop!(Alliance::elevate_ally(Origin::signed(2), 4), Error::::NotAlly); - assert_ok!(Alliance::submit_candidacy(Origin::signed(4))); - assert_ok!(Alliance::approve_candidate(Origin::signed(2), 4)); + assert_ok!(Alliance::join_alliance(Origin::signed(4))); assert_eq!(Alliance::members(MemberRole::Ally), vec![4]); assert_eq!(Alliance::members(MemberRole::Fellow), vec![3]); diff --git a/frame/alliance/src/types.rs b/frame/alliance/src/types.rs index 0bb8cc73613ad..07a5cca9603e1 100644 --- a/frame/alliance/src/types.rs +++ b/frame/alliance/src/types.rs @@ -20,6 +20,7 @@ use frame_support::{traits::ConstU32, BoundedVec}; use scale_info::TypeInfo; use sp_runtime::RuntimeDebug; use sp_std::prelude::*; +use sp_std::convert::TryInto; /// A Multihash instance that only supports the basic functionality and no hashing. #[derive( diff --git a/frame/alliance/src/weights.rs b/frame/alliance/src/weights.rs index dfb497bb9fe1e..6efd3c5885f29 100644 --- a/frame/alliance/src/weights.rs +++ b/frame/alliance/src/weights.rs @@ -56,10 +56,8 @@ pub trait WeightInfo { fn set_rule() -> Weight; fn announce() -> Weight; fn remove_announcement() -> Weight; - fn submit_candidacy() -> Weight; - fn nominate_candidate() -> Weight; - fn approve_candidate() -> Weight; - fn reject_candidate() -> Weight; + fn join_alliance() -> Weight; + fn nominate_ally() -> Weight; fn elevate_ally() -> Weight; fn retire() -> Weight; fn kick_member() -> Weight; @@ -205,39 +203,21 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Alliance AccountBlacklist (r:1 w:0) - // Storage: Alliance Candidates (r:1 w:1) // Storage: Alliance Members (r:4 w:0) // Storage: System Account (r:1 w:1) // Storage: Alliance DepositOf (r:0 w:1) - fn submit_candidacy() -> Weight { + fn join_alliance() -> Weight { (95_370_000 as Weight) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } // Storage: Alliance Members (r:4 w:0) // Storage: Alliance AccountBlacklist (r:1 w:0) - // Storage: Alliance Candidates (r:1 w:1) - fn nominate_candidate() -> Weight { + fn nominate_ally() -> Weight { (44_764_000 as Weight) .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - // Storage: Alliance Candidates (r:1 w:1) - // Storage: Alliance Members (r:4 w:1) - fn approve_candidate() -> Weight { - (71_876_000 as Weight) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) - .saturating_add(T::DbWeight::get().writes(2 as Weight)) - } - // Storage: Alliance Candidates (r:1 w:1) - // Storage: Alliance Members (r:4 w:0) - // Storage: Alliance DepositOf (r:1 w:1) - // Storage: System Account (r:1 w:1) - fn reject_candidate() -> Weight { - (69_732_000 as Weight) - .saturating_add(T::DbWeight::get().reads(7 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) - } // Storage: Alliance Members (r:3 w:2) // Storage: AllianceMotion Proposals (r:1 w:0) // Storage: AllianceMotion Members (r:0 w:1) @@ -432,39 +412,21 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Alliance AccountBlacklist (r:1 w:0) - // Storage: Alliance Candidates (r:1 w:1) // Storage: Alliance Members (r:4 w:0) // Storage: System Account (r:1 w:1) // Storage: Alliance DepositOf (r:0 w:1) - fn submit_candidacy() -> Weight { + fn join_alliance() -> Weight { (95_370_000 as Weight) .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } // Storage: Alliance Members (r:4 w:0) // Storage: Alliance AccountBlacklist (r:1 w:0) - // Storage: Alliance Candidates (r:1 w:1) - fn nominate_candidate() -> Weight { + fn nominate_ally() -> Weight { (44_764_000 as Weight) .saturating_add(RocksDbWeight::get().reads(6 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } - // Storage: Alliance Candidates (r:1 w:1) - // Storage: Alliance Members (r:4 w:1) - fn approve_candidate() -> Weight { - (71_876_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(5 as Weight)) - .saturating_add(RocksDbWeight::get().writes(2 as Weight)) - } - // Storage: Alliance Candidates (r:1 w:1) - // Storage: Alliance Members (r:4 w:0) - // Storage: Alliance DepositOf (r:1 w:1) - // Storage: System Account (r:1 w:1) - fn reject_candidate() -> Weight { - (69_732_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(7 as Weight)) - .saturating_add(RocksDbWeight::get().writes(3 as Weight)) - } // Storage: Alliance Members (r:3 w:2) // Storage: AllianceMotion Proposals (r:1 w:0) // Storage: AllianceMotion Members (r:0 w:1) From 0970b7843af59323bd5aff890eb2708a9765005c Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Sat, 30 Apr 2022 16:53:42 +0200 Subject: [PATCH 52/72] fmt grumbles --- frame/alliance/src/lib.rs | 10 +++++----- frame/alliance/src/tests.rs | 10 ++-------- frame/alliance/src/types.rs | 3 +-- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index da495fae05244..bf5bb9f08b699 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -101,8 +101,7 @@ use sp_runtime::{ traits::{StaticLookup, Zero}, RuntimeDebug, }; -use sp_std::prelude::*; -use sp_std::convert::TryInto; +use sp_std::{convert::TryInto, prelude::*}; use frame_support::{ codec::{Decode, Encode, MaxEncodedLen}, @@ -709,8 +708,7 @@ pub mod pallet { Self::has_identity(&who)?; let deposit = T::AllyDeposit::get(); - T::Currency::reserve(&who, deposit) - .map_err(|_| Error::::InsufficientFunds)?; + T::Currency::reserve(&who, deposit).map_err(|_| Error::::InsufficientFunds)?; >::insert(&who, deposit); Self::add_member(&who, MemberRole::Ally)?; @@ -969,7 +967,9 @@ impl, I: 'static> Pallet { ) -> DispatchResult { if !new_accounts.is_empty() { >::try_mutate(|accounts| -> DispatchResult { - accounts.try_append(new_accounts).map_err(|_| Error::::TooManyItemsInBlacklist)?; + accounts + .try_append(new_accounts) + .map_err(|_| Error::::TooManyItemsInBlacklist)?; accounts.sort(); Ok(()) diff --git a/frame/alliance/src/tests.rs b/frame/alliance/src/tests.rs index ea45f93f2f94d..c930f5c8cf9d6 100644 --- a/frame/alliance/src/tests.rs +++ b/frame/alliance/src/tests.rs @@ -280,10 +280,7 @@ fn remove_announcement_works() { fn join_alliance_works() { new_test_ext().execute_with(|| { // check already member - assert_noop!( - Alliance::join_alliance(Origin::signed(1)), - Error::::AlreadyMember - ); + assert_noop!(Alliance::join_alliance(Origin::signed(1)), Error::::AlreadyMember); // check already in blacklist assert_ok!(Alliance::add_blacklist_items( @@ -311,10 +308,7 @@ fn join_alliance_works() { assert_eq!(Alliance::members(MemberRole::Ally), vec![4]); // check already member - assert_noop!( - Alliance::join_alliance(Origin::signed(4)), - Error::::AlreadyMember - ); + assert_noop!(Alliance::join_alliance(Origin::signed(4)), Error::::AlreadyMember); // check missing identity judgement #[cfg(not(feature = "runtime-benchmarks"))] diff --git a/frame/alliance/src/types.rs b/frame/alliance/src/types.rs index 07a5cca9603e1..aec2a6e3cefb7 100644 --- a/frame/alliance/src/types.rs +++ b/frame/alliance/src/types.rs @@ -19,8 +19,7 @@ use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::{traits::ConstU32, BoundedVec}; use scale_info::TypeInfo; use sp_runtime::RuntimeDebug; -use sp_std::prelude::*; -use sp_std::convert::TryInto; +use sp_std::{convert::TryInto, prelude::*}; /// A Multihash instance that only supports the basic functionality and no hashing. #[derive( From d2925481c1a03dfe1b0207ade2898d4b591015de Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Sat, 30 Apr 2022 17:34:05 +0200 Subject: [PATCH 53/72] update lock --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 806875076afb5..82395dd5329a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5561,13 +5561,13 @@ dependencies = [ "frame-system", "hex", "hex-literal", - "log 0.4.14", + "log 0.4.16", "pallet-balances", "pallet-collective", "pallet-identity", "parity-scale-codec", "scale-info", - "sha2 0.10.1", + "sha2 0.10.2", "sp-core", "sp-io", "sp-runtime", From 6da40be2f8e3e8e7f6e95df4619e4ea2852d8ce6 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Sat, 30 Apr 2022 18:04:40 +0200 Subject: [PATCH 54/72] update recursion limit --- bin/node/runtime/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 1f01c3b6274bb..3bd9345c0c9ef 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -19,8 +19,8 @@ //! The Substrate runtime. This can be compiled with `#[no_std]`, ready for Wasm. #![cfg_attr(not(feature = "std"), no_std)] -// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. -#![recursion_limit = "256"] +// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 512. +#![recursion_limit = "512"] use codec::{Decode, Encode, MaxEncodedLen}; use frame_election_provider_support::{onchain, ExtendedBalance, SequentialPhragmen, VoteWeight}; From dc6400c699ef26f30e11fe6f5af4fc63aecc9902 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Sat, 30 Apr 2022 19:20:59 +0200 Subject: [PATCH 55/72] benchmarks --- frame/alliance/src/benchmarking.rs | 86 +++++------------------------- 1 file changed, 14 insertions(+), 72 deletions(-) diff --git a/frame/alliance/src/benchmarking.rs b/frame/alliance/src/benchmarking.rs index ba39108ba3d1f..307bc6e51dc7c 100644 --- a/frame/alliance/src/benchmarking.rs +++ b/frame/alliance/src/benchmarking.rs @@ -68,10 +68,6 @@ fn ally, I: 'static>(index: u32) -> T::AccountId { funded_account::("ally", index) } -fn candidate, I: 'static>(index: u32) -> T::AccountId { - funded_account::("candidate", index) -} - fn outsider, I: 'static>(index: u32) -> T::AccountId { funded_account::("outsider", index) } @@ -88,32 +84,22 @@ fn set_members, I: 'static>() { let fellows: BoundedVec<_, T::MaxMembersCount> = BoundedVec::try_from(vec![fellow::(1), fellow::(2)]).unwrap(); fellows.iter().for_each(|who| { - T::Currency::reserve(&who, T::CandidateDeposit::get()).unwrap(); - >::insert(&who, T::CandidateDeposit::get()); + T::Currency::reserve(&who, T::AllyDeposit::get()).unwrap(); + >::insert(&who, T::AllyDeposit::get()); }); Members::::insert(MemberRole::Fellow, fellows.clone()); let allies: BoundedVec<_, T::MaxMembersCount> = BoundedVec::try_from(vec![ally::(1)]).unwrap(); allies.iter().for_each(|who| { - T::Currency::reserve(&who, T::CandidateDeposit::get()).unwrap(); - >::insert(&who, T::CandidateDeposit::get()); + T::Currency::reserve(&who, T::AllyDeposit::get()).unwrap(); + >::insert(&who, T::AllyDeposit::get()); }); Members::::insert(MemberRole::Ally, allies); T::InitializeMembers::initialize_members(&[founders.as_slice(), fellows.as_slice()].concat()); } -fn set_candidates, I: 'static>(indexes: Vec) { - let candidates = indexes.into_iter().map(|i| candidate::(i)).collect::>(); - candidates.iter().for_each(|who| { - T::Currency::reserve(&who, T::CandidateDeposit::get()).unwrap(); - >::insert(&who, T::CandidateDeposit::get()); - }); - let candidates: BoundedVec<_, T::MaxCandidatesCount> = candidates.try_into().unwrap(); - Candidates::::put(candidates); -} - benchmarks_instance_pallet! { // This tests when proposal is created and queued as "proposed" propose_proposed { @@ -649,17 +635,15 @@ benchmarks_instance_pallet! { let outsider = outsider::(1); assert!(!Alliance::::is_member(&outsider)); - assert!(!Alliance::::is_candidate(&outsider)); assert_eq!(DepositOf::::get(&outsider), None); }: _(SystemOrigin::Signed(outsider.clone())) verify { assert!(!Alliance::::is_member(&outsider)); - assert!(Alliance::::is_candidate(&outsider)); - assert_eq!(DepositOf::::get(&outsider), Some(T::CandidateDeposit::get())); - assert_last_event::(Event::CandidateAdded { - candidate: outsider, + assert_eq!(DepositOf::::get(&outsider), Some(T::AllyDeposit::get())); + assert_last_event::(Event::NewAllyJoined { + ally: outsider, nominator: None, - reserved: Some(T::CandidateDeposit::get()) + reserved: Some(T::AllyDeposit::get()) }.into()); } @@ -671,62 +655,20 @@ benchmarks_instance_pallet! { let outsider = outsider::(1); assert!(!Alliance::::is_member(&outsider)); - assert!(!Alliance::::is_candidate(&outsider)); assert_eq!(DepositOf::::get(&outsider), None); let outsider_lookup: ::Source = T::Lookup::unlookup(outsider.clone()); }: _(SystemOrigin::Signed(founder1.clone()), outsider_lookup) verify { assert!(!Alliance::::is_member(&outsider)); - assert!(Alliance::::is_candidate(&outsider)); assert_eq!(DepositOf::::get(&outsider), None); - assert_last_event::(Event::CandidateAdded { - candidate: outsider, + assert_last_event::(Event::NewAllyJoined { + ally: outsider, nominator: Some(founder1), reserved: None }.into()); } - approve_candidate { - set_members::(); - set_candidates::(vec![1]); - - let candidate1 = candidate::(1); - assert!(Alliance::::is_candidate(&candidate1)); - assert!(!Alliance::::is_member(&candidate1)); - assert_eq!(DepositOf::::get(&candidate1), Some(T::CandidateDeposit::get())); - - let candidate1_lookup: ::Source = T::Lookup::unlookup(candidate1.clone()); - let call = Call::::approve_candidate { candidate: candidate1_lookup }; - let origin = T::MembershipManager::successful_origin(); - }: { call.dispatch_bypass_filter(origin)? } - verify { - assert!(!Alliance::::is_candidate(&candidate1)); - assert!(Alliance::::is_ally(&candidate1)); - assert_eq!(DepositOf::::get(&candidate1), Some(T::CandidateDeposit::get())); - assert_last_event::(Event::CandidateApproved { candidate: candidate1 }.into()); - } - - reject_candidate { - set_members::(); - set_candidates::(vec![1]); - - let candidate1 = candidate::(1); - assert!(Alliance::::is_candidate(&candidate1)); - assert!(!Alliance::::is_member(&candidate1)); - assert_eq!(DepositOf::::get(&candidate1), Some(T::CandidateDeposit::get())); - - let candidate1_lookup: ::Source = T::Lookup::unlookup(candidate1.clone()); - let call = Call::::reject_candidate { candidate: candidate1_lookup }; - let origin = T::MembershipManager::successful_origin(); - }: { call.dispatch_bypass_filter(origin)? } - verify { - assert!(!Alliance::::is_candidate(&candidate1)); - assert!(!Alliance::::is_member(&candidate1)); - assert_eq!(DepositOf::::get(&candidate1), None); - assert_last_event::(Event::CandidateRejected { candidate: candidate1 }.into()); - } - elevate_ally { set_members::(); @@ -750,14 +692,14 @@ benchmarks_instance_pallet! { assert!(Alliance::::is_fellow(&fellow2)); assert!(!Alliance::::is_up_for_kicking(&fellow2)); - assert_eq!(DepositOf::::get(&fellow2), Some(T::CandidateDeposit::get())); + assert_eq!(DepositOf::::get(&fellow2), Some(T::AllyDeposit::get())); }: _(SystemOrigin::Signed(fellow2.clone())) verify { assert!(!Alliance::::is_member(&fellow2)); assert_eq!(DepositOf::::get(&fellow2), None); assert_last_event::(Event::MemberRetired { member: fellow2, - unreserved: Some(T::CandidateDeposit::get()) + unreserved: Some(T::AllyDeposit::get()) }.into()); } @@ -770,7 +712,7 @@ benchmarks_instance_pallet! { assert!(Alliance::::is_member_of(&fellow2, MemberRole::Fellow)); assert!(Alliance::::is_up_for_kicking(&fellow2)); - assert_eq!(DepositOf::::get(&fellow2), Some(T::CandidateDeposit::get())); + assert_eq!(DepositOf::::get(&fellow2), Some(T::AllyDeposit::get())); let fellow2_lookup: ::Source = T::Lookup::unlookup(fellow2.clone()); let call = Call::::kick_member { who: fellow2_lookup }; @@ -781,7 +723,7 @@ benchmarks_instance_pallet! { assert_eq!(DepositOf::::get(&fellow2), None); assert_last_event::(Event::MemberKicked { member: fellow2, - slashed: Some(T::CandidateDeposit::get()) + slashed: Some(T::AllyDeposit::get()) }.into()); } From 428638ad8e01b20ad52abb5c3134d4080fd4eb52 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Sat, 30 Apr 2022 19:50:11 +0200 Subject: [PATCH 56/72] convert-try --- frame/alliance/src/benchmarking.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/alliance/src/benchmarking.rs b/frame/alliance/src/benchmarking.rs index 307bc6e51dc7c..264377b1905fb 100644 --- a/frame/alliance/src/benchmarking.rs +++ b/frame/alliance/src/benchmarking.rs @@ -18,7 +18,7 @@ //! Alliance pallet benchmarking. use sp_runtime::traits::{Bounded, Hash, StaticLookup}; -use sp_std::{mem::size_of, prelude::*}; +use sp_std::{convert::{TryFrom, TryInto}, mem::size_of, prelude::*}; use frame_benchmarking::{account, benchmarks_instance_pallet}; use frame_support::traits::{EnsureOrigin, Get, UnfilteredDispatchable}; From c029b0c8de70fbcdc4e5769f69787baff041c479 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Sat, 30 Apr 2022 20:33:31 +0200 Subject: [PATCH 57/72] benchmark assertions --- frame/alliance/src/benchmarking.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/frame/alliance/src/benchmarking.rs b/frame/alliance/src/benchmarking.rs index 264377b1905fb..5066cd709ed10 100644 --- a/frame/alliance/src/benchmarking.rs +++ b/frame/alliance/src/benchmarking.rs @@ -18,7 +18,11 @@ //! Alliance pallet benchmarking. use sp_runtime::traits::{Bounded, Hash, StaticLookup}; -use sp_std::{convert::{TryFrom, TryInto}, mem::size_of, prelude::*}; +use sp_std::{ + convert::{TryFrom, TryInto}, + mem::size_of, + prelude::* +}; use frame_benchmarking::{account, benchmarks_instance_pallet}; use frame_support::traits::{EnsureOrigin, Get, UnfilteredDispatchable}; @@ -638,8 +642,9 @@ benchmarks_instance_pallet! { assert_eq!(DepositOf::::get(&outsider), None); }: _(SystemOrigin::Signed(outsider.clone())) verify { - assert!(!Alliance::::is_member(&outsider)); - assert_eq!(DepositOf::::get(&outsider), Some(T::AllyDeposit::get())); + assert!(Alliance::::is_member_of(&outsider, MemberRole::Ally)); // outsider is now an ally + assert_eq!(DepositOf::::get(&outsider), Some(T::AllyDeposit::get())); // with a deposit + assert!(!Alliance::::has_voting_rights(&outsider)); // allies don't have voting rights assert_last_event::(Event::NewAllyJoined { ally: outsider, nominator: None, @@ -660,8 +665,9 @@ benchmarks_instance_pallet! { let outsider_lookup: ::Source = T::Lookup::unlookup(outsider.clone()); }: _(SystemOrigin::Signed(founder1.clone()), outsider_lookup) verify { - assert!(!Alliance::::is_member(&outsider)); - assert_eq!(DepositOf::::get(&outsider), None); + assert!(Alliance::::is_member_of(&outsider, MemberRole::Ally)); // outsider is now an ally + assert_eq!(DepositOf::::get(&outsider), None); // without a deposit + assert!(!Alliance::::has_voting_rights(&outsider)); // allies don't have voting rights assert_last_event::(Event::NewAllyJoined { ally: outsider, nominator: Some(founder1), From 5ed70ae33fa1456afc84e43408e89945b1f4e806 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Sat, 30 Apr 2022 20:37:33 +0200 Subject: [PATCH 58/72] fmt , --- frame/alliance/src/benchmarking.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/alliance/src/benchmarking.rs b/frame/alliance/src/benchmarking.rs index 5066cd709ed10..d6bfb54357af3 100644 --- a/frame/alliance/src/benchmarking.rs +++ b/frame/alliance/src/benchmarking.rs @@ -21,7 +21,7 @@ use sp_runtime::traits::{Bounded, Hash, StaticLookup}; use sp_std::{ convert::{TryFrom, TryInto}, mem::size_of, - prelude::* + prelude::*, }; use frame_benchmarking::{account, benchmarks_instance_pallet}; From 50726b32b4c01923a4c8cc2352e2048039b720e7 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Fri, 20 May 2022 06:35:44 +0200 Subject: [PATCH 59/72] cargo lock --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index cb6223304c2b3..83141a159bc6d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5130,7 +5130,7 @@ dependencies = [ "frame-system", "hex", "hex-literal", - "log 0.4.16", + "log", "pallet-balances", "pallet-collective", "pallet-identity", From 60d9434eaad3b24062737e9c27a2c0c517af97be Mon Sep 17 00:00:00 2001 From: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Date: Fri, 20 May 2022 14:50:24 +0200 Subject: [PATCH 60/72] Update frame/alliance/src/benchmarking.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- frame/alliance/src/benchmarking.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/alliance/src/benchmarking.rs b/frame/alliance/src/benchmarking.rs index d6bfb54357af3..24d53623628fa 100644 --- a/frame/alliance/src/benchmarking.rs +++ b/frame/alliance/src/benchmarking.rs @@ -1,6 +1,6 @@ // This file is part of Substrate. -// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd. +// Copyright (C) 2022 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); From 280971708f6fc6621a93c0ee0cb72e3b570be9ea Mon Sep 17 00:00:00 2001 From: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Date: Fri, 20 May 2022 14:52:27 +0200 Subject: [PATCH 61/72] Apply suggestions from code review Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- frame/collective/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index 20d17daa37322..36f0e7d41745c 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -678,7 +678,7 @@ impl, I: 'static> Pallet { proposal: Box<>::Proposal>, length_bound: MemberCount, ) -> Result<(u32, DispatchResultWithPostInfo), DispatchError> { - let proposal_len = proposal.using_encoded(|x| x.len()); + let proposal_len = proposal.encoded_size(); ensure!(proposal_len <= length_bound as usize, Error::::WrongProposalLength); let proposal_hash = T::Hashing::hash_of(&proposal); @@ -700,7 +700,7 @@ impl, I: 'static> Pallet { proposal: Box<>::Proposal>, length_bound: MemberCount, ) -> Result<(u32, u32), DispatchError> { - let proposal_len = proposal.using_encoded(|x| x.len()); + let proposal_len = proposal.encoded_size(); ensure!(proposal_len <= length_bound as usize, Error::::WrongProposalLength); let proposal_hash = T::Hashing::hash_of(&proposal); From f270ada849e011b8d49a760e4864f0d805287165 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Fri, 20 May 2022 15:17:20 +0200 Subject: [PATCH 62/72] add docs to public interfaces --- frame/alliance/src/lib.rs | 8 ++++++++ frame/collective/src/lib.rs | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index bf5bb9f08b699..2cf6e2ecea7ac 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -134,14 +134,21 @@ type NegativeImbalanceOf = <>::Currency as Currency< ::AccountId, >>::NegativeImbalance; +/// Interface required for identity verification. pub trait IdentityVerifier { + /// Function that returns whether an account has an identity registered with the identity + /// provider. fn has_identity(who: &AccountId, fields: u64) -> bool; + /// Whether an account has been deemed "good" by the provider. fn has_good_judgement(who: &AccountId) -> bool; + /// If the identity provider allows sub-accounts, provide the super of an account. Should + /// return `None` if the provider does not allow sub-accounts or if the account is not a sub. fn super_account_id(who: &AccountId) -> Option; } +/// The non-provider. Imposes no restrictions on account identity. impl IdentityVerifier for () { fn has_identity(_who: &AccountId, _fields: u64) -> bool { true @@ -156,6 +163,7 @@ impl IdentityVerifier for () { } } +/// The provider of a collective action interface, for example an instance of `pallet-collective`. pub trait ProposalProvider { fn propose_proposal( who: AccountId, diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index 36f0e7d41745c..61fda2b329b2c 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -437,7 +437,7 @@ pub mod pallet { let who = ensure_signed(origin)?; let members = Self::members(); ensure!(members.contains(&who), Error::::NotMember); - let proposal_len = proposal.using_encoded(|x| x.len()); + let proposal_len = proposal.encoded_size(); ensure!(proposal_len <= length_bound as usize, Error::::WrongProposalLength); let proposal_hash = T::Hashing::hash_of(&proposal); From 955854acb3c80f1baf73aa5ffe1d95ab50bc94c3 Mon Sep 17 00:00:00 2001 From: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Date: Mon, 23 May 2022 19:25:47 +0200 Subject: [PATCH 63/72] Apply suggestions from code review Co-authored-by: Squirrel --- bin/node/runtime/src/impls.rs | 3 +-- frame/alliance/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/bin/node/runtime/src/impls.rs b/bin/node/runtime/src/impls.rs index 26fdef2b6c384..aa111e09bb8a7 100644 --- a/bin/node/runtime/src/impls.rs +++ b/bin/node/runtime/src/impls.rs @@ -65,8 +65,7 @@ impl IdentityVerifier for AllianceIdentityVerifier { { judgements .iter() - .filter(|(_, j)| Judgement::KnownGood == *j || Judgement::Reasonable == *j) - .count() > 0 + .any(|(_, &j)| matches!(j, Judgement::KnownGood | Judgement::Reasonable)) } else { false } diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index 2cf6e2ecea7ac..95f58f7e7f4e1 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -948,7 +948,7 @@ impl, I: 'static> Pallet { Ok(()) })?; - if role == MemberRole::Founder || role == MemberRole::Fellow { + if matches!(role, MemberRole::Founder | MemberRole::Fellow) { let members = Self::votable_members_sorted(); T::MembershipChanged::change_members_sorted(&[], &[who.clone()], &members[..]); } From 944a612de78c036fc4542641d5cc12f4b52790e4 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Mon, 23 May 2022 20:03:02 +0200 Subject: [PATCH 64/72] fix build (node) --- bin/node/runtime/src/impls.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/node/runtime/src/impls.rs b/bin/node/runtime/src/impls.rs index aa111e09bb8a7..d2e292b2a870c 100644 --- a/bin/node/runtime/src/impls.rs +++ b/bin/node/runtime/src/impls.rs @@ -65,7 +65,7 @@ impl IdentityVerifier for AllianceIdentityVerifier { { judgements .iter() - .any(|(_, &j)| matches!(j, Judgement::KnownGood | Judgement::Reasonable)) + .any(|(_, j)| matches!(j, Judgement::KnownGood | Judgement::Reasonable)) } else { false } From 7c063c82adbcd6c355820b0e33f7ad4376948e98 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Mon, 23 May 2022 21:38:45 +0200 Subject: [PATCH 65/72] review --- frame/alliance/src/mock.rs | 3 +-- frame/alliance/src/types.rs | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/frame/alliance/src/mock.rs b/frame/alliance/src/mock.rs index a346eb48fe6e4..815bc74f3a2f3 100644 --- a/frame/alliance/src/mock.rs +++ b/frame/alliance/src/mock.rs @@ -145,8 +145,7 @@ impl IdentityVerifier for AllianceIdentityVerifier { { judgements .iter() - .filter(|(_, j)| Judgement::KnownGood == *j || Judgement::Reasonable == *j) - .count() > 0 + .any(|(_, j)| matches!(j, Judgement::KnownGood | Judgement::Reasonable)) } else { false } diff --git a/frame/alliance/src/types.rs b/frame/alliance/src/types.rs index aec2a6e3cefb7..8fb0ae96fd02d 100644 --- a/frame/alliance/src/types.rs +++ b/frame/alliance/src/types.rs @@ -84,7 +84,7 @@ impl Cid { const SHA2_256: u64 = 0x12; let digest = sha2_256_digest.into(); - assert!(digest.len() == 32); + assert_eq!(digest.len(), 32); Self { version: Version::V0, From 0e39490e37f74ab8a7b9f3c2af4ff6bdb4c57bec Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Wed, 8 Jun 2022 21:02:40 +0200 Subject: [PATCH 66/72] use EitherOfDiverse --- bin/node/runtime/src/lib.rs | 6 +++--- frame/alliance/src/mock.rs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 8234d72657f82..91daa69ba1253 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1536,15 +1536,15 @@ parameter_types! { impl pallet_alliance::Config for Runtime { type Event = Event; type Proposal = Call; - type AdminOrigin = EnsureOneOf< + type AdminOrigin = EitherOfDiverse< EnsureRoot, pallet_collective::EnsureProportionMoreThan, >; - type MembershipManager = EnsureOneOf< + type MembershipManager = EitherOfDiverse< EnsureRoot, pallet_collective::EnsureProportionMoreThan, >; - type AnnouncementOrigin = EnsureOneOf< + type AnnouncementOrigin = EitherOfDiverse< EnsureRoot, pallet_collective::EnsureProportionMoreThan, >; diff --git a/frame/alliance/src/mock.rs b/frame/alliance/src/mock.rs index 815bc74f3a2f3..c8c5588ae65db 100644 --- a/frame/alliance/src/mock.rs +++ b/frame/alliance/src/mock.rs @@ -27,7 +27,7 @@ use sp_std::convert::{TryFrom, TryInto}; pub use frame_support::{ assert_ok, ord_parameter_types, parameter_types, - traits::{EnsureOneOf, GenesisBuild, SortedMembers}, + traits::{EitherOfDiverse, GenesisBuild, SortedMembers}, BoundedVec, }; use frame_system::{EnsureRoot, EnsureSignedBy}; @@ -115,8 +115,8 @@ ord_parameter_types! { pub const Four: u64 = 4; pub const Five: u64 = 5; } -type EnsureOneOrRoot = EnsureOneOf, EnsureSignedBy>; -type EnsureTwoOrRoot = EnsureOneOf, EnsureSignedBy>; +type EnsureOneOrRoot = EitherOfDiverse, EnsureSignedBy>; +type EnsureTwoOrRoot = EitherOfDiverse, EnsureSignedBy>; impl pallet_identity::Config for Test { type Event = Event; From d89078de0fc8b61ddb6b0e373658a5c2ebb08d2e Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Thu, 9 Jun 2022 12:56:43 +0200 Subject: [PATCH 67/72] update cargo toml --- frame/alliance/Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frame/alliance/Cargo.toml b/frame/alliance/Cargo.toml index 1e6823234b487..706827708ce88 100644 --- a/frame/alliance/Cargo.toml +++ b/frame/alliance/Cargo.toml @@ -2,11 +2,11 @@ name = "pallet-alliance" version = "4.0.0-dev" authors = ["Parity Technologies "] -edition = "2018" +edition = "2021" license = "Apache-2.0" -homepage = "https://substrate.dev" +homepage = "https://docs.substrate.io/" repository = "https://github.com/paritytech/substrate/" -description = "The Alliance Pallet provides a DAO to form an industry group." +description = "The Alliance pallet provides a collective for standard-setting industry collaboration." readme = "README.md" [package.metadata.docs.rs] From 8338125bc02a3e333f42da109d5bb42bead78d20 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Fri, 10 Jun 2022 16:29:25 +0200 Subject: [PATCH 68/72] make all dispatch class Normal --- frame/alliance/src/lib.rs | 45 ++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index 95f58f7e7f4e1..8d8d4f2e04e03 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -495,14 +495,11 @@ pub mod pallet { /// Add a new proposal to be voted on. /// /// Requires the sender to be a founder or fellow. - #[pallet::weight(( - T::WeightInfo::propose_proposed( - *length_bound, // B - T::MaxFounders::get(), // X - T::MaxFellows::get(), // Y - T::MaxProposals::get(), // P2 - ), - DispatchClass::Normal + #[pallet::weight(T::WeightInfo::propose_proposed( + *length_bound, // B + T::MaxFounders::get(), // X + T::MaxFellows::get(), // Y + T::MaxProposals::get(), // P2 ))] pub fn propose( origin: OriginFor, @@ -525,10 +522,7 @@ pub mod pallet { /// Add an aye or nay vote for the sender to the given proposal. /// /// Requires the sender to be a founder or fellow. - #[pallet::weight(( - T::WeightInfo::vote(T::MaxFounders::get(), T::MaxFellows::get()), - DispatchClass::Operational - ))] + #[pallet::weight(T::WeightInfo::vote(T::MaxFounders::get(), T::MaxFellows::get()))] pub fn vote( origin: OriginFor, proposal: T::Hash, @@ -565,21 +559,18 @@ pub mod pallet { /// Close a vote that is either approved, disapproved, or whose voting period has ended. /// /// Requires the sender to be a founder or fellow. - #[pallet::weight(( - { - let b = *length_bound; - let x = T::MaxFounders::get(); - let y = T::MaxFellows::get(); - let p1 = *proposal_weight_bound; - let p2 = T::MaxProposals::get(); - T::WeightInfo::close_early_approved(b, x, y, p2) - .max(T::WeightInfo::close_early_disapproved(x, y, p2)) - .max(T::WeightInfo::close_approved(b, x, y, p2)) - .max(T::WeightInfo::close_disapproved(x, y, p2)) - .saturating_add(p1) - }, - DispatchClass::Operational - ))] + #[pallet::weight({ + let b = *length_bound; + let x = T::MaxFounders::get(); + let y = T::MaxFellows::get(); + let p1 = *proposal_weight_bound; + let p2 = T::MaxProposals::get(); + T::WeightInfo::close_early_approved(b, x, y, p2) + .max(T::WeightInfo::close_early_disapproved(x, y, p2)) + .max(T::WeightInfo::close_approved(b, x, y, p2)) + .max(T::WeightInfo::close_disapproved(x, y, p2)) + .saturating_add(p1) + })] pub fn close( origin: OriginFor, proposal_hash: T::Hash, From fdf4dc90f80ab41282d6ae34a8e631ca7c4f6eae Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Fri, 10 Jun 2022 18:53:45 +0200 Subject: [PATCH 69/72] change blacklist to unscrupulous --- bin/node/runtime/src/lib.rs | 2 +- frame/alliance/README.md | 19 ++-- frame/alliance/src/benchmarking.rs | 44 ++++----- frame/alliance/src/lib.rs | 154 +++++++++++++++-------------- frame/alliance/src/mock.rs | 2 +- frame/alliance/src/tests.rs | 58 +++++------ frame/alliance/src/weights.rs | 36 +++---- 7 files changed, 162 insertions(+), 153 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 91daa69ba1253..8e854b770a4ff 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1561,7 +1561,7 @@ impl pallet_alliance::Config for Runtime { type MaxFounders = MaxFounders; type MaxFellows = MaxFellows; type MaxAllies = MaxAllies; - type MaxBlacklistCount = ConstU32<100>; + type MaxUnscrupulousItems = ConstU32<100>; type MaxWebsiteUrlLength = ConstU32<255>; type MaxAnnouncementsCount = ConstU32<100>; type MaxMembersCount = AllianceMaxMembers; diff --git a/frame/alliance/README.md b/frame/alliance/README.md index f9d2199980d46..f0900c84cbd85 100644 --- a/frame/alliance/README.md +++ b/frame/alliance/README.md @@ -1,7 +1,7 @@ # Alliance Pallet -The Alliance Pallet provides a collective that curates a blacklist of accounts and URLs, -presumably agreed by the voting members to be bad actors. The alliance +The Alliance Pallet provides a collective that curates a list of accounts and URLs, deemed by +the voting members to be unscrupulous actors. The alliance - provides a set of ethics against bad behavior, and - provides recognition and influence for those teams that contribute something back to the @@ -13,8 +13,8 @@ The network initializes the Alliance via a Root call. After that, anyone with an identity and website can join as an Ally. The `MembershipManager` origin can elevate Allies to Fellows, giving them voting rights within the Alliance. -Voting members of the Alliance maintain a blacklist of accounts and websites. Members can also -vote to update the Alliance's rule and make announcements. +Voting members of the Alliance maintain a list of accounts and websites. Members can also vote +to update the Alliance's rule and make announcements. ### Terminology @@ -30,8 +30,8 @@ vote to update the Alliance's rule and make announcements. - Ally: An account who would like to join the alliance. To become a voting member, Fellow or Founder, it will need approval from the `MembershipManager` origin. Any account can join as an Ally either by placing a deposit or by nomination from a voting member. -- Blacklist: A list of bad websites and addresses, items can be added or removed by Founders and - Fellows. +- Unscrupulous List: A list of bad websites and addresses, items can be added or removed by + Founders and Fellows. ## Interface @@ -55,8 +55,9 @@ vote to update the Alliance's rule and make announcements. - `nominate_ally` - Nominate a non-member to become an Ally, without deposit. - `elevate_ally` - Approve an ally to become a Fellow. - `kick_member` - Kick a member and slash its deposit. -- `add_blacklist_items` - Add some items, either accounts or websites, to the blacklist. -- `remove_blacklist_items` - Remove some items from the blacklist. +- `add_unscrupulous_items` - Add some items, either accounts or websites, to the list of + unscrupulous items. +- `remove_unscrupulous_items` - Remove some items from the list of unscrupulous items. #### For Members (Only Founders) @@ -64,4 +65,4 @@ vote to update the Alliance's rule and make announcements. #### Root Calls -- `init_founders` - Initialize the founding members. \ No newline at end of file +- `init_founders` - Initialize the founding members. diff --git a/frame/alliance/src/benchmarking.rs b/frame/alliance/src/benchmarking.rs index 24d53623628fa..27021375d8e97 100644 --- a/frame/alliance/src/benchmarking.rs +++ b/frame/alliance/src/benchmarking.rs @@ -76,8 +76,8 @@ fn outsider, I: 'static>(index: u32) -> T::AccountId { funded_account::("outsider", index) } -fn blacklist, I: 'static>(index: u32) -> T::AccountId { - funded_account::("blacklist", index) +fn unscrupulous_list, I: 'static>(index: u32) -> T::AccountId { + funded_account::("unscrupulous", index) } fn set_members, I: 'static>() { @@ -733,54 +733,54 @@ benchmarks_instance_pallet! { }.into()); } - add_blacklist_items { - let n in 1 .. T::MaxBlacklistCount::get(); + add_unscrupulous_items { + let n in 1 .. T::MaxUnscrupulousItems::get(); let l in 1 .. T::MaxWebsiteUrlLength::get(); set_members::(); - let accounts = (0 .. n).map(|i| blacklist::(i)).collect::>(); + let accounts = (0 .. n).map(|i| unscrupulous_list::(i)).collect::>(); let websites = (0 .. n).map(|i| -> BoundedVec { BoundedVec::try_from(vec![i as u8; l as usize]).unwrap() }).collect::>(); - let mut blacklist = Vec::with_capacity(accounts.len() + websites.len()); - blacklist.extend(accounts.into_iter().map(BlacklistItem::AccountId)); - blacklist.extend(websites.into_iter().map(BlacklistItem::Website)); + let mut unscrupulous_list = Vec::with_capacity(accounts.len() + websites.len()); + unscrupulous_list.extend(accounts.into_iter().map(UnscrupulousItem::AccountId)); + unscrupulous_list.extend(websites.into_iter().map(UnscrupulousItem::Website)); - let call = Call::::add_blacklist_items { items: blacklist.clone() }; + let call = Call::::add_unscrupulous_items { items: unscrupulous_list.clone() }; let origin = T::AnnouncementOrigin::successful_origin(); }: { call.dispatch_bypass_filter(origin)? } verify { - assert_last_event::(Event::BlacklistItemsAdded { items: blacklist }.into()); + assert_last_event::(Event::UnscrupulousItemAdded { items: unscrupulous_list }.into()); } - remove_blacklist_items { - let n in 1 .. T::MaxBlacklistCount::get(); + remove_unscrupulous_items { + let n in 1 .. T::MaxUnscrupulousItems::get(); let l in 1 .. T::MaxWebsiteUrlLength::get(); set_members::(); - let mut accounts = (0 .. n).map(|i| blacklist::(i)).collect::>(); + let mut accounts = (0 .. n).map(|i| unscrupulous_list::(i)).collect::>(); accounts.sort(); - let accounts: BoundedVec<_, T::MaxBlacklistCount> = accounts.try_into().unwrap(); - AccountBlacklist::::put(accounts.clone()); + let accounts: BoundedVec<_, T::MaxUnscrupulousItems> = accounts.try_into().unwrap(); + UnscrupulousAccounts::::put(accounts.clone()); let mut websites = (0 .. n).map(|i| -> BoundedVec<_, T::MaxWebsiteUrlLength> { BoundedVec::try_from(vec![i as u8; l as usize]).unwrap() }).collect::>(); websites.sort(); - let websites: BoundedVec<_, T::MaxBlacklistCount> = websites.try_into().unwrap(); - WebsiteBlacklist::::put(websites.clone()); + let websites: BoundedVec<_, T::MaxUnscrupulousItems> = websites.try_into().unwrap(); + UnscrupulousWebsites::::put(websites.clone()); - let mut blacklist = Vec::with_capacity(accounts.len() + websites.len()); - blacklist.extend(accounts.into_iter().map(BlacklistItem::AccountId)); - blacklist.extend(websites.into_iter().map(BlacklistItem::Website)); + let mut unscrupulous_list = Vec::with_capacity(accounts.len() + websites.len()); + unscrupulous_list.extend(accounts.into_iter().map(UnscrupulousItem::AccountId)); + unscrupulous_list.extend(websites.into_iter().map(UnscrupulousItem::Website)); - let call = Call::::remove_blacklist_items { items: blacklist.clone() }; + let call = Call::::remove_unscrupulous_items { items: unscrupulous_list.clone() }; let origin = T::AnnouncementOrigin::successful_origin(); }: { call.dispatch_bypass_filter(origin)? } verify { - assert_last_event::(Event::BlacklistItemsRemoved { items: blacklist }.into()); + assert_last_event::(Event::UnscrupulousItemRemoved { items: unscrupulous_list }.into()); } impl_benchmark_test_suite!(Alliance, crate::mock::new_bench_ext(), crate::mock::Test); diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index 8d8d4f2e04e03..f9ce168252599 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -17,8 +17,8 @@ //! # Alliance Pallet //! -//! The Alliance Pallet provides a collective that curates a blacklist of accounts and URLs, -//! presumably agreed by the voting members to be bad actors. The alliance +//! The Alliance Pallet provides a collective that curates a list of accounts and URLs, deemed by +//! the voting members to be unscrupulous actors. The alliance //! //! - provides a set of ethics against bad behavior, and //! - provides recognition and influence for those teams that contribute something back to the @@ -30,8 +30,8 @@ //! identity and website can join as an Ally. The `MembershipManager` origin can elevate Allies to //! Fellows, giving them voting rights within the Alliance. //! -//! Voting members of the Alliance maintain a blacklist of accounts and websites. Members can also -//! vote to update the Alliance's rule and make announcements. +//! Voting members of the Alliance maintain a list of accounts and websites. Members can also vote +//! to update the Alliance's rule and make announcements. //! //! ### Terminology //! @@ -47,8 +47,8 @@ //! - Ally: An account who would like to join the alliance. To become a voting member, Fellow or //! Founder, it will need approval from the `MembershipManager` origin. Any account can join as an //! Ally either by placing a deposit or by nomination from a voting member. -//! - Blacklist: A list of bad websites and addresses, items can be added or removed by Founders and -//! Fellows. +//! - Unscrupulous List: A list of bad websites and addresses, items can be added or removed by +//! Founders and Fellows. //! //! ## Interface //! @@ -72,8 +72,9 @@ //! - `nominate_ally` - Nominate a non-member to become an Ally, without deposit. //! - `elevate_ally` - Approve an ally to become a Fellow. //! - `kick_member` - Kick a member and slash its deposit. -//! - `add_blacklist_items` - Add some items, either accounts or websites, to the blacklist. -//! - `remove_blacklist_items` - Remove some items from the blacklist. +//! - `add_unscrupulous_items` - Add some items, either accounts or websites, to the list of +//! unscrupulous items. +//! - `remove_unscrupulous_items` - Remove some items from the list of unscrupulous items. //! //! #### For Members (Only Founders) //! @@ -199,14 +200,15 @@ pub enum MemberRole { Ally, } -/// The type of item within the blacklist. +/// The type of item that may be deemed unscrupulous. #[derive(Clone, PartialEq, Eq, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)] -pub enum BlacklistItem { +pub enum UnscrupulousItem { AccountId(AccountId), Website(Url), } -type BlacklistItemOf = BlacklistItem<::AccountId, UrlOf>; +type UnscrupulousItemOf = + UnscrupulousItem<::AccountId, UrlOf>; #[frame_support::pallet] pub mod pallet { @@ -236,7 +238,7 @@ pub mod pallet { /// Origin that manages entry and forcible discharge from the Alliance. type MembershipManager: EnsureOrigin; - /// Origin for making announcements and adding/removing items from the blacklist. + /// Origin for making announcements and adding/removing unscrupulous items. type AnnouncementOrigin: EnsureOrigin; /// The currency used for deposits. @@ -281,9 +283,9 @@ pub mod pallet { /// + This pallet assumes that dependencies keep to the limit without enforcing it. type MaxAllies: Get; - /// The maximum length of the blacklist supported by the pallet. + /// The maximum number of the unscrupulous items supported by the pallet. #[pallet::constant] - type MaxBlacklistCount: Get; + type MaxUnscrupulousItems: Get; /// The maximum length of a website URL. #[pallet::constant] @@ -324,12 +326,15 @@ pub mod pallet { NoVotingRights, /// Account is already an elevated (fellow) member. AlreadyElevated, - /// Item is already in the blacklist. - AlreadyInBlacklist, - /// Item is not blacklisted. - NotInBlacklist, - /// Length of blacklist exceeds `MaxBlacklist`. - TooManyItemsInBlacklist, + /// Item is already listed as unscrupulous. + AlreadyUnscrupulous, + /// Account has been deemed unscrupulous by the Alliance and is not welcome to join or be + /// nominated. + AccountNonGrata, + /// Item has not been deemed unscrupulous. + NotListedAsUnscrupulous, + /// The number of unscrupulous items exceeds `MaxUnscrupulousItems`. + TooManyUnscrupulousItems, /// Length of website URL exceeds `MaxWebsiteUrlLength`. TooLongWebsiteUrl, /// Balance is insufficient for the required deposit. @@ -377,10 +382,10 @@ pub mod pallet { MemberRetired { member: T::AccountId, unreserved: Option> }, /// A member has been kicked out with its deposit slashed. MemberKicked { member: T::AccountId, slashed: Option> }, - /// Accounts or websites have been added into the blacklist. - BlacklistItemsAdded { items: Vec> }, - /// Accounts or websites have been removed from the blacklist. - BlacklistItemsRemoved { items: Vec> }, + /// Accounts or websites have been added into the list of unscrupulous items. + UnscrupulousItemAdded { items: Vec> }, + /// Accounts or websites have been removed from the list of unscrupulous items. + UnscrupulousItemRemoved { items: Vec> }, } #[pallet::genesis_config] @@ -478,17 +483,18 @@ pub mod pallet { pub type UpForKicking, I: 'static = ()> = StorageMap<_, Blake2_128Concat, T::AccountId, bool, ValueQuery>; - /// The current blacklist of accounts. These accounts cannot submit candidacy. + /// The current list of accounts deemed unscrupulous. These accounts non grata cannot submit + /// candidacy. #[pallet::storage] - #[pallet::getter(fn account_blacklist)] - pub type AccountBlacklist, I: 'static = ()> = - StorageValue<_, BoundedVec, ValueQuery>; + #[pallet::getter(fn unscrupulous_accounts)] + pub type UnscrupulousAccounts, I: 'static = ()> = + StorageValue<_, BoundedVec, ValueQuery>; - /// The current blacklist of websites. + /// The current list of websites deemed unscrupulous. #[pallet::storage] - #[pallet::getter(fn website_blacklist)] - pub type WebsiteBlacklist, I: 'static = ()> = - StorageValue<_, BoundedVec, T::MaxBlacklistCount>, ValueQuery>; + #[pallet::getter(fn unscrupulous_websites)] + pub type UnscrupulousWebsites, I: 'static = ()> = + StorageValue<_, BoundedVec, T::MaxUnscrupulousItems>, ValueQuery>; #[pallet::call] impl, I: 'static> Pallet { @@ -699,8 +705,8 @@ pub mod pallet { pub fn join_alliance(origin: OriginFor) -> DispatchResult { let who = ensure_signed(origin)?; - // Blacklisted accounts cannot join. - ensure!(!Self::account_blacklisted(&who), Error::::AlreadyInBlacklist); + // Unscrupulous accounts are non grata. + ensure!(!Self::is_unscrupulous_account(&who), Error::::AccountNonGrata); ensure!(!Self::is_member(&who), Error::::AlreadyMember); // check user self or parent should has verified identity to reuse display name and // website. @@ -731,8 +737,8 @@ pub mod pallet { ensure!(Self::has_voting_rights(&nominator), Error::::NoVotingRights); let who = T::Lookup::lookup(who)?; - // Individual voting members cannot nominate blacklisted accounts. - ensure!(!Self::account_blacklisted(&who), Error::::AlreadyInBlacklist); + // Individual voting members cannot nominate accounts non grata. + ensure!(!Self::is_unscrupulous_account(&who), Error::::AccountNonGrata); ensure!(!Self::is_member(&who), Error::::AlreadyMember); // check user self or parent should has verified identity to reuse display name and // website. @@ -806,21 +812,21 @@ pub mod pallet { Ok(()) } - /// Add accounts or websites to the blacklist. - #[pallet::weight(T::WeightInfo::add_blacklist_items(items.len() as u32, T::MaxWebsiteUrlLength::get()))] - pub fn add_blacklist_items( + /// Add accounts or websites to the list of unscrupulous items. + #[pallet::weight(T::WeightInfo::add_unscrupulous_items(items.len() as u32, T::MaxWebsiteUrlLength::get()))] + pub fn add_unscrupulous_items( origin: OriginFor, - items: Vec>, + items: Vec>, ) -> DispatchResult { T::AnnouncementOrigin::ensure_origin(origin)?; let mut accounts = vec![]; let mut webs = vec![]; for info in items.iter() { - ensure!(!Self::is_in_blacklist(info), Error::::AlreadyInBlacklist); + ensure!(!Self::is_unscrupulous(info), Error::::AlreadyUnscrupulous); match info { - BlacklistItem::AccountId(who) => accounts.push(who.clone()), - BlacklistItem::Website(url) => { + UnscrupulousItem::AccountId(who) => accounts.push(who.clone()), + UnscrupulousItem::Website(url) => { ensure!( url.len() as u32 <= T::MaxWebsiteUrlLength::get(), Error::::TooLongWebsiteUrl @@ -830,29 +836,31 @@ pub mod pallet { } } - Self::do_add_blacklist_items(&mut accounts, &mut webs)?; - Self::deposit_event(Event::BlacklistItemsAdded { items }); + Self::do_add_unscrupulous_items(&mut accounts, &mut webs)?; + Self::deposit_event(Event::UnscrupulousItemAdded { items }); Ok(()) } - /// Remove accounts or websites from the blacklist. - #[pallet::weight(>::WeightInfo::remove_blacklist_items(items.len() as u32, T::MaxWebsiteUrlLength::get()))] - pub fn remove_blacklist_items( + /// Deem an item no longer unscrupulous. + #[pallet::weight(>::WeightInfo::remove_unscrupulous_items( + items.len() as u32, T::MaxWebsiteUrlLength::get() + ))] + pub fn remove_unscrupulous_items( origin: OriginFor, - items: Vec>, + items: Vec>, ) -> DispatchResult { T::AnnouncementOrigin::ensure_origin(origin)?; let mut accounts = vec![]; let mut webs = vec![]; for info in items.iter() { - ensure!(Self::is_in_blacklist(info), Error::::NotInBlacklist); + ensure!(Self::is_unscrupulous(info), Error::::NotListedAsUnscrupulous); match info { - BlacklistItem::AccountId(who) => accounts.push(who.clone()), - BlacklistItem::Website(url) => webs.push(url.clone()), + UnscrupulousItem::AccountId(who) => accounts.push(who.clone()), + UnscrupulousItem::Website(url) => webs.push(url.clone()), } } - Self::do_remove_blacklist_items(&mut accounts, &mut webs)?; - Self::deposit_event(Event::BlacklistItemsRemoved { items }); + Self::do_remove_unscrupulous_items(&mut accounts, &mut webs)?; + Self::deposit_event(Event::UnscrupulousItemRemoved { items }); Ok(()) } } @@ -946,37 +954,37 @@ impl, I: 'static> Pallet { Ok(()) } - /// Check if an item is blacklisted. - fn is_in_blacklist(info: &BlacklistItemOf) -> bool { + /// Check if an item is listed as unscrupulous. + fn is_unscrupulous(info: &UnscrupulousItemOf) -> bool { match info { - BlacklistItem::Website(url) => >::get().contains(url), - BlacklistItem::AccountId(who) => >::get().contains(who), + UnscrupulousItem::Website(url) => >::get().contains(url), + UnscrupulousItem::AccountId(who) => >::get().contains(who), } } - /// Check if a user is blacklisted. - fn account_blacklisted(who: &T::AccountId) -> bool { - >::get().contains(who) + /// Check if an account is listed as unscrupulous. + fn is_unscrupulous_account(who: &T::AccountId) -> bool { + >::get().contains(who) } - /// Add identity info to the blacklist set. - fn do_add_blacklist_items( + /// Add item to the unscrupulous list. + fn do_add_unscrupulous_items( new_accounts: &mut Vec, new_webs: &mut Vec>, ) -> DispatchResult { if !new_accounts.is_empty() { - >::try_mutate(|accounts| -> DispatchResult { + >::try_mutate(|accounts| -> DispatchResult { accounts .try_append(new_accounts) - .map_err(|_| Error::::TooManyItemsInBlacklist)?; + .map_err(|_| Error::::TooManyUnscrupulousItems)?; accounts.sort(); Ok(()) })?; } if !new_webs.is_empty() { - >::try_mutate(|webs| -> DispatchResult { - webs.try_append(new_webs).map_err(|_| Error::::TooManyItemsInBlacklist)?; + >::try_mutate(|webs| -> DispatchResult { + webs.try_append(new_webs).map_err(|_| Error::::TooManyUnscrupulousItems)?; webs.sort(); Ok(()) @@ -986,25 +994,25 @@ impl, I: 'static> Pallet { Ok(()) } - /// Remove identity info from the blacklist. - fn do_remove_blacklist_items( + /// Remove item from the unscrupulous list. + fn do_remove_unscrupulous_items( out_accounts: &mut Vec, out_webs: &mut Vec>, ) -> DispatchResult { if !out_accounts.is_empty() { - >::try_mutate(|accounts| -> DispatchResult { + >::try_mutate(|accounts| -> DispatchResult { for who in out_accounts.iter() { let pos = - accounts.binary_search(who).ok().ok_or(Error::::NotInBlacklist)?; + accounts.binary_search(who).ok().ok_or(Error::::NotListedAsUnscrupulous)?; accounts.remove(pos); } Ok(()) })?; } if !out_webs.is_empty() { - >::try_mutate(|webs| -> DispatchResult { + >::try_mutate(|webs| -> DispatchResult { for web in out_webs.iter() { - let pos = webs.binary_search(web).ok().ok_or(Error::::NotInBlacklist)?; + let pos = webs.binary_search(web).ok().ok_or(Error::::NotListedAsUnscrupulous)?; webs.remove(pos); } Ok(()) diff --git a/frame/alliance/src/mock.rs b/frame/alliance/src/mock.rs index c8c5588ae65db..d6e9a92a10dec 100644 --- a/frame/alliance/src/mock.rs +++ b/frame/alliance/src/mock.rs @@ -219,7 +219,7 @@ impl Config for Test { type MaxFounders = MaxFounders; type MaxFellows = MaxFellows; type MaxAllies = MaxAllies; - type MaxBlacklistCount = ConstU32<100>; + type MaxUnscrupulousItems = ConstU32<100>; type MaxWebsiteUrlLength = ConstU32<255>; type MaxAnnouncementsCount = ConstU32<100>; type MaxMembersCount = MaxMembers; diff --git a/frame/alliance/src/tests.rs b/frame/alliance/src/tests.rs index c930f5c8cf9d6..e116f44d82f48 100644 --- a/frame/alliance/src/tests.rs +++ b/frame/alliance/src/tests.rs @@ -282,18 +282,18 @@ fn join_alliance_works() { // check already member assert_noop!(Alliance::join_alliance(Origin::signed(1)), Error::::AlreadyMember); - // check already in blacklist - assert_ok!(Alliance::add_blacklist_items( + // check already listed as unscrupulous + assert_ok!(Alliance::add_unscrupulous_items( Origin::signed(3), - vec![BlacklistItem::AccountId(4)] + vec![UnscrupulousItem::AccountId(4)] )); assert_noop!( Alliance::join_alliance(Origin::signed(4)), - Error::::AlreadyInBlacklist + Error::::AccountNonGrata ); - assert_ok!(Alliance::remove_blacklist_items( + assert_ok!(Alliance::remove_unscrupulous_items( Origin::signed(3), - vec![BlacklistItem::AccountId(4)] + vec![UnscrupulousItem::AccountId(4)] )); // check deposit funds @@ -340,18 +340,18 @@ fn nominate_ally_works() { Error::::NoVotingRights ); - // check already in blacklist - assert_ok!(Alliance::add_blacklist_items( + // check already listed as unscrupulous + assert_ok!(Alliance::add_unscrupulous_items( Origin::signed(3), - vec![BlacklistItem::AccountId(4)] + vec![UnscrupulousItem::AccountId(4)] )); assert_noop!( Alliance::nominate_ally(Origin::signed(1), 4), - Error::::AlreadyInBlacklist + Error::::AccountNonGrata ); - assert_ok!(Alliance::remove_blacklist_items( + assert_ok!(Alliance::remove_unscrupulous_items( Origin::signed(3), - vec![BlacklistItem::AccountId(4)] + vec![UnscrupulousItem::AccountId(4)] )); // success to nominate @@ -436,42 +436,42 @@ fn kick_member_works() { } #[test] -fn add_blacklist_items_works() { +fn add_unscrupulous_items_works() { new_test_ext().execute_with(|| { - assert_ok!(Alliance::add_blacklist_items( + assert_ok!(Alliance::add_unscrupulous_items( Origin::signed(3), vec![ - BlacklistItem::AccountId(3), - BlacklistItem::Website("abc".as_bytes().to_vec().try_into().unwrap()) + UnscrupulousItem::AccountId(3), + UnscrupulousItem::Website("abc".as_bytes().to_vec().try_into().unwrap()) ] )); - assert_eq!(Alliance::account_blacklist().into_inner(), vec![3]); - assert_eq!(Alliance::website_blacklist().into_inner(), vec!["abc".as_bytes().to_vec()]); + assert_eq!(Alliance::unscrupulous_accounts().into_inner(), vec![3]); + assert_eq!(Alliance::unscrupulous_websites().into_inner(), vec!["abc".as_bytes().to_vec()]); assert_noop!( - Alliance::add_blacklist_items(Origin::signed(3), vec![BlacklistItem::AccountId(3)]), - Error::::AlreadyInBlacklist + Alliance::add_unscrupulous_items(Origin::signed(3), vec![UnscrupulousItem::AccountId(3)]), + Error::::AlreadyUnscrupulous ); }); } #[test] -fn remove_blacklist_items_works() { +fn remove_unscrupulous_items_works() { new_test_ext().execute_with(|| { assert_noop!( - Alliance::remove_blacklist_items(Origin::signed(3), vec![BlacklistItem::AccountId(3)]), - Error::::NotInBlacklist + Alliance::remove_unscrupulous_items(Origin::signed(3), vec![UnscrupulousItem::AccountId(3)]), + Error::::NotListedAsUnscrupulous ); - assert_ok!(Alliance::add_blacklist_items( + assert_ok!(Alliance::add_unscrupulous_items( Origin::signed(3), - vec![BlacklistItem::AccountId(3)] + vec![UnscrupulousItem::AccountId(3)] )); - assert_eq!(Alliance::account_blacklist(), vec![3]); - assert_ok!(Alliance::remove_blacklist_items( + assert_eq!(Alliance::unscrupulous_accounts(), vec![3]); + assert_ok!(Alliance::remove_unscrupulous_items( Origin::signed(3), - vec![BlacklistItem::AccountId(3)] + vec![UnscrupulousItem::AccountId(3)] )); - assert_eq!(Alliance::account_blacklist(), Vec::::new()); + assert_eq!(Alliance::unscrupulous_accounts(), Vec::::new()); }); } diff --git a/frame/alliance/src/weights.rs b/frame/alliance/src/weights.rs index 6efd3c5885f29..495dd1b83df93 100644 --- a/frame/alliance/src/weights.rs +++ b/frame/alliance/src/weights.rs @@ -61,8 +61,8 @@ pub trait WeightInfo { fn elevate_ally() -> Weight; fn retire() -> Weight; fn kick_member() -> Weight; - fn add_blacklist_items(n: u32, l: u32, ) -> Weight; - fn remove_blacklist_items(n: u32, l: u32, ) -> Weight; + fn add_unscrupulous_items(n: u32, l: u32, ) -> Weight; + fn remove_unscrupulous_items(n: u32, l: u32, ) -> Weight; } /// Weights for pallet_alliance using the Substrate node and recommended hardware. @@ -202,7 +202,7 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } - // Storage: Alliance AccountBlacklist (r:1 w:0) + // Storage: Alliance UnscrupulousAccounts (r:1 w:0) // Storage: Alliance Members (r:4 w:0) // Storage: System Account (r:1 w:1) // Storage: Alliance DepositOf (r:0 w:1) @@ -212,7 +212,7 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().writes(3 as Weight)) } // Storage: Alliance Members (r:4 w:0) - // Storage: Alliance AccountBlacklist (r:1 w:0) + // Storage: Alliance UnscrupulousAccounts (r:1 w:0) fn nominate_ally() -> Weight { (44_764_000 as Weight) .saturating_add(T::DbWeight::get().reads(6 as Weight)) @@ -251,9 +251,9 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().writes(5 as Weight)) } - // Storage: Alliance AccountBlacklist (r:1 w:1) - // Storage: Alliance WebsiteBlacklist (r:1 w:1) - fn add_blacklist_items(n: u32, l: u32, ) -> Weight { + // Storage: Alliance UnscrupulousAccounts (r:1 w:1) + // Storage: Alliance UnscrupulousWebsites (r:1 w:1) + fn add_unscrupulous_items(n: u32, l: u32, ) -> Weight { (0 as Weight) // Standard Error: 16_000 .saturating_add((2_673_000 as Weight).saturating_mul(n as Weight)) @@ -262,9 +262,9 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } - // Storage: Alliance AccountBlacklist (r:1 w:1) - // Storage: Alliance WebsiteBlacklist (r:1 w:1) - fn remove_blacklist_items(n: u32, l: u32, ) -> Weight { + // Storage: Alliance UnscrupulousAccounts (r:1 w:1) + // Storage: Alliance UnscrupulousWebsites (r:1 w:1) + fn remove_unscrupulous_items(n: u32, l: u32, ) -> Weight { (0 as Weight) // Standard Error: 343_000 .saturating_add((59_025_000 as Weight).saturating_mul(n as Weight)) @@ -411,7 +411,7 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } - // Storage: Alliance AccountBlacklist (r:1 w:0) + // Storage: Alliance UnscrupulousAccounts (r:1 w:0) // Storage: Alliance Members (r:4 w:0) // Storage: System Account (r:1 w:1) // Storage: Alliance DepositOf (r:0 w:1) @@ -421,7 +421,7 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } // Storage: Alliance Members (r:4 w:0) - // Storage: Alliance AccountBlacklist (r:1 w:0) + // Storage: Alliance UnscrupulousAccounts (r:1 w:0) fn nominate_ally() -> Weight { (44_764_000 as Weight) .saturating_add(RocksDbWeight::get().reads(6 as Weight)) @@ -460,9 +460,9 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(7 as Weight)) .saturating_add(RocksDbWeight::get().writes(5 as Weight)) } - // Storage: Alliance AccountBlacklist (r:1 w:1) - // Storage: Alliance WebsiteBlacklist (r:1 w:1) - fn add_blacklist_items(n: u32, l: u32, ) -> Weight { + // Storage: Alliance UnscrupulousAccounts (r:1 w:1) + // Storage: Alliance UnscrupulousWebsites (r:1 w:1) + fn add_unscrupulous_items(n: u32, l: u32, ) -> Weight { (0 as Weight) // Standard Error: 16_000 .saturating_add((2_673_000 as Weight).saturating_mul(n as Weight)) @@ -471,9 +471,9 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(2 as Weight)) .saturating_add(RocksDbWeight::get().writes(2 as Weight)) } - // Storage: Alliance AccountBlacklist (r:1 w:1) - // Storage: Alliance WebsiteBlacklist (r:1 w:1) - fn remove_blacklist_items(n: u32, l: u32, ) -> Weight { + // Storage: Alliance UnscrupulousAccounts (r:1 w:1) + // Storage: Alliance UnscrupulousWebsites (r:1 w:1) + fn remove_unscrupulous_items(n: u32, l: u32, ) -> Weight { (0 as Weight) // Standard Error: 343_000 .saturating_add((59_025_000 as Weight).saturating_mul(n as Weight)) From 0c10bcd934baa7b214b43bb939182cd37acf0cbf Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Fri, 10 Jun 2022 19:01:03 +0200 Subject: [PATCH 70/72] formatting --- frame/alliance/src/lib.rs | 12 +++++++++--- frame/alliance/src/tests.rs | 10 ++++++++-- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index f9ce168252599..91d017d309e4b 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -207,7 +207,7 @@ pub enum UnscrupulousItem { Website(Url), } -type UnscrupulousItemOf = +type UnscrupulousItemOf = UnscrupulousItem<::AccountId, UrlOf>; #[frame_support::pallet] @@ -1003,7 +1003,10 @@ impl, I: 'static> Pallet { >::try_mutate(|accounts| -> DispatchResult { for who in out_accounts.iter() { let pos = - accounts.binary_search(who).ok().ok_or(Error::::NotListedAsUnscrupulous)?; + accounts + .binary_search(who) + .ok() + .ok_or(Error::::NotListedAsUnscrupulous)?; accounts.remove(pos); } Ok(()) @@ -1012,7 +1015,10 @@ impl, I: 'static> Pallet { if !out_webs.is_empty() { >::try_mutate(|webs| -> DispatchResult { for web in out_webs.iter() { - let pos = webs.binary_search(web).ok().ok_or(Error::::NotListedAsUnscrupulous)?; + let pos = webs + .binary_search(web) + .ok() + .ok_or(Error::::NotListedAsUnscrupulous)?; webs.remove(pos); } Ok(()) diff --git a/frame/alliance/src/tests.rs b/frame/alliance/src/tests.rs index e116f44d82f48..85c91b451d351 100644 --- a/frame/alliance/src/tests.rs +++ b/frame/alliance/src/tests.rs @@ -449,7 +449,10 @@ fn add_unscrupulous_items_works() { assert_eq!(Alliance::unscrupulous_websites().into_inner(), vec!["abc".as_bytes().to_vec()]); assert_noop!( - Alliance::add_unscrupulous_items(Origin::signed(3), vec![UnscrupulousItem::AccountId(3)]), + Alliance::add_unscrupulous_items( + Origin::signed(3), + vec![UnscrupulousItem::AccountId(3)] + ), Error::::AlreadyUnscrupulous ); }); @@ -459,7 +462,10 @@ fn add_unscrupulous_items_works() { fn remove_unscrupulous_items_works() { new_test_ext().execute_with(|| { assert_noop!( - Alliance::remove_unscrupulous_items(Origin::signed(3), vec![UnscrupulousItem::AccountId(3)]), + Alliance::remove_unscrupulous_items( + Origin::signed(3), + vec![UnscrupulousItem::AccountId(3)] + ), Error::::NotListedAsUnscrupulous ); From 3ee24a809c354fd458c2f4a02b9398e5ac5b20d6 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Fri, 10 Jun 2022 19:07:31 +0200 Subject: [PATCH 71/72] fmt oops --- frame/alliance/src/lib.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/frame/alliance/src/lib.rs b/frame/alliance/src/lib.rs index 91d017d309e4b..f9e85e270af16 100644 --- a/frame/alliance/src/lib.rs +++ b/frame/alliance/src/lib.rs @@ -1002,11 +1002,10 @@ impl, I: 'static> Pallet { if !out_accounts.is_empty() { >::try_mutate(|accounts| -> DispatchResult { for who in out_accounts.iter() { - let pos = - accounts - .binary_search(who) - .ok() - .ok_or(Error::::NotListedAsUnscrupulous)?; + let pos = accounts + .binary_search(who) + .ok() + .ok_or(Error::::NotListedAsUnscrupulous)?; accounts.remove(pos); } Ok(()) From 78b63c1136d139679d098f26024d68c9c64b4296 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Fri, 10 Jun 2022 19:21:34 +0200 Subject: [PATCH 72/72] rename benchmarking unscrupulous account creator --- frame/alliance/src/benchmarking.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/frame/alliance/src/benchmarking.rs b/frame/alliance/src/benchmarking.rs index 27021375d8e97..527c35b58a5d8 100644 --- a/frame/alliance/src/benchmarking.rs +++ b/frame/alliance/src/benchmarking.rs @@ -76,7 +76,7 @@ fn outsider, I: 'static>(index: u32) -> T::AccountId { funded_account::("outsider", index) } -fn unscrupulous_list, I: 'static>(index: u32) -> T::AccountId { +fn generate_unscrupulous_account, I: 'static>(index: u32) -> T::AccountId { funded_account::("unscrupulous", index) } @@ -739,7 +739,9 @@ benchmarks_instance_pallet! { set_members::(); - let accounts = (0 .. n).map(|i| unscrupulous_list::(i)).collect::>(); + let accounts = (0 .. n) + .map(|i| generate_unscrupulous_account::(i)) + .collect::>(); let websites = (0 .. n).map(|i| -> BoundedVec { BoundedVec::try_from(vec![i as u8; l as usize]).unwrap() }).collect::>(); @@ -761,7 +763,9 @@ benchmarks_instance_pallet! { set_members::(); - let mut accounts = (0 .. n).map(|i| unscrupulous_list::(i)).collect::>(); + let mut accounts = (0 .. n) + .map(|i| generate_unscrupulous_account::(i)) + .collect::>(); accounts.sort(); let accounts: BoundedVec<_, T::MaxUnscrupulousItems> = accounts.try_into().unwrap(); UnscrupulousAccounts::::put(accounts.clone());