From d3af49fdab8deac42b262ec8b4b59e21c5b2e062 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 1 Dec 2021 19:47:55 -0500 Subject: [PATCH 01/47] Remove Default for AccountId --- client/consensus/aura/src/lib.rs | 2 +- client/consensus/babe/src/verification.rs | 2 +- client/keystore/src/local.rs | 19 +++--- frame/examples/parallel/src/lib.rs | 8 ++- frame/session/src/lib.rs | 15 +++-- frame/support/src/traits/validation.rs | 2 +- frame/system/src/lib.rs | 1 - primitives/application-crypto/src/ecdsa.rs | 2 +- primitives/application-crypto/src/ed25519.rs | 2 +- primitives/application-crypto/src/lib.rs | 21 +++--- primitives/application-crypto/src/sr25519.rs | 2 +- primitives/core/src/crypto.rs | 71 +++++++++----------- primitives/core/src/ecdsa.rs | 31 +++------ primitives/core/src/ed25519.rs | 34 +++------- primitives/core/src/lib.rs | 2 +- primitives/core/src/sr25519.rs | 34 +++------- primitives/keyring/src/ed25519.rs | 2 +- primitives/keyring/src/sr25519.rs | 2 +- primitives/keystore/src/testing.rs | 8 +-- primitives/npos-elections/src/pjr.rs | 22 ++++-- primitives/npos-elections/src/traits.rs | 4 +- primitives/runtime/src/lib.rs | 31 ++++----- primitives/runtime/src/testing.rs | 8 +-- 23 files changed, 148 insertions(+), 177 deletions(-) diff --git a/client/consensus/aura/src/lib.rs b/client/consensus/aura/src/lib.rs index 16880ae188ad6..7f75cc265c03d 100644 --- a/client/consensus/aura/src/lib.rs +++ b/client/consensus/aura/src/lib.rs @@ -57,7 +57,7 @@ use sp_consensus::{ BlockOrigin, CanAuthorWith, Environment, Error as ConsensusError, Proposer, SelectChain, }; use sp_consensus_slots::Slot; -use sp_core::crypto::{Pair, Public}; +use sp_core::crypto::{Pair, Public, ByteArray}; use sp_inherents::CreateInherentDataProviders; use sp_keystore::{SyncCryptoStore, SyncCryptoStorePtr}; use sp_runtime::{ diff --git a/client/consensus/babe/src/verification.rs b/client/consensus/babe/src/verification.rs index 2322a96262161..6b949b487a54d 100644 --- a/client/consensus/babe/src/verification.rs +++ b/client/consensus/babe/src/verification.rs @@ -31,7 +31,7 @@ use sp_consensus_babe::{ make_transcript, AuthorityId, AuthorityPair, AuthoritySignature, }; use sp_consensus_slots::Slot; -use sp_core::{Pair, Public}; +use sp_core::{Pair, Public, ByteArray}; use sp_runtime::{traits::Header, DigestItem}; /// BABE verification parameters diff --git a/client/keystore/src/local.rs b/client/keystore/src/local.rs index 965e68336e3bc..1e298c83d2500 100644 --- a/client/keystore/src/local.rs +++ b/client/keystore/src/local.rs @@ -21,7 +21,7 @@ use async_trait::async_trait; use parking_lot::RwLock; use sp_application_crypto::{ecdsa, ed25519, sr25519, AppKey, AppPair, IsWrappedBy}; use sp_core::{ - crypto::{CryptoTypePublicPair, ExposeSecret, KeyTypeId, Pair as PairT, Public, SecretString}, + crypto::{CryptoTypePublicPair, ExposeSecret, KeyTypeId, Pair as PairT, ByteArray, SecretString}, sr25519::{Pair as Sr25519Pair, Public as Sr25519Public}, Encode, }; @@ -189,7 +189,8 @@ impl SyncCryptoStore for LocalKeystore { ) -> std::result::Result>, TraitError> { match key.0 { ed25519::CRYPTO_ID => { - let pub_key = ed25519::Public::from_slice(key.1.as_slice()); + let pub_key = ed25519::Public::from_slice(key.1.as_slice()) + .map_err(|()| TraitError::Other("Corrupted key - Invalid size".into()))?; let key_pair = self .0 .read() @@ -198,7 +199,8 @@ impl SyncCryptoStore for LocalKeystore { key_pair.map(|k| k.sign(msg).encode()).map(Ok).transpose() }, sr25519::CRYPTO_ID => { - let pub_key = sr25519::Public::from_slice(key.1.as_slice()); + let pub_key = sr25519::Public::from_slice(key.1.as_slice()) + .map_err(|()| TraitError::Other("Corrupted key - Invalid size".into()))?; let key_pair = self .0 .read() @@ -207,7 +209,8 @@ impl SyncCryptoStore for LocalKeystore { key_pair.map(|k| k.sign(msg).encode()).map(Ok).transpose() }, ecdsa::CRYPTO_ID => { - let pub_key = ecdsa::Public::from_slice(key.1.as_slice()); + let pub_key = ecdsa::Public::from_slice(key.1.as_slice()) + .map_err(|()| TraitError::Other("Corrupted key - Invalid size".into()))?; let key_pair = self .0 .read() @@ -223,7 +226,7 @@ impl SyncCryptoStore for LocalKeystore { self.0 .read() .raw_public_keys(key_type) - .map(|v| v.into_iter().map(|k| sr25519::Public::from_slice(k.as_slice())).collect()) + .map(|v| v.into_iter().filter_map(|k| sr25519::Public::from_slice(k.as_slice()).ok()).collect()) .unwrap_or_default() } @@ -246,7 +249,7 @@ impl SyncCryptoStore for LocalKeystore { self.0 .read() .raw_public_keys(key_type) - .map(|v| v.into_iter().map(|k| ed25519::Public::from_slice(k.as_slice())).collect()) + .map(|v| v.into_iter().filter_map(|k| ed25519::Public::from_slice(k.as_slice()).ok()).collect()) .unwrap_or_default() } @@ -269,7 +272,7 @@ impl SyncCryptoStore for LocalKeystore { self.0 .read() .raw_public_keys(key_type) - .map(|v| v.into_iter().map(|k| ecdsa::Public::from_slice(k.as_slice())).collect()) + .map(|v| v.into_iter().filter_map(|k| ecdsa::Public::from_slice(k.as_slice()).ok()).collect()) .unwrap_or_default() } @@ -562,7 +565,7 @@ mod tests { fn public_keys(&self) -> Result> { self.raw_public_keys(Public::ID) - .map(|v| v.into_iter().map(|k| Public::from_slice(k.as_slice())).collect()) + .map(|v| v.into_iter().filter_map(|k| Public::from_slice(k.as_slice()).ok()).collect()) } fn generate(&mut self) -> Result { diff --git a/frame/examples/parallel/src/lib.rs b/frame/examples/parallel/src/lib.rs index 51e022bed08b3..8844b3d3ee2aa 100644 --- a/frame/examples/parallel/src/lib.rs +++ b/frame/examples/parallel/src/lib.rs @@ -105,13 +105,15 @@ pub struct EnlistedParticipant { impl EnlistedParticipant { fn verify(&self, event_id: &[u8]) -> bool { - use sp_core::Public; + use sp_core::ByteArray; use sp_runtime::traits::Verify; match sp_core::sr25519::Signature::try_from(&self.signature[..]) { Ok(signature) => { - let public = sp_core::sr25519::Public::from_slice(self.account.as_ref()); - signature.verify(event_id, &public) + match sp_core::sr25519::Public::from_slice(self.account.as_ref()) { + Err(()) => false, + Ok(signer) => signature.verify(event_id, &signer), + } }, _ => false, } diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index f56d282c0f111..3243d81a3d631 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -312,8 +312,9 @@ impl SessionHandler for Tuple { for_tuples!( #( let our_keys: Box> = Box::new(validators.iter() - .map(|k| (&k.0, k.1.get::(::ID) - .unwrap_or_default()))); + .filter_map(|k| + (&k.0, k.1.get::(::ID))) + ); Tuple::on_genesis_session(our_keys); )* @@ -328,11 +329,13 @@ impl SessionHandler for Tuple { for_tuples!( #( let our_keys: Box> = Box::new(validators.iter() - .map(|k| (&k.0, k.1.get::(::ID) - .unwrap_or_default()))); + .filter_map(|k| + (&k.0, k.1.get::(::ID))) + ); let queued_keys: Box> = Box::new(queued_validators.iter() - .map(|k| (&k.0, k.1.get::(::ID) - .unwrap_or_default()))); + .filter_map(|k| + (&k.0, k.1.get::(::ID))) + ); Tuple::on_new_session(changed, our_keys, queued_keys); )* ) diff --git a/frame/support/src/traits/validation.rs b/frame/support/src/traits/validation.rs index 674f2d718fffa..e5c81a149e4d0 100644 --- a/frame/support/src/traits/validation.rs +++ b/frame/support/src/traits/validation.rs @@ -77,7 +77,7 @@ pub trait VerifySeal { /// A session handler for specific key type. pub trait OneSessionHandler: BoundToRuntimeAppPublic { /// The key type expected. - type Key: Decode + Default + RuntimeAppPublic; + type Key: Decode + RuntimeAppPublic; /// The given validator set will be used for the genesis session. /// It is guaranteed that the given validator set will also be used diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index aac104fa8f765..77f7d881c1544 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -235,7 +235,6 @@ pub mod pallet { + Debug + MaybeDisplay + Ord - + Default + MaxEncodedLen; /// Converting trait to take a source type and convert to `AccountId`. diff --git a/primitives/application-crypto/src/ecdsa.rs b/primitives/application-crypto/src/ecdsa.rs index 915e16ba3b1a2..fba1fc03b2533 100644 --- a/primitives/application-crypto/src/ecdsa.rs +++ b/primitives/application-crypto/src/ecdsa.rs @@ -57,6 +57,6 @@ impl RuntimePublic for Public { } fn to_raw_vec(&self) -> Vec { - sp_core::crypto::Public::to_raw_vec(self) + sp_core::crypto::ByteArray::to_raw_vec(self) } } diff --git a/primitives/application-crypto/src/ed25519.rs b/primitives/application-crypto/src/ed25519.rs index 09ce48fcb274c..35fcb2403a033 100644 --- a/primitives/application-crypto/src/ed25519.rs +++ b/primitives/application-crypto/src/ed25519.rs @@ -57,6 +57,6 @@ impl RuntimePublic for Public { } fn to_raw_vec(&self) -> Vec { - sp_core::crypto::Public::to_raw_vec(self) + sp_core::crypto::ByteArray::to_raw_vec(self) } } diff --git a/primitives/application-crypto/src/lib.rs b/primitives/application-crypto/src/lib.rs index baa6560667059..a511219fd229e 100644 --- a/primitives/application-crypto/src/lib.rs +++ b/primitives/application-crypto/src/lib.rs @@ -27,7 +27,7 @@ pub use sp_core::crypto::{DeriveJunction, Pair, SecretStringError, Ss58Codec}; #[doc(hidden)] pub use sp_core::{ self, - crypto::{CryptoType, CryptoTypePublicPair, Derive, IsWrappedBy, Public, Wraps}, + crypto::{CryptoType, CryptoTypePublicPair, Derive, IsWrappedBy, Public, Wraps, ByteArray}, RuntimeDebug, }; @@ -221,7 +221,7 @@ macro_rules! app_crypto_public_full_crypto { $crate::wrap! { /// A generic `AppPublic` wrapper type over $public crypto; this has no specific App. #[derive( - Clone, Default, Eq, Hash, PartialEq, PartialOrd, Ord, + Clone, Eq, Hash, PartialEq, PartialOrd, Ord, $crate::codec::Encode, $crate::codec::Decode, $crate::RuntimeDebug, @@ -258,7 +258,7 @@ macro_rules! app_crypto_public_not_full_crypto { $crate::wrap! { /// A generic `AppPublic` wrapper type over $public crypto; this has no specific App. #[derive( - Clone, Default, Eq, PartialEq, Ord, PartialOrd, + Clone, Eq, PartialEq, Ord, PartialOrd, $crate::codec::Encode, $crate::codec::Decode, $crate::RuntimeDebug, @@ -301,13 +301,12 @@ macro_rules! app_crypto_public_common { } } + impl $crate::ByteArray for Public { + const LEN: usize = <$public>::LEN; + } impl $crate::Public for Public { - fn from_slice(x: &[u8]) -> Self { - Self(<$public>::from_slice(x)) - } - fn to_public_crypto_pair(&self) -> $crate::CryptoTypePublicPair { - $crate::CryptoTypePublicPair($crypto_type, self.to_raw_vec()) + $crate::CryptoTypePublicPair($crypto_type, $crate::ByteArray::to_raw_vec(self)) } } @@ -357,7 +356,7 @@ macro_rules! app_crypto_public_common { impl From<&Public> for $crate::CryptoTypePublicPair { fn from(key: &Public) -> Self { - $crate::CryptoTypePublicPair($crypto_type, $crate::Public::to_raw_vec(key)) + $crate::CryptoTypePublicPair($crypto_type, $crate::ByteArray::to_raw_vec(key)) } } @@ -435,7 +434,7 @@ macro_rules! app_crypto_signature_full_crypto { ($sig:ty, $key_type:expr, $crypto_type:expr) => { $crate::wrap! { /// A generic `AppPublic` wrapper type over $public crypto; this has no specific App. - #[derive(Clone, Default, Eq, PartialEq, + #[derive(Clone, Eq, PartialEq, $crate::codec::Encode, $crate::codec::Decode, $crate::RuntimeDebug, @@ -470,7 +469,7 @@ macro_rules! app_crypto_signature_not_full_crypto { ($sig:ty, $key_type:expr, $crypto_type:expr) => { $crate::wrap! { /// A generic `AppPublic` wrapper type over $public crypto; this has no specific App. - #[derive(Clone, Default, Eq, PartialEq, + #[derive(Clone, Eq, PartialEq, $crate::codec::Encode, $crate::codec::Decode, $crate::scale_info::TypeInfo, diff --git a/primitives/application-crypto/src/sr25519.rs b/primitives/application-crypto/src/sr25519.rs index f51236f2ab384..6cd1bf35a2354 100644 --- a/primitives/application-crypto/src/sr25519.rs +++ b/primitives/application-crypto/src/sr25519.rs @@ -57,6 +57,6 @@ impl RuntimePublic for Public { } fn to_raw_vec(&self) -> Vec { - sp_core::crypto::Public::to_raw_vec(self) + sp_core::crypto::ByteArray::to_raw_vec(self) } } diff --git a/primitives/core/src/crypto.rs b/primitives/core/src/crypto.rs index 4f21d62f5850d..83fb31ed73141 100644 --- a/primitives/core/src/crypto.rs +++ b/primitives/core/src/crypto.rs @@ -222,7 +222,7 @@ pub enum PublicError { /// See /// for information on the codec. #[cfg(feature = "full_crypto")] -pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + Default { +pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + ByteArray { /// A format filterer, can be used to ensure that `from_ss58check` family only decode for /// allowed identifiers. By default just refuses the two reserved identifiers. fn format_is_allowed(f: Ss58AddressFormat) -> bool { @@ -243,10 +243,7 @@ pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + Default { #[cfg(feature = "std")] fn from_ss58check_with_version(s: &str) -> Result<(Self, Ss58AddressFormat), PublicError> { const CHECKSUM_LEN: usize = 2; - let mut res = Self::default(); - - // Must decode to our type. - let body_len = res.as_mut().len(); + let body_len = Self::LEN; let data = s.from_base58().map_err(|_| PublicError::BadBase58)?; if data.len() < 2 { @@ -280,8 +277,9 @@ pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + Default { // Invalid checksum. return Err(PublicError::InvalidChecksum) } - res.as_mut().copy_from_slice(&data[prefix_len..body_len + prefix_len]); - Ok((res, format)) + + let result = Self::from_slice(&data[prefix_len..body_len + prefix_len]).map_err(|()| PublicError::BadLength)?; + Ok((result, format)) } /// Some if the string is a properly encoded SS58Check address, optionally with @@ -391,19 +389,13 @@ lazy_static::lazy_static! { } #[cfg(feature = "std")] -impl + AsRef<[u8]> + Default + Derive> Ss58Codec for T { +impl + AsRef<[u8]> + Public + Derive> Ss58Codec for T { fn from_string(s: &str) -> Result { let cap = SS58_REGEX.captures(s).ok_or(PublicError::InvalidFormat)?; let s = cap.name("ss58").map(|r| r.as_str()).unwrap_or(DEV_ADDRESS); let addr = if let Some(stripped) = s.strip_prefix("0x") { let d = hex::decode(stripped).map_err(|_| PublicError::InvalidFormat)?; - let mut r = Self::default(); - if d.len() == r.as_ref().len() { - r.as_mut().copy_from_slice(&d); - r - } else { - return Err(PublicError::BadLength) - } + Self::from_slice(&d).map_err(|()| PublicError::BadLength)? } else { Self::from_ss58check(s)? }; @@ -431,25 +423,15 @@ impl + AsRef<[u8]> + Default + Derive> Ss58Codec for T { } } -/// Trait suitable for typical cryptographic PKI key public type. -pub trait Public: - AsRef<[u8]> - + AsMut<[u8]> - + Default - + Derive - + CryptoType - + PartialEq - + Eq - + Clone - + Send - + Sync - + for<'a> TryFrom<&'a [u8]> -{ - /// A new instance from the given slice. - /// - /// NOTE: No checking goes on to ensure this is a real public key. Only use it if - /// you are certain that the array actually is a pubkey. GIGO! - fn from_slice(data: &[u8]) -> Self; +/// Trait used for types that are really just a fixed-length array. +pub trait ByteArray: AsRef<[u8]> + AsMut<[u8]> + for<'a> TryFrom<&'a [u8], Error = ()> { + /// The "length" of the values of this type, which is always the same. + const LEN: usize; + + /// A new instance from the given slice that should be `Self::LEN` bytes long. + fn from_slice(data: &[u8]) -> Result { + Self::try_from(data) + } /// Return a `Vec` filled with raw data. fn to_raw_vec(&self) -> Vec { @@ -460,6 +442,10 @@ pub trait Public: fn as_slice(&self) -> &[u8] { self.as_ref() } +} + +/// Trait suitable for typical cryptographic PKI key public type. +pub trait Public: ByteArray + Derive + CryptoType + PartialEq + Eq + Clone + Send + Sync { /// Return `CryptoTypePublicPair` from public key. fn to_public_crypto_pair(&self) -> CryptoTypePublicPair; } @@ -487,6 +473,12 @@ impl UncheckedFrom for AccountId32 { } } +impl ByteArray for AccountId32 { + const LEN: usize = 32; + + +} + #[cfg(feature = "std")] impl Ss58Codec for AccountId32 {} @@ -649,9 +641,10 @@ mod dummy { impl Derive for Dummy {} - impl Public for Dummy { - fn from_slice(_: &[u8]) -> Self { - Self + impl ByteArray for Dummy { + const LEN: usize = 0; + fn from_slice(_: &[u8]) -> Result { + Ok(Self) } #[cfg(feature = "std")] fn to_raw_vec(&self) -> Vec { @@ -660,8 +653,10 @@ mod dummy { fn as_slice(&self) -> &[u8] { b"" } + } + impl Public for Dummy { fn to_public_crypto_pair(&self) -> CryptoTypePublicPair { - CryptoTypePublicPair(CryptoTypeId(*b"dumm"), Public::to_raw_vec(self)) + CryptoTypePublicPair(CryptoTypeId(*b"dumm"), ::to_raw_vec(self)) } } diff --git a/primitives/core/src/ecdsa.rs b/primitives/core/src/ecdsa.rs index 2751a0c40e3e5..4f61c6a77eb15 100644 --- a/primitives/core/src/ecdsa.rs +++ b/primitives/core/src/ecdsa.rs @@ -27,7 +27,7 @@ use sp_std::cmp::Ordering; #[cfg(feature = "std")] use crate::crypto::Ss58Codec; use crate::crypto::{ - CryptoType, CryptoTypeId, CryptoTypePublicPair, Derive, Public as TraitPublic, UncheckedFrom, + CryptoType, CryptoTypeId, CryptoTypePublicPair, Derive, Public as TraitPublic, UncheckedFrom, ByteArray }; #[cfg(feature = "full_crypto")] use crate::{ @@ -113,17 +113,11 @@ impl Public { } } -impl TraitPublic for Public { - /// A new instance from the given slice that should be 33 bytes long. - /// - /// NOTE: No checking goes on to ensure this is a real public key. Only use it if - /// you are certain that the array actually is a pubkey. GIGO! - fn from_slice(data: &[u8]) -> Self { - let mut r = [0u8; 33]; - r.copy_from_slice(data); - Self(r) - } +impl ByteArray for Public { + const LEN: usize = 33; +} +impl TraitPublic for Public { fn to_public_crypto_pair(&self) -> CryptoTypePublicPair { CryptoTypePublicPair(CRYPTO_ID, self.to_raw_vec()) } @@ -143,12 +137,6 @@ impl From<&Public> for CryptoTypePublicPair { impl Derive for Public {} -impl Default for Public { - fn default() -> Self { - Public([0u8; 33]) - } -} - impl AsRef<[u8]> for Public { fn as_ref(&self) -> &[u8] { &self.0[..] @@ -165,11 +153,12 @@ impl sp_std::convert::TryFrom<&[u8]> for Public { type Error = (); fn try_from(data: &[u8]) -> Result { - if data.len() == 33 { - Ok(Self::from_slice(data)) - } else { - Err(()) + if data.len() != Self::LEN { + return Err(()) } + let mut r = [0u8; Self::LEN]; + r.copy_from_slice(data); + Ok(Self::unchecked_from(r)) } } diff --git a/primitives/core/src/ed25519.rs b/primitives/core/src/ed25519.rs index d786ee9d255ff..d20c4e8ae7b74 100644 --- a/primitives/core/src/ed25519.rs +++ b/primitives/core/src/ed25519.rs @@ -22,7 +22,7 @@ #[cfg(feature = "full_crypto")] use sp_std::vec::Vec; -use crate::hash::{H256, H512}; +use crate::{crypto::ByteArray, hash::{H256, H512}}; use codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; @@ -66,7 +66,6 @@ type Seed = [u8; 32]; Copy, Encode, Decode, - Default, PassByInner, MaxEncodedLen, TypeInfo, @@ -118,13 +117,12 @@ impl sp_std::convert::TryFrom<&[u8]> for Public { type Error = (); fn try_from(data: &[u8]) -> Result { - if data.len() == 32 { - let mut inner = [0u8; 32]; - inner.copy_from_slice(data); - Ok(Public(inner)) - } else { - Err(()) + if data.len() != Self::LEN { + return Err(()) } + let mut r = [0u8; Self::LEN]; + r.copy_from_slice(data); + Ok(Self::unchecked_from(r)) } } @@ -258,12 +256,6 @@ impl Clone for Signature { } } -impl Default for Signature { - fn default() -> Self { - Signature([0u8; 64]) - } -} - impl PartialEq for Signature { fn eq(&self, b: &Self) -> bool { self.0[..] == b.0[..] @@ -400,17 +392,11 @@ impl Public { } } -impl TraitPublic for Public { - /// A new instance from the given slice that should be 32 bytes long. - /// - /// NOTE: No checking goes on to ensure this is a real public key. Only use it if - /// you are certain that the array actually is a pubkey. GIGO! - fn from_slice(data: &[u8]) -> Self { - let mut r = [0u8; 32]; - r.copy_from_slice(data); - Public(r) - } +impl ByteArray for Public { + const LEN: usize = 32; +} +impl TraitPublic for Public { fn to_public_crypto_pair(&self) -> CryptoTypePublicPair { CryptoTypePublicPair(CRYPTO_ID, self.to_raw_vec()) } diff --git a/primitives/core/src/lib.rs b/primitives/core/src/lib.rs index 3983f7cc155d9..e211dd1190780 100644 --- a/primitives/core/src/lib.rs +++ b/primitives/core/src/lib.rs @@ -76,7 +76,7 @@ pub use self::{ uint::{U256, U512}, }; #[cfg(feature = "full_crypto")] -pub use crypto::{DeriveJunction, Pair, Public}; +pub use crypto::{DeriveJunction, Pair, Public, ByteArray}; #[cfg(feature = "std")] pub use self::hasher::blake2::Blake2Hasher; diff --git a/primitives/core/src/sr25519.rs b/primitives/core/src/sr25519.rs index 4787c2d9d13ee..2b4725769366a 100644 --- a/primitives/core/src/sr25519.rs +++ b/primitives/core/src/sr25519.rs @@ -42,7 +42,7 @@ use substrate_bip39::mini_secret_from_entropy; use crate::{ crypto::{ CryptoType, CryptoTypeId, CryptoTypePublicPair, Derive, Public as TraitPublic, - UncheckedFrom, + UncheckedFrom, ByteArray, }, hash::{H256, H512}, }; @@ -74,7 +74,6 @@ pub const CRYPTO_ID: CryptoTypeId = CryptoTypeId(*b"sr25"); Copy, Encode, Decode, - Default, PassByInner, MaxEncodedLen, TypeInfo, @@ -147,13 +146,12 @@ impl sp_std::convert::TryFrom<&[u8]> for Public { type Error = (); fn try_from(data: &[u8]) -> Result { - if data.len() == 32 { - let mut inner = [0u8; 32]; - inner.copy_from_slice(data); - Ok(Public(inner)) - } else { - Err(()) + if data.len() != Self::LEN { + return Err(()) } + let mut r = [0u8; 32]; + r.copy_from_slice(data); + Ok(Self::unchecked_from(r)) } } @@ -261,12 +259,6 @@ impl Clone for Signature { } } -impl Default for Signature { - fn default() -> Self { - Signature([0u8; 64]) - } -} - impl PartialEq for Signature { fn eq(&self, b: &Self) -> bool { self.0[..] == b.0[..] @@ -412,17 +404,11 @@ impl Public { } } -impl TraitPublic for Public { - /// A new instance from the given slice that should be 32 bytes long. - /// - /// NOTE: No checking goes on to ensure this is a real public key. Only use it if - /// you are certain that the array actually is a pubkey. GIGO! - fn from_slice(data: &[u8]) -> Self { - let mut r = [0u8; 32]; - r.copy_from_slice(data); - Public(r) - } +impl ByteArray for Public { + const LEN: usize = 32; +} +impl TraitPublic for Public { fn to_public_crypto_pair(&self) -> CryptoTypePublicPair { CryptoTypePublicPair(CRYPTO_ID, self.to_raw_vec()) } diff --git a/primitives/keyring/src/ed25519.rs b/primitives/keyring/src/ed25519.rs index 65341a360579b..99d63e8619eba 100644 --- a/primitives/keyring/src/ed25519.rs +++ b/primitives/keyring/src/ed25519.rs @@ -21,7 +21,7 @@ use lazy_static::lazy_static; pub use sp_core::ed25519; use sp_core::{ ed25519::{Pair, Public, Signature}, - Pair as PairT, Public as PublicT, H256, + Pair as PairT, ByteArray, H256, }; use sp_runtime::AccountId32; use std::{collections::HashMap, ops::Deref}; diff --git a/primitives/keyring/src/sr25519.rs b/primitives/keyring/src/sr25519.rs index 604c330b1ea1b..91f1a7d240535 100644 --- a/primitives/keyring/src/sr25519.rs +++ b/primitives/keyring/src/sr25519.rs @@ -21,7 +21,7 @@ use lazy_static::lazy_static; pub use sp_core::sr25519; use sp_core::{ sr25519::{Pair, Public, Signature}, - Pair as PairT, Public as PublicT, H256, + Pair as PairT, ByteArray, H256, }; use sp_runtime::AccountId32; use std::{collections::HashMap, ops::Deref}; diff --git a/primitives/keystore/src/testing.rs b/primitives/keystore/src/testing.rs index 718ba798dc0f3..85d99c2574708 100644 --- a/primitives/keystore/src/testing.rs +++ b/primitives/keystore/src/testing.rs @@ -18,7 +18,7 @@ //! Types that should only be used for testing! use sp_core::{ - crypto::{CryptoTypePublicPair, KeyTypeId, Pair, Public}, + crypto::{CryptoTypePublicPair, KeyTypeId, Pair, ByteArray}, ecdsa, ed25519, sr25519, }; @@ -341,19 +341,19 @@ impl SyncCryptoStore for KeyStore { match key.0 { ed25519::CRYPTO_ID => { let key_pair = - self.ed25519_key_pair(id, &ed25519::Public::from_slice(key.1.as_slice())); + self.ed25519_key_pair(id, &ed25519::Public::from_slice(key.1.as_slice()).unwrap()); key_pair.map(|k| k.sign(msg).encode()).map(Ok).transpose() }, sr25519::CRYPTO_ID => { let key_pair = - self.sr25519_key_pair(id, &sr25519::Public::from_slice(key.1.as_slice())); + self.sr25519_key_pair(id, &sr25519::Public::from_slice(key.1.as_slice()).unwrap()); key_pair.map(|k| k.sign(msg).encode()).map(Ok).transpose() }, ecdsa::CRYPTO_ID => { let key_pair = - self.ecdsa_key_pair(id, &ecdsa::Public::from_slice(key.1.as_slice())); + self.ecdsa_key_pair(id, &ecdsa::Public::from_slice(key.1.as_slice()).unwrap()); key_pair.map(|k| k.sign(msg).encode()).map(Ok).transpose() }, diff --git a/primitives/npos-elections/src/pjr.rs b/primitives/npos-elections/src/pjr.rs index e27acf1408f96..d0d4f302895e1 100644 --- a/primitives/npos-elections/src/pjr.rs +++ b/primitives/npos-elections/src/pjr.rs @@ -322,7 +322,7 @@ fn prepare_pjr_input( let who = v; let budget: ExtendedBalance = w.into(); - Voter { who, budget, edges, ..Default::default() } + Voter { who, budget, edges, load: Default::default() } }) .collect::>(); @@ -387,7 +387,14 @@ mod tests { .into_iter() .map(|(t, w, e)| { budget += w; - Candidate { who: t, elected: e, backed_stake: w, ..Default::default() } + Candidate { + who: t, + elected: e, + backed_stake: w, + score: Default::default(), + approval_stake: Default::default(), + round: Default::default(), + } }) .collect::>(); let edges = candidates @@ -396,7 +403,7 @@ mod tests { who: c.who, weight: c.backed_stake, candidate: c.to_ptr(), - ..Default::default() + load: Default::default(), }) .collect::>(); voter.edges = edges; @@ -432,7 +439,14 @@ mod tests { // will give 10 slack. let v3 = setup_voter(30, vec![(1, 20, true), (2, 20, true), (3, 0, false)]); - let unelected = Candidate { who: 3u32, elected: false, ..Default::default() }.to_ptr(); + let unelected = Candidate { + who: 3u32, + elected: false, + score: Default::default(), + approval_stake: Default::default(), + backed_stake: Default::default(), + round: Default::default(), + }.to_ptr(); let score = pre_score(unelected, &vec![v1, v2, v3], 15); assert_eq!(score, 15); diff --git a/primitives/npos-elections/src/traits.rs b/primitives/npos-elections/src/traits.rs index 597d7e648fd9b..cb24f770cdea0 100644 --- a/primitives/npos-elections/src/traits.rs +++ b/primitives/npos-elections/src/traits.rs @@ -36,8 +36,8 @@ use sp_std::{ /// an aggregator trait for a generic type of a voter/target identifier. This usually maps to /// substrate's account id. -pub trait IdentifierT: Clone + Eq + Default + Ord + Debug + codec::Codec {} -impl IdentifierT for T {} +pub trait IdentifierT: Clone + Eq + Ord + Debug + codec::Codec {} +impl IdentifierT for T {} /// Aggregator trait for a PerThing that can be multiplied by u128 (ExtendedBalance). pub trait PerThing128: PerThing + Mul {} diff --git a/primitives/runtime/src/lib.rs b/primitives/runtime/src/lib.rs index 80293fe734844..081b5480c75d4 100644 --- a/primitives/runtime/src/lib.rs +++ b/primitives/runtime/src/lib.rs @@ -44,7 +44,7 @@ pub use sp_application_crypto as app_crypto; pub use sp_core::storage::{Storage, StorageChild}; use sp_core::{ - crypto::{self, Public}, + crypto::{self, ByteArray}, ecdsa, ed25519, hash::{H256, H512}, sr25519, @@ -284,12 +284,6 @@ impl TryFrom for ecdsa::Signature { } } -impl Default for MultiSignature { - fn default() -> Self { - Self::Ed25519(Default::default()) - } -} - /// Public key for any known crypto algorithm. #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Encode, Decode, RuntimeDebug, TypeInfo)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] @@ -302,12 +296,6 @@ pub enum MultiSigner { Ecdsa(ecdsa::Public), } -impl Default for MultiSigner { - fn default() -> Self { - Self::Ed25519(Default::default()) - } -} - /// NOTE: This implementations is required by `SimpleAddressDeterminer`, /// we convert the hash into some AccountId, it's fine to use any scheme. impl> crypto::UncheckedFrom for MultiSigner { @@ -403,10 +391,14 @@ impl Verify for MultiSignature { type Signer = MultiSigner; fn verify>(&self, mut msg: L, signer: &AccountId32) -> bool { match (self, signer) { - (Self::Ed25519(ref sig), who) => - sig.verify(msg, &ed25519::Public::from_slice(who.as_ref())), - (Self::Sr25519(ref sig), who) => - sig.verify(msg, &sr25519::Public::from_slice(who.as_ref())), + (Self::Ed25519(ref sig), who) => match ed25519::Public::from_slice(who.as_ref()) { + Ok(signer) => sig.verify(msg, &signer), + Err(()) => false, + }, + (Self::Sr25519(ref sig), who) => match sr25519::Public::from_slice(who.as_ref()) { + Ok(signer) => sig.verify(msg, &signer), + Err(()) => false, + }, (Self::Ecdsa(ref sig), who) => { let m = sp_io::hashing::blake2_256(msg.get()); match sp_io::crypto::secp256k1_ecdsa_recover_compressed(sig.as_ref(), &m) { @@ -433,7 +425,10 @@ impl Verify for AnySignature { .map(|s| s.verify(msg, signer)) .unwrap_or(false) || ed25519::Signature::try_from(self.0.as_fixed_bytes().as_ref()) - .map(|s| s.verify(msg, &ed25519::Public::from_slice(signer.as_ref()))) + .map(|s| match ed25519::Public::from_slice(signer.as_ref()) { + Err(()) => false, + Ok(signer) => s.verify(msg, &signer), + }) .unwrap_or(false) } } diff --git a/primitives/runtime/src/testing.rs b/primitives/runtime/src/testing.rs index 4573bc84473a3..e42d444ead1f4 100644 --- a/primitives/runtime/src/testing.rs +++ b/primitives/runtime/src/testing.rs @@ -30,7 +30,7 @@ use crate::{ }; use serde::{de::Error as DeError, Deserialize, Deserializer, Serialize, Serializer}; use sp_core::{ - crypto::{key_types, CryptoType, Dummy, Public}, + crypto::{key_types, CryptoType, Dummy, ByteArray}, U256, }; pub use sp_core::{sr25519, H256}; @@ -77,10 +77,10 @@ impl From for u64 { } impl UintAuthorityId { - /// Convert this authority id into a public key. - pub fn to_public_key(&self) -> T { + /// Convert this authority ID into a public key. + pub fn to_public_key(&self) -> T { let bytes: [u8; 32] = U256::from(self.0).into(); - T::from_slice(&bytes) + T::from_slice(&bytes).unwrap() } } From f6827f1137a709e28dfcbd274124018bf3c73caf Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 1 Dec 2021 21:11:35 -0500 Subject: [PATCH 02/47] More removals of default --- bin/node/runtime/src/impls.rs | 11 +++++--- frame/authorship/src/lib.rs | 23 ++++++++-------- frame/babe/src/equivocation.rs | 2 +- frame/benchmarking/src/utils.rs | 6 ++--- frame/elections-phragmen/src/lib.rs | 12 ++++++++- frame/grandpa/src/equivocation.rs | 2 +- frame/multisig/src/lib.rs | 2 +- frame/proxy/src/lib.rs | 2 +- frame/staking/src/pallet/impls.rs | 4 ++- frame/staking/src/tests.rs | 2 +- frame/sudo/src/lib.rs | 8 +++--- .../asset-tx-payment/src/tests.rs | 9 ++++--- primitives/npos-elections/src/lib.rs | 27 +++++++++++++++---- primitives/npos-elections/src/pjr.rs | 11 ++++++-- primitives/npos-elections/src/reduce.rs | 15 +++++------ primitives/runtime/src/traits.rs | 4 +-- 16 files changed, 91 insertions(+), 49 deletions(-) diff --git a/bin/node/runtime/src/impls.rs b/bin/node/runtime/src/impls.rs index cdd9f0900fd38..689dc8c23fb4f 100644 --- a/bin/node/runtime/src/impls.rs +++ b/bin/node/runtime/src/impls.rs @@ -27,7 +27,9 @@ use pallet_asset_tx_payment::HandleCredit; pub struct Author; impl OnUnbalanced for Author { fn on_nonzero_unbalanced(amount: NegativeImbalance) { - Balances::resolve_creating(&Authorship::author(), amount); + if let Some(author) = Authorship::author() { + Balances::resolve_creating(&author, amount); + } } } @@ -36,9 +38,10 @@ impl OnUnbalanced for Author { pub struct CreditToBlockAuthor; impl HandleCredit for CreditToBlockAuthor { fn handle_credit(credit: CreditOf) { - let author = pallet_authorship::Pallet::::author(); - // Drop the result which will trigger the `OnDrop` of the imbalance in case of error. - let _ = Assets::resolve(&author, credit); + if let Some(author) = pallet_authorship::Pallet::::author() { + // Drop the result which will trigger the `OnDrop` of the imbalance in case of error. + let _ = Assets::resolve(&author, credit); + } } } diff --git a/frame/authorship/src/lib.rs b/frame/authorship/src/lib.rs index 5d36adabe888f..53877f9b87b43 100644 --- a/frame/authorship/src/lib.rs +++ b/frame/authorship/src/lib.rs @@ -170,7 +170,9 @@ pub mod pallet { >::put(false); - T::EventHandler::note_author(Self::author()); + if let Some(author) = Self::author() { + T::EventHandler::note_author(author); + } 0 } @@ -300,19 +302,19 @@ impl Pallet { /// /// This is safe to invoke in `on_initialize` implementations, as well /// as afterwards. - pub fn author() -> T::AccountId { + pub fn author() -> Option { // Check the memoized storage value. if let Some(author) = >::get() { - return author + return Some(author) } let digest = >::digest(); let pre_runtime_digests = digest.logs.iter().filter_map(|d| d.as_pre_runtime()); if let Some(author) = T::FindAuthor::find_author(pre_runtime_digests) { >::put(&author); - author + Some(author) } else { - Default::default() + None } } @@ -329,14 +331,13 @@ impl Pallet { UncleEntryItem::InclusionHeight(_) => None, UncleEntryItem::Uncle(h, _) => Some(h), }); - let author = Self::verify_uncle(&uncle, prev_uncles, &mut acc)?; + let maybe_author = Self::verify_uncle(&uncle, prev_uncles, &mut acc)?; let hash = uncle.hash(); - T::EventHandler::note_uncle( - author.clone().unwrap_or_default(), - now - uncle.number().clone(), - ); - uncles.push(UncleEntryItem::Uncle(hash, author)); + if let Some(author) = maybe_author.clone() { + T::EventHandler::note_uncle(author, now - uncle.number().clone()); + } + uncles.push(UncleEntryItem::Uncle(hash, maybe_author)); } >::put(&uncles); diff --git a/frame/babe/src/equivocation.rs b/frame/babe/src/equivocation.rs index 2397918d1ef13..9247acbb3b12d 100644 --- a/frame/babe/src/equivocation.rs +++ b/frame/babe/src/equivocation.rs @@ -176,7 +176,7 @@ where } fn block_author() -> Option { - Some(>::author()) + >::author() } } diff --git a/frame/benchmarking/src/utils.rs b/frame/benchmarking/src/utils.rs index c24ad2f64e18d..b36c0fdf29a3a 100644 --- a/frame/benchmarking/src/utils.rs +++ b/frame/benchmarking/src/utils.rs @@ -321,17 +321,17 @@ pub trait BenchmarkingSetup { } /// Grab an account, seeded by a name and index. -pub fn account( +pub fn account( name: &'static str, index: u32, seed: u32, ) -> AccountId { let entropy = (name, index, seed).using_encoded(blake2_256); - AccountId::decode(&mut &entropy[..]).unwrap_or_default() + AccountId::decode(&mut &entropy[..]).expect("`AccountId` type must be able to decode from any 32 bytes; qed") } /// This caller account is automatically whitelisted for DB reads/writes by the benchmarking macro. -pub fn whitelisted_caller() -> AccountId { +pub fn whitelisted_caller() -> AccountId { account::("whitelisted_caller", 0, 0) } diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index 116c0937bf983..8df76e53c5d98 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -147,7 +147,7 @@ pub enum Renouncing { } /// An active voter. -#[derive(Encode, Decode, Clone, Default, RuntimeDebug, PartialEq, TypeInfo)] +#[derive(Encode, Decode, Clone, RuntimeDebug, PartialEq, TypeInfo)] pub struct Voter { /// The members being backed. pub votes: Vec, @@ -159,6 +159,16 @@ pub struct Voter { pub deposit: Balance, } +impl Default for Voter { + fn default() -> Self { + Self { + votes: vec![], + stake: Default::default(), + deposit: Default::default(), + } + } +} + /// A holder of a seat as either a member or a runner-up. #[derive(Encode, Decode, Clone, Default, RuntimeDebug, PartialEq, TypeInfo)] pub struct SeatHolder { diff --git a/frame/grandpa/src/equivocation.rs b/frame/grandpa/src/equivocation.rs index 8a23ce6e1ef1e..77e38cb63b7dc 100644 --- a/frame/grandpa/src/equivocation.rs +++ b/frame/grandpa/src/equivocation.rs @@ -185,7 +185,7 @@ where } fn block_author() -> Option { - Some(>::author()) + >::author() } } diff --git a/frame/multisig/src/lib.rs b/frame/multisig/src/lib.rs index 757a99b42dae8..8bba6759e5829 100644 --- a/frame/multisig/src/lib.rs +++ b/frame/multisig/src/lib.rs @@ -508,7 +508,7 @@ impl Pallet { /// NOTE: `who` must be sorted. If it is not, then you'll get the wrong answer. pub fn multi_account_id(who: &[T::AccountId], threshold: u16) -> T::AccountId { let entropy = (b"modlpy/utilisuba", who, threshold).using_encoded(blake2_256); - T::AccountId::decode(&mut &entropy[..]).unwrap_or_default() + T::AccountId::decode(&mut &entropy[..]).expect("`AccountId` is never larger than 256 bits; qed") } fn operate( diff --git a/frame/proxy/src/lib.rs b/frame/proxy/src/lib.rs index 695fa077f98d5..3eb15885ef13e 100644 --- a/frame/proxy/src/lib.rs +++ b/frame/proxy/src/lib.rs @@ -653,7 +653,7 @@ impl Pallet { }); let entropy = (b"modlpy/proxy____", who, height, ext_index, proxy_type, index) .using_encoded(blake2_256); - T::AccountId::decode(&mut &entropy[..]).unwrap_or_default() + T::AccountId::decode(&mut &entropy[..]).expect("`AccountId` type is never greater than 32 bytes; qed") } /// Register a proxy account for the delegator that is able to make calls on its behalf. diff --git a/frame/staking/src/pallet/impls.rs b/frame/staking/src/pallet/impls.rs index 8d86cfbe6b0d6..edcc061112d6f 100644 --- a/frame/staking/src/pallet/impls.rs +++ b/frame/staking/src/pallet/impls.rs @@ -1109,7 +1109,9 @@ where Self::reward_by_ids(vec![(author, 20)]) } fn note_uncle(author: T::AccountId, _age: T::BlockNumber) { - Self::reward_by_ids(vec![(>::author(), 2), (author, 1)]) + if let Some(author) = >::author() { + Self::reward_by_ids(vec![(author, 2), (author, 1)]) + } } } diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index f8f37bed0066c..b0c90dd66b51f 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -2051,7 +2051,7 @@ fn reward_from_authorship_event_handler_works() { ExtBuilder::default().build_and_execute(|| { use pallet_authorship::EventHandler; - assert_eq!(>::author(), 11); + assert_eq!(>::author(), Some(11)); >::note_author(11); >::note_uncle(21, 1); diff --git a/frame/sudo/src/lib.rs b/frame/sudo/src/lib.rs index de3b3439bc344..ec2eb51ac8f97 100644 --- a/frame/sudo/src/lib.rs +++ b/frame/sudo/src/lib.rs @@ -274,20 +274,22 @@ pub mod pallet { #[pallet::genesis_config] pub struct GenesisConfig { /// The `AccountId` of the sudo key. - pub key: T::AccountId, + pub key: Option, } #[cfg(feature = "std")] impl Default for GenesisConfig { fn default() -> Self { - Self { key: Default::default() } + Self { key: None } } } #[pallet::genesis_build] impl GenesisBuild for GenesisConfig { fn build(&self) { - >::put(&self.key); + if let Some(ref key) = self.key { + >::put(key); + } } } } diff --git a/frame/transaction-payment/asset-tx-payment/src/tests.rs b/frame/transaction-payment/asset-tx-payment/src/tests.rs index bd5dc57239a28..815134ddc9e3f 100644 --- a/frame/transaction-payment/asset-tx-payment/src/tests.rs +++ b/frame/transaction-payment/asset-tx-payment/src/tests.rs @@ -199,10 +199,11 @@ impl pallet_authorship::Config for Runtime { pub struct CreditToBlockAuthor; impl HandleCredit for CreditToBlockAuthor { fn handle_credit(credit: CreditOf) { - let author = pallet_authorship::Pallet::::author(); - // What to do in case paying the author fails (e.g. because `fee < min_balance`) - // default: drop the result which will trigger the `OnDrop` of the imbalance. - let _ = >::resolve(&author, credit); + if let Some(author) = pallet_authorship::Pallet::::author() { + // What to do in case paying the author fails (e.g. because `fee < min_balance`) + // default: drop the result which will trigger the `OnDrop` of the imbalance. + let _ = >::resolve(&author, credit); + } } } diff --git a/primitives/npos-elections/src/lib.rs b/primitives/npos-elections/src/lib.rs index afe85ef53b3a7..b1e1ed2745174 100644 --- a/primitives/npos-elections/src/lib.rs +++ b/primitives/npos-elections/src/lib.rs @@ -178,7 +178,7 @@ impl Candidate { } /// A vote being casted by a [`Voter`] to a [`Candidate`] is an `Edge`. -#[derive(Clone, Default)] +#[derive(Clone)] pub struct Edge { /// Identifier of the target. /// @@ -223,7 +223,7 @@ impl std::fmt::Debug for Voter { impl Voter { /// Create a new `Voter`. pub fn new(who: AccountId) -> Self { - Self { who, ..Default::default() } + Self { who, edges: Default::default(), budget: Default::default(), load: Default::default() } } /// Returns `true` if `self` votes for `target`. @@ -339,7 +339,7 @@ pub struct ElectionResult { /// /// This, at the current version, resembles the `Exposure` defined in the Staking pallet, yet they /// do not necessarily have to be the same. -#[derive(Default, RuntimeDebug, Encode, Decode, Clone, Eq, PartialEq, scale_info::TypeInfo)] +#[derive(RuntimeDebug, Encode, Decode, Clone, Eq, PartialEq, scale_info::TypeInfo)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct Support { /// Total support. @@ -348,6 +348,15 @@ pub struct Support { pub voters: Vec<(AccountId, ExtendedBalance)>, } +impl Default for Support { + fn default() -> Self { + Self { + total: Default::default(), + voters: vec![], + } + } +} + /// A target-major representation of the the election outcome. /// /// Essentially a flat variant of [`SupportMap`]. @@ -461,7 +470,14 @@ pub fn setup_inputs( .enumerate() .map(|(idx, who)| { c_idx_cache.insert(who.clone(), idx); - Candidate { who, ..Default::default() }.to_ptr() + Candidate { + who, + score: Default::default(), + approval_stake: Default::default(), + backed_stake: Default::default(), + elected: Default::default(), + round: Default::default(), + }.to_ptr() }) .collect::>>(); @@ -482,7 +498,8 @@ pub fn setup_inputs( edges.push(Edge { who: v.clone(), candidate: Rc::clone(&candidates[*idx]), - ..Default::default() + load: Default::default(), + weight: Default::default(), }); } // else {} would be wrong votes. We don't really care about it. } diff --git a/primitives/npos-elections/src/pjr.rs b/primitives/npos-elections/src/pjr.rs index d0d4f302895e1..08a7e6fa719ea 100644 --- a/primitives/npos-elections/src/pjr.rs +++ b/primitives/npos-elections/src/pjr.rs @@ -287,7 +287,14 @@ fn prepare_pjr_input( let elected = maybe_support.is_some(); let backed_stake = maybe_support.map(|support| support.total).unwrap_or_default(); - Candidate { who, elected, backed_stake, ..Default::default() }.to_ptr() + Candidate { + who, + elected, + backed_stake, + score: Default::default(), + approval_stake: Default::default(), + round: Default::default(), + }.to_ptr() }) .collect::>(); @@ -315,7 +322,7 @@ fn prepare_pjr_input( who: t, candidate: Rc::clone(&candidates[*idx]), weight, - ..Default::default() + load: Default::default(), }); } } diff --git a/primitives/npos-elections/src/reduce.rs b/primitives/npos-elections/src/reduce.rs index 8b90796af85ca..9a31a4aa6da58 100644 --- a/primitives/npos-elections/src/reduce.rs +++ b/primitives/npos-elections/src/reduce.rs @@ -55,7 +55,6 @@ use sp_arithmetic::traits::{Bounded, Zero}; use sp_std::{ collections::btree_map::{BTreeMap, Entry::*}, prelude::*, - vec, }; /// Map type used for reduce_4. Can be easily swapped with HashMap. @@ -417,8 +416,8 @@ fn reduce_all(assignments: &mut Vec>) -> u32 // find minimum of cycle. let mut min_value: ExtendedBalance = Bounded::max_value(); // The voter and the target pair that create the min edge. - let mut min_target: A = Default::default(); - let mut min_voter: A = Default::default(); + let mut min_target: Option = None; + let mut min_voter: Option = None; // The index of the min in opaque cycle list. let mut min_index = 0usize; // 1 -> next // 0 -> prev @@ -448,8 +447,8 @@ fn reduce_all(assignments: &mut Vec>) -> u32 ass.distribution.iter().find(|d| d.0 == next).map(|(_, w)| { if *w < min_value { min_value = *w; - min_target = next.clone(); - min_voter = current.clone(); + min_target = Some(next.clone()); + min_voter = Some(current.clone()); min_index = i; min_direction = 1; } @@ -459,8 +458,8 @@ fn reduce_all(assignments: &mut Vec>) -> u32 ass.distribution.iter().find(|d| d.0 == prev).map(|(_, w)| { if *w < min_value { min_value = *w; - min_target = prev.clone(); - min_voter = current.clone(); + min_target = Some(prev.clone()); + min_voter = Some(current.clone()); min_index = i; min_direction = 0; } @@ -578,7 +577,7 @@ fn reduce_all(assignments: &mut Vec>) -> u32 // re-org. if should_reorg { - let min_edge = vec![min_voter, min_target]; + let min_edge = min_voter.into_iter().chain(min_target.into_iter()).collect::>(); if min_chain_in_voter { // NOTE: safe; voter_root_path is always bigger than 1 element. for i in 0..voter_root_path.len() - 1 { diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index f61de70e35197..50b40440b641a 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -1260,11 +1260,11 @@ pub trait AccountIdConversion: Sized { /// Format is TYPE_ID ++ encode(parachain ID) ++ 00.... where 00... is indefinite trailing zeroes to /// fill AccountId. -impl AccountIdConversion for Id { +impl AccountIdConversion for Id { fn into_sub_account(&self, sub: S) -> T { (Id::TYPE_ID, self, sub) .using_encoded(|b| T::decode(&mut TrailingZeroInput(b))) - .unwrap_or_default() + .expect("`AccountId` type is never greater than 32 bytes; qed") } fn try_from_sub_account(x: &T) -> Option<(Self, S)> { From d397c5d19fa1391f9d0d8c4e57875531ad7a1836 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Thu, 2 Dec 2021 17:12:58 +0100 Subject: [PATCH 03/47] Update frame/authorship/src/lib.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- frame/authorship/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frame/authorship/src/lib.rs b/frame/authorship/src/lib.rs index 53877f9b87b43..8beda574a11a0 100644 --- a/frame/authorship/src/lib.rs +++ b/frame/authorship/src/lib.rs @@ -310,8 +310,7 @@ impl Pallet { let digest = >::digest(); let pre_runtime_digests = digest.logs.iter().filter_map(|d| d.as_pre_runtime()); - if let Some(author) = T::FindAuthor::find_author(pre_runtime_digests) { - >::put(&author); + T::FindAuthor::find_author(pre_runtime_digests).map(|a| { >::put(&a); a }) Some(author) } else { None From c446fff7bcc0432113052c65eca091a0bb042cf5 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Thu, 2 Dec 2021 17:13:36 +0100 Subject: [PATCH 04/47] Update frame/authorship/src/lib.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- frame/authorship/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/frame/authorship/src/lib.rs b/frame/authorship/src/lib.rs index 8beda574a11a0..42f32e749edf0 100644 --- a/frame/authorship/src/lib.rs +++ b/frame/authorship/src/lib.rs @@ -311,7 +311,6 @@ impl Pallet { let digest = >::digest(); let pre_runtime_digests = digest.logs.iter().filter_map(|d| d.as_pre_runtime()); T::FindAuthor::find_author(pre_runtime_digests).map(|a| { >::put(&a); a }) - Some(author) } else { None } From 19023db2e3aea15ec75d89689d30dbd8106800dc Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Thu, 2 Dec 2021 17:13:41 +0100 Subject: [PATCH 05/47] Update frame/authorship/src/lib.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- frame/authorship/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/frame/authorship/src/lib.rs b/frame/authorship/src/lib.rs index 42f32e749edf0..88b24719c6c5c 100644 --- a/frame/authorship/src/lib.rs +++ b/frame/authorship/src/lib.rs @@ -311,7 +311,6 @@ impl Pallet { let digest = >::digest(); let pre_runtime_digests = digest.logs.iter().filter_map(|d| d.as_pre_runtime()); T::FindAuthor::find_author(pre_runtime_digests).map(|a| { >::put(&a); a }) - } else { None } } From 80df1fb19e38103f1dcf0c9d0b143f1dcbfd6576 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Thu, 2 Dec 2021 17:13:45 +0100 Subject: [PATCH 06/47] Update frame/authorship/src/lib.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- frame/authorship/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/frame/authorship/src/lib.rs b/frame/authorship/src/lib.rs index 88b24719c6c5c..12a8c6de85030 100644 --- a/frame/authorship/src/lib.rs +++ b/frame/authorship/src/lib.rs @@ -311,8 +311,6 @@ impl Pallet { let digest = >::digest(); let pre_runtime_digests = digest.logs.iter().filter_map(|d| d.as_pre_runtime()); T::FindAuthor::find_author(pre_runtime_digests).map(|a| { >::put(&a); a }) - None - } } fn verify_and_import_uncles(new_uncles: Vec) -> dispatch::DispatchResult { From 2cbe13a08def6315e1021874c2e84b22e601abc8 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 2 Dec 2021 16:01:26 -0500 Subject: [PATCH 07/47] More work --- frame/transaction-payment/src/lib.rs | 9 ++++++--- primitives/runtime/src/traits.rs | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index ed96f26cc0079..c81ffc8367573 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -57,6 +57,7 @@ use sp_runtime::{ }, transaction_validity::{ TransactionPriority, TransactionValidity, TransactionValidityError, ValidTransaction, + InvalidTransaction, }, FixedPointNumber, FixedPointOperand, FixedU128, Perquintill, RuntimeDebug, }; @@ -704,8 +705,8 @@ where type Pre = ( // tip BalanceOf, - // who paid the fee - Self::AccountId, + // who paid the fee - this is an option to allow for a Default impl. + Option, // imbalance resulting from withdrawing the fee <::OnChargeTransaction as OnChargeTransaction>::LiquidityInfo, ); @@ -736,7 +737,7 @@ where len: usize, ) -> Result { let (_fee, imbalance) = self.withdraw_fee(who, call, info, len)?; - Ok((self.0, who.clone(), imbalance)) + Ok((self.0, Some(who.clone()), imbalance)) } fn post_dispatch( @@ -748,6 +749,8 @@ where ) -> Result<(), TransactionValidityError> { let (tip, who, imbalance) = pre; let actual_fee = Pallet::::compute_actual_fee(len as u32, info, post_info, tip); + let e = TransactionValidityError::Invalid(InvalidTransaction::Custom(255)); + let who = who.clone().ok_or(e)?; T::OnChargeTransaction::correct_and_deposit_fee( &who, info, post_info, actual_fee, tip, imbalance, )?; diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 50b40440b641a..fe13e567117f6 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -850,6 +850,7 @@ pub trait SignedExtension: /// from the transaction using the `additional_signed` function. type AdditionalSigned: Encode + TypeInfo; + // TODO: Refactor to remove the Default bound. /// The type that encodes information that can be passed from pre_dispatch to post-dispatch. type Pre: Default; From 0930529a92e19bbf7a16a1f9e676cc383421ab58 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 2 Dec 2021 17:36:22 -0500 Subject: [PATCH 08/47] More work --- frame/benchmarking/src/utils.rs | 4 +++- frame/elections/src/lib.rs | 20 ++++++++------------ frame/multisig/src/lib.rs | 8 +++----- frame/proxy/src/lib.rs | 8 +++----- frame/sudo/src/lib.rs | 20 ++++++++++---------- frame/utility/src/lib.rs | 5 +++-- 6 files changed, 30 insertions(+), 35 deletions(-) diff --git a/frame/benchmarking/src/utils.rs b/frame/benchmarking/src/utils.rs index b36c0fdf29a3a..afa4a1b37f914 100644 --- a/frame/benchmarking/src/utils.rs +++ b/frame/benchmarking/src/utils.rs @@ -23,6 +23,7 @@ use frame_support::{ traits::StorageInfo, }; use sp_io::hashing::blake2_256; +use sp_runtime::traits::TrailingZeroInput; use sp_std::{prelude::Box, vec::Vec}; use sp_storage::TrackedStorageKey; @@ -327,7 +328,8 @@ pub fn account( seed: u32, ) -> AccountId { let entropy = (name, index, seed).using_encoded(blake2_256); - AccountId::decode(&mut &entropy[..]).expect("`AccountId` type must be able to decode from any 32 bytes; qed") + Decode::decode(&mut TrailingZeroInput::new(entropy.as_ref())) + .expect("infinite length input; no invalid inputs for type; qed") } /// This caller account is automatically whitelisted for DB reads/writes by the benchmarking macro. diff --git a/frame/elections/src/lib.rs b/frame/elections/src/lib.rs index 7ca11f4ed20e8..f0911e740b188 100644 --- a/frame/elections/src/lib.rs +++ b/frame/elections/src/lib.rs @@ -657,8 +657,7 @@ pub mod pallet { let count = Self::candidate_count() as usize; let candidates = Self::candidates(); ensure!( - (slot == count && count == candidates.len()) || - (slot < candidates.len() && candidates[slot] == T::AccountId::default()), + slot == count && count == candidates.len(), Error::::InvalidCandidateSlot, ); // NOTE: This must be last as it has side-effects. @@ -1019,7 +1018,7 @@ impl Pallet { // initialize leaderboard. let leaderboard_size = empty_seats + T::CarryCount::get() as usize; >::put(vec![ - (BalanceOf::::zero(), T::AccountId::default()); + (BalanceOf::::zero(), None); leaderboard_size ]); @@ -1085,7 +1084,7 @@ impl Pallet { // clear all except runners-up from candidate list. let candidates = Self::candidates(); - let mut new_candidates = vec![T::AccountId::default(); candidates.len()]; // shrink later. + let mut new_candidates = vec![None; candidates.len()]; // shrink later. let runners_up = leaderboard .into_iter() .rev() @@ -1094,12 +1093,12 @@ impl Pallet { .filter_map(|(_, a)| Self::candidate_reg_info(&a).map(|i| (a, i.1))); let mut count = 0u32; for (address, slot) in runners_up { - new_candidates[slot as usize] = address; + new_candidates[slot as usize] = Some(address); count += 1; } - for (old, new) in candidates.iter().zip(new_candidates.iter()) { + for (old, new) in candidates.iter().map(Some).zip(new_candidates.iter()) { // candidate is not a runner up. - if old != new { + if new.as_ref() != old { // removed - kill it >::remove(old); @@ -1112,14 +1111,11 @@ impl Pallet { } } // discard any superfluous slots. - if let Some(last_index) = new_candidates.iter().rposition(|c| *c != T::AccountId::default()) - { - new_candidates.truncate(last_index + 1); - } + let new_candidates = new_candidates.into_iter().filter_map(|x| x).collect::>(); Self::deposit_event(Event::::TallyFinalized { incoming, outgoing }); - >::put(new_candidates); + Candidates::::put(new_candidates); CandidateCount::::put(count); VoteCount::::put(Self::vote_index() + 1); Ok(()) diff --git a/frame/multisig/src/lib.rs b/frame/multisig/src/lib.rs index 8bba6759e5829..3b80fa1b1cf41 100644 --- a/frame/multisig/src/lib.rs +++ b/frame/multisig/src/lib.rs @@ -63,10 +63,7 @@ use frame_support::{ use frame_system::{self as system, RawOrigin}; use scale_info::TypeInfo; use sp_io::hashing::blake2_256; -use sp_runtime::{ - traits::{Dispatchable, Zero}, - DispatchError, -}; +use sp_runtime::{DispatchError, traits::{Dispatchable, TrailingZeroInput, Zero}}; use sp_std::prelude::*; pub use weights::WeightInfo; @@ -508,7 +505,8 @@ impl Pallet { /// NOTE: `who` must be sorted. If it is not, then you'll get the wrong answer. pub fn multi_account_id(who: &[T::AccountId], threshold: u16) -> T::AccountId { let entropy = (b"modlpy/utilisuba", who, threshold).using_encoded(blake2_256); - T::AccountId::decode(&mut &entropy[..]).expect("`AccountId` is never larger than 256 bits; qed") + Decode::decode(&mut TrailingZeroInput::new(entropy.as_ref())) + .expect("infinite length input; no invalid inputs for type; qed") } fn operate( diff --git a/frame/proxy/src/lib.rs b/frame/proxy/src/lib.rs index 3eb15885ef13e..a8fd9f53880a3 100644 --- a/frame/proxy/src/lib.rs +++ b/frame/proxy/src/lib.rs @@ -44,10 +44,7 @@ use frame_support::{ use frame_system::{self as system}; use scale_info::TypeInfo; use sp_io::hashing::blake2_256; -use sp_runtime::{ - traits::{Dispatchable, Hash, Saturating, Zero}, - DispatchResult, -}; +use sp_runtime::{DispatchResult, traits::{Dispatchable, Hash, Saturating, TrailingZeroInput, Zero}}; use sp_std::{convert::TryInto, prelude::*}; pub use weights::WeightInfo; @@ -653,7 +650,8 @@ impl Pallet { }); let entropy = (b"modlpy/proxy____", who, height, ext_index, proxy_type, index) .using_encoded(blake2_256); - T::AccountId::decode(&mut &entropy[..]).expect("`AccountId` type is never greater than 32 bytes; qed") + Decode::decode(&mut TrailingZeroInput::new(entropy.as_ref())) + .expect("infinite length input; no invalid inputs for type; qed") } /// Register a proxy account for the delegator that is able to make calls on its behalf. diff --git a/frame/sudo/src/lib.rs b/frame/sudo/src/lib.rs index ec2eb51ac8f97..b6255da1d1c46 100644 --- a/frame/sudo/src/lib.rs +++ b/frame/sudo/src/lib.rs @@ -146,7 +146,7 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { // This is a public call, so we ensure that the origin is some signed account. let sender = ensure_signed(origin)?; - ensure!(sender == Self::key(), Error::::RequireSudo); + ensure!(Self::key().map_or(false, |k| sender == k), Error::::RequireSudo); let res = call.dispatch_bypass_filter(frame_system::RawOrigin::Root.into()); Self::deposit_event(Event::Sudid { sudo_result: res.map(|_| ()).map_err(|e| e.error) }); @@ -172,7 +172,7 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { // This is a public call, so we ensure that the origin is some signed account. let sender = ensure_signed(origin)?; - ensure!(sender == Self::key(), Error::::RequireSudo); + ensure!(Self::key().map_or(false, |k| sender == k), Error::::RequireSudo); let res = call.dispatch_bypass_filter(frame_system::RawOrigin::Root.into()); Self::deposit_event(Event::Sudid { sudo_result: res.map(|_| ()).map_err(|e| e.error) }); @@ -197,11 +197,11 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { // This is a public call, so we ensure that the origin is some signed account. let sender = ensure_signed(origin)?; - ensure!(sender == Self::key(), Error::::RequireSudo); + ensure!(Self::key().map_or(false, |k| sender == k), Error::::RequireSudo); let new = T::Lookup::lookup(new)?; - Self::deposit_event(Event::KeyChanged { new_sudoer: Self::key() }); - >::put(new); + Self::deposit_event(Event::KeyChanged { old_sudoer: Key::::get() }); + Key::::put(&new); // Sudo user does not pay a fee. Ok(Pays::No.into()) } @@ -234,7 +234,7 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { // This is a public call, so we ensure that the origin is some signed account. let sender = ensure_signed(origin)?; - ensure!(sender == Self::key(), Error::::RequireSudo); + ensure!(Self::key().map_or(false, |k| sender == k), Error::::RequireSudo); let who = T::Lookup::lookup(who)?; @@ -253,8 +253,8 @@ pub mod pallet { pub enum Event { /// A sudo just took place. \[result\] Sudid { sudo_result: DispatchResult }, - /// The \[sudoer\] just switched identity; the old key is supplied. - KeyChanged { new_sudoer: T::AccountId }, + /// The \[sudoer\] just switched identity; the old key is supplied if one existed. + KeyChanged { old_sudoer: Option }, /// A sudo just took place. \[result\] SudoAsDone { sudo_result: DispatchResult }, } @@ -269,7 +269,7 @@ pub mod pallet { /// The `AccountId` of the sudo key. #[pallet::storage] #[pallet::getter(fn key)] - pub(super) type Key = StorageValue<_, T::AccountId, ValueQuery>; + pub(super) type Key = StorageValue<_, T::AccountId, OptionQuery>; #[pallet::genesis_config] pub struct GenesisConfig { @@ -288,7 +288,7 @@ pub mod pallet { impl GenesisBuild for GenesisConfig { fn build(&self) { if let Some(ref key) = self.key { - >::put(key); + Key::::put(key); } } } diff --git a/frame/utility/src/lib.rs b/frame/utility/src/lib.rs index fde4e78366e68..2200d96da600e 100644 --- a/frame/utility/src/lib.rs +++ b/frame/utility/src/lib.rs @@ -65,7 +65,7 @@ use frame_support::{ }; use sp_core::TypeId; use sp_io::hashing::blake2_256; -use sp_runtime::traits::Dispatchable; +use sp_runtime::traits::{Dispatchable, TrailingZeroInput}; use sp_std::prelude::*; pub use weights::WeightInfo; @@ -400,6 +400,7 @@ impl Pallet { /// Derive a derivative account ID from the owner account and the sub-account index. pub fn derivative_account_id(who: T::AccountId, index: u16) -> T::AccountId { let entropy = (b"modlpy/utilisuba", who, index).using_encoded(blake2_256); - T::AccountId::decode(&mut &entropy[..]).unwrap_or_default() + Decode::decode(&mut TrailingZeroInput::new(entropy.as_ref())) + .expect("infinite length input; no invalid inputs for type; qed") } } From 016a1ee4c0553d793c0aafa21fdc9fa9a5a67885 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 2 Dec 2021 17:41:48 -0500 Subject: [PATCH 09/47] Remove old code --- Cargo.lock | 15 - Cargo.toml | 1 - frame/elections/Cargo.toml | 42 - frame/elections/README.md | 7 - frame/elections/src/lib.rs | 1320 ------------------------ frame/elections/src/mock.rs | 273 ----- frame/elections/src/tests.rs | 1881 ---------------------------------- 7 files changed, 3539 deletions(-) delete mode 100644 frame/elections/Cargo.toml delete mode 100644 frame/elections/README.md delete mode 100644 frame/elections/src/lib.rs delete mode 100644 frame/elections/src/mock.rs delete mode 100644 frame/elections/src/tests.rs diff --git a/Cargo.lock b/Cargo.lock index fbdf0297d4531..3d5fdcdfa4f3b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5528,21 +5528,6 @@ dependencies = [ "strum_macros", ] -[[package]] -name = "pallet-elections" -version = "4.0.0-dev" -dependencies = [ - "frame-support", - "frame-system", - "pallet-balances", - "parity-scale-codec", - "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", -] - [[package]] name = "pallet-elections-phragmen" version = "5.0.0-dev" diff --git a/Cargo.toml b/Cargo.toml index f30b223a9b205..ce47169e4326e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -80,7 +80,6 @@ members = [ "frame/contracts/rpc/runtime-api", "frame/democracy", "frame/try-runtime", - "frame/elections", "frame/election-provider-multi-phase", "frame/election-provider-support", "frame/examples/basic", diff --git a/frame/elections/Cargo.toml b/frame/elections/Cargo.toml deleted file mode 100644 index 2ca2e584d2f43..0000000000000 --- a/frame/elections/Cargo.toml +++ /dev/null @@ -1,42 +0,0 @@ -[package] -name = "pallet-elections" -version = "4.0.0-dev" -authors = ["Parity Technologies "] -edition = "2021" -license = "Apache-2.0" -homepage = "https://substrate.io" -repository = "https://github.com/paritytech/substrate/" -description = "FRAME pallet for elections" -readme = "README.md" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -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-core = { version = "4.0.0-dev", default-features = false, path = "../../primitives/core" } -sp-std = { version = "4.0.0-dev", default-features = false, path = "../../primitives/std" } -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-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] -pallet-balances = { version = "4.0.0-dev", path = "../balances" } - -[features] -default = ["std"] -std = [ - "codec/std", - "scale-info/std", - "sp-core/std", - "sp-std/std", - "sp-io/std", - "frame-support/std", - "sp-runtime/std", - "frame-system/std", -] -try-runtime = ["frame-support/try-runtime"] diff --git a/frame/elections/README.md b/frame/elections/README.md deleted file mode 100644 index 1f6fd42331c15..0000000000000 --- a/frame/elections/README.md +++ /dev/null @@ -1,7 +0,0 @@ -Election module for stake-weighted membership selection of a collective. - -The composition of a set of account IDs works according to one or more approval votes -weighted by stake. There is a partial carry-over facility to give greater weight to those -whose voting is serially unsuccessful. - -License: Apache-2.0 \ No newline at end of file diff --git a/frame/elections/src/lib.rs b/frame/elections/src/lib.rs deleted file mode 100644 index f0911e740b188..0000000000000 --- a/frame/elections/src/lib.rs +++ /dev/null @@ -1,1320 +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. - -//! # WARNING: NOT ACTIVELY MAINTAINED -//! -//! This pallet is currently not maintained and should not be used in production until further -//! notice. -//! -//! --- -//! -//! Election pallet for stake-weighted membership selection of a collective. -//! -//! The composition of a set of account IDs works according to one or more approval votes -//! weighted by stake. There is a partial carry-over facility to give greater weight to those -//! whose voting is serially unsuccessful. - -#![cfg_attr(not(feature = "std"), no_std)] -#![recursion_limit = "128"] - -use codec::{Decode, Encode}; -use frame_support::{ - ensure, - pallet_prelude::*, - traits::{ - BalanceStatus, ChangeMembers, Currency, ExistenceRequirement, LockIdentifier, - LockableCurrency, OnUnbalanced, ReservableCurrency, WithdrawReasons, - }, - weights::{DispatchClass, Weight}, -}; -use frame_system::pallet_prelude::*; -pub use pallet::*; -use sp_runtime::{ - print, - traits::{One, Saturating, StaticLookup, Zero}, - RuntimeDebug, -}; -use sp_std::prelude::*; - -mod mock; -mod tests; - -// no polynomial attacks: -// -// all unbonded public operations should be constant time. -// all other public operations must be linear time in terms of prior public operations and: -// - those "valid" ones that cost nothing be limited to a constant number per single protected -// operation -// - the rest costing the same order as the computational complexity -// all protected operations must complete in at most O(public operations) -// -// we assume "beneficial" transactions will have the same access as attack transactions. -// -// any storage requirements should be bonded by the same order as the volume. - -// public operations: -// - express approvals (you pay in a "voter" bond the first time you do this; O(1); one extra DB -// entry, one DB change) -// - remove active voter (you get your "voter" bond back; O(1); one fewer DB entry, one DB change) -// - remove inactive voter (either you or the target is removed; if the target, you get their -// "voter" bond back; O(1); one fewer DB entry, one DB change) -// - submit candidacy (you pay a "candidate" bond; O(1); one extra DB entry, two DB changes) -// - present winner/runner-up (you may pay a "presentation" bond of O(voters) if the presentation is -// invalid; O(voters) compute; ) protected operations: -// - remove candidacy (remove all votes for a candidate) (one fewer DB entry, two DB changes) - -// to avoid a potentially problematic case of not-enough approvals prior to voting causing a -// back-to-back votes that have no way of ending, then there's a forced grace period between votes. -// to keep the system as stateless as possible (making it a bit easier to reason about), we just -// restrict when votes can begin to blocks that lie on boundaries (`voting_period`). - -// for an approval vote of C members: - -// top K runners-up are maintained between votes. all others are discarded. -// - candidate removed & bond returned when elected. -// - candidate removed & bond burned when discarded. - -// at the point that the vote ends (), all voters' balances are snapshotted. - -// for B blocks following, there's a counting period whereby each of the candidates that believe -// they fall in the top K+C voted can present themselves. they get the total stake -// recorded (based on the snapshot); an ordered list is maintained (the leaderboard). No one may -// present themselves that, if elected, would result in being included twice in the collective -// (important since existing members will have their approval votes as it may be that they -// don't get removed), nor if existing presenters would mean they're not in the top K+C. - -// following B blocks, the top C candidates are elected and have their bond returned. the top C -// candidates and all other candidates beyond the top C+K are cleared. - -// vote-clearing happens lazily; for an approval to count, the most recent vote at the time of the -// voter's most recent vote must be no later than the most recent vote at the time that the -// candidate in the approval position was registered there. as candidates are removed from the -// register and others join in their place, this prevents an approval meant for an earlier candidate -// being used to elect a new candidate. - -// the candidate list increases as needed, but the contents (though not really the capacity) reduce -// after each vote as all but K entries are cleared. newly registering candidates must use cleared -// entries before they increase the capacity. - -/// The activity status of a voter. -#[derive( - PartialEq, Eq, Copy, Clone, Encode, Decode, Default, RuntimeDebug, scale_info::TypeInfo, -)] -pub struct VoterInfo { - /// Last VoteIndex in which this voter assigned (or initialized) approvals. - last_active: VoteIndex, - /// Last VoteIndex in which one of this voter's approvals won. - /// Note that `last_win = N` indicates a last win at index `N-1`, hence `last_win = 0` means no - /// win ever. - last_win: VoteIndex, - /// The amount of stored weight as a result of not winning but changing approvals. - pot: Balance, - /// Current staked amount. A lock equal to this value always exists. - stake: Balance, -} - -/// Used to demonstrate the status of a particular index in the global voter list. -#[derive(PartialEq, Eq, RuntimeDebug)] -pub enum CellStatus { - /// Any out of bound index. Means a push a must happen to the chunk pointed by - /// `NextVoterSet`. Voting fee is applied in case a new chunk is created. - Head, - /// Already occupied by another voter. Voting fee is applied. - Occupied, - /// Empty hole which should be filled. No fee will be applied. - Hole, -} - -/// Number of voters grouped in one chunk. -pub const VOTER_SET_SIZE: usize = 64; -/// NUmber of approvals grouped in one chunk. -pub const APPROVAL_SET_SIZE: usize = 8; - -type BalanceOf = - <::Currency as Currency<::AccountId>>::Balance; -type NegativeImbalanceOf = <::Currency as Currency< - ::AccountId, ->>::NegativeImbalance; - -/// Index used to access chunks. -type SetIndex = u32; -/// Index used to count voting rounds. -pub type VoteIndex = u32; -/// Underlying data type of the approvals. -type ApprovalFlag = u32; -/// Number of approval flags that can fit into [`ApprovalFlag`] type. -const APPROVAL_FLAG_LEN: usize = 32; - -#[frame_support::pallet] -pub mod pallet { - use super::*; - - #[pallet::pallet] - #[pallet::generate_store(pub(super) trait Store)] - pub struct Pallet(_); - - #[pallet::config] - pub trait Config: frame_system::Config { - type Event: From> + IsType<::Event>; - - /// Identifier for the elections pallet's lock - #[pallet::constant] - type PalletId: Get; - - /// The currency that people are electing with. - type Currency: LockableCurrency - + ReservableCurrency; - - /// Handler for the unbalanced reduction when slashing a validator. - type BadPresentation: OnUnbalanced>; - - /// Handler for the unbalanced reduction when slashing an invalid reaping attempt. - type BadReaper: OnUnbalanced>; - - /// Handler for the unbalanced reduction when submitting a bad `voter_index`. - type BadVoterIndex: OnUnbalanced>; - - /// Handler for the unbalanced reduction when a candidate has lost (and is not a runner up) - type LoserCandidate: OnUnbalanced>; - - /// What to do when the members change. - type ChangeMembers: ChangeMembers; - - /// How much should be locked up in order to submit one's candidacy. A reasonable - /// default value is 9. - #[pallet::constant] - type CandidacyBond: Get>; - - /// How much should be locked up in order to be able to submit votes. - #[pallet::constant] - type VotingBond: Get>; - - /// The amount of fee paid upon each vote submission, unless if they submit a - /// _hole_ index and replace it. - #[pallet::constant] - type VotingFee: Get>; - - /// Minimum about that can be used as the locked value for voting. - #[pallet::constant] - type MinimumVotingLock: Get>; - - /// The punishment, per voter, if you provide an invalid presentation. A - /// reasonable default value is 1. - #[pallet::constant] - type PresentSlashPerVoter: Get>; - - /// How many runners-up should have their approvals persist until the next - /// vote. A reasonable default value is 2. - #[pallet::constant] - type CarryCount: Get; - - /// How many vote indices need to go by after a target voter's last vote before - /// they can be reaped if their approvals are moot. A reasonable default value - /// is 1. - #[pallet::constant] - type InactiveGracePeriod: Get; - - /// How often (in blocks) to check for new votes. A reasonable default value - /// is 1000. - #[pallet::constant] - type VotingPeriod: Get; - - /// Decay factor of weight when being accumulated. It should typically be set to - /// __at least__ `membership_size -1` to keep the collective secure. - /// When set to `N`, it indicates `(1/N)^t` of staked is decayed at weight - /// increment step `t`. 0 will result in no weight being added at all (normal - /// approval voting). A reasonable default value is 24. - #[pallet::constant] - type DecayRatio: Get; - } - - #[pallet::extra_constants] - impl Pallet { - // TODO: rename to snake case after https://github.com/paritytech/substrate/issues/8826 fixed. - /// The chunk size of the voter vector. - #[allow(non_snake_case)] - fn VOTER_SET_SIZE() -> u32 { - VOTER_SET_SIZE as u32 - } - - // TODO: rename to snake case after https://github.com/paritytech/substrate/issues/8826 fixed. - /// The chunk size of the approval vector. - #[allow(non_snake_case)] - fn APPROVAL_SET_SIZE() -> u32 { - APPROVAL_SET_SIZE as u32 - } - } - - // ---- permanent state (always relevant, changes only at the finalization of voting) - - /// How long to give each top candidate to present themselves after the vote ends. - #[pallet::storage] - #[pallet::getter(fn presentation_duration)] - pub type PresentationDuration = StorageValue<_, T::BlockNumber, ValueQuery>; - - /// How long each position is active for. - #[pallet::storage] - #[pallet::getter(fn term_duration)] - pub type TermDuration = StorageValue<_, T::BlockNumber, ValueQuery>; - - /// Number of accounts that should constitute the collective. - #[pallet::storage] - #[pallet::getter(fn desired_seats)] - pub type DesiredSeats = StorageValue<_, u32, ValueQuery>; - - // ---- permanent state (always relevant, changes only at the finalization of voting) - - /// The current membership. When there's a vote going on, this should still be used for - /// executive matters. The block number (second element in the tuple) is the block that - /// their position is active until (calculated by the sum of the block number when the - /// member was elected and their term duration). - #[pallet::storage] - #[pallet::getter(fn members)] - pub type Members = StorageValue<_, Vec<(T::AccountId, T::BlockNumber)>, ValueQuery>; - - /// The total number of vote rounds that have happened or are in progress. - #[pallet::storage] - #[pallet::getter(fn vote_index)] - pub type VoteCount = StorageValue<_, VoteIndex, ValueQuery>; - - // ---- persistent state (always relevant, changes constantly) - - // A list of votes for each voter. The votes are stored as numeric values and parsed in a - // bit-wise manner. In order to get a human-readable representation (`Vec`), use - // [`all_approvals_of`]. Furthermore, each vector of scalars is chunked with the cap of - // `APPROVAL_SET_SIZE`. - /// TWOX-NOTE: SAFE as `AccountId` is a crypto hash and `SetIndex` is not - /// attacker-controlled. - #[pallet::storage] - #[pallet::getter(fn approvals_of)] - pub type ApprovalsOf = - StorageMap<_, Twox64Concat, (T::AccountId, SetIndex), Vec, ValueQuery>; - - /// The vote index and list slot that the candidate `who` was registered or `None` if they - /// are not currently registered. - /// - /// TWOX-NOTE: SAFE as `AccountId` is a crypto hash. - #[pallet::storage] - #[pallet::getter(fn candidate_reg_info)] - pub type RegisterInfoOf = - StorageMap<_, Twox64Concat, T::AccountId, (VoteIndex, u32)>; - - /// Basic information about a voter. - /// - /// TWOX-NOTE: SAFE as `AccountId` is a crypto hash. - #[pallet::storage] - #[pallet::getter(fn voter_info)] - pub type VoterInfoOf = - StorageMap<_, Twox64Concat, T::AccountId, VoterInfo>>; - - /// The present voter list (chunked and capped at [`VOTER_SET_SIZE`]). - /// - /// TWOX-NOTE: OKAY ― `SetIndex` is not user-controlled data. - #[pallet::storage] - #[pallet::getter(fn voters)] - pub type Voters = - StorageMap<_, Twox64Concat, SetIndex, Vec>, ValueQuery>; - - /// the next free set to store a voter in. This will keep growing. - #[pallet::storage] - #[pallet::getter(fn next_nonfull_voter_set)] - pub type NextVoterSet = StorageValue<_, SetIndex, ValueQuery>; - - /// Current number of Voters. - #[pallet::storage] - #[pallet::getter(fn voter_count)] - pub type VoterCount = StorageValue<_, SetIndex, ValueQuery>; - - /// The present candidate list. - #[pallet::storage] - #[pallet::getter(fn candidates)] - pub type Candidates = StorageValue<_, Vec, ValueQuery>; // has holes - - /// Current number of active candidates - #[pallet::storage] - #[pallet::getter(fn candidate_count)] - pub type CandidateCount = StorageValue<_, u32, ValueQuery>; - - // ---- temporary state (only relevant during finalization/presentation) - - /// The accounts holding the seats that will become free on the next tally. - #[pallet::storage] - #[pallet::getter(fn next_finalize)] - pub type NextFinalize = StorageValue<_, (T::BlockNumber, u32, Vec)>; - - /// Get the leaderboard if we're in the presentation phase. The first element is the weight - /// of each entry; It may be the direct summed approval stakes, or a weighted version of it. - /// Sorted from low to high. - #[pallet::storage] - #[pallet::getter(fn leaderboard)] - pub type Leaderboard = StorageValue<_, Vec<(BalanceOf, T::AccountId)>>; - - #[pallet::genesis_config] - pub struct GenesisConfig { - pub presentation_duration: T::BlockNumber, - pub term_duration: T::BlockNumber, - pub desired_seats: u32, - pub members: Vec<(T::AccountId, T::BlockNumber)>, - } - - #[cfg(feature = "std")] - impl Default for GenesisConfig { - fn default() -> Self { - GenesisConfig { - presentation_duration: Default::default(), - term_duration: Default::default(), - desired_seats: Default::default(), - members: Default::default(), - } - } - } - - #[pallet::genesis_build] - impl GenesisBuild for GenesisConfig { - fn build(&self) { - PresentationDuration::::put(self.presentation_duration); - TermDuration::::put(self.term_duration); - DesiredSeats::::put(self.desired_seats); - Members::::put(&self.members); - } - } - - #[pallet::error] - pub enum Error { - /// Reporter must be a voter. - NotVoter, - /// Target for inactivity cleanup must be active. - InactiveTarget, - /// Cannot reap during presentation period. - CannotReapPresenting, - /// Cannot reap during grace period. - ReapGrace, - /// Invalid reporter index. - InvalidReporterIndex, - /// Invalid target index. - InvalidTargetIndex, - /// Invalid vote index. - InvalidVoteIndex, - /// Cannot retract when presenting. - CannotRetractPresenting, - /// Cannot retract non-voter. - RetractNonVoter, - /// Invalid retraction index. - InvalidRetractionIndex, - /// Duplicate candidate submission. - DuplicatedCandidate, - /// Invalid candidate slot. - InvalidCandidateSlot, - /// Candidate has not enough funds. - InsufficientCandidateFunds, - /// Presenter must have sufficient slashable funds. - InsufficientPresenterFunds, - /// Stake deposited to present winner and be added to leaderboard should be non-zero. - ZeroDeposit, - /// Candidate not worthy of leaderboard. - UnworthyCandidate, - /// Leaderboard must exist while present phase active. - LeaderboardMustExist, - /// Cannot present outside of presentation period. - NotPresentationPeriod, - /// Presented candidate must be current. - InvalidCandidate, - /// Duplicated presentation. - DuplicatedPresentation, - /// Incorrect total. - IncorrectTotal, - /// Invalid voter index. - InvalidVoterIndex, - /// New voter must have sufficient funds to pay the bond. - InsufficientVoterFunds, - /// Locked value must be more than limit. - InsufficientLockedValue, - /// Amount of candidate votes cannot exceed amount of candidates. - TooManyVotes, - /// Amount of candidates to receive approval votes should be non-zero. - ZeroCandidates, - /// No approval changes during presentation period. - ApprovalPresentation, - } - - #[pallet::hooks] - impl Hooks> for Pallet { - fn on_initialize(n: T::BlockNumber) -> Weight { - if let Err(e) = Self::end_block(n) { - print("Guru meditation"); - print(e); - } - 0 - } - } - - #[pallet::event] - #[pallet::generate_deposit(pub(super) fn deposit_event)] - pub enum Event { - /// Reaped - VoterReaped { voter: T::AccountId, reaper: T::AccountId }, - /// Slashed - BadReaperSlashed { reaper: T::AccountId }, - /// A tally (for approval votes of seats) has started. - TallyStarted { seats: u32 }, - /// A tally (for approval votes of seat(s)) has ended (with one or more new members). - TallyFinalized { incoming: Vec, outgoing: Vec }, - } - - #[pallet::call] - impl Pallet { - /// Set candidate approvals. Approval slots stay valid as long as candidates in those slots - /// are registered. - /// - /// Locks `value` from the balance of `origin` indefinitely. Only - /// [`retract_voter`](Self::retract_voter) or - /// [`reap_inactive_voter`](Self::reap_inactive_voter) can unlock the balance. - /// - /// `hint` argument is interpreted differently based on: - /// - if `origin` is setting approvals for the first time: The index will be checked for - /// being a valid _hole_ in the voter list. - /// - if the hint is correctly pointing to a hole, no fee is deducted from `origin`. - /// - Otherwise, the call will succeed but the index is ignored and simply a push to the - /// last chunk with free space happens. If the new push causes a new chunk to be - /// created, a fee indicated by [`Config::VotingFee`] is deducted. - /// - if `origin` is already a voter: the index __must__ be valid and point to the correct - /// position of the `origin` in the current voters list. - /// - /// Note that any trailing `false` votes in `votes` is ignored; In approval voting, not - /// voting for a candidate and voting false, are equal. - /// - /// # - /// - O(1). - /// - Two extra DB entries, one DB change. - /// - Argument `votes` is limited in length to number of candidates. - /// # - #[pallet::weight(2_500_000_000)] - pub fn set_approvals( - origin: OriginFor, - votes: Vec, - #[pallet::compact] index: VoteIndex, - hint: SetIndex, - #[pallet::compact] value: BalanceOf, - ) -> DispatchResult { - let who = ensure_signed(origin)?; - Self::do_set_approvals(who, votes, index, hint, value) - } - - /// Remove a voter. For it not to be a bond-consuming no-op, all approved candidate indices - /// must now be either unregistered or registered to a candidate that registered the slot - /// after the voter gave their last approval set. - /// - /// Both indices must be provided according to the following principle: - /// Voter index does not take holes into account. This means that any account submitting an - /// index at any point in time should submit: - /// `VOTER_SET_SIZE * set_index + local_index`, meaning that you are ignoring all holes in - /// the first `set_index` sets. - /// - /// May be called by anyone. Returns the voter deposit to `signed`. - /// - /// # - /// - O(1). - /// - Two fewer DB entries, one DB change. - /// # - #[pallet::weight(2_500_000_000)] - pub fn reap_inactive_voter( - origin: OriginFor, - #[pallet::compact] reporter_index: u32, - who: ::Source, - #[pallet::compact] who_index: u32, - #[pallet::compact] assumed_vote_index: VoteIndex, - ) -> DispatchResult { - let reporter = ensure_signed(origin)?; - let who = T::Lookup::lookup(who)?; - - ensure!(!Self::presentation_active(), Error::::CannotReapPresenting); - ensure!(Self::voter_info(&reporter).is_some(), Error::::NotVoter); - - let info = Self::voter_info(&who).ok_or(Error::::InactiveTarget)?; - let last_active = info.last_active; - - ensure!(assumed_vote_index == Self::vote_index(), Error::::InvalidVoteIndex); - ensure!( - assumed_vote_index > last_active + T::InactiveGracePeriod::get(), - Error::::ReapGrace, - ); - - let reporter_index = reporter_index as usize; - let who_index = who_index as usize; - let assumed_reporter = - Self::voter_at(reporter_index).ok_or(Error::::InvalidReporterIndex)?; - let assumed_who = Self::voter_at(who_index).ok_or(Error::::InvalidTargetIndex)?; - - ensure!(assumed_reporter == reporter, Error::::InvalidReporterIndex); - ensure!(assumed_who == who, Error::::InvalidTargetIndex); - - // will definitely kill one of reporter or who now. - - let valid = !Self::all_approvals_of(&who).iter().zip(Self::candidates().iter()).any( - |(&appr, addr)| { - appr && - *addr != T::AccountId::default() && - // defensive only: all items in candidates list are registered - Self::candidate_reg_info(addr).map_or(false, |x| x.0 <= last_active) - }, - ); - - Self::remove_voter( - if valid { &who } else { &reporter }, - if valid { who_index } else { reporter_index }, - ); - - T::Currency::remove_lock(T::PalletId::get(), if valid { &who } else { &reporter }); - - if valid { - // This only fails if `reporter` doesn't exist, which it clearly must do since its - // the origin. Still, it's no more harmful to propagate any error at this point. - T::Currency::repatriate_reserved( - &who, - &reporter, - T::VotingBond::get(), - BalanceStatus::Free, - )?; - Self::deposit_event(Event::::VoterReaped { voter: who, reaper: reporter }); - } else { - let imbalance = T::Currency::slash_reserved(&reporter, T::VotingBond::get()).0; - T::BadReaper::on_unbalanced(imbalance); - Self::deposit_event(Event::::BadReaperSlashed { reaper: reporter }); - } - Ok(()) - } - - /// Remove a voter. All votes are cancelled and the voter deposit is returned. - /// - /// The index must be provided according to the following principle: - /// Voter index does not take holes into account. This means that any account submitting an - /// index at any point in time should submit: - /// `VOTER_SET_SIZE * set_index + local_index`, meaning that you are ignoring all holes in - /// the first `set_index` sets. - /// - /// Also removes the lock on the balance of the voter. - /// - /// # - /// - O(1). - /// - Two fewer DB entries, one DB change. - /// # - #[pallet::weight(1_250_000_000)] - pub fn retract_voter( - origin: OriginFor, - #[pallet::compact] index: u32, - ) -> DispatchResult { - let who = ensure_signed(origin)?; - - ensure!(!Self::presentation_active(), Error::::CannotRetractPresenting); - ensure!(>::contains_key(&who), Error::::RetractNonVoter); - let index = index as usize; - let voter = Self::voter_at(index).ok_or(Error::::InvalidRetractionIndex)?; - ensure!(voter == who, Error::::InvalidRetractionIndex); - - Self::remove_voter(&who, index); - T::Currency::unreserve(&who, T::VotingBond::get()); - T::Currency::remove_lock(T::PalletId::get(), &who); - Ok(()) - } - - /// Submit oneself for candidacy. - /// - /// Account must have enough transferrable funds in it to pay the bond. - /// - /// NOTE: if `origin` has already assigned approvals via - /// [`set_approvals`](Self::set_approvals), it will NOT have any usable funds to pass - /// candidacy bond and must first retract. - /// Note that setting approvals will lock the entire balance of the voter until - /// retraction or being reported. - /// - /// # - /// - Independent of input. - /// - Three DB changes. - /// # - #[pallet::weight(2_500_000_000)] - pub fn submit_candidacy( - origin: OriginFor, - #[pallet::compact] slot: u32, - ) -> DispatchResult { - let who = ensure_signed(origin)?; - - ensure!(!Self::is_a_candidate(&who), Error::::DuplicatedCandidate); - let slot = slot as usize; - let count = Self::candidate_count() as usize; - let candidates = Self::candidates(); - ensure!( - slot == count && count == candidates.len(), - Error::::InvalidCandidateSlot, - ); - // NOTE: This must be last as it has side-effects. - T::Currency::reserve(&who, T::CandidacyBond::get()) - .map_err(|_| Error::::InsufficientCandidateFunds)?; - - >::insert(&who, (Self::vote_index(), slot as u32)); - let mut candidates = candidates; - if slot == candidates.len() { - candidates.push(who); - } else { - candidates[slot] = who; - } - >::put(candidates); - CandidateCount::::put(count as u32 + 1); - Ok(()) - } - - /// Claim that `candidate` is one of the top `carry_count + desired_seats` candidates. Only - /// works iff the presentation period is active. `candidate` should have at least collected - /// some non-zero `total` votes and `origin` must have enough funds to pay for a potential - /// slash. - /// - /// # - /// - O(voters) compute. - /// - One DB change. - /// # - #[pallet::weight(10_000_000_000)] - pub fn present_winner( - origin: OriginFor, - candidate: ::Source, - #[pallet::compact] total: BalanceOf, - #[pallet::compact] index: VoteIndex, - ) -> DispatchResult { - let who = ensure_signed(origin)?; - ensure!(!total.is_zero(), Error::::ZeroDeposit); - - let candidate = T::Lookup::lookup(candidate)?; - ensure!(index == Self::vote_index(), Error::::InvalidVoteIndex); - let (_, _, expiring) = - Self::next_finalize().ok_or(Error::::NotPresentationPeriod)?; - let bad_presentation_punishment = - T::PresentSlashPerVoter::get() * BalanceOf::::from(Self::voter_count() as u32); - ensure!( - T::Currency::can_slash(&who, bad_presentation_punishment), - Error::::InsufficientPresenterFunds, - ); - - let mut leaderboard = Self::leaderboard().ok_or(Error::::LeaderboardMustExist)?; - ensure!(total > leaderboard[0].0, Error::::UnworthyCandidate); - - if let Some(p) = Self::members().iter().position(|&(ref c, _)| c == &candidate) { - ensure!(p < expiring.len(), Error::::DuplicatedCandidate); - } - - let voters = Self::all_voters(); - let (registered_since, candidate_index): (VoteIndex, u32) = - Self::candidate_reg_info(&candidate).ok_or(Error::::InvalidCandidate)?; - let actual_total = voters - .iter() - .filter_map(|maybe_voter| maybe_voter.as_ref()) - .filter_map(|voter| match Self::voter_info(voter) { - Some(b) if b.last_active >= registered_since => { - let last_win = b.last_win; - let now = Self::vote_index(); - let stake = b.stake; - let offset = Self::get_offset(stake, now - last_win); - let weight = stake + offset + b.pot; - if Self::approvals_of_at(voter, candidate_index as usize) { - Some(weight) - } else { - None - } - }, - _ => None, - }) - .fold(Zero::zero(), |acc, n| acc + n); - let dupe = leaderboard.iter().find(|&&(_, ref c)| c == &candidate).is_some(); - if total == actual_total && !dupe { - // insert into leaderboard - leaderboard[0] = (total, candidate); - leaderboard.sort_by_key(|&(t, _)| t); - >::put(leaderboard); - Ok(()) - } else { - // we can rest assured it will be Ok since we checked `can_slash` earlier; still - // better safe than sorry. - let imbalance = T::Currency::slash(&who, bad_presentation_punishment).0; - T::BadPresentation::on_unbalanced(imbalance); - Err(if dupe { - Error::::DuplicatedPresentation - } else { - Error::::IncorrectTotal - })? - } - } - - /// Set the desired member count; if lower than the current count, then seats will not be up - /// election when they expire. If more, then a new vote will be started if one is not - /// already in progress. - #[pallet::weight((0, DispatchClass::Operational))] - pub fn set_desired_seats( - origin: OriginFor, - #[pallet::compact] count: u32, - ) -> DispatchResult { - ensure_root(origin)?; - DesiredSeats::::put(count); - Ok(()) - } - - /// Remove a particular member from the set. This is effective immediately. - /// - /// Note: A tally should happen instantly (if not already in a presentation - /// period) to fill the seat if removal means that the desired members are not met. - #[pallet::weight((0, DispatchClass::Operational))] - pub fn remove_member( - origin: OriginFor, - who: ::Source, - ) -> DispatchResult { - ensure_root(origin)?; - let who = T::Lookup::lookup(who)?; - let new_set: Vec<(T::AccountId, T::BlockNumber)> = - Self::members().into_iter().filter(|i| i.0 != who).collect(); - >::put(&new_set); - let new_set = new_set.into_iter().map(|x| x.0).collect::>(); - T::ChangeMembers::change_members(&[], &[who], new_set); - Ok(()) - } - - /// Set the presentation duration. If there is currently a vote being presented for, will - /// invoke `finalize_vote`. - #[pallet::weight((0, DispatchClass::Operational))] - pub fn set_presentation_duration( - origin: OriginFor, - #[pallet::compact] count: T::BlockNumber, - ) -> DispatchResult { - ensure_root(origin)?; - >::put(count); - Ok(()) - } - - /// Set the presentation duration. If there is current a vote being presented for, will - /// invoke `finalize_vote`. - #[pallet::weight((0, DispatchClass::Operational))] - pub fn set_term_duration( - origin: OriginFor, - #[pallet::compact] count: T::BlockNumber, - ) -> DispatchResult { - ensure_root(origin)?; - >::put(count); - Ok(()) - } - } -} - -impl Pallet { - // exposed immutables. - - /// True if we're currently in a presentation period. - pub fn presentation_active() -> bool { - >::exists() - } - - /// If `who` a candidate at the moment? - pub fn is_a_candidate(who: &T::AccountId) -> bool { - >::contains_key(who) - } - - /// Iff the member `who` still has a seat at blocknumber `n` returns `true`. - pub fn will_still_be_member_at(who: &T::AccountId, n: T::BlockNumber) -> bool { - Self::members() - .iter() - .find(|&&(ref a, _)| a == who) - .map(|&(_, expires)| expires > n) - .unwrap_or(false) - } - - /// Determine the block that a vote can happen on which is no less than `n`. - pub fn next_vote_from(n: T::BlockNumber) -> T::BlockNumber { - let voting_period = T::VotingPeriod::get(); - (n + voting_period - One::one()) / voting_period * voting_period - } - - /// The block number on which the tally for the next election will happen. `None` only if the - /// desired seats of the set is zero. - pub fn next_tally() -> Option { - let desired_seats = Self::desired_seats(); - if desired_seats == 0 { - None - } else { - let c = Self::members(); - let (next_possible, count, coming) = if let Some((tally_end, comers, leavers)) = - Self::next_finalize() - { - // if there's a tally in progress, then next tally can begin immediately afterwards - (tally_end, c.len() - leavers.len() + comers as usize, comers) - } else { - (>::block_number(), c.len(), 0) - }; - if count < desired_seats as usize { - Some(next_possible) - } else { - // next tally begins once enough members expire to bring members below desired. - if desired_seats <= coming { - // the entire amount of desired seats is less than those new members - we'll - // have to wait until they expire. - Some(next_possible + Self::term_duration()) - } else { - Some(c[c.len() - (desired_seats - coming) as usize].1) - } - } - .map(Self::next_vote_from) - } - } - - // Private - /// Check there's nothing to do this block - fn end_block(block_number: T::BlockNumber) -> DispatchResult { - if (block_number % T::VotingPeriod::get()).is_zero() { - if let Some(number) = Self::next_tally() { - if block_number == number { - Self::start_tally(); - } - } - } - if let Some((number, _, _)) = Self::next_finalize() { - if block_number == number { - Self::finalize_tally()? - } - } - Ok(()) - } - - /// Remove a voter at a specified index from the system. - fn remove_voter(voter: &T::AccountId, index: usize) { - let (set_index, vec_index) = Self::split_index(index, VOTER_SET_SIZE); - let mut set = Self::voters(set_index); - set[vec_index] = None; - >::insert(set_index, set); - VoterCount::::mutate(|c| *c = *c - 1); - Self::remove_all_approvals_of(voter); - >::remove(voter); - } - - /// Actually do the voting. - /// - /// The voter index must be provided as explained in [`voter_at`] function. - fn do_set_approvals( - who: T::AccountId, - votes: Vec, - index: VoteIndex, - hint: SetIndex, - value: BalanceOf, - ) -> DispatchResult { - let candidates_len = ::Candidates::decode_len().unwrap_or(0_usize); - - ensure!(!Self::presentation_active(), Error::::ApprovalPresentation); - ensure!(index == Self::vote_index(), Error::::InvalidVoteIndex); - ensure!(!candidates_len.is_zero(), Error::::ZeroCandidates); - // Prevent a vote from voters that provide a list of votes that exceeds the candidates - // length since otherwise an attacker may be able to submit a very long list of `votes` that - // far exceeds the amount of candidates and waste more computation than a reasonable voting - // bond would cover. - ensure!(candidates_len >= votes.len(), Error::::TooManyVotes); - ensure!(value >= T::MinimumVotingLock::get(), Error::::InsufficientLockedValue); - - // Amount to be locked up. - let mut locked_balance = value.min(T::Currency::total_balance(&who)); - let mut pot_to_set = Zero::zero(); - let hint = hint as usize; - - if let Some(info) = Self::voter_info(&who) { - // already a voter. Index must be valid. No fee. update pot. O(1) - let voter = Self::voter_at(hint).ok_or(Error::::InvalidVoterIndex)?; - ensure!(voter == who, Error::::InvalidVoterIndex); - - // write new accumulated offset. - let last_win = info.last_win; - let now = index; - let offset = Self::get_offset(info.stake, now - last_win); - pot_to_set = info.pot + offset; - } else { - // not yet a voter. Index _could be valid_. Fee might apply. Bond will be reserved O(1). - ensure!( - T::Currency::free_balance(&who) > T::VotingBond::get(), - Error::::InsufficientVoterFunds, - ); - - let (set_index, vec_index) = Self::split_index(hint, VOTER_SET_SIZE); - match Self::cell_status(set_index, vec_index) { - CellStatus::Hole => { - // requested cell was a valid hole. - >::mutate(set_index, |set| set[vec_index] = Some(who.clone())); - }, - CellStatus::Head | CellStatus::Occupied => { - // Either occupied or out-of-range. - let next = Self::next_nonfull_voter_set(); - let set_len = >::decode_len(next).unwrap_or(0_usize); - // Caused a new set to be created. Pay for it. - // This is the last potential error. Writes will begin afterwards. - if set_len == 0 { - let imbalance = T::Currency::withdraw( - &who, - T::VotingFee::get(), - WithdrawReasons::FEE, - ExistenceRequirement::KeepAlive, - )?; - T::BadVoterIndex::on_unbalanced(imbalance); - // NOTE: this is safe since the `withdraw()` will check this. - locked_balance -= T::VotingFee::get(); - } - if set_len + 1 == VOTER_SET_SIZE { - NextVoterSet::::put(next + 1); - } - >::append(next, Some(who.clone())); - }, - } - - T::Currency::reserve(&who, T::VotingBond::get())?; - VoterCount::::mutate(|c| *c = *c + 1); - } - - T::Currency::set_lock(T::PalletId::get(), &who, locked_balance, WithdrawReasons::all()); - - >::insert( - &who, - VoterInfo::> { - last_active: index, - last_win: index, - stake: locked_balance, - pot: pot_to_set, - }, - ); - Self::set_approvals_chunked(&who, votes); - - Ok(()) - } - - /// Close the voting, record the number of seats that are actually up for grabs. - fn start_tally() { - let members = Self::members(); - let desired_seats = Self::desired_seats() as usize; - let number = >::block_number(); - let expiring = members - .iter() - .take_while(|i| i.1 <= number) - .map(|i| i.0.clone()) - .collect::>(); - let retaining_seats = members.len() - expiring.len(); - if retaining_seats < desired_seats { - let empty_seats = desired_seats - retaining_seats; - >::put(( - number + Self::presentation_duration(), - empty_seats as u32, - expiring, - )); - - // initialize leaderboard. - let leaderboard_size = empty_seats + T::CarryCount::get() as usize; - >::put(vec![ - (BalanceOf::::zero(), None); - leaderboard_size - ]); - - Self::deposit_event(Event::::TallyStarted { seats: empty_seats as u32 }); - } - } - - /// Finalize the vote, removing each of the `removals` and inserting `seats` of the most - /// approved candidates in their place. If the total number of members is less than the desired - /// membership a new vote is started. Clears all presented candidates, returning the bond of the - /// elected ones. - fn finalize_tally() -> DispatchResult { - let (_, coming, expiring): (T::BlockNumber, u32, Vec) = - >::take() - .ok_or("finalize can only be called after a tally is started.")?; - let leaderboard: Vec<(BalanceOf, T::AccountId)> = - >::take().unwrap_or_default(); - let new_expiry = >::block_number() + Self::term_duration(); - - // return bond to winners. - let candidacy_bond = T::CandidacyBond::get(); - let incoming: Vec<_> = leaderboard - .iter() - .rev() - .take_while(|&&(b, _)| !b.is_zero()) - .take(coming as usize) - .map(|(_, a)| a) - .cloned() - .inspect(|a| { - T::Currency::unreserve(a, candidacy_bond); - }) - .collect(); - - // Update last win index for anyone voted for any of the incomings. - incoming.iter().filter_map(|i| Self::candidate_reg_info(i)).for_each(|r| { - let index = r.1 as usize; - Self::all_voters() - .iter() - .filter_map(|mv| mv.as_ref()) - .filter(|v| Self::approvals_of_at(*v, index)) - .for_each(|v| { - >::mutate(v, |a| { - if let Some(activity) = a { - activity.last_win = Self::vote_index() + 1; - } - }) - }); - }); - let members = Self::members(); - let outgoing: Vec<_> = members.iter().take(expiring.len()).map(|a| a.0.clone()).collect(); - - // set the new membership set. - let mut new_set: Vec<_> = members - .into_iter() - .skip(expiring.len()) - .chain(incoming.iter().cloned().map(|a| (a, new_expiry))) - .collect(); - new_set.sort_by_key(|&(_, expiry)| expiry); - >::put(&new_set); - - let new_set = new_set.into_iter().map(|x| x.0).collect::>(); - T::ChangeMembers::change_members(&incoming, &outgoing, new_set); - - // clear all except runners-up from candidate list. - let candidates = Self::candidates(); - let mut new_candidates = vec![None; candidates.len()]; // shrink later. - let runners_up = leaderboard - .into_iter() - .rev() - .take_while(|&(b, _)| !b.is_zero()) - .skip(coming as usize) - .filter_map(|(_, a)| Self::candidate_reg_info(&a).map(|i| (a, i.1))); - let mut count = 0u32; - for (address, slot) in runners_up { - new_candidates[slot as usize] = Some(address); - count += 1; - } - for (old, new) in candidates.iter().map(Some).zip(new_candidates.iter()) { - // candidate is not a runner up. - if new.as_ref() != old { - // removed - kill it - >::remove(old); - - // and candidate is not a winner. - if incoming.iter().find(|e| *e == old).is_none() { - // slash the bond. - let (imbalance, _) = T::Currency::slash_reserved(&old, T::CandidacyBond::get()); - T::LoserCandidate::on_unbalanced(imbalance); - } - } - } - // discard any superfluous slots. - let new_candidates = new_candidates.into_iter().filter_map(|x| x).collect::>(); - - Self::deposit_event(Event::::TallyFinalized { incoming, outgoing }); - - Candidates::::put(new_candidates); - CandidateCount::::put(count); - VoteCount::::put(Self::vote_index() + 1); - Ok(()) - } - - /// Get the set and vector index of a global voter index. - /// - /// Note that this function does not take holes into account. - /// See [`voter_at`]. - fn split_index(index: usize, scale: usize) -> (SetIndex, usize) { - let set_index = (index / scale) as u32; - let vec_index = index % scale; - (set_index, vec_index) - } - - /// Return a concatenated vector over all voter sets. - fn all_voters() -> Vec> { - let mut all = >::get(0); - let mut index = 1; - // NOTE: we could also use `Self::next_nonfull_voter_set()` here but that might change based - // on how we do chunking. This is more generic. - loop { - let next_set = >::get(index); - if next_set.is_empty() { - break - } else { - index += 1; - all.extend(next_set); - } - } - all - } - - /// Shorthand for fetching a voter at a specific (global) index. - /// - /// NOTE: this function is used for checking indices. Yet, it does not take holes into account. - /// This means that any account submitting an index at any point in time should submit: - /// `VOTER_SET_SIZE * set_index + local_index`, meaning that you are ignoring all holes in the - /// first `set_index` sets. - fn voter_at(index: usize) -> Option { - let (set_index, vec_index) = Self::split_index(index, VOTER_SET_SIZE); - let set = Self::voters(set_index); - if vec_index < set.len() { - set[vec_index].clone() - } else { - None - } - } - - /// A more sophisticated version of `voter_at`. Will be kept separate as most often it is an - /// overdue compared to `voter_at`. Only used when setting approvals. - fn cell_status(set_index: SetIndex, vec_index: usize) -> CellStatus { - let set = Self::voters(set_index); - if vec_index < set.len() { - if let Some(_) = set[vec_index] { - CellStatus::Occupied - } else { - CellStatus::Hole - } - } else { - CellStatus::Head - } - } - - /// Sets the approval of a voter in a chunked manner. - fn set_approvals_chunked(who: &T::AccountId, approvals: Vec) { - let approvals_flag_vec = Self::bool_to_flag(approvals); - approvals_flag_vec - .chunks(APPROVAL_SET_SIZE) - .enumerate() - .for_each(|(index, slice)| >::insert((&who, index as SetIndex), slice)); - } - - /// shorthand for fetching a specific approval of a voter at a specific (global) index. - /// - /// Using this function to read a vote is preferred as it reads `APPROVAL_SET_SIZE` items of - /// type `ApprovalFlag` from storage at most; not all of them. - /// - /// Note that false is returned in case of no-vote or an explicit `false`. - fn approvals_of_at(who: &T::AccountId, index: usize) -> bool { - let (flag_index, bit) = Self::split_index(index, APPROVAL_FLAG_LEN); - let (set_index, vec_index) = Self::split_index(flag_index as usize, APPROVAL_SET_SIZE); - let set = Self::approvals_of((who.clone(), set_index)); - if vec_index < set.len() { - // This is because bit_at treats numbers in lsb -> msb order. - let reversed_index = set.len() - 1 - vec_index; - Self::bit_at(set[reversed_index], bit) - } else { - false - } - } - - /// Return true of the bit `n` of scalar `x` is set to `1` and false otherwise. - fn bit_at(x: ApprovalFlag, n: usize) -> bool { - if n < APPROVAL_FLAG_LEN { - x & (1 << n) != 0 - } else { - false - } - } - - /// Convert a vec of boolean approval flags to a vec of integers, as denoted by - /// the type `ApprovalFlag`. see `bool_to_flag_should_work` test for examples. - pub fn bool_to_flag(x: Vec) -> Vec { - let mut result: Vec = Vec::with_capacity(x.len() / APPROVAL_FLAG_LEN); - if x.is_empty() { - return result - } - result.push(0); - let mut index = 0; - let mut counter = 0; - loop { - let shl_index = counter % APPROVAL_FLAG_LEN; - result[index] += (if x[counter] { 1 } else { 0 }) << shl_index; - counter += 1; - if counter > x.len() - 1 { - break - } - if counter % APPROVAL_FLAG_LEN == 0 { - result.push(0); - index += 1; - } - } - result - } - - /// Convert a vec of flags (u32) to boolean. - pub fn flag_to_bool(chunk: Vec) -> Vec { - let mut result = Vec::with_capacity(chunk.len()); - if chunk.is_empty() { - return vec![] - } - chunk - .into_iter() - .map(|num| { - (0..APPROVAL_FLAG_LEN).map(|bit| Self::bit_at(num, bit)).collect::>() - }) - .for_each(|c| { - let last_approve = match c.iter().rposition(|n| *n) { - Some(index) => index + 1, - None => 0, - }; - result.extend(c.into_iter().take(last_approve)); - }); - result - } - - /// Return a concatenated vector over all approvals of a voter as boolean. - /// The trailing zeros are removed. - fn all_approvals_of(who: &T::AccountId) -> Vec { - let mut all: Vec = vec![]; - let mut index = 0_u32; - loop { - let chunk = Self::approvals_of((who.clone(), index)); - if chunk.is_empty() { - break - } - all.extend(Self::flag_to_bool(chunk)); - index += 1; - } - all - } - - /// Remove all approvals associated with one account. - fn remove_all_approvals_of(who: &T::AccountId) { - let mut index = 0; - loop { - let set = Self::approvals_of((who.clone(), index)); - if set.len() > 0 { - >::remove((who.clone(), index)); - index += 1; - } else { - break - } - } - } - - /// Calculates the offset value (stored pot) of a stake, based on the distance - /// to the last win_index, `t`. Regardless of the internal implementation, - /// it should always be used with the following structure: - /// - /// Given Stake of voter `V` being `x` and distance to last_win index `t`, the new weight - /// of `V` is `x + get_offset(x, t)`. - /// - /// In other words, this function returns everything extra that should be added - /// to a voter's stake value to get the correct weight. Indeed, zero is - /// returned if `t` is zero. - fn get_offset(stake: BalanceOf, t: VoteIndex) -> BalanceOf { - let decay_ratio: BalanceOf = T::DecayRatio::get().into(); - if t > 150 { - return stake * decay_ratio - } - let mut offset = stake; - let mut r = Zero::zero(); - let decay = decay_ratio + One::one(); - for _ in 0..t { - offset = offset.saturating_sub(offset / decay); - r += offset - } - r - } -} diff --git a/frame/elections/src/mock.rs b/frame/elections/src/mock.rs deleted file mode 100644 index 91318e1e07bcc..0000000000000 --- a/frame/elections/src/mock.rs +++ /dev/null @@ -1,273 +0,0 @@ -// 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. - -//! Mock file for election module. - -#![cfg(test)] - -use crate as elections; -use frame_support::{ - assert_ok, parameter_types, - traits::{ChangeMembers, Currency, LockIdentifier}, -}; -use sp_core::H256; -use sp_runtime::{ - testing::Header, - traits::{BlakeTwo256, IdentityLookup}, - BuildStorage, -}; - -parameter_types! { - pub const BlockHashCount: u64 = 250; - pub BlockWeights: frame_system::limits::BlockWeights = - frame_system::limits::BlockWeights::simple_max(1024); -} -impl frame_system::Config for Test { - type BaseCallFilter = frame_support::traits::Everything; - type BlockWeights = (); - type BlockLength = (); - type DbWeight = (); - 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 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; -} -impl pallet_balances::Config for Test { - type MaxLocks = (); - type MaxReserves = (); - type ReserveIdentifier = [u8; 8]; - type Balance = u64; - type DustRemoval = (); - type Event = Event; - type ExistentialDeposit = ExistentialDeposit; - type AccountStore = System; - type WeightInfo = (); -} - -parameter_types! { - pub const CandidacyBond: u64 = 3; - pub const CarryCount: u32 = 2; - pub const InactiveGracePeriod: u32 = 1; - pub const VotingPeriod: u64 = 4; - pub const MinimumVotingLock: u64 = 5; - pub static VotingBond: u64 = 0; - pub static VotingFee: u64 = 0; - pub static PresentSlashPerVoter: u64 = 0; - pub static DecayRatio: u32 = 0; - pub static Members: Vec = vec![]; -} - -pub struct TestChangeMembers; -impl ChangeMembers for TestChangeMembers { - fn change_members_sorted(incoming: &[u64], outgoing: &[u64], new: &[u64]) { - let mut old_plus_incoming = MEMBERS.with(|m| m.borrow().to_vec()); - old_plus_incoming.extend_from_slice(incoming); - old_plus_incoming.sort(); - let mut new_plus_outgoing = new.to_vec(); - new_plus_outgoing.extend_from_slice(outgoing); - new_plus_outgoing.sort(); - assert_eq!(old_plus_incoming, new_plus_outgoing); - - MEMBERS.with(|m| *m.borrow_mut() = new.to_vec()); - } -} - -parameter_types! { - pub const ElectionPalletId: LockIdentifier = *b"py/elect"; -} - -impl elections::Config for Test { - type Event = Event; - type Currency = Balances; - type BadPresentation = (); - type BadReaper = (); - type BadVoterIndex = (); - type LoserCandidate = (); - type ChangeMembers = TestChangeMembers; - type CandidacyBond = CandidacyBond; - type VotingBond = VotingBond; - type VotingFee = VotingFee; - type MinimumVotingLock = MinimumVotingLock; - type PresentSlashPerVoter = PresentSlashPerVoter; - type CarryCount = CarryCount; - type InactiveGracePeriod = InactiveGracePeriod; - type VotingPeriod = VotingPeriod; - type DecayRatio = DecayRatio; - type PalletId = ElectionPalletId; -} - -pub type Block = sp_runtime::generic::Block; -pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic; - -use frame_system as system; -frame_support::construct_runtime!( - pub enum Test where - Block = Block, - NodeBlock = Block, - UncheckedExtrinsic = UncheckedExtrinsic - { - System: system::{Pallet, Call, Event}, - Balances: pallet_balances::{Pallet, Call, Event, Config}, - Elections: elections::{Pallet, Call, Event, Config}, - } -); - -pub struct ExtBuilder { - balance_factor: u64, - decay_ratio: u32, - desired_seats: u32, - voting_fee: u64, - voting_bond: u64, - bad_presentation_punishment: u64, -} - -impl Default for ExtBuilder { - fn default() -> Self { - Self { - balance_factor: 1, - decay_ratio: 24, - desired_seats: 2, - voting_fee: 0, - voting_bond: 0, - bad_presentation_punishment: 1, - } - } -} - -impl ExtBuilder { - pub fn balance_factor(mut self, factor: u64) -> Self { - self.balance_factor = factor; - self - } - pub fn decay_ratio(mut self, ratio: u32) -> Self { - self.decay_ratio = ratio; - self - } - pub fn voting_fee(mut self, fee: u64) -> Self { - self.voting_fee = fee; - self - } - pub fn bad_presentation_punishment(mut self, fee: u64) -> Self { - self.bad_presentation_punishment = fee; - self - } - pub fn voting_bond(mut self, fee: u64) -> Self { - self.voting_bond = fee; - self - } - pub fn desired_seats(mut self, seats: u32) -> Self { - self.desired_seats = seats; - self - } - pub fn build(self) -> sp_io::TestExternalities { - VOTING_BOND.with(|v| *v.borrow_mut() = self.voting_bond); - VOTING_FEE.with(|v| *v.borrow_mut() = self.voting_fee); - PRESENT_SLASH_PER_VOTER.with(|v| *v.borrow_mut() = self.bad_presentation_punishment); - DECAY_RATIO.with(|v| *v.borrow_mut() = self.decay_ratio); - let mut ext: sp_io::TestExternalities = GenesisConfig { - balances: pallet_balances::GenesisConfig:: { - balances: vec![ - (1, 10 * self.balance_factor), - (2, 20 * self.balance_factor), - (3, 30 * self.balance_factor), - (4, 40 * self.balance_factor), - (5, 50 * self.balance_factor), - (6, 60 * self.balance_factor), - ], - }, - elections: elections::GenesisConfig:: { - members: vec![], - desired_seats: self.desired_seats, - presentation_duration: 2, - term_duration: 5, - }, - } - .build_storage() - .unwrap() - .into(); - ext.execute_with(|| System::set_block_number(1)); - ext - } -} - -pub(crate) fn voter_ids() -> Vec { - Elections::all_voters().iter().map(|v| v.unwrap_or(0)).collect::>() -} - -pub(crate) fn vote(i: u64, l: usize) { - let _ = Balances::make_free_balance_be(&i, 20); - assert_ok!(Elections::set_approvals( - Origin::signed(i), - (0..l).map(|_| true).collect::>(), - 0, - 0, - 20, - )); -} - -pub(crate) fn vote_at(i: u64, l: usize, index: elections::VoteIndex) { - let _ = Balances::make_free_balance_be(&i, 20); - assert_ok!(Elections::set_approvals( - Origin::signed(i), - (0..l).map(|_| true).collect::>(), - 0, - index, - 20, - )); -} - -pub(crate) fn create_candidate(i: u64, index: u32) { - let _ = Balances::make_free_balance_be(&i, 20); - assert_ok!(Elections::submit_candidacy(Origin::signed(i), index)); -} - -pub(crate) fn balances(who: &u64) -> (u64, u64) { - (Balances::free_balance(who), Balances::reserved_balance(who)) -} - -pub(crate) fn locks(who: &u64) -> Vec { - Balances::locks(who).iter().map(|l| l.amount).collect::>() -} - -pub(crate) fn new_test_ext_with_candidate_holes() -> sp_io::TestExternalities { - let mut t = ExtBuilder::default().build(); - t.execute_with(|| { - >::put(vec![0, 0, 1]); - elections::CandidateCount::::put(1); - >::insert(1, (0, 2)); - }); - t -} diff --git a/frame/elections/src/tests.rs b/frame/elections/src/tests.rs deleted file mode 100644 index 0df84c6d79baf..0000000000000 --- a/frame/elections/src/tests.rs +++ /dev/null @@ -1,1881 +0,0 @@ -// 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 election module. - -#![cfg(test)] - -use crate::{mock::*, *}; - -use frame_support::{assert_err, assert_noop, assert_ok}; - -#[test] -fn params_should_work() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!(Elections::next_vote_from(1), 4); - assert_eq!(Elections::next_vote_from(4), 4); - assert_eq!(Elections::next_vote_from(5), 8); - assert_eq!(Elections::vote_index(), 0); - assert_eq!(Elections::presentation_duration(), 2); - assert_eq!(Elections::term_duration(), 5); - assert_eq!(Elections::desired_seats(), 2); - - assert_eq!(Elections::members(), vec![]); - assert_eq!(Elections::next_tally(), Some(4)); - assert_eq!(Elections::presentation_active(), false); - assert_eq!(Elections::next_finalize(), None); - - assert_eq!(Elections::candidates(), Vec::::new()); - assert_eq!(Elections::is_a_candidate(&1), false); - assert_eq!(Elections::candidate_reg_info(1), None); - - assert_eq!(Elections::voters(0), Vec::>::new()); - assert_eq!(Elections::voter_info(1), None); - assert!(Elections::all_approvals_of(&1).is_empty()); - }); -} - -#[test] -fn chunking_bool_to_flag_should_work() { - ExtBuilder::default().build().execute_with(|| { - assert!(Elections::bool_to_flag(vec![]).is_empty()); - assert_eq!(Elections::bool_to_flag(vec![false]), vec![0]); - assert_eq!(Elections::bool_to_flag(vec![true]), vec![1]); - assert_eq!(Elections::bool_to_flag(vec![true, true, true, true]), vec![15]); - assert_eq!(Elections::bool_to_flag(vec![true, true, true, true, true]), vec![15 + 16]); - - let set_1 = vec![ - true, false, false, false, // 0x1 - false, true, true, true, // 0xE - ]; - assert_eq!(Elections::bool_to_flag(set_1.clone()), vec![0x00_00_00_E1_u32]); - assert_eq!(Elections::flag_to_bool(vec![0x00_00_00_E1_u32]), set_1); - - let set_2 = vec![ - false, false, false, true, // 0x8 - false, true, false, true, // 0xA - ]; - assert_eq!(Elections::bool_to_flag(set_2.clone()), vec![0x00_00_00_A8_u32]); - assert_eq!(Elections::flag_to_bool(vec![0x00_00_00_A8_u32]), set_2); - - let mut rhs = (0..100 / APPROVAL_FLAG_LEN).map(|_| 0xFFFFFFFF_u32).collect::>(); - // NOTE: this might be need change based on `APPROVAL_FLAG_LEN`. - rhs.extend(vec![0x00_00_00_0F]); - assert_eq!(Elections::bool_to_flag((0..100).map(|_| true).collect()), rhs) - }) -} - -#[test] -fn chunking_voter_set_growth_should_work() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - - // create 65. 64 (set0) + 1 (set1) - (1..=63).for_each(|i| vote(i, 0)); - assert_eq!(Elections::next_nonfull_voter_set(), 0); - vote(64, 0); - assert_eq!(Elections::next_nonfull_voter_set(), 1); - vote(65, 0); - - let set1 = Elections::voters(0); - let set2 = Elections::voters(1); - - assert_eq!(set1.len(), 64); - assert_eq!(set2.len(), 1); - - assert_eq!(set1[0], Some(1)); - assert_eq!(set1[10], Some(11)); - assert_eq!(set2[0], Some(65)); - }) -} - -#[test] -fn chunking_voter_set_reclaim_should_work() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - - (1..=129).for_each(|i| vote(i, 0)); - assert_eq!(Elections::next_nonfull_voter_set(), 2); - - assert_ok!(Elections::retract_voter(Origin::signed(11), 10)); - - assert_ok!(Elections::retract_voter(Origin::signed(66), 65)); - assert_ok!(Elections::retract_voter(Origin::signed(67), 66)); - - // length does not show it but holes do exist. - assert_eq!(Elections::voters(0).len(), 64); - assert_eq!(Elections::voters(1).len(), 64); - assert_eq!(Elections::voters(2).len(), 1); - - assert_eq!(Elections::voters(0)[10], None); - assert_eq!(Elections::voters(1)[1], None); - assert_eq!(Elections::voters(1)[2], None); - // Next set with capacity is 2. - assert_eq!(Elections::next_nonfull_voter_set(), 2); - - // But we can fill a hole. - vote_at(130, 0, 10); - - // Nothing added to set 2. A hole was filled. - assert_eq!(Elections::voters(0).len(), 64); - assert_eq!(Elections::voters(1).len(), 64); - assert_eq!(Elections::voters(2).len(), 1); - - // and the next two (scheduled) to the second set. - assert_eq!(Elections::next_nonfull_voter_set(), 2); - }) -} - -#[test] -fn chunking_approvals_set_growth_should_work() { - ExtBuilder::default().build().execute_with(|| { - // create candidates and voters. - (1..=250).for_each(|i| create_candidate(i, (i - 1) as u32)); - (1..=250).for_each(|i| vote(i, i as usize)); - - // all approvals of should return the exact expected vector. - assert_eq!( - Elections::all_approvals_of(&180), - (0..180).map(|_| true).collect::>() - ); - assert_eq!(Elections::all_approvals_of(&32), (0..32).map(|_| true).collect::>()); - assert_eq!(Elections::all_approvals_of(&8), (0..8).map(|_| true).collect::>()); - assert_eq!(Elections::all_approvals_of(&64), (0..64).map(|_| true).collect::>()); - assert_eq!(Elections::all_approvals_of(&65), (0..65).map(|_| true).collect::>()); - assert_eq!(Elections::all_approvals_of(&63), (0..63).map(|_| true).collect::>()); - - // NOTE: assuming that APPROVAL_SET_SIZE is more or less small-ish. Might fail otherwise. - let full_sets = (180 / APPROVAL_FLAG_LEN) / APPROVAL_SET_SIZE; - let left_over = (180 / APPROVAL_FLAG_LEN) / APPROVAL_SET_SIZE; - let rem = 180 % APPROVAL_FLAG_LEN; - - // grab and check the last full set, if it exists. - if full_sets > 0 { - assert_eq!( - Elections::approvals_of((180, (full_sets - 1) as SetIndex)), - Elections::bool_to_flag( - (0..APPROVAL_SET_SIZE * APPROVAL_FLAG_LEN).map(|_| true).collect::>() - ) - ); - } - - // grab and check the last, half-empty, set. - if left_over > 0 { - assert_eq!( - Elections::approvals_of((180, full_sets as SetIndex)), - Elections::bool_to_flag( - (0..left_over * APPROVAL_FLAG_LEN + rem).map(|_| true).collect::>() - ) - ); - } - }) -} - -#[test] -fn chunking_cell_status_works() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - - (1..=63).for_each(|i| vote(i, 0)); - - assert_ok!(Elections::retract_voter(Origin::signed(11), 10)); - assert_ok!(Elections::retract_voter(Origin::signed(21), 20)); - - assert_eq!(Elections::cell_status(0, 10), CellStatus::Hole); - assert_eq!(Elections::cell_status(0, 0), CellStatus::Occupied); - assert_eq!(Elections::cell_status(0, 20), CellStatus::Hole); - assert_eq!(Elections::cell_status(0, 63), CellStatus::Head); - assert_eq!(Elections::cell_status(1, 0), CellStatus::Head); - assert_eq!(Elections::cell_status(1, 10), CellStatus::Head); - }) -} - -#[test] -fn chunking_voter_index_does_not_take_holes_into_account() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - - // create 65. 64 (set0) + 1 (set1) - (1..=65).for_each(|i| vote(i, 0)); - - // account 65 has global index 65. - assert_eq!(Elections::voter_at(64).unwrap(), 65); - - assert_ok!(Elections::retract_voter(Origin::signed(1), 0)); - assert_ok!(Elections::retract_voter(Origin::signed(2), 1)); - - // still the same. These holes are in some other set. - assert_eq!(Elections::voter_at(64).unwrap(), 65); - // proof: can submit a new approval with the old index. - assert_noop!( - Elections::set_approvals(Origin::signed(65), vec![], 0, 64 - 2, 10), - Error::::InvalidVoterIndex, - ); - assert_ok!(Elections::set_approvals(Origin::signed(65), vec![], 0, 64, 10)); - }) -} - -#[test] -fn chunking_approval_storage_should_work() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); - - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false], 0, 0, 20)); - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false], 0, 0, 30)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![], 0, 0, 40)); - - assert_eq!(Elections::all_approvals_of(&2), vec![true]); - // NOTE: these two are stored in mem differently though. - assert!(Elections::all_approvals_of(&3).is_empty()); - assert!(Elections::all_approvals_of(&4).is_empty()); - - assert_eq!(Elections::approvals_of((3, 0)), vec![0]); - assert!(Elections::approvals_of((4, 0)).is_empty()); - }); -} - -#[test] -fn voting_initial_set_approvals_ignores_voter_index() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - - // Last argument is essentially irrelevant. You might get or miss a tip. - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![], 0, 0, 30)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![], 0, 5, 40)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![], 0, 100, 50)); - - // indices are more or less ignored. all is pushed. - assert_eq!(voter_ids(), vec![3, 4, 5]); - }) -} -#[test] -fn voting_bad_approval_index_slashes_voters_and_bond_reduces_stake() { - ExtBuilder::default().voting_fee(5).voting_bond(2).build().execute_with(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - - (1..=63).for_each(|i| vote(i, 0)); - assert_eq!(balances(&1), (13, 2)); - assert_eq!(balances(&10), (18, 2)); - assert_eq!(balances(&60), (18, 2)); - - // still no fee - vote(64, 0); - assert_eq!(balances(&64), (18, 2)); - assert_eq!( - Elections::voter_info(&64).unwrap(), - VoterInfo { last_win: 0, last_active: 0, stake: 20, pot: 0 } - ); - - assert_eq!(Elections::next_nonfull_voter_set(), 1); - - // now we charge the next voter. - vote(65, 0); - assert_eq!(balances(&65), (13, 2)); - assert_eq!( - Elections::voter_info(&65).unwrap(), - VoterInfo { last_win: 0, last_active: 0, stake: 15, pot: 0 } - ); - }); -} - -#[test] -fn voting_subsequent_set_approvals_checks_voter_index() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![], 0, 0, 30)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![], 0, 5, 40)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![], 0, 100, 50)); - - // invalid index - assert_noop!( - Elections::set_approvals(Origin::signed(4), vec![true], 0, 5, 40), - Error::::InvalidVoterIndex, - ); - // wrong index - assert_noop!( - Elections::set_approvals(Origin::signed(4), vec![true], 0, 0, 40), - Error::::InvalidVoterIndex, - ); - // correct - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true], 0, 1, 40)); - }) -} - -#[test] -fn voting_cannot_lock_less_than_limit() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - - assert_noop!( - Elections::set_approvals(Origin::signed(3), vec![], 0, 0, 4), - Error::::InsufficientLockedValue, - ); - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![], 0, 0, 5)); - }); -} - -#[test] -fn voting_locking_more_than_total_balance_is_moot() { - ExtBuilder::default().voting_bond(2).build().execute_with(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - - assert_eq!(balances(&3), (30, 0)); - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![], 0, 0, 35)); - - assert_eq!(balances(&3), (28, 2)); - assert_eq!( - Elections::voter_info(&3).unwrap(), - VoterInfo { last_win: 0, last_active: 0, stake: 30, pot: 0 } - ); - }); -} - -#[test] -fn voting_locking_stake_and_reserving_bond_works() { - ExtBuilder::default().voting_bond(2).build().execute_with(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - - assert_eq!(balances(&2), (20, 0)); - assert!(locks(&2).is_empty()); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![], 0, 0, 15)); - assert_eq!(balances(&2), (18, 2)); - assert_eq!(locks(&2), vec![15]); - - // deposit a bit more. - let _ = Balances::make_free_balance_be(&2, 100); - - // change vote - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 70)); - assert_eq!(balances(&2), (100, 2)); - assert_eq!(locks(&2), vec![70]); - - assert_ok!(Elections::retract_voter(Origin::signed(2), 0)); - - assert_eq!(balances(&2), (102, 0)); - assert!(locks(&2).is_empty()); - }); -} - -#[test] -fn voting_without_any_candidate_count_should_not_work() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!(Elections::candidates().len(), 0); - - assert_noop!( - Elections::set_approvals(Origin::signed(4), vec![], 0, 0, 40), - Error::::ZeroCandidates, - ); - }); -} - -#[test] -fn voting_setting_an_approval_vote_count_more_than_candidate_count_should_not_work() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_eq!(Elections::candidates().len(), 1); - - assert_noop!( - Elections::set_approvals(Origin::signed(4), vec![true, true], 0, 0, 40), - Error::::TooManyVotes, - ); - }); -} - -#[test] -fn voting_resubmitting_approvals_should_work() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true], 0, 0, 40)); - - assert_eq!(Elections::all_approvals_of(&4), vec![true]); - - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - assert_eq!(Elections::candidates().len(), 3); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true, false, true], 0, 0, 40)); - - assert_eq!(Elections::all_approvals_of(&4), vec![true, false, true]); - }); -} - -#[test] -fn voting_retracting_voter_should_work() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_eq!(Elections::candidates().len(), 1); - - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0, 10)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 1, 20)); - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![true], 0, 2, 30)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true], 0, 3, 40)); - - assert_eq!(voter_ids(), vec![1, 2, 3, 4]); - assert_eq!(Elections::all_approvals_of(&1), vec![true]); - assert_eq!(Elections::all_approvals_of(&2), vec![true]); - assert_eq!(Elections::all_approvals_of(&3), vec![true]); - assert_eq!(Elections::all_approvals_of(&4), vec![true]); - - assert_ok!(Elections::retract_voter(Origin::signed(1), 0)); - - assert_eq!(voter_ids(), vec![0, 2, 3, 4]); - assert_eq!(Elections::all_approvals_of(&1), Vec::::new()); - assert_eq!(Elections::all_approvals_of(&2), vec![true]); - assert_eq!(Elections::all_approvals_of(&3), vec![true]); - assert_eq!(Elections::all_approvals_of(&4), vec![true]); - - assert_ok!(Elections::retract_voter(Origin::signed(2), 1)); - - assert_eq!(voter_ids(), vec![0, 0, 3, 4]); - assert_eq!(Elections::all_approvals_of(&1), Vec::::new()); - assert_eq!(Elections::all_approvals_of(&2), Vec::::new()); - assert_eq!(Elections::all_approvals_of(&3), vec![true]); - assert_eq!(Elections::all_approvals_of(&4), vec![true]); - - assert_ok!(Elections::retract_voter(Origin::signed(3), 2)); - - assert_eq!(voter_ids(), vec![0, 0, 0, 4]); - assert_eq!(Elections::all_approvals_of(&1), Vec::::new()); - assert_eq!(Elections::all_approvals_of(&2), Vec::::new()); - assert_eq!(Elections::all_approvals_of(&3), Vec::::new()); - assert_eq!(Elections::all_approvals_of(&4), vec![true]); - }); -} - -#[test] -fn voting_invalid_retraction_index_should_not_work() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); - - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0, 10)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); - assert_eq!(voter_ids(), vec![1, 2]); - assert_noop!( - Elections::retract_voter(Origin::signed(1), 1), - Error::::InvalidRetractionIndex - ); - }); -} - -#[test] -fn voting_overflow_retraction_index_should_not_work() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); - - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0, 10)); - assert_noop!( - Elections::retract_voter(Origin::signed(1), 1), - Error::::InvalidRetractionIndex - ); - }); -} - -#[test] -fn voting_non_voter_retraction_should_not_work() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); - - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0, 10)); - assert_noop!( - Elections::retract_voter(Origin::signed(2), 0), - Error::::RetractNonVoter - ); - }); -} - -#[test] -fn retracting_inactive_voter_should_work() { - ExtBuilder::default().build().execute_with(|| { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(8); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 1, 0, 50)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(10); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 1)); - assert_ok!(Elections::end_block(System::block_number())); - - assert_ok!(Elections::reap_inactive_voter( - Origin::signed(5), - (voter_ids().iter().position(|&i| i == 5).unwrap() as u32).into(), - 2, - (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), - 2 - )); - - assert_eq!(voter_ids(), vec![0, 5]); - assert_eq!(Elections::all_approvals_of(&2).len(), 0); - assert_eq!(Balances::total_balance(&2), 20); - assert_eq!(Balances::total_balance(&5), 50); - }); -} - -#[test] -fn retracting_inactive_voter_with_other_candidates_in_slots_should_work() { - ExtBuilder::default().voting_bond(2).build().execute_with(|| { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(8); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 1, 0, 50)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(10); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 1)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(11); - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - - assert_ok!(Elections::reap_inactive_voter( - Origin::signed(5), - (voter_ids().iter().position(|&i| i == 5).unwrap() as u32).into(), - 2, - (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), - 2 - )); - - assert_eq!(voter_ids(), vec![0, 5]); - assert_eq!(Elections::all_approvals_of(&2).len(), 0); - }); -} - -#[test] -fn retracting_inactive_voter_with_bad_reporter_index_should_not_work() { - ExtBuilder::default().build().execute_with(|| { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(8); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 1, 0, 50)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(10); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 1)); - assert_ok!(Elections::end_block(System::block_number())); - - assert_noop!( - Elections::reap_inactive_voter( - Origin::signed(2), - 42, - 2, - (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), - 2 - ), - Error::::InvalidReporterIndex - ); - }); -} - -#[test] -fn retracting_inactive_voter_with_bad_target_index_should_not_work() { - ExtBuilder::default().build().execute_with(|| { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(8); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 1, 0, 50)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(10); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 1)); - assert_ok!(Elections::end_block(System::block_number())); - - assert_noop!( - Elections::reap_inactive_voter( - Origin::signed(2), - (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), - 2, - 42, - 2 - ), - Error::::InvalidTargetIndex - ); - }); -} - -#[test] -fn retracting_active_voter_should_slash_reporter() { - ExtBuilder::default().build().execute_with(|| { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(4), 2)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 3)); - assert_ok!(Elections::set_approvals( - Origin::signed(2), - vec![true, false, false, false], - 0, - 0, - 20 - )); - assert_ok!(Elections::set_approvals( - Origin::signed(3), - vec![false, true, false, false], - 0, - 0, - 30 - )); - assert_ok!(Elections::set_approvals( - Origin::signed(4), - vec![false, false, true, false], - 0, - 0, - 40 - )); - assert_ok!(Elections::set_approvals( - Origin::signed(5), - vec![false, false, false, true], - 0, - 0, - 50 - )); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(8); - assert_ok!(Elections::set_desired_seats(Origin::root(), 3)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(10); - assert_ok!(Elections::present_winner( - Origin::signed(4), - 2, - 20 + Elections::get_offset(20, 1), - 1 - )); - assert_ok!(Elections::present_winner( - Origin::signed(4), - 3, - 30 + Elections::get_offset(30, 1), - 1 - )); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::vote_index(), 2); - assert_eq!(::InactiveGracePeriod::get(), 1); - assert_eq!(::VotingPeriod::get(), 4); - assert_eq!( - Elections::voter_info(4), - Some(VoterInfo { last_win: 1, last_active: 0, stake: 40, pot: 0 }) - ); - - assert_ok!(Elections::reap_inactive_voter( - Origin::signed(4), - (voter_ids().iter().position(|&i| i == 4).unwrap() as u32).into(), - 2, - (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), - 2 - )); - - assert_eq!(voter_ids(), vec![2, 3, 0, 5]); - assert_eq!(Elections::all_approvals_of(&4).len(), 0); - assert_eq!(Balances::total_balance(&4), 40); - }); -} - -#[test] -fn retracting_inactive_voter_by_nonvoter_should_not_work() { - ExtBuilder::default().build().execute_with(|| { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(8); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 1, 0, 50)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(10); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 1)); - assert_ok!(Elections::end_block(System::block_number())); - - assert_noop!( - Elections::reap_inactive_voter( - Origin::signed(4), - 0, - 2, - (voter_ids().iter().position(|&i| i == 2).unwrap() as u32).into(), - 2 - ), - Error::::NotVoter - ); - }); -} - -#[test] -fn candidacy_simple_candidate_submission_should_work() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!(Elections::candidates(), Vec::::new()); - assert_eq!(Elections::candidate_reg_info(1), None); - assert_eq!(Elections::candidate_reg_info(2), None); - assert_eq!(Elections::is_a_candidate(&1), false); - assert_eq!(Elections::is_a_candidate(&2), false); - - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - assert_eq!(Elections::candidates(), vec![1]); - assert_eq!(Elections::candidate_reg_info(1), Some((0, 0))); - assert_eq!(Elections::candidate_reg_info(2), None); - assert_eq!(Elections::is_a_candidate(&1), true); - assert_eq!(Elections::is_a_candidate(&2), false); - - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_eq!(Elections::candidates(), vec![1, 2]); - assert_eq!(Elections::candidate_reg_info(1), Some((0, 0))); - assert_eq!(Elections::candidate_reg_info(2), Some((0, 1))); - assert_eq!(Elections::is_a_candidate(&1), true); - assert_eq!(Elections::is_a_candidate(&2), true); - }); -} - -#[test] -fn candidacy_submission_using_free_slot_should_work() { - let mut t = new_test_ext_with_candidate_holes(); - - t.execute_with(|| { - assert_eq!(Elections::candidates(), vec![0, 0, 1]); - - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_eq!(Elections::candidates(), vec![0, 2, 1]); - - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 0)); - assert_eq!(Elections::candidates(), vec![3, 2, 1]); - }); -} - -#[test] -fn candidacy_submission_using_alternative_free_slot_should_work() { - let mut t = new_test_ext_with_candidate_holes(); - - t.execute_with(|| { - assert_eq!(Elections::candidates(), vec![0, 0, 1]); - - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_eq!(Elections::candidates(), vec![2, 0, 1]); - - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 1)); - assert_eq!(Elections::candidates(), vec![2, 3, 1]); - }); -} - -#[test] -fn candidacy_submission_not_using_free_slot_should_not_work() { - let mut t = new_test_ext_with_candidate_holes(); - - t.execute_with(|| { - assert_noop!( - Elections::submit_candidacy(Origin::signed(4), 3), - Error::::InvalidCandidateSlot - ); - }); -} - -#[test] -fn candidacy_bad_candidate_slot_submission_should_not_work() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!(Elections::candidates(), Vec::::new()); - assert_noop!( - Elections::submit_candidacy(Origin::signed(1), 1), - Error::::InvalidCandidateSlot - ); - }); -} - -#[test] -fn candidacy_non_free_candidate_slot_submission_should_not_work() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!(Elections::candidates(), Vec::::new()); - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - assert_eq!(Elections::candidates(), vec![1]); - assert_noop!( - Elections::submit_candidacy(Origin::signed(2), 0), - Error::::InvalidCandidateSlot - ); - }); -} - -#[test] -fn candidacy_dupe_candidate_submission_should_not_work() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!(Elections::candidates(), Vec::::new()); - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - assert_eq!(Elections::candidates(), vec![1]); - assert_noop!( - Elections::submit_candidacy(Origin::signed(1), 1), - Error::::DuplicatedCandidate, - ); - }); -} - -#[test] -fn candidacy_poor_candidate_submission_should_not_work() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!(Elections::candidates(), Vec::::new()); - assert_noop!( - Elections::submit_candidacy(Origin::signed(7), 0), - Error::::InsufficientCandidateFunds, - ); - }); -} - -#[test] -fn election_voting_should_work() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0, 10)); - assert_ok!(Elections::set_approvals(Origin::signed(4), vec![true], 0, 1, 40)); - - assert_eq!(Elections::all_approvals_of(&1), vec![true]); - assert_eq!(Elections::all_approvals_of(&4), vec![true]); - assert_eq!(voter_ids(), vec![1, 4]); - - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![false, true, true], 0, 2, 20)); - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, true, true], 0, 3, 30)); - - assert_eq!(Elections::all_approvals_of(&1), vec![true]); - assert_eq!(Elections::all_approvals_of(&4), vec![true]); - assert_eq!(Elections::all_approvals_of(&2), vec![false, true, true]); - assert_eq!(Elections::all_approvals_of(&3), vec![false, true, true]); - - assert_eq!(voter_ids(), vec![1, 4, 2, 3]); - }); -} - -#[test] -fn election_simple_tally_should_work() { - ExtBuilder::default().build().execute_with(|| { - System::set_block_number(4); - assert!(!Elections::presentation_active()); - - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true], 0, 0, 50)); - assert_eq!(voter_ids(), vec![2, 5]); - assert_eq!(Elections::all_approvals_of(&2), vec![true]); - assert_eq!(Elections::all_approvals_of(&5), vec![false, true]); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(4), 2, 20, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(4), 5, 50, 0), Ok(())); - assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (0, 0), (20, 2), (50, 5)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert!(!Elections::presentation_active()); - assert_eq!(Elections::members(), vec![(5, 11), (2, 11)]); - - assert!(!Elections::is_a_candidate(&2)); - assert!(!Elections::is_a_candidate(&5)); - assert_eq!(Elections::vote_index(), 1); - assert_eq!( - Elections::voter_info(2), - Some(VoterInfo { last_win: 1, last_active: 0, stake: 20, pot: 0 }) - ); - assert_eq!( - Elections::voter_info(5), - Some(VoterInfo { last_win: 1, last_active: 0, stake: 50, pot: 0 }) - ); - }); -} - -#[test] -fn election_seats_should_be_released() { - ExtBuilder::default().build().execute_with(|| { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false], 0, 0, 20)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true], 0, 0, 50)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(4), 2, 20, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(4), 5, 50, 0), Ok(())); - assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (0, 0), (20, 2), (50, 5)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(5, 11), (2, 11)]); - let mut current = System::block_number(); - let free_block; - loop { - current += 1; - System::set_block_number(current); - assert_ok!(Elections::end_block(System::block_number())); - if Elections::members().len() == 0 { - free_block = current; - break - } - } - // 11 + 2 which is the next voting period. - assert_eq!(free_block, 14); - }); -} - -#[test] -fn election_presentations_with_zero_staked_deposit_should_not_work() { - ExtBuilder::default().build().execute_with(|| { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_noop!( - Elections::present_winner(Origin::signed(4), 2, 0, 0), - Error::::ZeroDeposit, - ); - }); -} - -#[test] -fn election_double_presentations_should_be_punished() { - ExtBuilder::default().build().execute_with(|| { - assert!(Balances::can_slash(&4, 10)); - - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false], 0, 0, 20)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true], 0, 0, 50)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); - assert_eq!( - Elections::present_winner(Origin::signed(4), 5, 50, 0), - Err(Error::::DuplicatedPresentation.into()), - ); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(5, 11), (2, 11)]); - assert_eq!(Balances::total_balance(&4), 38); - }); -} - -#[test] -fn election_presenting_for_double_election_should_not_work() { - ExtBuilder::default().build().execute_with(|| { - System::set_block_number(4); - assert_eq!(Elections::submit_candidacy(Origin::signed(2), 0), Ok(())); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 0, 0, 20)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(8); - // NOTE: This is now mandatory to disable the lock - assert_ok!(Elections::retract_voter(Origin::signed(2), 0)); - assert_eq!(Elections::submit_candidacy(Origin::signed(2), 0), Ok(())); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true], 1, 0, 20)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(10); - assert_noop!( - Elections::present_winner(Origin::signed(4), 2, 20, 1), - Error::::DuplicatedCandidate, - ); - }); -} - -#[test] -fn election_presenting_loser_should_not_work() { - ExtBuilder::default().build().execute_with(|| { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true], 0, 0, 60)); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![false, true], 0, 0, 20)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false, true], 0, 0, 30)); - assert_ok!(Elections::submit_candidacy(Origin::signed(4), 3)); - assert_ok!(Elections::set_approvals( - Origin::signed(4), - vec![false, false, false, true], - 0, - 0, - 40 - )); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 4)); - assert_ok!(Elections::set_approvals( - Origin::signed(5), - vec![false, false, false, false, true], - 0, - 0, - 50 - )); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 1, 60, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); - - assert_eq!(Elections::leaderboard(), Some(vec![(30, 3), (40, 4), (50, 5), (60, 1)])); - - assert_noop!( - Elections::present_winner(Origin::signed(4), 2, 20, 0), - Error::::UnworthyCandidate - ); - }); -} - -#[test] -fn election_presenting_loser_first_should_not_matter() { - ExtBuilder::default().build().execute_with(|| { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true], 0, 0, 60)); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![false, true], 0, 0, 20)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false, true], 0, 0, 30)); - assert_ok!(Elections::submit_candidacy(Origin::signed(4), 3)); - assert_ok!(Elections::set_approvals( - Origin::signed(4), - vec![false, false, false, true], - 0, - 0, - 40 - )); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 4)); - assert_ok!(Elections::set_approvals( - Origin::signed(5), - vec![false, false, false, false, true], - 0, - 0, - 50 - )); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 2, 20, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 1, 60, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); - - assert_eq!(Elections::leaderboard(), Some(vec![(30, 3), (40, 4), (50, 5), (60, 1)])); - }); -} - -#[test] -fn election_present_outside_of_presentation_period_should_not_work() { - ExtBuilder::default().build().execute_with(|| { - System::set_block_number(4); - assert!(!Elections::presentation_active()); - assert_noop!( - Elections::present_winner(Origin::signed(5), 5, 1, 0), - Error::::NotPresentationPeriod, - ); - }); -} - -#[test] -fn election_present_with_invalid_vote_index_should_not_work() { - ExtBuilder::default().build().execute_with(|| { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false], 0, 0, 20)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true], 0, 0, 50)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_noop!( - Elections::present_winner(Origin::signed(4), 2, 20, 1), - Error::::InvalidVoteIndex - ); - }); -} - -#[test] -fn election_present_when_presenter_is_poor_should_not_work() { - let test_present = |p| { - ExtBuilder::default() - .voting_fee(5) - .voting_bond(2) - .bad_presentation_punishment(p) - .build() - .execute_with(|| { - System::set_block_number(4); - let _ = Balances::make_free_balance_be(&1, 15); - assert!(!Elections::presentation_active()); - - // -3 - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - assert_eq!(Balances::free_balance(1), 12); - // -2 -5 - assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0, 15)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_eq!(Balances::free_balance(1), 5); - assert_eq!(Balances::reserved_balance(1), 5); - if p > 5 { - assert_noop!( - Elections::present_winner(Origin::signed(1), 1, 10, 0), - Error::::InsufficientPresenterFunds, - ); - } else { - assert_ok!(Elections::present_winner(Origin::signed(1), 1, 10, 0)); - } - }); - }; - test_present(4); - test_present(6); -} - -#[test] -fn election_invalid_present_tally_should_slash() { - ExtBuilder::default().build().execute_with(|| { - System::set_block_number(4); - assert!(!Elections::presentation_active()); - assert_eq!(Balances::total_balance(&4), 40); - - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![true, false], 0, 0, 20)); - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![false, true], 0, 0, 50)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_err!( - Elections::present_winner(Origin::signed(4), 2, 80, 0), - Error::::IncorrectTotal - ); - - assert_eq!(Balances::total_balance(&4), 38); - }); -} - -#[test] -fn election_runners_up_should_be_kept() { - ExtBuilder::default().build().execute_with(|| { - System::set_block_number(4); - assert!(!Elections::presentation_active()); - - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true], 0, 0, 60)); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![false, true], 0, 0, 20)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false, true], 0, 0, 30)); - assert_ok!(Elections::submit_candidacy(Origin::signed(4), 3)); - assert_ok!(Elections::set_approvals( - Origin::signed(4), - vec![false, false, false, true], - 0, - 0, - 40 - )); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 4)); - assert_ok!(Elections::set_approvals( - Origin::signed(5), - vec![false, false, false, false, true], - 0, - 0, - 50 - )); - - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert!(Elections::presentation_active()); - assert_ok!(Elections::present_winner(Origin::signed(4), 1, 60, 0)); - // leaderboard length is the empty seats plus the carry count (i.e. 5 + 2), where those - // to be carried are the lowest and stored in lowest indices - assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (0, 0), (0, 0), (60, 1)])); - assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); - assert_eq!(Elections::leaderboard(), Some(vec![(30, 3), (40, 4), (50, 5), (60, 1)])); - - assert_ok!(Elections::end_block(System::block_number())); - - assert!(!Elections::presentation_active()); - assert_eq!(Elections::members(), vec![(1, 11), (5, 11)]); - - assert!(!Elections::is_a_candidate(&1)); - assert!(!Elections::is_a_candidate(&5)); - assert!(!Elections::is_a_candidate(&2)); - assert!(Elections::is_a_candidate(&3)); - assert!(Elections::is_a_candidate(&4)); - assert_eq!(Elections::vote_index(), 1); - assert_eq!( - Elections::voter_info(2), - Some(VoterInfo { last_win: 0, last_active: 0, stake: 20, pot: 0 }) - ); - assert_eq!( - Elections::voter_info(3), - Some(VoterInfo { last_win: 0, last_active: 0, stake: 30, pot: 0 }) - ); - assert_eq!( - Elections::voter_info(4), - Some(VoterInfo { last_win: 0, last_active: 0, stake: 40, pot: 0 }) - ); - assert_eq!( - Elections::voter_info(5), - Some(VoterInfo { last_win: 1, last_active: 0, stake: 50, pot: 0 }) - ); - assert_eq!( - Elections::voter_info(6), - Some(VoterInfo { last_win: 1, last_active: 0, stake: 60, pot: 0 }) - ); - assert_eq!(Elections::candidate_reg_info(3), Some((0, 2))); - assert_eq!(Elections::candidate_reg_info(4), Some((0, 3))); - }); -} - -#[test] -fn election_second_tally_should_use_runners_up() { - ExtBuilder::default().build().execute_with(|| { - System::set_block_number(4); - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - assert_ok!(Elections::set_approvals(Origin::signed(6), vec![true], 0, 0, 60)); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_ok!(Elections::set_approvals(Origin::signed(2), vec![false, true], 0, 0, 20)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - assert_ok!(Elections::set_approvals(Origin::signed(3), vec![false, false, true], 0, 0, 30)); - assert_ok!(Elections::submit_candidacy(Origin::signed(4), 3)); - assert_ok!(Elections::set_approvals( - Origin::signed(4), - vec![false, false, false, true], - 0, - 0, - 40 - )); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 4)); - assert_ok!(Elections::set_approvals( - Origin::signed(5), - vec![false, false, false, false, true], - 0, - 0, - 50 - )); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert_ok!(Elections::present_winner(Origin::signed(4), 1, 60, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 3, 30, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 4, 40, 0)); - assert_ok!(Elections::present_winner(Origin::signed(4), 5, 50, 0)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(8); - assert_ok!(Elections::set_approvals( - Origin::signed(6), - vec![false, false, true, false], - 1, - 0, - 60 - )); - assert_ok!(Elections::set_desired_seats(Origin::root(), 3)); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(10); - assert_ok!(Elections::present_winner( - Origin::signed(4), - 3, - 30 + Elections::get_offset(30, 1) + 60, - 1 - )); - assert_ok!(Elections::present_winner( - Origin::signed(4), - 4, - 40 + Elections::get_offset(40, 1), - 1 - )); - assert_ok!(Elections::end_block(System::block_number())); - - assert!(!Elections::presentation_active()); - assert_eq!(Elections::members(), vec![(1, 11), (5, 11), (3, 15)]); - - assert!(!Elections::is_a_candidate(&1)); - assert!(!Elections::is_a_candidate(&2)); - assert!(!Elections::is_a_candidate(&3)); - assert!(!Elections::is_a_candidate(&5)); - assert!(Elections::is_a_candidate(&4)); - assert_eq!(Elections::vote_index(), 2); - assert_eq!( - Elections::voter_info(2), - Some(VoterInfo { last_win: 0, last_active: 0, stake: 20, pot: 0 }) - ); - assert_eq!( - Elections::voter_info(3), - Some(VoterInfo { last_win: 2, last_active: 0, stake: 30, pot: 0 }) - ); - assert_eq!( - Elections::voter_info(4), - Some(VoterInfo { last_win: 0, last_active: 0, stake: 40, pot: 0 }) - ); - assert_eq!( - Elections::voter_info(5), - Some(VoterInfo { last_win: 1, last_active: 0, stake: 50, pot: 0 }) - ); - assert_eq!( - Elections::voter_info(6), - Some(VoterInfo { last_win: 2, last_active: 1, stake: 60, pot: 0 }) - ); - - assert_eq!(Elections::candidate_reg_info(4), Some((0, 3))); - }); -} - -#[test] -fn election_loser_candidates_bond_gets_slashed() { - ExtBuilder::default().desired_seats(1).build().execute_with(|| { - System::set_block_number(4); - assert!(!Elections::presentation_active()); - - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - assert_ok!(Elections::submit_candidacy(Origin::signed(4), 3)); - - assert_eq!(balances(&2), (17, 3)); - - assert_ok!(Elections::set_approvals(Origin::signed(5), vec![true], 0, 0, 50)); - assert_ok!(Elections::set_approvals( - Origin::signed(1), - vec![false, true, true, true], - 0, - 0, - 10 - )); - - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(4), 4, 10, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(3), 3, 10, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(2), 2, 10, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(1), 1, 50, 0), Ok(())); - - // winner + carry - assert_eq!(Elections::leaderboard(), Some(vec![(10, 3), (10, 4), (50, 1)])); - assert_ok!(Elections::end_block(System::block_number())); - assert!(!Elections::presentation_active()); - assert_eq!(Elections::members(), vec![(1, 11)]); - - // account 2 is not a runner up or in leaderboard. - assert_eq!(balances(&2), (17, 0)); - }); -} - -#[test] -fn pot_accumulating_weight_and_decaying_should_work() { - ExtBuilder::default().balance_factor(10).build().execute_with(|| { - System::set_block_number(4); - assert!(!Elections::presentation_active()); - - assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 2)); - - assert_ok!(Elections::set_approvals( - Origin::signed(6), - vec![true, false, false], - 0, - 0, - 600 - )); - assert_ok!(Elections::set_approvals( - Origin::signed(5), - vec![false, true, false], - 0, - 0, - 500 - )); - assert_ok!(Elections::set_approvals( - Origin::signed(1), - vec![false, false, true], - 0, - 0, - 100 - )); - - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert!(Elections::presentation_active()); - - assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(1), 1, 100, 0), Ok(())); - assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (100, 1), (500, 5), (600, 6)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(6, 11), (5, 11)]); - assert_eq!( - Elections::voter_info(6).unwrap(), - VoterInfo { last_win: 1, last_active: 0, stake: 600, pot: 0 }, - ); - assert_eq!( - Elections::voter_info(5).unwrap(), - VoterInfo { last_win: 1, last_active: 0, stake: 500, pot: 0 }, - ); - assert_eq!( - Elections::voter_info(1).unwrap(), - VoterInfo { last_win: 0, last_active: 0, stake: 100, pot: 0 }, - ); - - System::set_block_number(12); - // retract needed to unlock approval funds => submit candidacy again. - assert_ok!(Elections::retract_voter(Origin::signed(6), 0)); - assert_ok!(Elections::retract_voter(Origin::signed(5), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals( - Origin::signed(6), - vec![true, false, false], - 1, - 0, - 600 - )); - assert_ok!(Elections::set_approvals( - Origin::signed(5), - vec![false, true, false], - 1, - 1, - 500 - )); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(14); - assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 1), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 1), Ok(())); - assert_eq!( - Elections::present_winner(Origin::signed(1), 1, 100 + Elections::get_offset(100, 1), 1), - Ok(()) - ); - assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (100 + 96, 1), (500, 5), (600, 6)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(6, 19), (5, 19)]); - assert_eq!( - Elections::voter_info(6).unwrap(), - VoterInfo { last_win: 2, last_active: 1, stake: 600, pot: 0 } - ); - assert_eq!( - Elections::voter_info(5).unwrap(), - VoterInfo { last_win: 2, last_active: 1, stake: 500, pot: 0 } - ); - assert_eq!( - Elections::voter_info(1).unwrap(), - VoterInfo { last_win: 0, last_active: 0, stake: 100, pot: 0 } - ); - - System::set_block_number(20); - assert_ok!(Elections::retract_voter(Origin::signed(6), 0)); - assert_ok!(Elections::retract_voter(Origin::signed(5), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals( - Origin::signed(6), - vec![true, false, false], - 2, - 0, - 600 - )); - assert_ok!(Elections::set_approvals( - Origin::signed(5), - vec![false, true, false], - 2, - 1, - 500 - )); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(22); - assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 2), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 2), Ok(())); - assert_eq!( - Elections::present_winner(Origin::signed(1), 1, 100 + Elections::get_offset(100, 2), 2), - Ok(()) - ); - assert_eq!( - Elections::leaderboard(), - Some(vec![(0, 0), (100 + 96 + 93, 1), (500, 5), (600, 6)]) - ); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(6, 27), (5, 27)]); - assert_eq!( - Elections::voter_info(6).unwrap(), - VoterInfo { last_win: 3, last_active: 2, stake: 600, pot: 0 } - ); - assert_eq!( - Elections::voter_info(5).unwrap(), - VoterInfo { last_win: 3, last_active: 2, stake: 500, pot: 0 } - ); - assert_eq!( - Elections::voter_info(1).unwrap(), - VoterInfo { last_win: 0, last_active: 0, stake: 100, pot: 0 } - ); - - System::set_block_number(28); - assert_ok!(Elections::retract_voter(Origin::signed(6), 0)); - assert_ok!(Elections::retract_voter(Origin::signed(5), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals( - Origin::signed(6), - vec![true, false, false], - 3, - 0, - 600 - )); - assert_ok!(Elections::set_approvals( - Origin::signed(5), - vec![false, true, false], - 3, - 1, - 500 - )); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(30); - assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 3), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 3), Ok(())); - assert_eq!( - Elections::present_winner(Origin::signed(1), 1, 100 + Elections::get_offset(100, 3), 3), - Ok(()) - ); - assert_eq!( - Elections::leaderboard(), - Some(vec![(0, 0), (100 + 96 + 93 + 90, 1), (500, 5), (600, 6)]) - ); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(6, 35), (5, 35)]); - assert_eq!( - Elections::voter_info(6).unwrap(), - VoterInfo { last_win: 4, last_active: 3, stake: 600, pot: 0 } - ); - assert_eq!( - Elections::voter_info(5).unwrap(), - VoterInfo { last_win: 4, last_active: 3, stake: 500, pot: 0 } - ); - assert_eq!( - Elections::voter_info(1).unwrap(), - VoterInfo { last_win: 0, last_active: 0, stake: 100, pot: 0 } - ); - }) -} - -#[test] -fn pot_winning_resets_accumulated_pot() { - ExtBuilder::default().balance_factor(10).build().execute_with(|| { - System::set_block_number(4); - assert!(!Elections::presentation_active()); - - assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(4), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 3)); - - assert_ok!(Elections::set_approvals( - Origin::signed(6), - vec![true, false, false, false], - 0, - 0, - 600 - )); - assert_ok!(Elections::set_approvals( - Origin::signed(4), - vec![false, true, false, false], - 0, - 1, - 400 - )); - assert_ok!(Elections::set_approvals( - Origin::signed(3), - vec![false, false, true, true], - 0, - 2, - 300 - )); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(4), 4, 400, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(3), 3, 300, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(2), 2, 300, 0), Ok(())); - assert_eq!(Elections::leaderboard(), Some(vec![(300, 2), (300, 3), (400, 4), (600, 6)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(6, 11), (4, 11)]); - - System::set_block_number(12); - assert_ok!(Elections::retract_voter(Origin::signed(6), 0)); - assert_ok!(Elections::retract_voter(Origin::signed(4), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(4), 1)); - assert_ok!(Elections::set_approvals( - Origin::signed(6), - vec![true, false, false, false], - 1, - 0, - 600 - )); - assert_ok!(Elections::set_approvals( - Origin::signed(4), - vec![false, true, false, false], - 1, - 1, - 400 - )); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(14); - assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 1), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(4), 4, 400, 1), Ok(())); - assert_eq!( - Elections::present_winner(Origin::signed(3), 3, 300 + Elections::get_offset(300, 1), 1), - Ok(()) - ); - assert_eq!( - Elections::present_winner(Origin::signed(2), 2, 300 + Elections::get_offset(300, 1), 1), - Ok(()) - ); - assert_eq!(Elections::leaderboard(), Some(vec![(400, 4), (588, 2), (588, 3), (600, 6)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(6, 19), (3, 19)]); - - System::set_block_number(20); - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(22); - // 2 will not get re-elected with 300 + 288, instead just 300. - // because one of 3's candidates (3) won in previous round - // 4 on the other hand will get extra weight since it was unlucky. - assert_eq!(Elections::present_winner(Origin::signed(3), 2, 300, 2), Ok(())); - assert_eq!( - Elections::present_winner(Origin::signed(4), 4, 400 + Elections::get_offset(400, 1), 2), - Ok(()) - ); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(4, 27), (2, 27)]); - }) -} - -#[test] -fn pot_resubmitting_approvals_stores_pot() { - ExtBuilder::default() - .voting_bond(0) - .voting_fee(0) - .balance_factor(10) - .build() - .execute_with(|| { - System::set_block_number(4); - assert!(!Elections::presentation_active()); - - assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(1), 2)); - - assert_ok!(Elections::set_approvals( - Origin::signed(6), - vec![true, false, false], - 0, - 0, - 600 - ),); - assert_ok!(Elections::set_approvals( - Origin::signed(5), - vec![false, true, false], - 0, - 1, - 500 - ),); - assert_ok!(Elections::set_approvals( - Origin::signed(1), - vec![false, false, true], - 0, - 2, - 100 - ),); - - assert_ok!(Elections::end_block(System::block_number())); - - System::set_block_number(6); - assert!(Elections::presentation_active()); - - assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 0), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(1), 1, 100, 0), Ok(())); - assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (100, 1), (500, 5), (600, 6)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(6, 11), (5, 11)]); - - System::set_block_number(12); - assert_ok!(Elections::retract_voter(Origin::signed(6), 0)); - assert_ok!(Elections::retract_voter(Origin::signed(5), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(6), 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 1)); - assert_ok!(Elections::set_approvals( - Origin::signed(6), - vec![true, false, false], - 1, - 0, - 600 - ),); - assert_ok!(Elections::set_approvals( - Origin::signed(5), - vec![false, true, false], - 1, - 1, - 500 - ),); - // give 1 some new high balance - let _ = Balances::make_free_balance_be(&1, 997); - assert_ok!(Elections::set_approvals( - Origin::signed(1), - vec![false, false, true], - 1, - 2, - 1000 - ),); - assert_eq!( - Elections::voter_info(1).unwrap(), - VoterInfo { - stake: 1000, // 997 + 3 which is candidacy bond. - pot: Elections::get_offset(100, 1), - last_active: 1, - last_win: 1, - } - ); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(6, 11), (5, 11)]); - - System::set_block_number(14); - assert!(Elections::presentation_active()); - assert_eq!(Elections::present_winner(Origin::signed(6), 6, 600, 1), Ok(())); - assert_eq!(Elections::present_winner(Origin::signed(5), 5, 500, 1), Ok(())); - assert_eq!( - Elections::present_winner(Origin::signed(1), 1, 1000 + 96 /* pot */, 1), - Ok(()), - ); - assert_eq!(Elections::leaderboard(), Some(vec![(0, 0), (500, 5), (600, 6), (1096, 1)])); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members(), vec![(1, 19), (6, 19)]); - }) -} - -#[test] -fn pot_get_offset_should_work() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!(Elections::get_offset(100, 0), 0); - assert_eq!(Elections::get_offset(100, 1), 96); - assert_eq!(Elections::get_offset(100, 2), 96 + 93); - assert_eq!(Elections::get_offset(100, 3), 96 + 93 + 90); - assert_eq!(Elections::get_offset(100, 4), 96 + 93 + 90 + 87); - // limit - assert_eq!(Elections::get_offset(100, 1000), 100 * 24); - - assert_eq!(Elections::get_offset(50_000_000_000, 0), 0); - assert_eq!(Elections::get_offset(50_000_000_000, 1), 48_000_000_000); - assert_eq!(Elections::get_offset(50_000_000_000, 2), 48_000_000_000 + 46_080_000_000); - assert_eq!( - Elections::get_offset(50_000_000_000, 3), - 48_000_000_000 + 46_080_000_000 + 44_236_800_000 - ); - assert_eq!( - Elections::get_offset(50_000_000_000, 4), - 48_000_000_000 + 46_080_000_000 + 44_236_800_000 + 42_467_328_000 - ); - // limit - assert_eq!(Elections::get_offset(50_000_000_000, 1000), 50_000_000_000 * 24); - }) -} - -#[test] -fn pot_get_offset_with_zero_decay() { - ExtBuilder::default().decay_ratio(0).build().execute_with(|| { - assert_eq!(Elections::get_offset(100, 0), 0); - assert_eq!(Elections::get_offset(100, 1), 0); - assert_eq!(Elections::get_offset(100, 2), 0); - assert_eq!(Elections::get_offset(100, 3), 0); - // limit - assert_eq!(Elections::get_offset(100, 1000), 0); - }) -} From 594deb9a95f06b8cb1976ec69c647f64f8c0e612 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 2 Dec 2021 17:49:52 -0500 Subject: [PATCH 10/47] More work --- client/consensus/babe/src/lib.rs | 2 +- .../election-provider-multi-phase/src/lib.rs | 2 +- .../src/signed.rs | 20 +++++++++---------- frame/examples/offchain-worker/src/lib.rs | 12 +++++------ 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/client/consensus/babe/src/lib.rs b/client/consensus/babe/src/lib.rs index 4fb9f750004c5..db89b952830fa 100644 --- a/client/consensus/babe/src/lib.rs +++ b/client/consensus/babe/src/lib.rs @@ -110,7 +110,7 @@ use sp_consensus::{ }; use sp_consensus_babe::inherents::BabeInherentData; use sp_consensus_slots::Slot; -use sp_core::{crypto::Public, ExecutionContext}; +use sp_core::{crypto::{Public, ByteArray}, ExecutionContext}; use sp_inherents::{CreateInherentDataProviders, InherentData, InherentDataProvider}; use sp_keystore::{SyncCryptoStore, SyncCryptoStorePtr}; use sp_runtime::{ diff --git a/frame/election-provider-multi-phase/src/lib.rs b/frame/election-provider-multi-phase/src/lib.rs index 70bbed95fe973..70668dbe9f67a 100644 --- a/frame/election-provider-multi-phase/src/lib.rs +++ b/frame/election-provider-multi-phase/src/lib.rs @@ -1189,7 +1189,7 @@ pub mod pallet { /// affect; we shouldn't need a cryptographically secure hasher. #[pallet::storage] pub(crate) type SignedSubmissionsMap = - StorageMap<_, Twox64Concat, u32, SignedSubmissionOf, ValueQuery>; + StorageMap<_, Twox64Concat, u32, SignedSubmissionOf, OptionQuery>; // `SignedSubmissions` items end here. diff --git a/frame/election-provider-multi-phase/src/signed.rs b/frame/election-provider-multi-phase/src/signed.rs index b762ad706486c..08cae62ef7d37 100644 --- a/frame/election-provider-multi-phase/src/signed.rs +++ b/frame/election-provider-multi-phase/src/signed.rs @@ -42,7 +42,7 @@ use sp_std::{ /// A raw, unchecked signed submission. /// /// This is just a wrapper around [`RawSolution`] and some additional info. -#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, Default, scale_info::TypeInfo)] +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, scale_info::TypeInfo)] pub struct SignedSubmission { /// Who submitted this solution. pub who: AccountId, @@ -167,17 +167,17 @@ impl SignedSubmissions { } /// Get the submission at a particular index. - fn get_submission(&self, idx: u32) -> Option> { - if self.deletion_overlay.contains(&idx) { + fn get_submission(&self, index: u32) -> Option> { + if self.deletion_overlay.contains(&index) { // Note: can't actually remove the item from the insertion overlay (if present) // because we don't want to use `&mut self` here. There may be some kind of // `RefCell` optimization possible here in the future. None } else { self.insertion_overlay - .get(&idx) + .get(&index) .cloned() - .or_else(|| SignedSubmissionsMap::::try_get(idx).ok()) + .or_else(|| SignedSubmissionsMap::::get(index)) } } @@ -200,18 +200,18 @@ impl SignedSubmissions { remove_score: ElectionScore, insert: Option<(ElectionScore, u32)>, ) -> Option> { - let remove_idx = self.indices.remove(&remove_score)?; + let remove_index = self.indices.remove(&remove_score)?; if let Some((insert_score, insert_idx)) = insert { self.indices .try_insert(insert_score, insert_idx) .expect("just removed an item, we must be under capacity; qed"); } - self.insertion_overlay.remove(&remove_idx).or_else(|| { - (!self.deletion_overlay.contains(&remove_idx)) + self.insertion_overlay.remove(&remove_index).or_else(|| { + (!self.deletion_overlay.contains(&remove_index)) .then(|| { - self.deletion_overlay.insert(remove_idx); - SignedSubmissionsMap::::try_get(remove_idx).ok() + self.deletion_overlay.insert(remove_index); + SignedSubmissionsMap::::get(remove_index) }) .flatten() }) diff --git a/frame/examples/offchain-worker/src/lib.rs b/frame/examples/offchain-worker/src/lib.rs index 9812d35ffa074..ec728e791295c 100644 --- a/frame/examples/offchain-worker/src/lib.rs +++ b/frame/examples/offchain-worker/src/lib.rs @@ -233,7 +233,7 @@ pub mod pallet { // Retrieve sender of the transaction. let who = ensure_signed(origin)?; // Add the price to the on-chain list. - Self::add_price(who, price); + Self::add_price(Some(who), price); Ok(().into()) } @@ -262,7 +262,7 @@ pub mod pallet { // This ensures that the function can only be called via unsigned transaction. ensure_none(origin)?; // Add the price to the on-chain list, but mark it as coming from an empty address. - Self::add_price(Default::default(), price); + Self::add_price(None, price); // now increment the block number at which we expect next unsigned transaction. let current_block = >::block_number(); >::put(current_block + T::UnsignedInterval::get()); @@ -278,7 +278,7 @@ pub mod pallet { // This ensures that the function can only be called via unsigned transaction. ensure_none(origin)?; // Add the price to the on-chain list, but mark it as coming from an empty address. - Self::add_price(Default::default(), price_payload.price); + Self::add_price(None, price_payload.price); // now increment the block number at which we expect next unsigned transaction. let current_block = >::block_number(); >::put(current_block + T::UnsignedInterval::get()); @@ -291,7 +291,7 @@ pub mod pallet { #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { /// Event generated when new price is accepted to contribute to the average. - NewPrice { price: u32, who: T::AccountId }, + NewPrice { price: u32, maybe_who: Option }, } #[pallet::validate_unsigned] @@ -641,7 +641,7 @@ impl Pallet { } /// Add new price to the list. - fn add_price(who: T::AccountId, price: u32) { + fn add_price(maybe_who: Option, price: u32) { log::info!("Adding to the average: {}", price); >::mutate(|prices| { const MAX_LEN: usize = 64; @@ -657,7 +657,7 @@ impl Pallet { .expect("The average is not empty, because it was just mutated; qed"); log::info!("Current average price is: {}", average); // here we are raising the NewPrice event - Self::deposit_event(Event::NewPrice { price, who }); + Self::deposit_event(Event::NewPrice { price, maybe_who }); } /// Calculate current average price. From daa29421c6d46570e9ceda8b25e6746a358886ef Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 2 Dec 2021 17:53:55 -0500 Subject: [PATCH 11/47] pallet-asset-tx-payment --- frame/transaction-payment/asset-tx-payment/src/lib.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/frame/transaction-payment/asset-tx-payment/src/lib.rs b/frame/transaction-payment/asset-tx-payment/src/lib.rs index 1f22669857d76..5d2845314c4bf 100644 --- a/frame/transaction-payment/asset-tx-payment/src/lib.rs +++ b/frame/transaction-payment/asset-tx-payment/src/lib.rs @@ -210,7 +210,7 @@ where // tip BalanceOf, // who paid the fee - Self::AccountId, + Option, // imbalance resulting from withdrawing the fee InitialPayment, ); @@ -240,7 +240,7 @@ where len: usize, ) -> Result { let (_fee, initial_payment) = self.withdraw_fee(who, call, info, len)?; - Ok((self.tip, who.clone(), initial_payment)) + Ok((self.tip, Some(who.clone()), initial_payment)) } fn post_dispatch( @@ -265,6 +265,7 @@ where let actual_fee = pallet_transaction_payment::Pallet::::compute_actual_fee( len as u32, info, post_info, tip, ); + let who = who.ok_or(TransactionValidityError::Invalid(InvalidTransaction::Custom(255)))?; T::OnChargeAssetTransaction::correct_and_deposit_fee( &who, info, From 0f270da7a45078a046374e4ae98bc55fae77255e Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 2 Dec 2021 18:03:37 -0500 Subject: [PATCH 12/47] tips --- frame/tips/src/lib.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/frame/tips/src/lib.rs b/frame/tips/src/lib.rs index 0d2a56520a154..9e5f225b09d37 100644 --- a/frame/tips/src/lib.rs +++ b/frame/tips/src/lib.rs @@ -60,10 +60,7 @@ mod tests; pub mod migrations; pub mod weights; -use sp_runtime::{ - traits::{AccountIdConversion, BadOrigin, Hash, Zero}, - Percent, RuntimeDebug, -}; +use sp_runtime::{Percent, RuntimeDebug, traits::{AccountIdConversion, BadOrigin, Hash, TrailingZeroInput, Zero}}; use sp_std::prelude::*; use codec::{Decode, Encode}; @@ -580,6 +577,8 @@ impl Pallet { use frame_support::{migration::storage_key_iter, Twox64Concat}; + let zero_account = T::AccountId::decode(&mut TrailingZeroInput::new(&[][..])).expect("infinite input; qed"); + for (hash, old_tip) in storage_key_iter::< T::Hash, OldOpenTip, T::BlockNumber, T::Hash>, @@ -589,7 +588,7 @@ impl Pallet { { let (finder, deposit, finders_fee) = match old_tip.finder { Some((finder, deposit)) => (finder, deposit, true), - None => (T::AccountId::default(), Zero::zero(), false), + None => (zero_account.clone(), Zero::zero(), false), }; let new_tip = OpenTip { reason: old_tip.reason, From 393ed87fcf2e89ea1b2244e765d23df4f8b08d55 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 2 Dec 2021 18:05:04 -0500 Subject: [PATCH 13/47] sc-consensus-babe --- client/consensus/babe/src/authorship.rs | 2 +- client/consensus/babe/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/consensus/babe/src/authorship.rs b/client/consensus/babe/src/authorship.rs index 609f96c83c194..1bee73f40858a 100644 --- a/client/consensus/babe/src/authorship.rs +++ b/client/consensus/babe/src/authorship.rs @@ -27,7 +27,7 @@ use sp_consensus_babe::{ make_transcript, make_transcript_data, AuthorityId, BabeAuthorityWeight, Slot, BABE_VRF_PREFIX, }; use sp_consensus_vrf::schnorrkel::{VRFOutput, VRFProof}; -use sp_core::{blake2_256, crypto::Public, U256}; +use sp_core::{blake2_256, crypto::ByteArray, U256}; use sp_keystore::{SyncCryptoStore, SyncCryptoStorePtr}; /// Calculates the primary selection threshold for a given authority, taking diff --git a/client/consensus/babe/src/lib.rs b/client/consensus/babe/src/lib.rs index db89b952830fa..168cdff43cda2 100644 --- a/client/consensus/babe/src/lib.rs +++ b/client/consensus/babe/src/lib.rs @@ -110,7 +110,7 @@ use sp_consensus::{ }; use sp_consensus_babe::inherents::BabeInherentData; use sp_consensus_slots::Slot; -use sp_core::{crypto::{Public, ByteArray}, ExecutionContext}; +use sp_core::{crypto::ByteArray, ExecutionContext}; use sp_inherents::{CreateInherentDataProviders, InherentData, InherentDataProvider}; use sp_keystore::{SyncCryptoStore, SyncCryptoStorePtr}; use sp_runtime::{ From 7169d84731526856cf071d228b7ee36480533300 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 2 Dec 2021 18:11:12 -0500 Subject: [PATCH 14/47] sc-finality-grandpa --- client/finality-grandpa/src/lib.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/client/finality-grandpa/src/lib.rs b/client/finality-grandpa/src/lib.rs index e7618929fd089..6d6ba0f9f662d 100644 --- a/client/finality-grandpa/src/lib.rs +++ b/client/finality-grandpa/src/lib.rs @@ -73,7 +73,7 @@ use sp_api::ProvideRuntimeApi; use sp_application_crypto::AppKey; use sp_blockchain::{Error as ClientError, HeaderBackend, HeaderMetadata}; use sp_consensus::SelectChain; -use sp_core::crypto::Public; +use sp_core::crypto::ByteArray; use sp_keystore::{SyncCryptoStore, SyncCryptoStorePtr}; use sp_runtime::{ generic::BlockId, @@ -763,8 +763,7 @@ where let events = telemetry_on_connect.for_each(move |_| { let current_authorities = authorities.current_authorities(); let set_id = authorities.set_id(); - let authority_id = local_authority_id(¤t_authorities, conf.keystore.as_ref()) - .unwrap_or_default(); + let maybe_authority_id = local_authority_id(¤t_authorities, conf.keystore.as_ref()); let authorities = current_authorities.iter().map(|(id, _)| id.to_string()).collect::>(); @@ -778,7 +777,7 @@ where telemetry; CONSENSUS_INFO; "afg.authority_set"; - "authority_id" => authority_id.to_string(), + "authority_id" => maybe_authority_id.map_or("".into(), |s| s.to_string()), "authority_set_id" => ?set_id, "authorities" => authorities, ); @@ -917,8 +916,8 @@ where fn rebuild_voter(&mut self) { debug!(target: "afg", "{}: Starting new voter with set ID {}", self.env.config.name(), self.env.set_id); - let authority_id = local_authority_id(&self.env.voters, self.env.config.keystore.as_ref()) - .unwrap_or_default(); + let maybe_authority_id = local_authority_id(&self.env.voters, self.env.config.keystore.as_ref()); + let authority_id = maybe_authority_id.map_or("".into(), |s| s.to_string()); telemetry!( self.telemetry; @@ -926,7 +925,7 @@ where "afg.starting_new_voter"; "name" => ?self.env.config.name(), "set_id" => ?self.env.set_id, - "authority_id" => authority_id.to_string(), + "authority_id" => authority_id, ); let chain_info = self.env.client.info(); @@ -943,7 +942,7 @@ where "afg.authority_set"; "number" => ?chain_info.finalized_number, "hash" => ?chain_info.finalized_hash, - "authority_id" => authority_id.to_string(), + "authority_id" => authority_id, "authority_set_id" => ?self.env.set_id, "authorities" => authorities, ); From a853bcca46f794e0ac9071f58d3aa137feb83f34 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 2 Dec 2021 18:12:52 -0500 Subject: [PATCH 15/47] sc-consensus-babe-rpc --- client/consensus/babe/rpc/src/lib.rs | 2 +- client/consensus/babe/src/verification.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/consensus/babe/rpc/src/lib.rs b/client/consensus/babe/rpc/src/lib.rs index 285cfe543cee8..eeec7b86b1f14 100644 --- a/client/consensus/babe/rpc/src/lib.rs +++ b/client/consensus/babe/rpc/src/lib.rs @@ -30,7 +30,7 @@ use sp_application_crypto::AppKey; use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata}; use sp_consensus::{Error as ConsensusError, SelectChain}; use sp_consensus_babe::{digests::PreDigest, AuthorityId, BabeApi as BabeRuntimeApi}; -use sp_core::crypto::Public; +use sp_core::crypto::ByteArray; use sp_keystore::{SyncCryptoStore, SyncCryptoStorePtr}; use sp_runtime::traits::{Block as BlockT, Header as _}; use std::{collections::HashMap, sync::Arc}; diff --git a/client/consensus/babe/src/verification.rs b/client/consensus/babe/src/verification.rs index 6b949b487a54d..0a87e4b05ba76 100644 --- a/client/consensus/babe/src/verification.rs +++ b/client/consensus/babe/src/verification.rs @@ -31,7 +31,7 @@ use sp_consensus_babe::{ make_transcript, AuthorityId, AuthorityPair, AuthoritySignature, }; use sp_consensus_slots::Slot; -use sp_core::{Pair, Public, ByteArray}; +use sp_core::{Pair, ByteArray}; use sp_runtime::{traits::Header, DigestItem}; /// BABE verification parameters From 4cb42ffe93aeb0e030a7b54886388bebb57d0526 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 2 Dec 2021 18:35:07 -0500 Subject: [PATCH 16/47] sc-cli --- client/cli/src/commands/verify.rs | 18 ++++++------------ client/cli/src/error.rs | 12 +++++------- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/client/cli/src/commands/verify.rs b/client/cli/src/commands/verify.rs index 760793374242e..d1be4801dc02b 100644 --- a/client/cli/src/commands/verify.rs +++ b/client/cli/src/commands/verify.rs @@ -19,7 +19,7 @@ //! implementation of the `verify` subcommand use crate::{error, utils, with_crypto_scheme, CryptoSchemeFlag}; -use sp_core::{crypto::Ss58Codec, Public}; +use sp_core::crypto::{Ss58Codec, ByteArray}; use structopt::StructOpt; /// The `verify` command @@ -63,22 +63,16 @@ impl VerifyCmd { } } -fn verify(sig_data: Vec, message: Vec, uri: &str) -> error::Result<()> -where +fn verify(sig_data: Vec, message: Vec, uri: &str) -> error::Result<()> where Pair: sp_core::Pair, - Pair::Signature: Default + AsMut<[u8]>, + Pair::Signature: for <'a> std::convert::TryFrom<&'a [u8]>, { - let mut signature = Pair::Signature::default(); - if sig_data.len() != signature.as_ref().len() { - return Err(error::Error::SignatureInvalidLength { - read: sig_data.len(), - expected: signature.as_ref().len(), - }) - } - signature.as_mut().copy_from_slice(&sig_data); + let signature = Pair::Signature::try_from(&sig_data) + .map_err(|_| error::Error::SignatureFormatInvalid)?; let pubkey = if let Ok(pubkey_vec) = hex::decode(uri) { Pair::Public::from_slice(pubkey_vec.as_slice()) + .map_err(|_| error::Error::KeyFormatInvalid)? } else { Pair::Public::from_string(uri)? }; diff --git a/client/cli/src/error.rs b/client/cli/src/error.rs index c5784b2018172..9a09e560063ea 100644 --- a/client/cli/src/error.rs +++ b/client/cli/src/error.rs @@ -51,13 +51,11 @@ pub enum Error { #[error("Invalid URI; expecting either a secret URI or a public URI.")] InvalidUri(crypto::PublicError), - #[error("Signature has an invalid length. Read {read} bytes, expected {expected} bytes")] - SignatureInvalidLength { - /// Amount of signature bytes read. - read: usize, - /// Expected number of signature bytes. - expected: usize, - }, + #[error("Signature is an invalid format.")] + SignatureFormatInvalid, + + #[error("Key is an invalid format.")] + KeyFormatInvalid, #[error("Unknown key type, must be a known 4-character sequence")] KeyTypeInvalid, From 2a04445240adfd93c5fad71b3c0ece8c51479555 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Sat, 4 Dec 2021 01:00:41 +0100 Subject: [PATCH 17/47] make npos crates accept non-default account (#10420) * minimal changes to make npos pallets all work * make this pesky reduce.rs a bit cleaner --- frame/session/src/lib.rs | 13 ++--- frame/staking/src/lib.rs | 18 +++++-- frame/staking/src/pallet/impls.rs | 9 ++-- primitives/npos-elections/src/lib.rs | 24 ++++++--- primitives/npos-elections/src/reduce.rs | 70 +++++++++++++++++-------- primitives/npos-elections/src/tests.rs | 12 ++--- 6 files changed, 100 insertions(+), 46 deletions(-) diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index 3243d81a3d631..780e7e71c5675 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -313,8 +313,9 @@ impl SessionHandler for Tuple { #( let our_keys: Box> = Box::new(validators.iter() .filter_map(|k| - (&k.0, k.1.get::(::ID))) - ); + k.1.get::(::ID).map(|k1| (&k.0, k1)) + ) + ); Tuple::on_genesis_session(our_keys); )* @@ -330,12 +331,12 @@ impl SessionHandler for Tuple { #( let our_keys: Box> = Box::new(validators.iter() .filter_map(|k| - (&k.0, k.1.get::(::ID))) - ); + k.1.get::(::ID).map(|k1| (&k.0, k1)) + )); let queued_keys: Box> = Box::new(queued_validators.iter() .filter_map(|k| - (&k.0, k.1.get::(::ID))) - ); + k.1.get::(::ID).map(|k1| (&k.0, k1)) + )); Tuple::on_new_session(changed, our_keys, queued_keys); )* ) diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index f2e5f0f783895..081ff7d1e4290 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -364,7 +364,7 @@ pub struct ActiveEraInfo { /// Reward points of an era. Used to split era total payout between validators. /// /// This points will be used to reward validators and their respective nominators. -#[derive(PartialEq, Encode, Decode, Default, RuntimeDebug, TypeInfo)] +#[derive(PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] pub struct EraRewardPoints { /// Total number of points. Equals the sum of reward points for each validator. total: RewardPoint, @@ -372,6 +372,12 @@ pub struct EraRewardPoints { individual: BTreeMap, } +impl Default for EraRewardPoints { + fn default() -> Self { + EraRewardPoints { total: Default::default(), individual: BTreeMap::new() } + } +} + /// Indicates the initial status of the staker. #[derive(RuntimeDebug, TypeInfo)] #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] @@ -593,9 +599,7 @@ pub struct IndividualExposure { } /// A snapshot of the stake backing a single validator in the system. -#[derive( - PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default, RuntimeDebug, TypeInfo, -)] +#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, RuntimeDebug, TypeInfo)] pub struct Exposure { /// The total balance backing this validator. #[codec(compact)] @@ -607,6 +611,12 @@ pub struct Exposure { pub others: Vec>, } +impl Default for Exposure { + fn default() -> Self { + Self { total: Default::default(), own: Default::default(), others: vec![] } + } +} + /// A pending slash record. The value of the slash has been computed but not applied yet, /// rather deferred for several eras. #[derive(Encode, Decode, Default, RuntimeDebug, TypeInfo)] diff --git a/frame/staking/src/pallet/impls.rs b/frame/staking/src/pallet/impls.rs index edcc061112d6f..dd6515c500db1 100644 --- a/frame/staking/src/pallet/impls.rs +++ b/frame/staking/src/pallet/impls.rs @@ -1108,9 +1108,12 @@ where fn note_author(author: T::AccountId) { Self::reward_by_ids(vec![(author, 20)]) } - fn note_uncle(author: T::AccountId, _age: T::BlockNumber) { - if let Some(author) = >::author() { - Self::reward_by_ids(vec![(author, 2), (author, 1)]) + fn note_uncle(uncle_author: T::AccountId, _age: T::BlockNumber) { + // defensive-only: block author must exist. + if let Some(block_author) = >::author() { + Self::reward_by_ids(vec![(block_author, 2), (uncle_author, 1)]) + } else { + crate::log!(warn, "block author not set, this should never happen"); } } } diff --git a/primitives/npos-elections/src/lib.rs b/primitives/npos-elections/src/lib.rs index b1e1ed2745174..0b10b4c7c1b8f 100644 --- a/primitives/npos-elections/src/lib.rs +++ b/primitives/npos-elections/src/lib.rs @@ -193,6 +193,15 @@ pub struct Edge { weight: ExtendedBalance, } +#[cfg(test)] +impl Edge { + fn new(candidate: Candidate, weight: ExtendedBalance) -> Self { + let who = candidate.who.clone(); + let candidate = Rc::new(RefCell::new(candidate)); + Self { weight, who, candidate, load: Default::default() } + } +} + #[cfg(feature = "std")] impl sp_std::fmt::Debug for Edge { fn fmt(&self, f: &mut sp_std::fmt::Formatter<'_>) -> sp_std::fmt::Result { @@ -223,7 +232,12 @@ impl std::fmt::Debug for Voter { impl Voter { /// Create a new `Voter`. pub fn new(who: AccountId) -> Self { - Self { who, edges: Default::default(), budget: Default::default(), load: Default::default() } + Self { + who, + edges: Default::default(), + budget: Default::default(), + load: Default::default(), + } } /// Returns `true` if `self` votes for `target`. @@ -350,10 +364,7 @@ pub struct Support { impl Default for Support { fn default() -> Self { - Self { - total: Default::default(), - voters: vec![], - } + Self { total: Default::default(), voters: vec![] } } } @@ -477,7 +488,8 @@ pub fn setup_inputs( backed_stake: Default::default(), elected: Default::default(), round: Default::default(), - }.to_ptr() + } + .to_ptr() }) .collect::>>(); diff --git a/primitives/npos-elections/src/reduce.rs b/primitives/npos-elections/src/reduce.rs index 9a31a4aa6da58..98e015497fad1 100644 --- a/primitives/npos-elections/src/reduce.rs +++ b/primitives/npos-elections/src/reduce.rs @@ -355,7 +355,7 @@ fn reduce_all(assignments: &mut Vec>) -> u32 .or_insert_with(|| Node::new(target_id).into_ref()) .clone(); - // If one exists but the other one doesn't, or if both does not, then set the existing + // If one exists but the other one doesn't, or if both do not, then set the existing // one as the parent of the non-existing one and move on. Else, continue with the rest // of the code. match (voter_exists, target_exists) { @@ -389,39 +389,43 @@ fn reduce_all(assignments: &mut Vec>) -> u32 let common_count = trailing_common(&voter_root_path, &target_root_path); // because roots are the same. - #[cfg(feature = "std")] debug_assert_eq!(target_root_path.last().unwrap(), voter_root_path.last().unwrap()); + // the common path must be non-void.. debug_assert!(common_count > 0); + // and smaller than btoh + debug_assert!(common_count <= voter_root_path.len()); + debug_assert!(common_count <= target_root_path.len()); // cycle part of each path will be `path[path.len() - common_count - 1 : 0]` // NOTE: the order of chaining is important! it is always build from [target, ..., // voter] let cycle = target_root_path .iter() - .take(target_root_path.len() - common_count + 1) + .take(target_root_path.len().saturating_sub(common_count).saturating_add(1)) .cloned() .chain( voter_root_path .iter() - .take(voter_root_path.len() - common_count) + .take(voter_root_path.len().saturating_sub(common_count)) .rev() .cloned(), ) .collect::>>(); // a cycle's length shall always be multiple of two. - #[cfg(feature = "std")] debug_assert_eq!(cycle.len() % 2, 0); // find minimum of cycle. let mut min_value: ExtendedBalance = Bounded::max_value(); - // The voter and the target pair that create the min edge. - let mut min_target: Option = None; - let mut min_voter: Option = None; + // The voter and the target pair that create the min edge. These MUST be set by the + // end of this code block, otherwise we skip. + let mut maybe_min_target: Option = None; + let mut maybe_min_voter: Option = None; // The index of the min in opaque cycle list. - let mut min_index = 0usize; + let mut maybe_min_index: Option = None; // 1 -> next // 0 -> prev - let mut min_direction = 0u32; + let mut maybe_min_direction: Option = None; + // helpers let next_index = |i| { if i < (cycle.len() - 1) { @@ -437,6 +441,7 @@ fn reduce_all(assignments: &mut Vec>) -> u32 cycle.len() - 1 } }; + for i in 0..cycle.len() { if cycle[i].borrow().id.role == NodeRole::Voter { // NOTE: sadly way too many clones since I don't want to make A: Copy @@ -447,10 +452,10 @@ fn reduce_all(assignments: &mut Vec>) -> u32 ass.distribution.iter().find(|d| d.0 == next).map(|(_, w)| { if *w < min_value { min_value = *w; - min_target = Some(next.clone()); - min_voter = Some(current.clone()); - min_index = i; - min_direction = 1; + maybe_min_target = Some(next.clone()); + maybe_min_voter = Some(current.clone()); + maybe_min_index = Some(i); + maybe_min_direction = Some(1); } }) }); @@ -458,16 +463,39 @@ fn reduce_all(assignments: &mut Vec>) -> u32 ass.distribution.iter().find(|d| d.0 == prev).map(|(_, w)| { if *w < min_value { min_value = *w; - min_target = Some(prev.clone()); - min_voter = Some(current.clone()); - min_index = i; - min_direction = 0; + maybe_min_target = Some(prev.clone()); + maybe_min_voter = Some(current.clone()); + maybe_min_index = Some(i); + maybe_min_direction = Some(0); } }) }); } } + // all of these values must be set by now, we assign them to un-mut values, no + // longer being optional either. + let (min_value, min_target, min_voter, min_index, min_direction) = + match ( + min_value, + maybe_min_target, + maybe_min_voter, + maybe_min_index, + maybe_min_direction, + ) { + ( + min_value, + Some(min_target), + Some(min_voter), + Some(min_index), + Some(min_direction), + ) => (min_value, min_target, min_voter, min_index, min_direction), + _ => { + sp_runtime::print("UNREACHABLE code reached in `reduce` algorithm. This must be a bug."); + break + }, + }; + // if the min edge is in the voter's sub-chain. // [target, ..., X, Y, ... voter] let target_chunk = target_root_path.len() - common_count; @@ -577,7 +605,7 @@ fn reduce_all(assignments: &mut Vec>) -> u32 // re-org. if should_reorg { - let min_edge = min_voter.into_iter().chain(min_target.into_iter()).collect::>(); + let min_edge = vec![min_voter, min_target]; if min_chain_in_voter { // NOTE: safe; voter_root_path is always bigger than 1 element. for i in 0..voter_root_path.len() - 1 { @@ -623,8 +651,8 @@ fn reduce_all(assignments: &mut Vec>) -> u32 num_changed } -/// Reduce the given [`Vec>`]. This removes redundant edges from -/// without changing the overall backing of any of the elected candidates. +/// Reduce the given [`Vec>`]. This removes redundant edges without +/// changing the overall backing of any of the elected candidates. /// /// Returns the number of edges removed. /// diff --git a/primitives/npos-elections/src/tests.rs b/primitives/npos-elections/src/tests.rs index bf9ca57677efa..c745ee1d7706d 100644 --- a/primitives/npos-elections/src/tests.rs +++ b/primitives/npos-elections/src/tests.rs @@ -199,9 +199,9 @@ fn voter_normalize_ops_works() { let c2 = Candidate { who: 20, elected: false, ..Default::default() }; let c3 = Candidate { who: 30, elected: false, ..Default::default() }; - let e1 = Edge { candidate: Rc::new(RefCell::new(c1)), weight: 30, ..Default::default() }; - let e2 = Edge { candidate: Rc::new(RefCell::new(c2)), weight: 33, ..Default::default() }; - let e3 = Edge { candidate: Rc::new(RefCell::new(c3)), weight: 30, ..Default::default() }; + let e1 = Edge::new(c1, 30); + let e2 = Edge::new(c2, 33); + let e3 = Edge::new(c3, 30); let mut v = Voter { who: 1, budget: 100, edges: vec![e1, e2, e3], ..Default::default() }; @@ -214,9 +214,9 @@ fn voter_normalize_ops_works() { let c2 = Candidate { who: 20, elected: true, ..Default::default() }; let c3 = Candidate { who: 30, elected: true, ..Default::default() }; - let e1 = Edge { candidate: Rc::new(RefCell::new(c1)), weight: 30, ..Default::default() }; - let e2 = Edge { candidate: Rc::new(RefCell::new(c2)), weight: 33, ..Default::default() }; - let e3 = Edge { candidate: Rc::new(RefCell::new(c3)), weight: 30, ..Default::default() }; + let e1 = Edge::new(c1, 30); + let e2 = Edge::new(c2, 33); + let e3 = Edge::new(c3, 30); let mut v = Voter { who: 1, budget: 100, edges: vec![e1, e2, e3], ..Default::default() }; From 452651c093b501477289fd677d1e942df3c4ffd7 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 3 Dec 2021 19:50:29 -0500 Subject: [PATCH 18/47] more work --- bin/node-template/node/src/chain_spec.rs | 2 +- frame/aura/src/lib.rs | 1 - frame/babe/src/lib.rs | 2 +- frame/beefy-mmr/src/lib.rs | 2 +- frame/im-online/src/lib.rs | 1 - frame/session/src/lib.rs | 10 +++---- frame/staking/src/benchmarking.rs | 20 ++++++++++---- frame/staking/src/lib.rs | 27 ++++++++++++++++--- frame/staking/src/pallet/impls.rs | 6 +++-- primitives/npos-elections/src/reduce.rs | 3 ++- primitives/runtime/src/traits.rs | 7 ++++- .../runtime/transaction-pool/src/lib.rs | 11 +++----- test-utils/test-runner/src/node.rs | 2 +- 13 files changed, 64 insertions(+), 30 deletions(-) diff --git a/bin/node-template/node/src/chain_spec.rs b/bin/node-template/node/src/chain_spec.rs index d32a0dcb29d00..af94a63335e0e 100644 --- a/bin/node-template/node/src/chain_spec.rs +++ b/bin/node-template/node/src/chain_spec.rs @@ -147,7 +147,7 @@ fn testnet_genesis( }, sudo: SudoConfig { // Assign network admin rights. - key: root_key, + key: Some(root_key), }, transaction_payment: Default::default(), } diff --git a/frame/aura/src/lib.rs b/frame/aura/src/lib.rs index 887bb359ed3db..e98097055920d 100644 --- a/frame/aura/src/lib.rs +++ b/frame/aura/src/lib.rs @@ -69,7 +69,6 @@ pub mod pallet { type AuthorityId: Member + Parameter + RuntimeAppPublic - + Default + MaybeSerializeDeserialize + MaxEncodedLen; /// The maximum number of authorities that the pallet can hold. diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index 569722ca38ced..6ae0796c866f0 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -31,7 +31,7 @@ use frame_support::{ weights::{Pays, Weight}, BoundedVec, WeakBoundedVec, }; -use sp_application_crypto::Public; +use sp_application_crypto::ByteArray; use sp_runtime::{ generic::DigestItem, traits::{IsMember, One, SaturatedConversion, Saturating, Zero}, diff --git a/frame/beefy-mmr/src/lib.rs b/frame/beefy-mmr/src/lib.rs index b846aa4a7dd6b..cf65e39dba533 100644 --- a/frame/beefy-mmr/src/lib.rs +++ b/frame/beefy-mmr/src/lib.rs @@ -72,7 +72,7 @@ where pub struct BeefyEcdsaToEthereum; impl Convert> for BeefyEcdsaToEthereum { fn convert(a: beefy_primitives::crypto::AuthorityId) -> Vec { - use sp_core::crypto::Public; + use sp_core::crypto::ByteArray; let compressed_key = a.as_slice(); libsecp256k1::PublicKey::parse_slice( diff --git a/frame/im-online/src/lib.rs b/frame/im-online/src/lib.rs index dbae5ed96d58a..3499078149f2e 100644 --- a/frame/im-online/src/lib.rs +++ b/frame/im-online/src/lib.rs @@ -324,7 +324,6 @@ pub mod pallet { type AuthorityId: Member + Parameter + RuntimeAppPublic - + Default + Ord + MaybeSerializeDeserialize + MaxEncodedLen; diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index 780e7e71c5675..d786ea147a533 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -407,7 +407,7 @@ pub mod pallet { type SessionHandler: SessionHandler; /// The keys. - type Keys: OpaqueKeys + Member + Parameter + Default + MaybeSerializeDeserialize; + type Keys: OpaqueKeys + Member + Parameter + MaybeSerializeDeserialize; /// Weight information for extrinsics in this pallet. type WeightInfo: WeightInfo; @@ -480,7 +480,7 @@ pub mod pallet { let queued_keys: Vec<_> = initial_validators_1 .iter() .cloned() - .map(|v| (v.clone(), >::load_keys(&v).unwrap_or_default())) + .filter_map(|v| Some((v.clone(), Pallet::::load_keys(&v)?))) .collect(); // Tell everyone about the genesis session keys @@ -693,10 +693,10 @@ impl Pallet { }; let queued_amalgamated = next_validators .into_iter() - .map(|a| { - let k = Self::load_keys(&a).unwrap_or_default(); + .filter_map(|a| { + let k = Self::load_keys(&a)?; check_next_changed(&k); - (a, k) + Some((a, k)) }) .collect::>(); diff --git a/frame/staking/src/benchmarking.rs b/frame/staking/src/benchmarking.rs index 5feb1692d955d..4dbaf7423b10c 100644 --- a/frame/staking/src/benchmarking.rs +++ b/frame/staking/src/benchmarking.rs @@ -21,6 +21,7 @@ use super::*; use crate::Pallet as Staking; use testing_utils::*; +use codec::Decode; use frame_election_provider_support::SortedListProvider; use frame_support::{ dispatch::UnfilteredDispatchable, @@ -535,8 +536,9 @@ benchmarks! { let s in 1 .. MAX_SLASHES; let mut unapplied_slashes = Vec::new(); let era = EraIndex::one(); + let dummy = || T::AccountId::decode(&mut TrailingZeroInput::zeroes()).unwrap(); for _ in 0 .. MAX_SLASHES { - unapplied_slashes.push(UnappliedSlash::>::default()); + unapplied_slashes.push(UnappliedSlash::>::default_from(dummy())); } UnappliedSlashes::::insert(era, &unapplied_slashes); @@ -667,10 +669,11 @@ benchmarks! { let e in 1 .. 100; HistoryDepth::::put(e); CurrentEra::::put(e); + let dummy = || -> AccountId { codec::Decode::decode(&mut TrailingZeroInput::zeroes()).unwrap() }; for i in 0 .. e { - >::insert(i, T::AccountId::default(), Exposure::>::default()); - >::insert(i, T::AccountId::default(), Exposure::>::default()); - >::insert(i, T::AccountId::default(), ValidatorPrefs::default()); + >::insert(i, dummy(), Exposure::>::default()); + >::insert(i, dummy(), Exposure::>::default()); + >::insert(i, dummy(), ValidatorPrefs::default()); >::insert(i, BalanceOf::::one()); >::insert(i, EraRewardPoints::::default()); >::insert(i, BalanceOf::::one()); @@ -695,7 +698,14 @@ benchmarks! { let stash = scenario.origin_stash1.clone(); add_slashing_spans::(&stash, s); - Ledger::::insert(&controller, StakingLedger { active: T::Currency::minimum_balance() - One::one(), total: T::Currency::minimum_balance() - One::one(), ..Default::default() }); + let l = StakingLedger { + stash: stash.clone(), + active: T::Currency::minimum_balance() - One::one(), + total: T::Currency::minimum_balance() - One::one(), + unlocking: vec![], + claimed_rewards: vec![], + }; + Ledger::::insert(&controller, l); assert!(Bonded::::contains_key(&stash)); assert!(T::SortedListProvider::contains(&stash)); diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 081ff7d1e4290..f629c4e494d93 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -442,7 +442,6 @@ pub struct UnlockChunk { } /// The ledger of a (bonded) stash. -#[cfg_attr(feature = "runtime-benchmarks", derive(Default))] #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, TypeInfo)] pub struct StakingLedger { /// The stash account whose balance is actually locked and at stake. @@ -463,9 +462,19 @@ pub struct StakingLedger { pub claimed_rewards: Vec, } -impl +impl StakingLedger { + pub fn default_from(stash: AccountId) -> Self { + Self { + stash, + total: Zero::zero(), + active: Zero::zero(), + unlocking: vec![], + claimed_rewards: vec![], + } + } + /// Remove entries from `unlocking` that are sufficiently old and reduce the /// total by the sum of their balances. fn consolidate_unlocked(self, current_era: EraIndex) -> Self { @@ -619,7 +628,7 @@ impl Default for Exposure { /// The stash ID of the offending validator. validator: AccountId, @@ -633,6 +642,18 @@ pub struct UnappliedSlash { payout: Balance, } +impl UnappliedSlash { + fn default_from(validator: AccountId) -> Self { + Self { + validator, + own: Zero::zero(), + others: vec![], + reporters: vec![], + payout: Zero::zero(), + } + } +} + /// Means for interacting with a specialized version of the `session` trait. /// /// This is needed because `Staking` sets the `ValidatorIdOf` of the `pallet_session::Config` diff --git a/frame/staking/src/pallet/impls.rs b/frame/staking/src/pallet/impls.rs index dd6515c500db1..aafac811d0986 100644 --- a/frame/staking/src/pallet/impls.rs +++ b/frame/staking/src/pallet/impls.rs @@ -1262,8 +1262,10 @@ impl VoteWeightProvider for Pallet { // this will clearly results in an inconsistent state, but it should not matter for a // benchmark. let active: BalanceOf = weight.try_into().map_err(|_| ()).unwrap(); - let mut ledger = Self::ledger(who).unwrap_or_default(); - ledger.active = active; + let ledger = match Self::ledger(who) { + None => StakingLedger::default_from(active), + Some(mut l) => { l.active = active; l }, + }; >::insert(who, ledger); >::insert(who, who); diff --git a/primitives/npos-elections/src/reduce.rs b/primitives/npos-elections/src/reduce.rs index 98e015497fad1..9f1cef71e2455 100644 --- a/primitives/npos-elections/src/reduce.rs +++ b/primitives/npos-elections/src/reduce.rs @@ -389,7 +389,8 @@ fn reduce_all(assignments: &mut Vec>) -> u32 let common_count = trailing_common(&voter_root_path, &target_root_path); // because roots are the same. - debug_assert_eq!(target_root_path.last().unwrap(), voter_root_path.last().unwrap()); + //debug_assert_eq!(target_root_path.last().unwrap(), voter_root_path.last().unwrap()); + // TODO: @kian // the common path must be non-void.. debug_assert!(common_count > 0); // and smaller than btoh diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index fe13e567117f6..1409e94e6da7c 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -1213,6 +1213,11 @@ impl<'a> TrailingZeroInput<'a> { pub fn new(data: &'a [u8]) -> Self { Self(data) } + + /// Create a new instance which only contains zeroes as input. + pub fn zeroes() -> Self { + Self::new(&[][..]) + } } impl<'a> codec::Input for TrailingZeroInput<'a> { @@ -1318,7 +1323,7 @@ macro_rules! impl_opaque_keys_inner { ) => { $( #[ $attr ] )* #[derive( - Default, Clone, PartialEq, Eq, + Clone, PartialEq, Eq, $crate::codec::Encode, $crate::codec::Decode, $crate::scale_info::TypeInfo, diff --git a/test-utils/runtime/transaction-pool/src/lib.rs b/test-utils/runtime/transaction-pool/src/lib.rs index d0cd50394c533..2a32375cfecc0 100644 --- a/test-utils/runtime/transaction-pool/src/lib.rs +++ b/test-utils/runtime/transaction-pool/src/lib.rs @@ -23,14 +23,10 @@ use codec::Encode; use futures::future::ready; use parking_lot::RwLock; use sp_blockchain::CachedHeaderMetadata; -use sp_runtime::{ - generic::{self, BlockId}, - traits::{BlakeTwo256, Block as BlockT, Hash as HashT, Header as _}, - transaction_validity::{ +use sp_runtime::{generic::{self, BlockId}, traits::{BlakeTwo256, Block as BlockT, Hash as HashT, Header as _, TrailingZeroInput}, transaction_validity::{ InvalidTransaction, TransactionSource, TransactionValidity, TransactionValidityError, ValidTransaction, - }, -}; + }}; use std::collections::{BTreeMap, HashMap, HashSet}; use substrate_test_runtime_client::{ runtime::{AccountId, Block, BlockNumber, Extrinsic, Hash, Header, Index, Transfer}, @@ -370,7 +366,8 @@ impl sp_blockchain::HeaderMetadata for TestApi { /// /// Part of the test api. pub fn uxt(who: AccountKeyring, nonce: Index) -> Extrinsic { - let transfer = Transfer { from: who.into(), to: AccountId::default(), nonce, amount: 1 }; + let dummy = codec::Decode::decode(&mut TrailingZeroInput::zeroes()).unwrap(); + let transfer = Transfer { from: who.into(), to: dummy, nonce, amount: 1 }; let signature = transfer.using_encoded(|e| who.sign(e)).into(); Extrinsic::Transfer { transfer, signature, exhaust_resources_when_not_first: false } } diff --git a/test-utils/test-runner/src/node.rs b/test-utils/test-runner/src/node.rs index 5fd8e4669c33d..d78de1d3ac015 100644 --- a/test-utils/test-runner/src/node.rs +++ b/test-utils/test-runner/src/node.rs @@ -195,7 +195,7 @@ where { let signed_data = if let Some(signer) = signer { let extra = self.with_state(|| T::signed_extras(signer.clone())); - Some((signer.into(), MultiSignature::Sr25519(Default::default()), extra)) + Some((signer.into(), MultiSignature::Sr25519(sp_core::sr25519::Signature::from_raw([0u8; 64])), extra)) } else { None }; From 227f3600d1f841860433a9b242ecfff5eb41a259 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 4 Dec 2021 13:54:08 -0500 Subject: [PATCH 19/47] more work --- bin/node/cli/src/chain_spec.rs | 2 +- frame/session/benchmarking/src/lib.rs | 7 ++++--- frame/staking/src/benchmarking.rs | 4 ++-- frame/staking/src/pallet/impls.rs | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/bin/node/cli/src/chain_spec.rs b/bin/node/cli/src/chain_spec.rs index 6d11722081e30..b29248519cc08 100644 --- a/bin/node/cli/src/chain_spec.rs +++ b/bin/node/cli/src/chain_spec.rs @@ -338,7 +338,7 @@ pub fn testnet_genesis( .collect(), phantom: Default::default(), }, - sudo: SudoConfig { key: root_key }, + sudo: SudoConfig { key: Some(root_key) }, babe: BabeConfig { authorities: vec![], epoch_config: Some(node_runtime::BABE_GENESIS_EPOCH_CONFIG), diff --git a/frame/session/benchmarking/src/lib.rs b/frame/session/benchmarking/src/lib.rs index 6d9d81f385176..4e0e51b76fe18 100644 --- a/frame/session/benchmarking/src/lib.rs +++ b/frame/session/benchmarking/src/lib.rs @@ -22,7 +22,7 @@ mod mock; -use sp_runtime::traits::{One, StaticLookup}; +use sp_runtime::traits::{One, StaticLookup, TrailingZeroInput}; use sp_std::{prelude::*, vec}; use frame_benchmarking::benchmarks; @@ -61,7 +61,8 @@ benchmarks! { RewardDestination::Staked, )?; let v_controller = pallet_staking::Pallet::::bonded(&v_stash).ok_or("not stash")?; - let keys = T::Keys::default(); + + let keys = T::Keys::decode(&mut TrailingZeroInput::zeroes()).unwrap(); let proof: Vec = vec![0,1,2,3]; // Whitelist controller account from further DB operations. let v_controller_key = frame_system::Account::::hashed_key_for(&v_controller); @@ -77,7 +78,7 @@ benchmarks! { RewardDestination::Staked )?; let v_controller = pallet_staking::Pallet::::bonded(&v_stash).ok_or("not stash")?; - let keys = T::Keys::default(); + let keys = T::Keys::decode(&mut TrailingZeroInput::zeroes()).unwrap(); let proof: Vec = vec![0,1,2,3]; Session::::set_keys(RawOrigin::Signed(v_controller.clone()).into(), keys, proof)?; // Whitelist controller account from further DB operations. diff --git a/frame/staking/src/benchmarking.rs b/frame/staking/src/benchmarking.rs index 4dbaf7423b10c..9d48df69edd8c 100644 --- a/frame/staking/src/benchmarking.rs +++ b/frame/staking/src/benchmarking.rs @@ -29,7 +29,7 @@ use frame_support::{ traits::{Currency, CurrencyToVote, Get, Imbalance}, }; use sp_runtime::{ - traits::{Bounded, One, StaticLookup, Zero}, + traits::{Bounded, One, StaticLookup, Zero, TrailingZeroInput}, Perbill, Percent, }; use sp_staking::SessionIndex; @@ -669,7 +669,7 @@ benchmarks! { let e in 1 .. 100; HistoryDepth::::put(e); CurrentEra::::put(e); - let dummy = || -> AccountId { codec::Decode::decode(&mut TrailingZeroInput::zeroes()).unwrap() }; + let dummy = || -> T::AccountId { codec::Decode::decode(&mut TrailingZeroInput::zeroes()).unwrap() }; for i in 0 .. e { >::insert(i, dummy(), Exposure::>::default()); >::insert(i, dummy(), Exposure::>::default()); diff --git a/frame/staking/src/pallet/impls.rs b/frame/staking/src/pallet/impls.rs index aafac811d0986..553deaa2fd662 100644 --- a/frame/staking/src/pallet/impls.rs +++ b/frame/staking/src/pallet/impls.rs @@ -1263,7 +1263,7 @@ impl VoteWeightProvider for Pallet { // benchmark. let active: BalanceOf = weight.try_into().map_err(|_| ()).unwrap(); let ledger = match Self::ledger(who) { - None => StakingLedger::default_from(active), + None => StakingLedger::default_from(who.clone()), Some(mut l) => { l.active = active; l }, }; >::insert(who, ledger); From 345c87b9b805347165ac4f8beac17cac42593248 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 6 Dec 2021 15:46:42 +0000 Subject: [PATCH 20/47] Tests build --- bin/node/executor/tests/submit_transaction.rs | 2 +- bin/utils/chain-spec-builder/src/main.rs | 2 +- .../authority-discovery/src/worker/tests.rs | 2 +- .../basic-authorship/src/basic_authorship.rs | 8 ++--- client/cli/src/commands/insert_key.rs | 2 +- client/finality-grandpa/rpc/src/lib.rs | 8 ++--- client/finality-grandpa/src/authorities.rs | 32 +++++++++---------- client/finality-grandpa/src/aux_schema.rs | 12 ++++--- .../src/communication/gossip.rs | 20 ++++++------ .../src/communication/tests.rs | 4 +-- client/finality-grandpa/src/finality_proof.rs | 10 +++--- client/finality-grandpa/src/tests.rs | 2 +- client/finality-grandpa/src/until_imported.rs | 17 +++++----- client/rpc/src/author/tests.rs | 6 ++-- client/service/src/lib.rs | 2 +- client/transaction-pool/src/graph/pool.rs | 3 +- frame/authorship/src/lib.rs | 2 +- frame/beefy/src/lib.rs | 2 +- frame/examples/offchain-worker/src/tests.rs | 8 +++-- frame/examples/parallel/src/tests.rs | 16 +++++++--- frame/sudo/src/mock.rs | 2 +- frame/sudo/src/tests.rs | 8 ++--- frame/support/test/tests/construct_runtime.rs | 18 +++++++---- primitives/api/test/tests/runtime_calls.rs | 2 +- primitives/application-crypto/src/lib.rs | 12 +++++-- primitives/core/src/crypto.rs | 17 +++++++--- primitives/core/src/ecdsa.rs | 6 ++++ primitives/core/src/ed25519.rs | 6 ++++ primitives/core/src/sr25519.rs | 6 ++++ primitives/io/src/lib.rs | 26 ++++++++++++--- primitives/npos-elections/src/tests.rs | 1 - primitives/runtime/src/lib.rs | 6 ++-- primitives/runtime/src/traits.rs | 6 ++-- 33 files changed, 175 insertions(+), 101 deletions(-) diff --git a/bin/node/executor/tests/submit_transaction.rs b/bin/node/executor/tests/submit_transaction.rs index f047c6a44a667..3ab446ea11521 100644 --- a/bin/node/executor/tests/submit_transaction.rs +++ b/bin/node/executor/tests/submit_transaction.rs @@ -33,7 +33,7 @@ fn should_submit_unsigned_transaction() { t.register_extension(TransactionPoolExt::new(pool)); t.execute_with(|| { - let signature = Default::default(); + let signature = pallet_im_online::sr25519::AuthoritySignature::try_from(vec![0; 64]).unwrap(); let heartbeat_data = pallet_im_online::Heartbeat { block_number: 1, network_state: Default::default(), diff --git a/bin/utils/chain-spec-builder/src/main.rs b/bin/utils/chain-spec-builder/src/main.rs index bf5f1a149578e..f45031f1eb811 100644 --- a/bin/utils/chain-spec-builder/src/main.rs +++ b/bin/utils/chain-spec-builder/src/main.rs @@ -29,7 +29,7 @@ use structopt::StructOpt; use node_cli::chain_spec::{self, AccountId}; use sc_keystore::LocalKeystore; use sp_core::{ - crypto::{Public, Ss58Codec}, + crypto::{ByteArray, Ss58Codec}, sr25519, }; use sp_keystore::{SyncCryptoStore, SyncCryptoStorePtr}; diff --git a/client/authority-discovery/src/worker/tests.rs b/client/authority-discovery/src/worker/tests.rs index 130aea71fdfb0..bd8a0311f07aa 100644 --- a/client/authority-discovery/src/worker/tests.rs +++ b/client/authority-discovery/src/worker/tests.rs @@ -36,7 +36,7 @@ use libp2p::{core::multiaddr, kad, PeerId}; use prometheus_endpoint::prometheus::default_registry; use sp_api::{ApiRef, ProvideRuntimeApi}; -use sp_core::crypto::Public; +use sp_core::crypto::ByteArray; use sp_keystore::{testing::KeyStore, CryptoStore}; use sp_runtime::traits::{Block as BlockT, NumberFor, Zero}; use substrate_test_runtime_client::runtime::Block; diff --git a/client/basic-authorship/src/basic_authorship.rs b/client/basic-authorship/src/basic_authorship.rs index 70633925c5ba6..e79fc1f03a545 100644 --- a/client/basic-authorship/src/basic_authorship.rs +++ b/client/basic-authorship/src/basic_authorship.rs @@ -581,7 +581,7 @@ mod tests { amount: Default::default(), nonce, from: AccountKeyring::Alice.into(), - to: Default::default(), + to: AccountKeyring::Bob.into(), } .into_signed_tx() } @@ -593,7 +593,7 @@ mod tests { amount: 1, nonce: 0, from: pair.public(), - to: Default::default(), + to: AccountKeyring::Bob.into(), }; let signature = pair.sign(&transfer.encode()).into(); Extrinsic::Transfer { transfer, signature, exhaust_resources_when_not_first: true } @@ -777,14 +777,14 @@ mod tests { amount: Default::default(), nonce: 2, from: AccountKeyring::Alice.into(), - to: Default::default(), + to: AccountKeyring::Bob.into(), }.into_resources_exhausting_tx(), extrinsic(3), Transfer { amount: Default::default(), nonce: 4, from: AccountKeyring::Alice.into(), - to: Default::default(), + to: AccountKeyring::Bob.into(), }.into_resources_exhausting_tx(), extrinsic(5), extrinsic(6), diff --git a/client/cli/src/commands/insert_key.rs b/client/cli/src/commands/insert_key.rs index 081c319081607..a979a703f7156 100644 --- a/client/cli/src/commands/insert_key.rs +++ b/client/cli/src/commands/insert_key.rs @@ -99,7 +99,7 @@ fn to_vec(uri: &str, pass: Option) -> Result HashSet { - let voter_id_1 = AuthorityId::from_slice(&[1; 32]); - let voter_id_2 = AuthorityId::from_slice(&[2; 32]); + let voter_id_1 = AuthorityId::from_slice(&[1; 32]).unwrap(); + let voter_id_2 = AuthorityId::from_slice(&[2; 32]).unwrap(); vec![voter_id_1, voter_id_2].into_iter().collect() } @@ -245,7 +245,7 @@ mod tests { impl ReportVoterState for TestVoterState { fn get(&self) -> Option> { - let voter_id_1 = AuthorityId::from_slice(&[1; 32]); + let voter_id_1 = AuthorityId::from_slice(&[1; 32]).unwrap(); let voters_best: HashSet<_> = vec![voter_id_1].into_iter().collect(); let best_round_state = sc_finality_grandpa::report::RoundState { diff --git a/client/finality-grandpa/src/authorities.rs b/client/finality-grandpa/src/authorities.rs index 6eb13099aa202..638257b62a8e0 100644 --- a/client/finality-grandpa/src/authorities.rs +++ b/client/finality-grandpa/src/authorities.rs @@ -753,7 +753,7 @@ impl AuthoritySetChanges { #[cfg(test)] mod tests { use super::*; - use sp_core::crypto::Public; + use sp_core::crypto::{ByteArray, UncheckedFrom}; fn static_is_descendent_of(value: bool) -> impl Fn(&A, &A) -> Result { move |_, _| Ok(value) @@ -768,7 +768,7 @@ mod tests { #[test] fn current_limit_filters_min() { - let current_authorities = vec![(AuthorityId::from_slice(&[1; 32]), 1)]; + let current_authorities = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 1)]; let mut authorities = AuthoritySet { current_authorities: current_authorities.clone(), @@ -802,7 +802,7 @@ mod tests { #[test] fn changes_iterated_in_pre_order() { - let current_authorities = vec![(AuthorityId::from_slice(&[1; 32]), 1)]; + let current_authorities = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 1)]; let mut authorities = AuthoritySet { current_authorities: current_authorities.clone(), @@ -894,8 +894,8 @@ mod tests { authority_set_changes: AuthoritySetChanges::empty(), }; - let set_a = vec![(AuthorityId::from_slice(&[1; 32]), 5)]; - let set_b = vec![(AuthorityId::from_slice(&[2; 32]), 5)]; + let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 5)]; + let set_b = vec![(AuthorityId::from_slice(&[2; 32]).unwrap(), 5)]; // two competing changes at the same height on different forks let change_a = PendingChange { @@ -977,8 +977,8 @@ mod tests { authority_set_changes: AuthoritySetChanges::empty(), }; - let set_a = vec![(AuthorityId::from_slice(&[1; 32]), 5)]; - let set_c = vec![(AuthorityId::from_slice(&[2; 32]), 5)]; + let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 5)]; + let set_c = vec![(AuthorityId::from_slice(&[2; 32]).unwrap(), 5)]; // two competing changes at the same height on different forks let change_a = PendingChange { @@ -1057,7 +1057,7 @@ mod tests { authority_set_changes: AuthoritySetChanges::empty(), }; - let set_a = vec![(AuthorityId::from_slice(&[1; 32]), 5)]; + let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 5)]; let change_a = PendingChange { next_authorities: set_a.clone(), @@ -1128,8 +1128,8 @@ mod tests { authority_set_changes: AuthoritySetChanges::empty(), }; - let set_a = vec![(AuthorityId::from_slice(&[1; 32]), 5)]; - let set_b = vec![(AuthorityId::from_slice(&[2; 32]), 5)]; + let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 5)]; + let set_b = vec![(AuthorityId::from_slice(&[2; 32]).unwrap(), 5)]; let change_a = PendingChange { next_authorities: set_a.clone(), @@ -1228,7 +1228,7 @@ mod tests { authority_set_changes: AuthoritySetChanges::empty(), }; - let set_a = vec![(AuthorityId::from_slice(&[1; 32]), 5)]; + let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 5)]; // we create a forced change with no delay let change_a = PendingChange { @@ -1253,7 +1253,7 @@ mod tests { #[test] fn forced_changes_blocked_by_standard_changes() { - let set_a = vec![(AuthorityId::from_slice(&[1; 32]), 1)]; + let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 1)]; let mut authorities = AuthoritySet { current_authorities: set_a.clone(), @@ -1378,7 +1378,7 @@ mod tests { #[test] fn next_change_works() { - let current_authorities = vec![(AuthorityId::from_slice(&[1; 32]), 1)]; + let current_authorities = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 1)]; let mut authorities = AuthoritySet { current_authorities: current_authorities.clone(), @@ -1494,7 +1494,7 @@ mod tests { ); let invalid_authorities_weight = - vec![(AuthorityId::from_slice(&[1; 32]), 5), (AuthorityId::from_slice(&[2; 32]), 0)]; + vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 5), (AuthorityId::from_slice(&[2; 32]).unwrap(), 0)]; // authority weight of zero is invalid assert_eq!(AuthoritySet::<(), ()>::genesis(invalid_authorities_weight.clone()), None); @@ -1510,7 +1510,7 @@ mod tests { ); let mut authority_set = - AuthoritySet::<(), u64>::genesis(vec![(AuthorityId::from_slice(&[1; 32]), 5)]).unwrap(); + AuthoritySet::<(), u64>::genesis(vec![(AuthorityId::unchecked_from([1; 32]), 5)]).unwrap(); let invalid_change_empty_authorities = PendingChange { next_authorities: vec![], @@ -1550,7 +1550,7 @@ mod tests { #[test] fn cleans_up_stale_forced_changes_when_applying_standard_change() { - let current_authorities = vec![(AuthorityId::from_slice(&[1; 32]), 1)]; + let current_authorities = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 1)]; let mut authorities = AuthoritySet { current_authorities: current_authorities.clone(), diff --git a/client/finality-grandpa/src/aux_schema.rs b/client/finality-grandpa/src/aux_schema.rs index bad01e6dfc62f..b1b2557fbba6e 100644 --- a/client/finality-grandpa/src/aux_schema.rs +++ b/client/finality-grandpa/src/aux_schema.rs @@ -498,15 +498,19 @@ pub(crate) fn load_authorities( #[cfg(test)] mod test { use super::*; - use sp_core::H256; + use sp_core::{H256, crypto::UncheckedFrom}; use sp_finality_grandpa::AuthorityId; use substrate_test_runtime_client; + fn dummy_id() -> AuthorityId { + AuthorityId::unchecked_from([1; 32]) + } + #[test] fn load_decode_from_v0_migrates_data_format() { let client = substrate_test_runtime_client::new(); - let authorities = vec![(AuthorityId::default(), 100)]; + let authorities = vec![(dummy_id(), 100)]; let set_id = 3; let round_number: RoundNumber = 42; let round_state = RoundState:: { @@ -595,7 +599,7 @@ mod test { fn load_decode_from_v1_migrates_data_format() { let client = substrate_test_runtime_client::new(); - let authorities = vec![(AuthorityId::default(), 100)]; + let authorities = vec![(dummy_id(), 100)]; let set_id = 3; let round_number: RoundNumber = 42; let round_state = RoundState:: { @@ -688,7 +692,7 @@ mod test { fn load_decode_from_v2_migrates_data_format() { let client = substrate_test_runtime_client::new(); - let authorities = vec![(AuthorityId::default(), 100)]; + let authorities = vec![(dummy_id(), 100)]; let set_id = 3; { diff --git a/client/finality-grandpa/src/communication/gossip.rs b/client/finality-grandpa/src/communication/gossip.rs index 2e50a3bac01d9..3135fe7112bb4 100644 --- a/client/finality-grandpa/src/communication/gossip.rs +++ b/client/finality-grandpa/src/communication/gossip.rs @@ -1670,7 +1670,7 @@ mod tests { use sc_network::config::Role; use sc_network_gossip::Validator as GossipValidatorT; use sc_network_test::Block; - use sp_core::{crypto::Public, H256}; + use sp_core::{crypto::UncheckedFrom, H256}; // some random config (not really needed) fn config() -> crate::Config { @@ -1691,7 +1691,7 @@ mod tests { let base = (H256::zero(), 0); - let voters = vec![(AuthorityId::from_slice(&[1; 32]), 1)]; + let voters = vec![(AuthorityId::unchecked_from([1; 32]), 1)]; let voters = AuthoritySet::genesis(voters).unwrap(); let set_state = VoterSetState::live(0, &voters, base); @@ -1861,7 +1861,7 @@ mod tests { let (val, _) = GossipValidator::::new(config(), voter_set_state(), None, None); let set_id = 1; - let auth = AuthorityId::from_slice(&[1u8; 32]); + let auth = AuthorityId::unchecked_from([1u8; 32]); let peer = PeerId::random(); val.note_set(SetId(set_id), vec![auth.clone()], |_, _| {}); @@ -1878,8 +1878,8 @@ mod tests { target_hash: Default::default(), target_number: 10, }), - signature: Default::default(), - id: AuthorityId::from_slice(&[2u8; 32]), + signature: UncheckedFrom::unchecked_from([1; 64]), + id: UncheckedFrom::unchecked_from([2u8; 32]), }, }, ); @@ -1894,7 +1894,7 @@ mod tests { target_hash: Default::default(), target_number: 10, }), - signature: Default::default(), + signature: UncheckedFrom::unchecked_from([1; 64]), id: auth.clone(), }, }, @@ -1909,7 +1909,7 @@ mod tests { let (val, _) = GossipValidator::::new(config(), voter_set_state(), None, None); let set_id = 1; - let auth = AuthorityId::from_slice(&[1u8; 32]); + let auth = AuthorityId::unchecked_from([1u8; 32]); let peer = PeerId::random(); val.note_set(SetId(set_id), vec![auth.clone()], |_, _| {}); @@ -1972,7 +1972,7 @@ mod tests { let (val, _) = GossipValidator::::new(config(), set_state.clone(), None, None); let set_id = 1; - let auth = AuthorityId::from_slice(&[1u8; 32]); + let auth = AuthorityId::unchecked_from([1u8; 32]); let peer = PeerId::random(); val.note_set(SetId(set_id), vec![auth.clone()], |_, _| {}); @@ -2550,12 +2550,12 @@ mod tests { fn allow_noting_different_authorities_for_same_set() { let (val, _) = GossipValidator::::new(config(), voter_set_state(), None, None); - let a1 = vec![AuthorityId::from_slice(&[0; 32])]; + let a1 = vec![UncheckedFrom::unchecked_from([0; 32])]; val.note_set(SetId(1), a1.clone(), |_, _| {}); assert_eq!(val.inner().read().authorities, a1); - let a2 = vec![AuthorityId::from_slice(&[1; 32]), AuthorityId::from_slice(&[2; 32])]; + let a2 = vec![UncheckedFrom::unchecked_from([1; 32]), UncheckedFrom::unchecked_from([2; 32])]; val.note_set(SetId(1), a2.clone(), |_, _| {}); assert_eq!(val.inner().read().authorities, a2); diff --git a/client/finality-grandpa/src/communication/tests.rs b/client/finality-grandpa/src/communication/tests.rs index 1fac0230b2a84..1e88f8a934047 100644 --- a/client/finality-grandpa/src/communication/tests.rs +++ b/client/finality-grandpa/src/communication/tests.rs @@ -155,13 +155,13 @@ fn config() -> crate::Config { fn voter_set_state() -> SharedVoterSetState { use crate::{authorities::AuthoritySet, environment::VoterSetState}; use finality_grandpa::round::State as RoundState; - use sp_core::{crypto::Public, H256}; + use sp_core::{crypto::ByteArray, H256}; use sp_finality_grandpa::AuthorityId; let state = RoundState::genesis((H256::zero(), 0)); let base = state.prevote_ghost.unwrap(); - let voters = vec![(AuthorityId::from_slice(&[1; 32]), 1)]; + let voters = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 1)]; let voters = AuthoritySet::genesis(voters).unwrap(); let set_state = VoterSetState::live(0, &voters, base); diff --git a/client/finality-grandpa/src/finality_proof.rs b/client/finality-grandpa/src/finality_proof.rs index 1e20c2edc3a6e..ac7be37eb20ca 100644 --- a/client/finality-grandpa/src/finality_proof.rs +++ b/client/finality-grandpa/src/finality_proof.rs @@ -243,8 +243,8 @@ pub(crate) mod tests { use sc_block_builder::BlockBuilderProvider; use sc_client_api::{apply_aux, LockImportRun}; use sp_consensus::BlockOrigin; - use sp_core::crypto::Public; - use sp_finality_grandpa::{AuthorityId, GRANDPA_ENGINE_ID as ID}; + use sp_core::crypto::UncheckedFrom; + use sp_finality_grandpa::GRANDPA_ENGINE_ID as ID; use sp_keyring::Ed25519Keyring; use substrate_test_runtime_client::{ runtime::{Block, Header, H256}, @@ -350,7 +350,7 @@ pub(crate) mod tests { // When we can't decode proof from Vec check_finality_proof::( 1, - vec![(AuthorityId::from_slice(&[3u8; 32]), 1u64)], + vec![(UncheckedFrom::unchecked_from([3u8; 32]), 1u64)], vec![42], ) .unwrap_err(); @@ -361,7 +361,7 @@ pub(crate) mod tests { // When decoded proof has zero length check_finality_proof::( 1, - vec![(AuthorityId::from_slice(&[3u8; 32]), 1u64)], + vec![(UncheckedFrom::unchecked_from([3u8; 32]), 1u64)], Vec::>::new().encode(), ) .unwrap_err(); @@ -387,7 +387,7 @@ pub(crate) mod tests { check_finality_proof::( 1, - vec![(AuthorityId::from_slice(&[3u8; 32]), 1u64)], + vec![(UncheckedFrom::unchecked_from([3u8; 32]), 1u64)], finality_proof.encode(), ) .unwrap_err(); diff --git a/client/finality-grandpa/src/tests.rs b/client/finality-grandpa/src/tests.rs index 8439bf6963d01..7af02d066be32 100644 --- a/client/finality-grandpa/src/tests.rs +++ b/client/finality-grandpa/src/tests.rs @@ -1671,7 +1671,7 @@ fn grandpa_environment_doesnt_send_equivocation_reports_for_itself() { // if we set the equivocation offender to another id for which we don't have // keys it should work - equivocation.identity = Default::default(); + equivocation.identity = TryFrom::try_from(&[1; 32][..]).unwrap(); let equivocation_proof = sp_finality_grandpa::Equivocation::Prevote(equivocation); assert!(environment.report_equivocation(equivocation_proof).is_ok()); } diff --git a/client/finality-grandpa/src/until_imported.rs b/client/finality-grandpa/src/until_imported.rs index deb6577264347..f11f19a677761 100644 --- a/client/finality-grandpa/src/until_imported.rs +++ b/client/finality-grandpa/src/until_imported.rs @@ -562,6 +562,7 @@ mod tests { use futures_timer::Delay; use sc_client_api::BlockImportNotification; use sc_utils::mpsc::{tracing_unbounded, TracingUnboundedSender}; + use sp_core::crypto::UncheckedFrom; use sp_consensus::BlockOrigin; use substrate_test_runtime_client::runtime::{Block, Hash, Header}; @@ -796,8 +797,8 @@ mod tests { let h3 = make_header(7); let signed_prevote = |header: &Header| finality_grandpa::SignedPrevote { - id: Default::default(), - signature: Default::default(), + id: UncheckedFrom::unchecked_from([1; 32]), + signature: UncheckedFrom::unchecked_from([1; 64]), prevote: finality_grandpa::Prevote { target_hash: header.hash(), target_number: *header.number(), @@ -805,8 +806,8 @@ mod tests { }; let signed_precommit = |header: &Header| finality_grandpa::SignedPrecommit { - id: Default::default(), - signature: Default::default(), + id: UncheckedFrom::unchecked_from([1; 32]), + signature: UncheckedFrom::unchecked_from([1; 64]), precommit: finality_grandpa::Precommit { target_hash: header.hash(), target_number: *header.number(), @@ -844,8 +845,8 @@ mod tests { let h3 = make_header(7); let signed_prevote = |header: &Header| finality_grandpa::SignedPrevote { - id: Default::default(), - signature: Default::default(), + id: UncheckedFrom::unchecked_from([1; 32]), + signature: UncheckedFrom::unchecked_from([1; 64]), prevote: finality_grandpa::Prevote { target_hash: header.hash(), target_number: *header.number(), @@ -853,8 +854,8 @@ mod tests { }; let signed_precommit = |header: &Header| finality_grandpa::SignedPrecommit { - id: Default::default(), - signature: Default::default(), + id: UncheckedFrom::unchecked_from([1; 32]), + signature: UncheckedFrom::unchecked_from([1; 64]), precommit: finality_grandpa::Precommit { target_hash: header.hash(), target_number: *header.number(), diff --git a/client/rpc/src/author/tests.rs b/client/rpc/src/author/tests.rs index 2349e08fee506..480a3d288ffe2 100644 --- a/client/rpc/src/author/tests.rs +++ b/client/rpc/src/author/tests.rs @@ -24,7 +24,7 @@ use futures::executor; use sc_transaction_pool::{BasicPool, FullChainApi}; use sp_core::{ blake2_256, - crypto::{CryptoTypePublicPair, Pair, Public}, + crypto::{CryptoTypePublicPair, Pair, ByteArray}, ed25519, hexdisplay::HexDisplay, sr25519, @@ -41,7 +41,7 @@ use substrate_test_runtime_client::{ fn uxt(sender: AccountKeyring, nonce: u64) -> Extrinsic { let tx = - Transfer { amount: Default::default(), nonce, from: sender.into(), to: Default::default() }; + Transfer { amount: Default::default(), nonce, from: sender.into(), to: AccountKeyring::Bob.into() }; tx.into_signed_tx() } @@ -133,7 +133,7 @@ fn should_watch_extrinsic() { amount: 5, nonce: 0, from: AccountKeyring::Alice.into(), - to: Default::default(), + to: AccountKeyring::Bob.into(), }; tx.into_signed_tx() }; diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 563846c75d89a..9cf5cc69bdc35 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -576,7 +576,7 @@ mod tests { amount: 5, nonce: 0, from: AccountKeyring::Alice.into(), - to: Default::default(), + to: AccountKeyring::Bob.into(), } .into_signed_tx(); block_on(pool.submit_one(&BlockId::hash(best.hash()), source, transaction.clone())) diff --git a/client/transaction-pool/src/graph/pool.rs b/client/transaction-pool/src/graph/pool.rs index 2af5a8a19a5a9..e8b73925cb3b8 100644 --- a/client/transaction-pool/src/graph/pool.rs +++ b/client/transaction-pool/src/graph/pool.rs @@ -587,9 +587,10 @@ mod tests { } fn uxt(transfer: Transfer) -> Extrinsic { + let signature = TryFrom::try_from(&[0; 64][..]).unwrap(); Extrinsic::Transfer { transfer, - signature: Default::default(), + signature, exhaust_resources_when_not_first: false, } } diff --git a/frame/authorship/src/lib.rs b/frame/authorship/src/lib.rs index 12a8c6de85030..3a8ded4c57750 100644 --- a/frame/authorship/src/lib.rs +++ b/frame/authorship/src/lib.rs @@ -688,7 +688,7 @@ mod tests { header.digest_mut().pop(); // pop the seal off. System::initialize(&1, &Default::default(), header.digest(), Default::default()); - assert_eq!(Authorship::author(), author); + assert_eq!(Authorship::author(), Some(author)); }); } diff --git a/frame/beefy/src/lib.rs b/frame/beefy/src/lib.rs index 6a7118c1f5c96..c18b28901bb62 100644 --- a/frame/beefy/src/lib.rs +++ b/frame/beefy/src/lib.rs @@ -47,7 +47,7 @@ pub mod pallet { #[pallet::config] pub trait Config: frame_system::Config { /// Authority identifier type - type BeefyId: Member + Parameter + RuntimeAppPublic + Default + MaybeSerializeDeserialize; + type BeefyId: Member + Parameter + RuntimeAppPublic + MaybeSerializeDeserialize; } #[pallet::pallet] diff --git a/frame/examples/offchain-worker/src/tests.rs b/frame/examples/offchain-worker/src/tests.rs index 1dde8a1df60c8..6b6792667abb6 100644 --- a/frame/examples/offchain-worker/src/tests.rs +++ b/frame/examples/offchain-worker/src/tests.rs @@ -124,15 +124,19 @@ impl Config for Test { type UnsignedPriority = UnsignedPriority; } +fn test_pub() -> sp_core::sr25519::Public { + sp_core::sr25519::Public::from_raw([1u8; 32]) +} + #[test] fn it_aggregates_the_price() { sp_io::TestExternalities::default().execute_with(|| { assert_eq!(Example::average_price(), None); - assert_ok!(Example::submit_price(Origin::signed(Default::default()), 27)); + assert_ok!(Example::submit_price(Origin::signed(test_pub()), 27)); assert_eq!(Example::average_price(), Some(27)); - assert_ok!(Example::submit_price(Origin::signed(Default::default()), 43)); + assert_ok!(Example::submit_price(Origin::signed(test_pub()), 43)); assert_eq!(Example::average_price(), Some(35)); }); } diff --git a/frame/examples/parallel/src/tests.rs b/frame/examples/parallel/src/tests.rs index 4c36f0d6eb858..548ee915bf721 100644 --- a/frame/examples/parallel/src/tests.rs +++ b/frame/examples/parallel/src/tests.rs @@ -80,6 +80,14 @@ impl Config for Test { type Call = Call; } +fn test_pub(n: u8) -> sp_core::sr25519::Public { + sp_core::sr25519::Public::from_raw([n; 32]) +} + +fn test_origin(n: u8) -> Origin { + Origin::signed(test_pub(n)) +} + #[test] fn it_can_enlist() { use sp_core::Pair; @@ -90,7 +98,7 @@ fn it_can_enlist() { let event_name = b"test"; - Example::run_event(Origin::signed(Default::default()), event_name.to_vec()) + Example::run_event(test_origin(1), event_name.to_vec()) .expect("Failed to enlist"); let participants = vec![ @@ -104,7 +112,7 @@ fn it_can_enlist() { }, ]; - Example::enlist_participants(Origin::signed(Default::default()), participants) + Example::enlist_participants(Origin::signed(test_pub(1)), participants) .expect("Failed to enlist"); assert_eq!(Example::participants().len(), 2); @@ -122,7 +130,7 @@ fn one_wrong_will_not_enlist_anyone() { let event_name = b"test"; - Example::run_event(Origin::signed(Default::default()), event_name.to_vec()) + Example::run_event(test_origin(1), event_name.to_vec()) .expect("Failed to enlist"); let participants = vec![ @@ -141,7 +149,7 @@ fn one_wrong_will_not_enlist_anyone() { }, ]; - Example::enlist_participants(Origin::signed(Default::default()), participants) + Example::enlist_participants(test_origin(1), participants) .expect("Failed to enlist"); assert_eq!(Example::participants().len(), 0); diff --git a/frame/sudo/src/mock.rs b/frame/sudo/src/mock.rs index bfbed0d38ab34..df958aaac8423 100644 --- a/frame/sudo/src/mock.rs +++ b/frame/sudo/src/mock.rs @@ -164,7 +164,7 @@ pub type LoggerCall = logger::Call; // Build test environment by setting the root `key` for the Genesis. pub fn new_test_ext(root_key: u64) -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - sudo::GenesisConfig:: { key: root_key } + sudo::GenesisConfig:: { key: Some(root_key) } .assimilate_storage(&mut t) .unwrap(); t.into() diff --git a/frame/sudo/src/tests.rs b/frame/sudo/src/tests.rs index 3fd199a1c8ca3..8821879061677 100644 --- a/frame/sudo/src/tests.rs +++ b/frame/sudo/src/tests.rs @@ -28,7 +28,7 @@ use mock::{ fn test_setup_works() { // Environment setup, logger storage, and sudo `key` retrieval should work as expected. new_test_ext(1).execute_with(|| { - assert_eq!(Sudo::key(), 1u64); + assert_eq!(Sudo::key(), Some(1u64)); assert!(Logger::i32_log().is_empty()); assert!(Logger::account_log().is_empty()); }); @@ -105,7 +105,7 @@ fn set_key_basics() { new_test_ext(1).execute_with(|| { // A root `key` can change the root `key` assert_ok!(Sudo::set_key(Origin::signed(1), 2)); - assert_eq!(Sudo::key(), 2u64); + assert_eq!(Sudo::key(), Some(2u64)); }); new_test_ext(1).execute_with(|| { @@ -123,10 +123,10 @@ fn set_key_emits_events_correctly() { // A root `key` can change the root `key`. assert_ok!(Sudo::set_key(Origin::signed(1), 2)); - System::assert_has_event(TestEvent::Sudo(Event::KeyChanged { new_sudoer: 1 })); + System::assert_has_event(TestEvent::Sudo(Event::KeyChanged { old_sudoer: Some(1) })); // Double check. assert_ok!(Sudo::set_key(Origin::signed(2), 4)); - System::assert_has_event(TestEvent::Sudo(Event::KeyChanged { new_sudoer: 2 })); + System::assert_has_event(TestEvent::Sudo(Event::KeyChanged { old_sudoer: Some(2) })); }); } diff --git a/frame/support/test/tests/construct_runtime.rs b/frame/support/test/tests/construct_runtime.rs index 2d14da04f64b7..b2717b0f095ca 100644 --- a/frame/support/test/tests/construct_runtime.rs +++ b/frame/support/test/tests/construct_runtime.rs @@ -229,6 +229,10 @@ pub type AccountId = ::Signer; pub type BlockNumber = u64; pub type Index = u64; +fn test_pub() -> AccountId { + AccountId::from_raw([0; 32]) +} + impl system::Config for Runtime { type BaseCallFilter = frame_support::traits::Everything; type Hash = H256; @@ -451,13 +455,13 @@ fn event_codec() { let event = system::Event::::ExtrinsicSuccess; assert_eq!(Event::from(event).encode()[0], 30); - let event = module1::Event::::A(Default::default()); + let event = module1::Event::::A(test_pub()); assert_eq!(Event::from(event).encode()[0], 31); let event = module2::Event::A; assert_eq!(Event::from(event).encode()[0], 32); - let event = module1::Event::::A(Default::default()); + let event = module1::Event::::A(test_pub()); assert_eq!(Event::from(event).encode()[0], 33); let event = nested::module3::Event::A; @@ -466,19 +470,19 @@ fn event_codec() { let event = module3::Event::A; assert_eq!(Event::from(event).encode()[0], 35); - let event = module1::Event::::A(Default::default()); + let event = module1::Event::::A(test_pub()); assert_eq!(Event::from(event).encode()[0], 4); - let event = module1::Event::::A(Default::default()); + let event = module1::Event::::A(test_pub()); assert_eq!(Event::from(event).encode()[0], 1); - let event = module1::Event::::A(Default::default()); + let event = module1::Event::::A(test_pub()); assert_eq!(Event::from(event).encode()[0], 2); - let event = module1::Event::::A(Default::default()); + let event = module1::Event::::A(test_pub()); assert_eq!(Event::from(event).encode()[0], 12); - let event = module1::Event::::A(Default::default()); + let event = module1::Event::::A(test_pub()); assert_eq!(Event::from(event).encode()[0], 13); } diff --git a/primitives/api/test/tests/runtime_calls.rs b/primitives/api/test/tests/runtime_calls.rs index e32290b12a599..449f9ebbcb4f7 100644 --- a/primitives/api/test/tests/runtime_calls.rs +++ b/primitives/api/test/tests/runtime_calls.rs @@ -187,7 +187,7 @@ fn record_proof_works() { amount: 1000, nonce: 0, from: AccountKeyring::Alice.into(), - to: Default::default(), + to: AccountKeyring::Bob.into(), } .into_signed_tx(); diff --git a/primitives/application-crypto/src/lib.rs b/primitives/application-crypto/src/lib.rs index a511219fd229e..e9edb16772f3e 100644 --- a/primitives/application-crypto/src/lib.rs +++ b/primitives/application-crypto/src/lib.rs @@ -27,7 +27,7 @@ pub use sp_core::crypto::{DeriveJunction, Pair, SecretStringError, Ss58Codec}; #[doc(hidden)] pub use sp_core::{ self, - crypto::{CryptoType, CryptoTypePublicPair, Derive, IsWrappedBy, Public, Wraps, ByteArray}, + crypto::{CryptoType, CryptoTypePublicPair, Derive, IsWrappedBy, Public, Wraps, ByteArray, UncheckedFrom}, RuntimeDebug, }; @@ -515,11 +515,19 @@ macro_rules! app_crypto_signature_common { type Generic = $sig; } + impl<'a> $crate::TryFrom<&'a [u8]> for Signature { + type Error = (); + + fn try_from(data: &'a [u8]) -> Result { + <$sig>::try_from(data).map(Into::into) + } + } + impl $crate::TryFrom<$crate::Vec> for Signature { type Error = (); fn try_from(data: $crate::Vec) -> Result { - Ok(<$sig>::try_from(data.as_slice())?.into()) + Self::try_from(&data[..]) } } }; diff --git a/primitives/core/src/crypto.rs b/primitives/core/src/crypto.rs index 83fb31ed73141..0af19efec104c 100644 --- a/primitives/core/src/crypto.rs +++ b/primitives/core/src/crypto.rs @@ -1042,17 +1042,22 @@ mod tests { impl<'a> TryFrom<&'a [u8]> for TestPublic { type Error = (); - fn try_from(_: &'a [u8]) -> Result { - Ok(Self) + fn try_from(data: &'a [u8]) -> Result { + Self::from_slice(data) } } impl CryptoType for TestPublic { type Pair = TestPair; } impl Derive for TestPublic {} - impl Public for TestPublic { - fn from_slice(_bytes: &[u8]) -> Self { - Self + impl ByteArray for TestPublic { + const LEN: usize = 0; + fn from_slice(bytes: &[u8]) -> Result { + if bytes.len() == 0 { + Ok(Self) + } else { + Err(()) + } } fn as_slice(&self) -> &[u8] { &[] @@ -1060,6 +1065,8 @@ mod tests { fn to_raw_vec(&self) -> Vec { vec![] } + } + impl Public for TestPublic { fn to_public_crypto_pair(&self) -> CryptoTypePublicPair { CryptoTypePublicPair(CryptoTypeId(*b"dumm"), self.to_raw_vec()) } diff --git a/primitives/core/src/ecdsa.rs b/primitives/core/src/ecdsa.rs index 4f61c6a77eb15..325853e4750b5 100644 --- a/primitives/core/src/ecdsa.rs +++ b/primitives/core/src/ecdsa.rs @@ -329,6 +329,12 @@ impl sp_std::hash::Hash for Signature { } } +impl UncheckedFrom<[u8; 65]> for Signature { + fn unchecked_from(data: [u8; 65]) -> Signature { + Signature(data) + } +} + impl Signature { /// A new instance from the given 65-byte `data`. /// diff --git a/primitives/core/src/ed25519.rs b/primitives/core/src/ed25519.rs index d20c4e8ae7b74..0f69d54337664 100644 --- a/primitives/core/src/ed25519.rs +++ b/primitives/core/src/ed25519.rs @@ -313,6 +313,12 @@ impl sp_std::hash::Hash for Signature { } } +impl UncheckedFrom<[u8; 64]> for Signature { + fn unchecked_from(data: [u8; 64]) -> Signature { + Signature(data) + } +} + impl Signature { /// A new instance from the given 64-byte `data`. /// diff --git a/primitives/core/src/sr25519.rs b/primitives/core/src/sr25519.rs index 2b4725769366a..709dbef8c6a33 100644 --- a/primitives/core/src/sr25519.rs +++ b/primitives/core/src/sr25519.rs @@ -334,6 +334,12 @@ pub struct LocalizedSignature { pub signature: Signature, } +impl UncheckedFrom<[u8; 64]> for Signature { + fn unchecked_from(data: [u8; 64]) -> Signature { + Signature(data) + } +} + impl Signature { /// A new instance from the given 64-byte `data`. /// diff --git a/primitives/io/src/lib.rs b/primitives/io/src/lib.rs index e4f52fd4e0e21..e66392a53b851 100644 --- a/primitives/io/src/lib.rs +++ b/primitives/io/src/lib.rs @@ -1517,6 +1517,7 @@ pub type SubstrateHostFunctions = ( mod tests { use super::*; use sp_core::{map, storage::Storage, testing::TaskExecutor, traits::TaskExecutorExt}; + use sp_core::crypto::UncheckedInto; use sp_state_machine::BasicExternalities; use std::any::TypeId; @@ -1617,7 +1618,7 @@ mod tests { } // push invlaid - crypto::sr25519_batch_verify(&Default::default(), &Vec::new(), &Default::default()); + crypto::sr25519_batch_verify(&zero_sr_sig(), &Vec::new(), &zero_sr_pub()); assert!(!crypto::finish_batch_verify()); crypto::start_batch_verify(); @@ -1630,14 +1631,31 @@ mod tests { }); } + fn zero_ed_pub() -> ed25519::Public { + [0u8; 32].unchecked_into() + } + + fn zero_ed_sig() -> ed25519::Signature { + ed25519::Signature::from_raw([0u8; 64]) + } + + fn zero_sr_pub() -> sr25519::Public { + [0u8; 32].unchecked_into() + } + + fn zero_sr_sig() -> sr25519::Signature { + sr25519::Signature::from_raw([0u8; 64]) + } + #[test] fn batching_works() { let mut ext = BasicExternalities::default(); ext.register_extension(TaskExecutorExt::new(TaskExecutor::new())); + ext.execute_with(|| { // invalid ed25519 signature crypto::start_batch_verify(); - crypto::ed25519_batch_verify(&Default::default(), &Vec::new(), &Default::default()); + crypto::ed25519_batch_verify(&zero_ed_sig(), &Vec::new(), &zero_ed_pub()); assert!(!crypto::finish_batch_verify()); // 2 valid ed25519 signatures @@ -1663,7 +1681,7 @@ mod tests { let signature = pair.sign(msg); crypto::ed25519_batch_verify(&signature, msg, &pair.public()); - crypto::ed25519_batch_verify(&Default::default(), &Vec::new(), &Default::default()); + crypto::ed25519_batch_verify(&zero_ed_sig(), &Vec::new(), &zero_ed_pub()); assert!(!crypto::finish_batch_verify()); @@ -1695,7 +1713,7 @@ mod tests { let signature = pair.sign(msg); crypto::sr25519_batch_verify(&signature, msg, &pair.public()); - crypto::sr25519_batch_verify(&Default::default(), &Vec::new(), &Default::default()); + crypto::sr25519_batch_verify(&zero_sr_sig(), &Vec::new(), &zero_sr_pub()); assert!(!crypto::finish_batch_verify()); }); diff --git a/primitives/npos-elections/src/tests.rs b/primitives/npos-elections/src/tests.rs index c745ee1d7706d..0aac5c3c35df4 100644 --- a/primitives/npos-elections/src/tests.rs +++ b/primitives/npos-elections/src/tests.rs @@ -192,7 +192,6 @@ fn balancing_core_works() { #[test] fn voter_normalize_ops_works() { use crate::{Candidate, Edge}; - use sp_std::{cell::RefCell, rc::Rc}; // normalize { let c1 = Candidate { who: 10, elected: false, ..Default::default() }; diff --git a/primitives/runtime/src/lib.rs b/primitives/runtime/src/lib.rs index 081b5480c75d4..bcbe3bd7f6123 100644 --- a/primitives/runtime/src/lib.rs +++ b/primitives/runtime/src/lib.rs @@ -913,7 +913,7 @@ impl TransactionOutcome { mod tests { use super::*; use codec::{Decode, Encode}; - use sp_core::crypto::Pair; + use sp_core::crypto::{Pair, UncheckedFrom}; #[test] fn opaque_extrinsic_serialization() { @@ -997,7 +997,9 @@ mod tests { ext.execute_with(|| { let _batching = SignatureBatching::start(); - sp_io::crypto::sr25519_verify(&Default::default(), &Vec::new(), &Default::default()); + let dummy = UncheckedFrom::unchecked_from([1; 32]); + let dummy_sig = UncheckedFrom::unchecked_from([1; 64]); + sp_io::crypto::sr25519_verify(&dummy_sig, &Vec::new(), &dummy); }); } diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 1409e94e6da7c..f9d87668ef737 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -1622,7 +1622,7 @@ pub trait BlockNumberProvider { mod tests { use super::*; use crate::codec::{Decode, Encode, Input}; - use sp_core::{crypto::Pair, ecdsa}; + use sp_core::{crypto::{Pair, UncheckedFrom}, ecdsa}; mod t { use sp_application_crypto::{app_crypto, sr25519}; @@ -1635,8 +1635,8 @@ mod tests { use super::AppVerify; use t::*; - let s = Signature::default(); - let _ = s.verify(&[0u8; 100][..], &Public::default()); + let s = Signature::try_from(vec![0; 64]).unwrap(); + let _ = s.verify(&[0u8; 100][..], &Public::unchecked_from([0; 32])); } #[derive(Encode, Decode, Default, PartialEq, Debug)] From c12d8cfd3bb0d870338335ae4acc2601b4491d81 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 7 Dec 2021 12:53:35 +0100 Subject: [PATCH 21/47] Fix imonline tests --- bin/node/runtime/src/lib.rs | 2 +- frame/im-online/src/mock.rs | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 2cf6548b79211..d3334e7a36bad 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1782,7 +1782,7 @@ mod tests { #[test] fn call_size() { assert!( - core::mem::size_of::() <= 200, + core::mem::size_of::() <= 208, "size of Call is more than 200 bytes: some calls have too big arguments, use Box to reduce the size of Call. If the limit is too strong, maybe consider increase the limit to 300.", diff --git a/frame/im-online/src/mock.rs b/frame/im-online/src/mock.rs index 1e4d4b43d5789..171941999a90f 100644 --- a/frame/im-online/src/mock.rs +++ b/frame/im-online/src/mock.rs @@ -106,7 +106,15 @@ impl ReportOffence for OffenceHandler { pub fn new_test_ext() -> sp_io::TestExternalities { let t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - t.into() + let mut result: sp_io::TestExternalities = t.into(); + // Set the default keys, otherwise session will discard the validator. + result.execute_with(|| { + for i in 1..=6 { + System::inc_providers(&i); + assert_eq!(Session::set_keys(Origin::signed(i), (i - 1).into(), vec![]), Ok(())); + } + }); + result } parameter_types! { From 2cfd1d0bdb93e5b2d0545ea3b649275055e43d7a Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 7 Dec 2021 12:54:56 +0100 Subject: [PATCH 22/47] Formatting --- bin/node/executor/tests/submit_transaction.rs | 3 ++- client/cli/src/commands/insert_key.rs | 2 +- client/cli/src/commands/verify.rs | 11 ++++---- client/consensus/aura/src/lib.rs | 2 +- client/consensus/babe/src/verification.rs | 2 +- client/finality-grandpa/src/authorities.rs | 9 ++++--- client/finality-grandpa/src/aux_schema.rs | 2 +- .../src/communication/gossip.rs | 3 ++- client/finality-grandpa/src/lib.rs | 6 +++-- client/finality-grandpa/src/until_imported.rs | 2 +- client/keystore/src/local.rs | 27 ++++++++++++++----- client/rpc/src/author/tests.rs | 10 ++++--- client/transaction-pool/src/graph/pool.rs | 6 +---- frame/authorship/src/lib.rs | 5 +++- frame/benchmarking/src/utils.rs | 6 +---- frame/elections-phragmen/src/lib.rs | 6 +---- frame/examples/parallel/src/lib.rs | 8 +++--- frame/examples/parallel/src/tests.rs | 9 +++---- frame/multisig/src/lib.rs | 5 +++- frame/proxy/src/lib.rs | 5 +++- frame/staking/src/benchmarking.rs | 2 +- frame/staking/src/pallet/impls.rs | 5 +++- frame/tips/src/lib.rs | 8 ++++-- .../asset-tx-payment/src/lib.rs | 3 ++- frame/transaction-payment/src/lib.rs | 4 +-- primitives/application-crypto/src/lib.rs | 5 +++- primitives/core/src/crypto.rs | 5 ++-- primitives/core/src/ecdsa.rs | 3 ++- primitives/core/src/ed25519.rs | 5 +++- primitives/core/src/lib.rs | 2 +- primitives/core/src/sr25519.rs | 4 +-- primitives/io/src/lib.rs | 6 +++-- primitives/keyring/src/ed25519.rs | 2 +- primitives/keyring/src/sr25519.rs | 2 +- primitives/keystore/src/testing.rs | 10 +++---- primitives/npos-elections/src/pjr.rs | 8 +++--- primitives/npos-elections/src/reduce.rs | 4 +-- primitives/runtime/src/testing.rs | 2 +- primitives/runtime/src/traits.rs | 5 +++- .../runtime/transaction-pool/src/lib.rs | 8 ++++-- test-utils/test-runner/src/node.rs | 6 ++++- 41 files changed, 138 insertions(+), 90 deletions(-) diff --git a/bin/node/executor/tests/submit_transaction.rs b/bin/node/executor/tests/submit_transaction.rs index 3ab446ea11521..7315cab2426c2 100644 --- a/bin/node/executor/tests/submit_transaction.rs +++ b/bin/node/executor/tests/submit_transaction.rs @@ -33,7 +33,8 @@ fn should_submit_unsigned_transaction() { t.register_extension(TransactionPoolExt::new(pool)); t.execute_with(|| { - let signature = pallet_im_online::sr25519::AuthoritySignature::try_from(vec![0; 64]).unwrap(); + let signature = + pallet_im_online::sr25519::AuthoritySignature::try_from(vec![0; 64]).unwrap(); let heartbeat_data = pallet_im_online::Heartbeat { block_number: 1, network_state: Default::default(), diff --git a/client/cli/src/commands/insert_key.rs b/client/cli/src/commands/insert_key.rs index a979a703f7156..e85b85f111ad5 100644 --- a/client/cli/src/commands/insert_key.rs +++ b/client/cli/src/commands/insert_key.rs @@ -99,7 +99,7 @@ fn to_vec(uri: &str, pass: Option) -> Result(sig_data: Vec, message: Vec, uri: &str) -> error::Result<()> where +fn verify(sig_data: Vec, message: Vec, uri: &str) -> error::Result<()> +where Pair: sp_core::Pair, - Pair::Signature: for <'a> std::convert::TryFrom<&'a [u8]>, + Pair::Signature: for<'a> std::convert::TryFrom<&'a [u8]>, { - let signature = Pair::Signature::try_from(&sig_data) - .map_err(|_| error::Error::SignatureFormatInvalid)?; + let signature = + Pair::Signature::try_from(&sig_data).map_err(|_| error::Error::SignatureFormatInvalid)?; let pubkey = if let Ok(pubkey_vec) = hex::decode(uri) { Pair::Public::from_slice(pubkey_vec.as_slice()) diff --git a/client/consensus/aura/src/lib.rs b/client/consensus/aura/src/lib.rs index 7f75cc265c03d..0d79e3c4ecf04 100644 --- a/client/consensus/aura/src/lib.rs +++ b/client/consensus/aura/src/lib.rs @@ -57,7 +57,7 @@ use sp_consensus::{ BlockOrigin, CanAuthorWith, Environment, Error as ConsensusError, Proposer, SelectChain, }; use sp_consensus_slots::Slot; -use sp_core::crypto::{Pair, Public, ByteArray}; +use sp_core::crypto::{ByteArray, Pair, Public}; use sp_inherents::CreateInherentDataProviders; use sp_keystore::{SyncCryptoStore, SyncCryptoStorePtr}; use sp_runtime::{ diff --git a/client/consensus/babe/src/verification.rs b/client/consensus/babe/src/verification.rs index 0a87e4b05ba76..13d2f956c8d51 100644 --- a/client/consensus/babe/src/verification.rs +++ b/client/consensus/babe/src/verification.rs @@ -31,7 +31,7 @@ use sp_consensus_babe::{ make_transcript, AuthorityId, AuthorityPair, AuthoritySignature, }; use sp_consensus_slots::Slot; -use sp_core::{Pair, ByteArray}; +use sp_core::{ByteArray, Pair}; use sp_runtime::{traits::Header, DigestItem}; /// BABE verification parameters diff --git a/client/finality-grandpa/src/authorities.rs b/client/finality-grandpa/src/authorities.rs index 638257b62a8e0..6ab36847fe3dd 100644 --- a/client/finality-grandpa/src/authorities.rs +++ b/client/finality-grandpa/src/authorities.rs @@ -1493,8 +1493,10 @@ mod tests { None, ); - let invalid_authorities_weight = - vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 5), (AuthorityId::from_slice(&[2; 32]).unwrap(), 0)]; + let invalid_authorities_weight = vec![ + (AuthorityId::from_slice(&[1; 32]).unwrap(), 5), + (AuthorityId::from_slice(&[2; 32]).unwrap(), 0), + ]; // authority weight of zero is invalid assert_eq!(AuthoritySet::<(), ()>::genesis(invalid_authorities_weight.clone()), None); @@ -1510,7 +1512,8 @@ mod tests { ); let mut authority_set = - AuthoritySet::<(), u64>::genesis(vec![(AuthorityId::unchecked_from([1; 32]), 5)]).unwrap(); + AuthoritySet::<(), u64>::genesis(vec![(AuthorityId::unchecked_from([1; 32]), 5)]) + .unwrap(); let invalid_change_empty_authorities = PendingChange { next_authorities: vec![], diff --git a/client/finality-grandpa/src/aux_schema.rs b/client/finality-grandpa/src/aux_schema.rs index b1b2557fbba6e..9294fbc4161b0 100644 --- a/client/finality-grandpa/src/aux_schema.rs +++ b/client/finality-grandpa/src/aux_schema.rs @@ -498,7 +498,7 @@ pub(crate) fn load_authorities( #[cfg(test)] mod test { use super::*; - use sp_core::{H256, crypto::UncheckedFrom}; + use sp_core::{crypto::UncheckedFrom, H256}; use sp_finality_grandpa::AuthorityId; use substrate_test_runtime_client; diff --git a/client/finality-grandpa/src/communication/gossip.rs b/client/finality-grandpa/src/communication/gossip.rs index 3135fe7112bb4..54c73d4b329e7 100644 --- a/client/finality-grandpa/src/communication/gossip.rs +++ b/client/finality-grandpa/src/communication/gossip.rs @@ -2555,7 +2555,8 @@ mod tests { assert_eq!(val.inner().read().authorities, a1); - let a2 = vec![UncheckedFrom::unchecked_from([1; 32]), UncheckedFrom::unchecked_from([2; 32])]; + let a2 = + vec![UncheckedFrom::unchecked_from([1; 32]), UncheckedFrom::unchecked_from([2; 32])]; val.note_set(SetId(1), a2.clone(), |_, _| {}); assert_eq!(val.inner().read().authorities, a2); diff --git a/client/finality-grandpa/src/lib.rs b/client/finality-grandpa/src/lib.rs index 6d6ba0f9f662d..a55474c2d5ed7 100644 --- a/client/finality-grandpa/src/lib.rs +++ b/client/finality-grandpa/src/lib.rs @@ -763,7 +763,8 @@ where let events = telemetry_on_connect.for_each(move |_| { let current_authorities = authorities.current_authorities(); let set_id = authorities.set_id(); - let maybe_authority_id = local_authority_id(¤t_authorities, conf.keystore.as_ref()); + let maybe_authority_id = + local_authority_id(¤t_authorities, conf.keystore.as_ref()); let authorities = current_authorities.iter().map(|(id, _)| id.to_string()).collect::>(); @@ -916,7 +917,8 @@ where fn rebuild_voter(&mut self) { debug!(target: "afg", "{}: Starting new voter with set ID {}", self.env.config.name(), self.env.set_id); - let maybe_authority_id = local_authority_id(&self.env.voters, self.env.config.keystore.as_ref()); + let maybe_authority_id = + local_authority_id(&self.env.voters, self.env.config.keystore.as_ref()); let authority_id = maybe_authority_id.map_or("".into(), |s| s.to_string()); telemetry!( diff --git a/client/finality-grandpa/src/until_imported.rs b/client/finality-grandpa/src/until_imported.rs index f11f19a677761..b8e051f73fc75 100644 --- a/client/finality-grandpa/src/until_imported.rs +++ b/client/finality-grandpa/src/until_imported.rs @@ -562,8 +562,8 @@ mod tests { use futures_timer::Delay; use sc_client_api::BlockImportNotification; use sc_utils::mpsc::{tracing_unbounded, TracingUnboundedSender}; - use sp_core::crypto::UncheckedFrom; use sp_consensus::BlockOrigin; + use sp_core::crypto::UncheckedFrom; use substrate_test_runtime_client::runtime::{Block, Hash, Header}; #[derive(Clone)] diff --git a/client/keystore/src/local.rs b/client/keystore/src/local.rs index 1e298c83d2500..42a945f8fe3a8 100644 --- a/client/keystore/src/local.rs +++ b/client/keystore/src/local.rs @@ -21,7 +21,9 @@ use async_trait::async_trait; use parking_lot::RwLock; use sp_application_crypto::{ecdsa, ed25519, sr25519, AppKey, AppPair, IsWrappedBy}; use sp_core::{ - crypto::{CryptoTypePublicPair, ExposeSecret, KeyTypeId, Pair as PairT, ByteArray, SecretString}, + crypto::{ + ByteArray, CryptoTypePublicPair, ExposeSecret, KeyTypeId, Pair as PairT, SecretString, + }, sr25519::{Pair as Sr25519Pair, Public as Sr25519Public}, Encode, }; @@ -226,7 +228,11 @@ impl SyncCryptoStore for LocalKeystore { self.0 .read() .raw_public_keys(key_type) - .map(|v| v.into_iter().filter_map(|k| sr25519::Public::from_slice(k.as_slice()).ok()).collect()) + .map(|v| { + v.into_iter() + .filter_map(|k| sr25519::Public::from_slice(k.as_slice()).ok()) + .collect() + }) .unwrap_or_default() } @@ -249,7 +255,11 @@ impl SyncCryptoStore for LocalKeystore { self.0 .read() .raw_public_keys(key_type) - .map(|v| v.into_iter().filter_map(|k| ed25519::Public::from_slice(k.as_slice()).ok()).collect()) + .map(|v| { + v.into_iter() + .filter_map(|k| ed25519::Public::from_slice(k.as_slice()).ok()) + .collect() + }) .unwrap_or_default() } @@ -272,7 +282,11 @@ impl SyncCryptoStore for LocalKeystore { self.0 .read() .raw_public_keys(key_type) - .map(|v| v.into_iter().filter_map(|k| ecdsa::Public::from_slice(k.as_slice()).ok()).collect()) + .map(|v| { + v.into_iter() + .filter_map(|k| ecdsa::Public::from_slice(k.as_slice()).ok()) + .collect() + }) .unwrap_or_default() } @@ -564,8 +578,9 @@ mod tests { } fn public_keys(&self) -> Result> { - self.raw_public_keys(Public::ID) - .map(|v| v.into_iter().filter_map(|k| Public::from_slice(k.as_slice()).ok()).collect()) + self.raw_public_keys(Public::ID).map(|v| { + v.into_iter().filter_map(|k| Public::from_slice(k.as_slice()).ok()).collect() + }) } fn generate(&mut self) -> Result { diff --git a/client/rpc/src/author/tests.rs b/client/rpc/src/author/tests.rs index 480a3d288ffe2..5c1ade96f96b7 100644 --- a/client/rpc/src/author/tests.rs +++ b/client/rpc/src/author/tests.rs @@ -24,7 +24,7 @@ use futures::executor; use sc_transaction_pool::{BasicPool, FullChainApi}; use sp_core::{ blake2_256, - crypto::{CryptoTypePublicPair, Pair, ByteArray}, + crypto::{ByteArray, CryptoTypePublicPair, Pair}, ed25519, hexdisplay::HexDisplay, sr25519, @@ -40,8 +40,12 @@ use substrate_test_runtime_client::{ }; fn uxt(sender: AccountKeyring, nonce: u64) -> Extrinsic { - let tx = - Transfer { amount: Default::default(), nonce, from: sender.into(), to: AccountKeyring::Bob.into() }; + let tx = Transfer { + amount: Default::default(), + nonce, + from: sender.into(), + to: AccountKeyring::Bob.into(), + }; tx.into_signed_tx() } diff --git a/client/transaction-pool/src/graph/pool.rs b/client/transaction-pool/src/graph/pool.rs index e8b73925cb3b8..65230536b563b 100644 --- a/client/transaction-pool/src/graph/pool.rs +++ b/client/transaction-pool/src/graph/pool.rs @@ -588,11 +588,7 @@ mod tests { fn uxt(transfer: Transfer) -> Extrinsic { let signature = TryFrom::try_from(&[0; 64][..]).unwrap(); - Extrinsic::Transfer { - transfer, - signature, - exhaust_resources_when_not_first: false, - } + Extrinsic::Transfer { transfer, signature, exhaust_resources_when_not_first: false } } fn pool() -> Pool { diff --git a/frame/authorship/src/lib.rs b/frame/authorship/src/lib.rs index 3a8ded4c57750..0241547fa11f4 100644 --- a/frame/authorship/src/lib.rs +++ b/frame/authorship/src/lib.rs @@ -310,7 +310,10 @@ impl Pallet { let digest = >::digest(); let pre_runtime_digests = digest.logs.iter().filter_map(|d| d.as_pre_runtime()); - T::FindAuthor::find_author(pre_runtime_digests).map(|a| { >::put(&a); a }) + T::FindAuthor::find_author(pre_runtime_digests).map(|a| { + >::put(&a); + a + }) } fn verify_and_import_uncles(new_uncles: Vec) -> dispatch::DispatchResult { diff --git a/frame/benchmarking/src/utils.rs b/frame/benchmarking/src/utils.rs index afa4a1b37f914..0bbe8156a9f99 100644 --- a/frame/benchmarking/src/utils.rs +++ b/frame/benchmarking/src/utils.rs @@ -322,11 +322,7 @@ pub trait BenchmarkingSetup { } /// Grab an account, seeded by a name and index. -pub fn account( - name: &'static str, - index: u32, - seed: u32, -) -> AccountId { +pub fn account(name: &'static str, index: u32, seed: u32) -> AccountId { let entropy = (name, index, seed).using_encoded(blake2_256); Decode::decode(&mut TrailingZeroInput::new(entropy.as_ref())) .expect("infinite length input; no invalid inputs for type; qed") diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index 8df76e53c5d98..5709cc3515de1 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -161,11 +161,7 @@ pub struct Voter { impl Default for Voter { fn default() -> Self { - Self { - votes: vec![], - stake: Default::default(), - deposit: Default::default(), - } + Self { votes: vec![], stake: Default::default(), deposit: Default::default() } } } diff --git a/frame/examples/parallel/src/lib.rs b/frame/examples/parallel/src/lib.rs index 8844b3d3ee2aa..55714abb4827f 100644 --- a/frame/examples/parallel/src/lib.rs +++ b/frame/examples/parallel/src/lib.rs @@ -109,11 +109,9 @@ impl EnlistedParticipant { use sp_runtime::traits::Verify; match sp_core::sr25519::Signature::try_from(&self.signature[..]) { - Ok(signature) => { - match sp_core::sr25519::Public::from_slice(self.account.as_ref()) { - Err(()) => false, - Ok(signer) => signature.verify(event_id, &signer), - } + Ok(signature) => match sp_core::sr25519::Public::from_slice(self.account.as_ref()) { + Err(()) => false, + Ok(signer) => signature.verify(event_id, &signer), }, _ => false, } diff --git a/frame/examples/parallel/src/tests.rs b/frame/examples/parallel/src/tests.rs index 548ee915bf721..3959e8a1cee08 100644 --- a/frame/examples/parallel/src/tests.rs +++ b/frame/examples/parallel/src/tests.rs @@ -98,8 +98,7 @@ fn it_can_enlist() { let event_name = b"test"; - Example::run_event(test_origin(1), event_name.to_vec()) - .expect("Failed to enlist"); + Example::run_event(test_origin(1), event_name.to_vec()).expect("Failed to enlist"); let participants = vec![ EnlistedParticipant { @@ -130,8 +129,7 @@ fn one_wrong_will_not_enlist_anyone() { let event_name = b"test"; - Example::run_event(test_origin(1), event_name.to_vec()) - .expect("Failed to enlist"); + Example::run_event(test_origin(1), event_name.to_vec()).expect("Failed to enlist"); let participants = vec![ EnlistedParticipant { @@ -149,8 +147,7 @@ fn one_wrong_will_not_enlist_anyone() { }, ]; - Example::enlist_participants(test_origin(1), participants) - .expect("Failed to enlist"); + Example::enlist_participants(test_origin(1), participants).expect("Failed to enlist"); assert_eq!(Example::participants().len(), 0); }); diff --git a/frame/multisig/src/lib.rs b/frame/multisig/src/lib.rs index 3b80fa1b1cf41..c02efdc0d3712 100644 --- a/frame/multisig/src/lib.rs +++ b/frame/multisig/src/lib.rs @@ -63,7 +63,10 @@ use frame_support::{ use frame_system::{self as system, RawOrigin}; use scale_info::TypeInfo; use sp_io::hashing::blake2_256; -use sp_runtime::{DispatchError, traits::{Dispatchable, TrailingZeroInput, Zero}}; +use sp_runtime::{ + traits::{Dispatchable, TrailingZeroInput, Zero}, + DispatchError, +}; use sp_std::prelude::*; pub use weights::WeightInfo; diff --git a/frame/proxy/src/lib.rs b/frame/proxy/src/lib.rs index a8fd9f53880a3..fefc66554f450 100644 --- a/frame/proxy/src/lib.rs +++ b/frame/proxy/src/lib.rs @@ -44,7 +44,10 @@ use frame_support::{ use frame_system::{self as system}; use scale_info::TypeInfo; use sp_io::hashing::blake2_256; -use sp_runtime::{DispatchResult, traits::{Dispatchable, Hash, Saturating, TrailingZeroInput, Zero}}; +use sp_runtime::{ + traits::{Dispatchable, Hash, Saturating, TrailingZeroInput, Zero}, + DispatchResult, +}; use sp_std::{convert::TryInto, prelude::*}; pub use weights::WeightInfo; diff --git a/frame/staking/src/benchmarking.rs b/frame/staking/src/benchmarking.rs index 9d48df69edd8c..7b53deea630ab 100644 --- a/frame/staking/src/benchmarking.rs +++ b/frame/staking/src/benchmarking.rs @@ -29,7 +29,7 @@ use frame_support::{ traits::{Currency, CurrencyToVote, Get, Imbalance}, }; use sp_runtime::{ - traits::{Bounded, One, StaticLookup, Zero, TrailingZeroInput}, + traits::{Bounded, One, StaticLookup, TrailingZeroInput, Zero}, Perbill, Percent, }; use sp_staking::SessionIndex; diff --git a/frame/staking/src/pallet/impls.rs b/frame/staking/src/pallet/impls.rs index 553deaa2fd662..151d9a2c85b82 100644 --- a/frame/staking/src/pallet/impls.rs +++ b/frame/staking/src/pallet/impls.rs @@ -1264,7 +1264,10 @@ impl VoteWeightProvider for Pallet { let active: BalanceOf = weight.try_into().map_err(|_| ()).unwrap(); let ledger = match Self::ledger(who) { None => StakingLedger::default_from(who.clone()), - Some(mut l) => { l.active = active; l }, + Some(mut l) => { + l.active = active; + l + }, }; >::insert(who, ledger); >::insert(who, who); diff --git a/frame/tips/src/lib.rs b/frame/tips/src/lib.rs index 9e5f225b09d37..5edb5f042a61d 100644 --- a/frame/tips/src/lib.rs +++ b/frame/tips/src/lib.rs @@ -60,7 +60,10 @@ mod tests; pub mod migrations; pub mod weights; -use sp_runtime::{Percent, RuntimeDebug, traits::{AccountIdConversion, BadOrigin, Hash, TrailingZeroInput, Zero}}; +use sp_runtime::{ + traits::{AccountIdConversion, BadOrigin, Hash, TrailingZeroInput, Zero}, + Percent, RuntimeDebug, +}; use sp_std::prelude::*; use codec::{Decode, Encode}; @@ -577,7 +580,8 @@ impl Pallet { use frame_support::{migration::storage_key_iter, Twox64Concat}; - let zero_account = T::AccountId::decode(&mut TrailingZeroInput::new(&[][..])).expect("infinite input; qed"); + let zero_account = T::AccountId::decode(&mut TrailingZeroInput::new(&[][..])) + .expect("infinite input; qed"); for (hash, old_tip) in storage_key_iter::< T::Hash, diff --git a/frame/transaction-payment/asset-tx-payment/src/lib.rs b/frame/transaction-payment/asset-tx-payment/src/lib.rs index 5d2845314c4bf..49fac2a382778 100644 --- a/frame/transaction-payment/asset-tx-payment/src/lib.rs +++ b/frame/transaction-payment/asset-tx-payment/src/lib.rs @@ -265,7 +265,8 @@ where let actual_fee = pallet_transaction_payment::Pallet::::compute_actual_fee( len as u32, info, post_info, tip, ); - let who = who.ok_or(TransactionValidityError::Invalid(InvalidTransaction::Custom(255)))?; + let who = + who.ok_or(TransactionValidityError::Invalid(InvalidTransaction::Custom(255)))?; T::OnChargeAssetTransaction::correct_and_deposit_fee( &who, info, diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index c81ffc8367573..5a2d8b8738e2f 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -56,8 +56,8 @@ use sp_runtime::{ SignedExtension, Zero, }, transaction_validity::{ - TransactionPriority, TransactionValidity, TransactionValidityError, ValidTransaction, - InvalidTransaction, + InvalidTransaction, TransactionPriority, TransactionValidity, TransactionValidityError, + ValidTransaction, }, FixedPointNumber, FixedPointOperand, FixedU128, Perquintill, RuntimeDebug, }; diff --git a/primitives/application-crypto/src/lib.rs b/primitives/application-crypto/src/lib.rs index e9edb16772f3e..a6bba43632221 100644 --- a/primitives/application-crypto/src/lib.rs +++ b/primitives/application-crypto/src/lib.rs @@ -27,7 +27,10 @@ pub use sp_core::crypto::{DeriveJunction, Pair, SecretStringError, Ss58Codec}; #[doc(hidden)] pub use sp_core::{ self, - crypto::{CryptoType, CryptoTypePublicPair, Derive, IsWrappedBy, Public, Wraps, ByteArray, UncheckedFrom}, + crypto::{ + ByteArray, CryptoType, CryptoTypePublicPair, Derive, IsWrappedBy, Public, UncheckedFrom, + Wraps, + }, RuntimeDebug, }; diff --git a/primitives/core/src/crypto.rs b/primitives/core/src/crypto.rs index 0af19efec104c..3ccdd3c7a79c2 100644 --- a/primitives/core/src/crypto.rs +++ b/primitives/core/src/crypto.rs @@ -278,7 +278,8 @@ pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + ByteArray { return Err(PublicError::InvalidChecksum) } - let result = Self::from_slice(&data[prefix_len..body_len + prefix_len]).map_err(|()| PublicError::BadLength)?; + let result = Self::from_slice(&data[prefix_len..body_len + prefix_len]) + .map_err(|()| PublicError::BadLength)?; Ok((result, format)) } @@ -475,8 +476,6 @@ impl UncheckedFrom for AccountId32 { impl ByteArray for AccountId32 { const LEN: usize = 32; - - } #[cfg(feature = "std")] diff --git a/primitives/core/src/ecdsa.rs b/primitives/core/src/ecdsa.rs index 325853e4750b5..827be8eb9aabf 100644 --- a/primitives/core/src/ecdsa.rs +++ b/primitives/core/src/ecdsa.rs @@ -27,7 +27,8 @@ use sp_std::cmp::Ordering; #[cfg(feature = "std")] use crate::crypto::Ss58Codec; use crate::crypto::{ - CryptoType, CryptoTypeId, CryptoTypePublicPair, Derive, Public as TraitPublic, UncheckedFrom, ByteArray + ByteArray, CryptoType, CryptoTypeId, CryptoTypePublicPair, Derive, Public as TraitPublic, + UncheckedFrom, }; #[cfg(feature = "full_crypto")] use crate::{ diff --git a/primitives/core/src/ed25519.rs b/primitives/core/src/ed25519.rs index 0f69d54337664..7d60998b15dfc 100644 --- a/primitives/core/src/ed25519.rs +++ b/primitives/core/src/ed25519.rs @@ -22,7 +22,10 @@ #[cfg(feature = "full_crypto")] use sp_std::vec::Vec; -use crate::{crypto::ByteArray, hash::{H256, H512}}; +use crate::{ + crypto::ByteArray, + hash::{H256, H512}, +}; use codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; diff --git a/primitives/core/src/lib.rs b/primitives/core/src/lib.rs index e211dd1190780..5fca42adde991 100644 --- a/primitives/core/src/lib.rs +++ b/primitives/core/src/lib.rs @@ -76,7 +76,7 @@ pub use self::{ uint::{U256, U512}, }; #[cfg(feature = "full_crypto")] -pub use crypto::{DeriveJunction, Pair, Public, ByteArray}; +pub use crypto::{ByteArray, DeriveJunction, Pair, Public}; #[cfg(feature = "std")] pub use self::hasher::blake2::Blake2Hasher; diff --git a/primitives/core/src/sr25519.rs b/primitives/core/src/sr25519.rs index 709dbef8c6a33..97e9de5de09a7 100644 --- a/primitives/core/src/sr25519.rs +++ b/primitives/core/src/sr25519.rs @@ -41,8 +41,8 @@ use substrate_bip39::mini_secret_from_entropy; use crate::{ crypto::{ - CryptoType, CryptoTypeId, CryptoTypePublicPair, Derive, Public as TraitPublic, - UncheckedFrom, ByteArray, + ByteArray, CryptoType, CryptoTypeId, CryptoTypePublicPair, Derive, Public as TraitPublic, + UncheckedFrom, }, hash::{H256, H512}, }; diff --git a/primitives/io/src/lib.rs b/primitives/io/src/lib.rs index e66392a53b851..2b4d8dbcb33eb 100644 --- a/primitives/io/src/lib.rs +++ b/primitives/io/src/lib.rs @@ -1516,8 +1516,10 @@ pub type SubstrateHostFunctions = ( #[cfg(test)] mod tests { use super::*; - use sp_core::{map, storage::Storage, testing::TaskExecutor, traits::TaskExecutorExt}; - use sp_core::crypto::UncheckedInto; + use sp_core::{ + crypto::UncheckedInto, map, storage::Storage, testing::TaskExecutor, + traits::TaskExecutorExt, + }; use sp_state_machine::BasicExternalities; use std::any::TypeId; diff --git a/primitives/keyring/src/ed25519.rs b/primitives/keyring/src/ed25519.rs index 99d63e8619eba..4d99de6c59d70 100644 --- a/primitives/keyring/src/ed25519.rs +++ b/primitives/keyring/src/ed25519.rs @@ -21,7 +21,7 @@ use lazy_static::lazy_static; pub use sp_core::ed25519; use sp_core::{ ed25519::{Pair, Public, Signature}, - Pair as PairT, ByteArray, H256, + ByteArray, Pair as PairT, H256, }; use sp_runtime::AccountId32; use std::{collections::HashMap, ops::Deref}; diff --git a/primitives/keyring/src/sr25519.rs b/primitives/keyring/src/sr25519.rs index 91f1a7d240535..d400cde035b70 100644 --- a/primitives/keyring/src/sr25519.rs +++ b/primitives/keyring/src/sr25519.rs @@ -21,7 +21,7 @@ use lazy_static::lazy_static; pub use sp_core::sr25519; use sp_core::{ sr25519::{Pair, Public, Signature}, - Pair as PairT, ByteArray, H256, + ByteArray, Pair as PairT, H256, }; use sp_runtime::AccountId32; use std::{collections::HashMap, ops::Deref}; diff --git a/primitives/keystore/src/testing.rs b/primitives/keystore/src/testing.rs index 85d99c2574708..92a73eb98c90f 100644 --- a/primitives/keystore/src/testing.rs +++ b/primitives/keystore/src/testing.rs @@ -18,7 +18,7 @@ //! Types that should only be used for testing! use sp_core::{ - crypto::{CryptoTypePublicPair, KeyTypeId, Pair, ByteArray}, + crypto::{ByteArray, CryptoTypePublicPair, KeyTypeId, Pair}, ecdsa, ed25519, sr25519, }; @@ -340,14 +340,14 @@ impl SyncCryptoStore for KeyStore { match key.0 { ed25519::CRYPTO_ID => { - let key_pair = - self.ed25519_key_pair(id, &ed25519::Public::from_slice(key.1.as_slice()).unwrap()); + let key_pair = self + .ed25519_key_pair(id, &ed25519::Public::from_slice(key.1.as_slice()).unwrap()); key_pair.map(|k| k.sign(msg).encode()).map(Ok).transpose() }, sr25519::CRYPTO_ID => { - let key_pair = - self.sr25519_key_pair(id, &sr25519::Public::from_slice(key.1.as_slice()).unwrap()); + let key_pair = self + .sr25519_key_pair(id, &sr25519::Public::from_slice(key.1.as_slice()).unwrap()); key_pair.map(|k| k.sign(msg).encode()).map(Ok).transpose() }, diff --git a/primitives/npos-elections/src/pjr.rs b/primitives/npos-elections/src/pjr.rs index 08a7e6fa719ea..50556ea9cc335 100644 --- a/primitives/npos-elections/src/pjr.rs +++ b/primitives/npos-elections/src/pjr.rs @@ -294,7 +294,8 @@ fn prepare_pjr_input( score: Default::default(), approval_stake: Default::default(), round: Default::default(), - }.to_ptr() + } + .to_ptr() }) .collect::>(); @@ -322,7 +323,7 @@ fn prepare_pjr_input( who: t, candidate: Rc::clone(&candidates[*idx]), weight, - load: Default::default(), + load: Default::default(), }); } } @@ -453,7 +454,8 @@ mod tests { approval_stake: Default::default(), backed_stake: Default::default(), round: Default::default(), - }.to_ptr(); + } + .to_ptr(); let score = pre_score(unelected, &vec![v1, v2, v3], 15); assert_eq!(score, 15); diff --git a/primitives/npos-elections/src/reduce.rs b/primitives/npos-elections/src/reduce.rs index 9f1cef71e2455..8ff0244b4694f 100644 --- a/primitives/npos-elections/src/reduce.rs +++ b/primitives/npos-elections/src/reduce.rs @@ -389,8 +389,8 @@ fn reduce_all(assignments: &mut Vec>) -> u32 let common_count = trailing_common(&voter_root_path, &target_root_path); // because roots are the same. - //debug_assert_eq!(target_root_path.last().unwrap(), voter_root_path.last().unwrap()); - // TODO: @kian + //debug_assert_eq!(target_root_path.last().unwrap(), + // voter_root_path.last().unwrap()); TODO: @kian // the common path must be non-void.. debug_assert!(common_count > 0); // and smaller than btoh diff --git a/primitives/runtime/src/testing.rs b/primitives/runtime/src/testing.rs index e42d444ead1f4..46e7ee634c25d 100644 --- a/primitives/runtime/src/testing.rs +++ b/primitives/runtime/src/testing.rs @@ -30,7 +30,7 @@ use crate::{ }; use serde::{de::Error as DeError, Deserialize, Deserializer, Serialize, Serializer}; use sp_core::{ - crypto::{key_types, CryptoType, Dummy, ByteArray}, + crypto::{key_types, ByteArray, CryptoType, Dummy}, U256, }; pub use sp_core::{sr25519, H256}; diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index f9d87668ef737..547fdb6d254ac 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -1622,7 +1622,10 @@ pub trait BlockNumberProvider { mod tests { use super::*; use crate::codec::{Decode, Encode, Input}; - use sp_core::{crypto::{Pair, UncheckedFrom}, ecdsa}; + use sp_core::{ + crypto::{Pair, UncheckedFrom}, + ecdsa, + }; mod t { use sp_application_crypto::{app_crypto, sr25519}; diff --git a/test-utils/runtime/transaction-pool/src/lib.rs b/test-utils/runtime/transaction-pool/src/lib.rs index 2a32375cfecc0..e80c24b17144b 100644 --- a/test-utils/runtime/transaction-pool/src/lib.rs +++ b/test-utils/runtime/transaction-pool/src/lib.rs @@ -23,10 +23,14 @@ use codec::Encode; use futures::future::ready; use parking_lot::RwLock; use sp_blockchain::CachedHeaderMetadata; -use sp_runtime::{generic::{self, BlockId}, traits::{BlakeTwo256, Block as BlockT, Hash as HashT, Header as _, TrailingZeroInput}, transaction_validity::{ +use sp_runtime::{ + generic::{self, BlockId}, + traits::{BlakeTwo256, Block as BlockT, Hash as HashT, Header as _, TrailingZeroInput}, + transaction_validity::{ InvalidTransaction, TransactionSource, TransactionValidity, TransactionValidityError, ValidTransaction, - }}; + }, +}; use std::collections::{BTreeMap, HashMap, HashSet}; use substrate_test_runtime_client::{ runtime::{AccountId, Block, BlockNumber, Extrinsic, Hash, Header, Index, Transfer}, diff --git a/test-utils/test-runner/src/node.rs b/test-utils/test-runner/src/node.rs index d78de1d3ac015..421a4b641b59d 100644 --- a/test-utils/test-runner/src/node.rs +++ b/test-utils/test-runner/src/node.rs @@ -195,7 +195,11 @@ where { let signed_data = if let Some(signer) = signer { let extra = self.with_state(|| T::signed_extras(signer.clone())); - Some((signer.into(), MultiSignature::Sr25519(sp_core::sr25519::Signature::from_raw([0u8; 64])), extra)) + Some(( + signer.into(), + MultiSignature::Sr25519(sp_core::sr25519::Signature::from_raw([0u8; 64])), + extra, + )) } else { None }; From f5758f1b7d5fb1738a6905af674f804ef31af47f Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 7 Dec 2021 16:36:57 +0100 Subject: [PATCH 23/47] Fixes --- frame/collective/src/benchmarking.rs | 4 ++-- frame/democracy/src/benchmarking.rs | 7 ++++++- frame/election-provider-multi-phase/src/benchmarking.rs | 9 +++++++-- frame/elections-phragmen/src/lib.rs | 9 ++++++++- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/frame/collective/src/benchmarking.rs b/frame/collective/src/benchmarking.rs index 5ca57cf72e8fc..d8051493b9bc0 100644 --- a/frame/collective/src/benchmarking.rs +++ b/frame/collective/src/benchmarking.rs @@ -43,7 +43,7 @@ benchmarks_instance_pallet! { // Set old members. // We compute the difference of old and new members, so it should influence timing. let mut old_members = vec![]; - let mut last_old_member = T::AccountId::default(); + let mut last_old_member: T::AccountId = account("old member", 0, SEED); for i in 0 .. m { last_old_member = account("old member", i, SEED); old_members.push(last_old_member.clone()); @@ -91,7 +91,7 @@ benchmarks_instance_pallet! { // Construct `new_members`. // It should influence timing since it will sort this vector. let mut new_members = vec![]; - let mut last_member = T::AccountId::default(); + let mut last_member = account("member", 0, SEED); for i in 0 .. n { last_member = account("member", i, SEED); new_members.push(last_member.clone()); diff --git a/frame/democracy/src/benchmarking.rs b/frame/democracy/src/benchmarking.rs index 136c2d2a7c9e2..5a9ef21e698a1 100644 --- a/frame/democracy/src/benchmarking.rs +++ b/frame/democracy/src/benchmarking.rs @@ -239,9 +239,14 @@ benchmarks! { let origin = T::ExternalOrigin::successful_origin(); let proposal_hash = T::Hashing::hash_of(&0); // Add proposal to blacklist with block number 0 + + let addresses = (0..v) + .into_iter() + .map(|i| account("blacklist", i, SEED)) + .collect::>(); Blacklist::::insert( proposal_hash, - (T::BlockNumber::zero(), vec![T::AccountId::default(); v as usize]) + (T::BlockNumber::zero(), addresses), ); }: _(origin, proposal_hash) verify { diff --git a/frame/election-provider-multi-phase/src/benchmarking.rs b/frame/election-provider-multi-phase/src/benchmarking.rs index d9db6c3090994..ea7fc4de2a349 100644 --- a/frame/election-provider-multi-phase/src/benchmarking.rs +++ b/frame/election-provider-multi-phase/src/benchmarking.rs @@ -209,7 +209,7 @@ frame_benchmarking::benchmarks! { let receiver = account("receiver", 0, SEED); let initial_balance = T::Currency::minimum_balance() * 10u32.into(); T::Currency::make_free_balance_be(&receiver, initial_balance); - let ready: ReadySolution = Default::default(); + let ready: ReadySolution = account("ready", 0, SEED); let deposit: BalanceOf = 10u32.into(); let reward: BalanceOf = 20u32.into(); @@ -314,7 +314,12 @@ frame_benchmarking::benchmarks! { score: [(10_000_000 + i).into(), 0, 0], ..Default::default() }; - let signed_submission = SignedSubmission { raw_solution, ..Default::default() }; + let signed_submission = SignedSubmission { + raw_solution, + who: account("submitters", i, SEED), + deposit: Default::default(), + reward: Default::default(), + }; signed_submissions.insert(signed_submission); } signed_submissions.put(); diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index 5709cc3515de1..f3f630d22771a 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -1093,7 +1093,14 @@ impl SortedMembers for Pallet { fn add(who: &T::AccountId) { Members::::mutate(|members| match members.binary_search_by(|m| m.who.cmp(who)) { Ok(_) => (), - Err(pos) => members.insert(pos, SeatHolder { who: who.clone(), ..Default::default() }), + Err(pos) => { + let s = SeatHolder { + who: who.clone(), + stake: Default::default(), + deposit: Default::default(), + }; + members.insert(pos, s) + }, }) } } From 3dc3969cb7d3c52f52e482ffb30fdf7b818c2401 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 7 Dec 2021 20:21:02 +0100 Subject: [PATCH 24/47] Fixes --- frame/collective/src/benchmarking.rs | 36 ++++++++++++++-------------- frame/democracy/src/benchmarking.rs | 4 ++-- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/frame/collective/src/benchmarking.rs b/frame/collective/src/benchmarking.rs index d8051493b9bc0..9dcfa2a9c6c87 100644 --- a/frame/collective/src/benchmarking.rs +++ b/frame/collective/src/benchmarking.rs @@ -43,9 +43,9 @@ benchmarks_instance_pallet! { // Set old members. // We compute the difference of old and new members, so it should influence timing. let mut old_members = vec![]; - let mut last_old_member: T::AccountId = account("old member", 0, SEED); + let mut last_old_member = account::("old member", 0, SEED); for i in 0 .. m { - last_old_member = account("old member", i, SEED); + last_old_member = account::("old member", i, SEED); old_members.push(last_old_member.clone()); } let old_members_count = old_members.len() as u32; @@ -91,9 +91,9 @@ benchmarks_instance_pallet! { // Construct `new_members`. // It should influence timing since it will sort this vector. let mut new_members = vec![]; - let mut last_member = account("member", 0, SEED); + let mut last_member = account::("member", 0, SEED); for i in 0 .. n { - last_member = account("member", i, SEED); + last_member = account::("member", i, SEED); new_members.push(last_member.clone()); } @@ -112,7 +112,7 @@ benchmarks_instance_pallet! { // Construct `members`. let mut members = vec![]; for i in 0 .. m - 1 { - let member = account("member", i, SEED); + let member = account::("member", i, SEED); members.push(member); } @@ -142,7 +142,7 @@ benchmarks_instance_pallet! { // Construct `members`. let mut members = vec![]; for i in 0 .. m - 1 { - let member = account("member", i, SEED); + let member = account::("member", i, SEED); members.push(member); } @@ -174,7 +174,7 @@ benchmarks_instance_pallet! { // Construct `members`. let mut members = vec![]; for i in 0 .. m - 1 { - let member = account("member", i, SEED); + let member = account::("member", i, SEED); members.push(member); } let caller: T::AccountId = whitelisted_caller(); @@ -216,13 +216,13 @@ benchmarks_instance_pallet! { // Construct `members`. let mut members = vec![]; - let proposer: T::AccountId = account("proposer", 0, SEED); + let proposer: T::AccountId = account::("proposer", 0, SEED); members.push(proposer.clone()); for i in 1 .. m - 1 { - let member = account("member", i, SEED); + let member = account::("member", i, SEED); members.push(member); } - let voter: T::AccountId = account("voter", 0, SEED); + let voter: T::AccountId = account::("voter", 0, SEED); members.push(voter.clone()); Collective::::set_members(SystemOrigin::Root.into(), members.clone(), None, T::MaxMembers::get())?; @@ -291,13 +291,13 @@ benchmarks_instance_pallet! { // Construct `members`. let mut members = vec![]; - let proposer: T::AccountId = account("proposer", 0, SEED); + let proposer = account::("proposer", 0, SEED); members.push(proposer.clone()); for i in 1 .. m - 1 { - let member = account("member", i, SEED); + let member = account::("member", i, SEED); members.push(member); } - let voter: T::AccountId = account("voter", 0, SEED); + let voter = account::("voter", 0, SEED); members.push(voter.clone()); Collective::::set_members(SystemOrigin::Root.into(), members.clone(), None, T::MaxMembers::get())?; @@ -373,7 +373,7 @@ benchmarks_instance_pallet! { // Construct `members`. let mut members = vec![]; for i in 0 .. m - 1 { - let member = account("member", i, SEED); + let member = account::("member", i, SEED); members.push(member); } let caller: T::AccountId = whitelisted_caller(); @@ -454,7 +454,7 @@ benchmarks_instance_pallet! { // Construct `members`. let mut members = vec![]; for i in 0 .. m - 1 { - let member = account("member", i, SEED); + let member = account::("member", i, SEED); members.push(member); } let caller: T::AccountId = whitelisted_caller(); @@ -528,7 +528,7 @@ benchmarks_instance_pallet! { // Construct `members`. let mut members = vec![]; for i in 0 .. m - 1 { - let member = account("member", i, SEED); + let member = account::("member", i, SEED); members.push(member); } let caller: T::AccountId = whitelisted_caller(); @@ -599,10 +599,10 @@ benchmarks_instance_pallet! { // Construct `members`. let mut members = vec![]; for i in 0 .. m - 1 { - let member = account("member", i, SEED); + let member = account::("member", i, SEED); members.push(member); } - let caller: T::AccountId = account("caller", 0, SEED); + let caller = account::("caller", 0, SEED); members.push(caller.clone()); Collective::::set_members( SystemOrigin::Root.into(), diff --git a/frame/democracy/src/benchmarking.rs b/frame/democracy/src/benchmarking.rs index 5a9ef21e698a1..4068b55f6e7bc 100644 --- a/frame/democracy/src/benchmarking.rs +++ b/frame/democracy/src/benchmarking.rs @@ -242,7 +242,7 @@ benchmarks! { let addresses = (0..v) .into_iter() - .map(|i| account("blacklist", i, SEED)) + .map(|i| account::("blacklist", i, SEED)) .collect::>(); Blacklist::::insert( proposal_hash, @@ -297,7 +297,7 @@ benchmarks! { let mut vetoers: Vec = Vec::new(); for i in 0 .. v { - vetoers.push(account("vetoer", i, SEED)); + vetoers.push(account::("vetoer", i, SEED)); } vetoers.sort(); Blacklist::::insert(proposal_hash, (T::BlockNumber::zero(), vetoers)); From c9c7ba79168b773e23d1606cbdb9634705845bd5 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Thu, 9 Dec 2021 20:38:52 +0330 Subject: [PATCH 25/47] Fix bench --- frame/election-provider-multi-phase/src/benchmarking.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/frame/election-provider-multi-phase/src/benchmarking.rs b/frame/election-provider-multi-phase/src/benchmarking.rs index ea7fc4de2a349..1e0d3b1e9325a 100644 --- a/frame/election-provider-multi-phase/src/benchmarking.rs +++ b/frame/election-provider-multi-phase/src/benchmarking.rs @@ -209,7 +209,11 @@ frame_benchmarking::benchmarks! { let receiver = account("receiver", 0, SEED); let initial_balance = T::Currency::minimum_balance() * 10u32.into(); T::Currency::make_free_balance_be(&receiver, initial_balance); - let ready: ReadySolution = account("ready", 0, SEED); + let ready = ReadySolution { + supports: vec![], + score: Default::default(), + compute: Default::default() + }; let deposit: BalanceOf = 10u32.into(); let reward: BalanceOf = 20u32.into(); From ea520fa8bb42d072c0eaefdefc7b619b93287f63 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 9 Dec 2021 19:58:04 +0100 Subject: [PATCH 26/47] Fixes --- frame/contracts/src/migration.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frame/contracts/src/migration.rs b/frame/contracts/src/migration.rs index 93eb2e64a1d84..7751eb1a2c77d 100644 --- a/frame/contracts/src/migration.rs +++ b/frame/contracts/src/migration.rs @@ -224,13 +224,16 @@ mod v6 { }) }); + let nobody = T::AccountId::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes()) + .expect("Infinite input; no dead input space; qed"); + >::translate(|key, old: OldPrefabWasmModule| { weight = weight.saturating_add(T::DbWeight::get().reads_writes(1, 2)); >::insert( key, OwnerInfo { refcount: old.refcount, - owner: Default::default(), + owner: nobody.clone(), deposit: Default::default(), }, ); From b69459945b47e1804bb3fc76389213492fc87f38 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 9 Dec 2021 20:03:05 +0100 Subject: [PATCH 27/47] Fixes --- frame/bounties/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/bounties/src/lib.rs b/frame/bounties/src/lib.rs index 7e8ba60050561..752697ce668f4 100644 --- a/frame/bounties/src/lib.rs +++ b/frame/bounties/src/lib.rs @@ -123,7 +123,7 @@ pub struct Bounty { status: BountyStatus, } -impl +impl Bounty { /// Getter for bounty status, to be used for child bounties. From 97ec65ad865a6ee261ba1762310aa3223bb2eab2 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 10 Dec 2021 12:09:57 +0100 Subject: [PATCH 28/47] Fixes --- frame/session/src/lib.rs | 10 +++++--- frame/staking/src/lib.rs | 4 +-- frame/staking/src/mock.rs | 12 ++++++--- frame/staking/src/tests.rs | 52 ++++++++++++++++++++------------------ 4 files changed, 44 insertions(+), 34 deletions(-) diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index d786ea147a533..75f3d6703fe2e 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -480,13 +480,15 @@ pub mod pallet { let queued_keys: Vec<_> = initial_validators_1 .iter() .cloned() - .filter_map(|v| Some((v.clone(), Pallet::::load_keys(&v)?))) + .filter_map(|v| Some((v.clone(), Pallet::::load_keys(&v) + .expect("Validator in session 1 missing keys!") + ))) .collect(); // Tell everyone about the genesis session keys T::SessionHandler::on_genesis_session::(&queued_keys); - >::put(initial_validators_0); + Validators::::put(initial_validators_0); >::put(queued_keys); T::SessionManager::start_session(0); @@ -645,7 +647,7 @@ impl Pallet { let session_keys = >::get(); let validators = session_keys.iter().map(|(validator, _)| validator.clone()).collect::>(); - >::put(&validators); + Validators::::put(&validators); if changed { // reset disabled validators @@ -667,7 +669,7 @@ impl Pallet { // same as before, as underlying economic conditions may have changed. (validators, true) } else { - (>::get(), false) + (Validators::::get(), false) }; // Queue next session keys. diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index f629c4e494d93..9354f2ab654cb 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -380,7 +380,7 @@ impl Default for EraRewardPoints { /// Indicates the initial status of the staker. #[derive(RuntimeDebug, TypeInfo)] -#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize, Clone))] pub enum StakerStatus { /// Chilling. Idle, @@ -643,7 +643,7 @@ pub struct UnappliedSlash { } impl UnappliedSlash { - fn default_from(validator: AccountId) -> Self { + pub fn default_from(validator: AccountId) -> Self { Self { validator, own: Zero::zero(), diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index 89ab86259b95f..f6e2ce0e4bc18 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -480,7 +480,7 @@ impl ExtBuilder { } let _ = pallet_staking::GenesisConfig:: { - stakers, + stakers: stakers.clone(), validator_count: self.validator_count, minimum_validator_count: self.minimum_validator_count, invulnerables: self.invulnerables, @@ -493,12 +493,15 @@ impl ExtBuilder { let _ = pallet_session::GenesisConfig:: { keys: if self.has_stakers { - // genesis election will overwrite this, no worries. - Default::default() + // set the keys for the first session. + stakers + .into_iter() + .map(|(id, ..)| (id, id, SessionKeys { other: id.into() })) + .collect() } else { // set some dummy validators in genesis. (0..self.validator_count as u64) - .map(|x| (x, x, SessionKeys { other: UintAuthorityId(x as u64) })) + .map(|id| (id, id, SessionKeys { other: id.into() })) .collect() }, } @@ -644,6 +647,7 @@ pub(crate) fn bond(stash: AccountId, ctrl: AccountId, val: Balance) { pub(crate) fn bond_validator(stash: AccountId, ctrl: AccountId, val: Balance) { bond(stash, ctrl, val); assert_ok!(Staking::validate(Origin::signed(ctrl), ValidatorPrefs::default())); + assert_ok!(Session::set_keys(Origin::signed(ctrl), SessionKeys { other: ctrl.into() }, vec![])); } pub(crate) fn bond_nominator( diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index e09c5f28546ec..b290ad33f13a5 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -217,16 +217,17 @@ fn rewards_should_work() { Payee::::insert(21, RewardDestination::Controller); Payee::::insert(101, RewardDestination::Controller); - >::reward_by_ids(vec![(11, 50)]); - >::reward_by_ids(vec![(11, 50)]); + Pallet::::reward_by_ids(vec![(11, 50)]); + Pallet::::reward_by_ids(vec![(11, 50)]); // This is the second validator of the current elected set. - >::reward_by_ids(vec![(21, 50)]); + Pallet::::reward_by_ids(vec![(21, 50)]); // Compute total payout now for whole duration of the session. let total_payout_0 = current_total_payout_for_duration(reward_time_per_era()); let maximum_payout = maximum_payout_for_duration(reward_time_per_era()); start_session(1); + assert_eq_uvec!(Session::validators(), vec![11, 21]); assert_eq!(Balances::total_balance(&10), init_balance_10); assert_eq!(Balances::total_balance(&11), init_balance_11); @@ -234,7 +235,6 @@ fn rewards_should_work() { assert_eq!(Balances::total_balance(&21), init_balance_21); assert_eq!(Balances::total_balance(&100), init_balance_100); assert_eq!(Balances::total_balance(&101), init_balance_101); - assert_eq_uvec!(Session::validators(), vec![11, 21]); assert_eq!( Staking::eras_reward_points(active_era()), EraRewardPoints { @@ -283,7 +283,7 @@ fn rewards_should_work() { assert_eq_error_rate!(Balances::total_balance(&101), init_balance_101, 2); assert_eq_uvec!(Session::validators(), vec![11, 21]); - >::reward_by_ids(vec![(11, 1)]); + Pallet::::reward_by_ids(vec![(11, 1)]); // Compute total payout now for whole duration as other parameter won't change let total_payout_1 = current_total_payout_for_duration(reward_time_per_era()); @@ -338,6 +338,7 @@ fn staking_should_work() { // add a new candidate for being a validator. account 3 controlled by 4. assert_ok!(Staking::bond(Origin::signed(3), 4, 1500, RewardDestination::Controller)); assert_ok!(Staking::validate(Origin::signed(4), ValidatorPrefs::default())); + assert_ok!(Session::set_keys(Origin::signed(4), SessionKeys { other: 4.into() }, vec![])); // No effects will be seen so far. assert_eq_uvec!(validator_controllers(), vec![20, 10]); @@ -519,8 +520,8 @@ fn nominating_and_rewards_should_work() { // the total reward for era 0 let total_payout_0 = current_total_payout_for_duration(reward_time_per_era()); - >::reward_by_ids(vec![(41, 1)]); - >::reward_by_ids(vec![(21, 1)]); + Pallet::::reward_by_ids(vec![(41, 1)]); + Pallet::::reward_by_ids(vec![(21, 1)]); mock::start_active_era(1); @@ -561,8 +562,8 @@ fn nominating_and_rewards_should_work() { // the total reward for era 1 let total_payout_1 = current_total_payout_for_duration(reward_time_per_era()); - >::reward_by_ids(vec![(21, 2)]); - >::reward_by_ids(vec![(11, 1)]); + Pallet::::reward_by_ids(vec![(21, 2)]); + Pallet::::reward_by_ids(vec![(11, 1)]); mock::start_active_era(2); @@ -942,7 +943,7 @@ fn reward_destination_works() { // Compute total payout now for whole duration as other parameter won't change let total_payout_0 = current_total_payout_for_duration(reward_time_per_era()); - >::reward_by_ids(vec![(11, 1)]); + Pallet::::reward_by_ids(vec![(11, 1)]); mock::start_active_era(1); mock::make_all_reward_payment(0); @@ -968,7 +969,7 @@ fn reward_destination_works() { // Compute total payout now for whole duration as other parameter won't change let total_payout_1 = current_total_payout_for_duration(reward_time_per_era()); - >::reward_by_ids(vec![(11, 1)]); + Pallet::::reward_by_ids(vec![(11, 1)]); mock::start_active_era(2); mock::make_all_reward_payment(1); @@ -999,7 +1000,7 @@ fn reward_destination_works() { // Compute total payout now for whole duration as other parameter won't change let total_payout_2 = current_total_payout_for_duration(reward_time_per_era()); - >::reward_by_ids(vec![(11, 1)]); + Pallet::::reward_by_ids(vec![(11, 1)]); mock::start_active_era(3); mock::make_all_reward_payment(2); @@ -1049,7 +1050,7 @@ fn validator_payment_prefs_work() { // Compute total payout now for whole duration as other parameter won't change let total_payout_1 = current_total_payout_for_duration(reward_time_per_era()); let exposure_1 = Staking::eras_stakers(active_era(), 11); - >::reward_by_ids(vec![(11, 1)]); + Pallet::::reward_by_ids(vec![(11, 1)]); mock::start_active_era(2); mock::make_all_reward_payment(1); @@ -1610,8 +1611,8 @@ fn reward_to_stake_works() { // Compute total payout now for whole duration as other parameter won't change let total_payout_0 = current_total_payout_for_duration(reward_time_per_era()); - >::reward_by_ids(vec![(11, 1)]); - >::reward_by_ids(vec![(21, 1)]); + Pallet::::reward_by_ids(vec![(11, 1)]); + Pallet::::reward_by_ids(vec![(21, 1)]); // New era --> rewards are paid --> stakes are changed mock::start_active_era(1); @@ -1707,6 +1708,7 @@ fn switching_roles() { // add a new validator candidate assert_ok!(Staking::bond(Origin::signed(5), 6, 1000, RewardDestination::Controller)); assert_ok!(Staking::validate(Origin::signed(6), ValidatorPrefs::default())); + assert_ok!(Session::set_keys(Origin::signed(6), SessionKeys { other: 6.into() }, vec![])); mock::start_active_era(1); @@ -1715,6 +1717,7 @@ fn switching_roles() { // 2 decides to be a validator. Consequences: assert_ok!(Staking::validate(Origin::signed(2), ValidatorPrefs::default())); + assert_ok!(Session::set_keys(Origin::signed(2), SessionKeys { other: 2.into() }, vec![])); // new stakes: // 10: 1000 self vote // 20: 1000 self vote + 250 vote @@ -1819,6 +1822,7 @@ fn bond_with_little_staked_value_bounded() { // Stingy validator. assert_ok!(Staking::bond(Origin::signed(1), 2, 1, RewardDestination::Controller)); assert_ok!(Staking::validate(Origin::signed(2), ValidatorPrefs::default())); + assert_ok!(Session::set_keys(Origin::signed(2), SessionKeys { other: 2.into() }, vec![])); // 1 era worth of reward. BUT, we set the timestamp after on_initialize, so outdated by // one block. @@ -2053,10 +2057,10 @@ fn reward_from_authorship_event_handler_works() { assert_eq!(>::author(), Some(11)); - >::note_author(11); - >::note_uncle(21, 1); + Pallet::::note_author(11); + Pallet::::note_uncle(21, 1); // Rewarding the same two times works. - >::note_uncle(11, 1); + Pallet::::note_uncle(11, 1); // Not mandatory but must be coherent with rewards assert_eq_uvec!(Session::validators(), vec![11, 21]); @@ -2079,9 +2083,9 @@ fn add_reward_points_fns_works() { // Not mandatory but must be coherent with rewards assert_eq_uvec!(Session::validators(), vec![21, 11]); - >::reward_by_ids(vec![(21, 1), (11, 1), (11, 1)]); + Pallet::::reward_by_ids(vec![(21, 1), (11, 1), (11, 1)]); - >::reward_by_ids(vec![(21, 1), (11, 1), (11, 1)]); + Pallet::::reward_by_ids(vec![(21, 1), (11, 1), (11, 1)]); assert_eq!( ErasRewardPoints::::get(active_era()), @@ -3091,13 +3095,13 @@ fn claim_reward_at_the_last_era_and_no_double_claim_and_invalid_claim() { Payee::::insert(11, RewardDestination::Controller); Payee::::insert(101, RewardDestination::Controller); - >::reward_by_ids(vec![(11, 1)]); + Pallet::::reward_by_ids(vec![(11, 1)]); // Compute total payout now for whole duration as other parameter won't change let total_payout_0 = current_total_payout_for_duration(reward_time_per_era()); mock::start_active_era(1); - >::reward_by_ids(vec![(11, 1)]); + Pallet::::reward_by_ids(vec![(11, 1)]); // Change total issuance in order to modify total payout let _ = Balances::deposit_creating(&999, 1_000_000_000); // Compute total payout now for whole duration as other parameter won't change @@ -3106,7 +3110,7 @@ fn claim_reward_at_the_last_era_and_no_double_claim_and_invalid_claim() { mock::start_active_era(2); - >::reward_by_ids(vec![(11, 1)]); + Pallet::::reward_by_ids(vec![(11, 1)]); // Change total issuance in order to modify total payout let _ = Balances::deposit_creating(&999, 1_000_000_000); // Compute total payout now for whole duration as other parameter won't change @@ -3266,7 +3270,7 @@ fn test_max_nominator_rewarded_per_validator_and_cant_steal_someone_else_reward( } mock::start_active_era(1); - >::reward_by_ids(vec![(11, 1)]); + Pallet::::reward_by_ids(vec![(11, 1)]); // compute and ensure the reward amount is greater than zero. let _ = current_total_payout_for_duration(reward_time_per_era()); From b9c1e17b00ec4b799ad8bf5bc04eb960f9c53edb Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 10 Dec 2021 12:42:30 +0100 Subject: [PATCH 29/47] Fixes --- bin/node/testing/src/genesis.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/node/testing/src/genesis.rs b/bin/node/testing/src/genesis.rs index fa0dd22c9c995..52296230b055a 100644 --- a/bin/node/testing/src/genesis.rs +++ b/bin/node/testing/src/genesis.rs @@ -54,11 +54,11 @@ pub fn config_endowed(code: Option<&[u8]>, extra_endowed: Vec) -> Gen balances: BalancesConfig { balances: endowed }, session: SessionConfig { keys: vec![ - (dave(), alice(), to_session_keys(&Ed25519Keyring::Alice, &Sr25519Keyring::Alice)), - (eve(), bob(), to_session_keys(&Ed25519Keyring::Bob, &Sr25519Keyring::Bob)), + (alice(), dave(), to_session_keys(&Ed25519Keyring::Alice, &Sr25519Keyring::Alice)), + (bob(), eve(), to_session_keys(&Ed25519Keyring::Bob, &Sr25519Keyring::Bob)), ( - ferdie(), charlie(), + ferdie(), to_session_keys(&Ed25519Keyring::Charlie, &Sr25519Keyring::Charlie), ), ], From ddfbfa9a2194e1250c5816310468025fec930a70 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 10 Dec 2021 12:58:33 +0100 Subject: [PATCH 30/47] Fixes --- client/transaction-pool/benches/basics.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/transaction-pool/benches/basics.rs b/client/transaction-pool/benches/basics.rs index cf30a0200ad76..48fb66d880a07 100644 --- a/client/transaction-pool/benches/basics.rs +++ b/client/transaction-pool/benches/basics.rs @@ -126,7 +126,8 @@ impl ChainApi for TestApi { fn uxt(transfer: Transfer) -> Extrinsic { Extrinsic::Transfer { transfer, - signature: Default::default(), + signature: Decode::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes()) + .expect("infinite input; no dead input space; qed"), exhaust_resources_when_not_first: false, } } From 231610339caed53ade7705961edf785c13da80ed Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 10 Dec 2021 14:03:41 +0100 Subject: [PATCH 31/47] Formatting --- frame/session/src/lib.rs | 9 ++++++--- frame/staking/src/tests.rs | 6 +++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index 75f3d6703fe2e..0f80494550849 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -480,9 +480,12 @@ pub mod pallet { let queued_keys: Vec<_> = initial_validators_1 .iter() .cloned() - .filter_map(|v| Some((v.clone(), Pallet::::load_keys(&v) - .expect("Validator in session 1 missing keys!") - ))) + .filter_map(|v| { + Some(( + v.clone(), + Pallet::::load_keys(&v).expect("Validator in session 1 missing keys!"), + )) + }) .collect(); // Tell everyone about the genesis session keys diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index b290ad33f13a5..aa806d4a15e2c 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -1822,7 +1822,11 @@ fn bond_with_little_staked_value_bounded() { // Stingy validator. assert_ok!(Staking::bond(Origin::signed(1), 2, 1, RewardDestination::Controller)); assert_ok!(Staking::validate(Origin::signed(2), ValidatorPrefs::default())); - assert_ok!(Session::set_keys(Origin::signed(2), SessionKeys { other: 2.into() }, vec![])); + assert_ok!(Session::set_keys( + Origin::signed(2), + SessionKeys { other: 2.into() }, + vec![] + )); // 1 era worth of reward. BUT, we set the timestamp after on_initialize, so outdated by // one block. From d302551d3eb72efd1a6c76a3c941dbcc53f709a8 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 10 Dec 2021 15:13:37 +0100 Subject: [PATCH 32/47] Fixes --- client/transaction-pool/benches/basics.rs | 2 +- primitives/runtime/src/multiaddress.rs | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/client/transaction-pool/benches/basics.rs b/client/transaction-pool/benches/basics.rs index 48fb66d880a07..ea1f0157c2666 100644 --- a/client/transaction-pool/benches/basics.rs +++ b/client/transaction-pool/benches/basics.rs @@ -18,7 +18,7 @@ use criterion::{criterion_group, criterion_main, Criterion}; -use codec::Encode; +use codec::{Encode, Decode}; use futures::{ executor::block_on, future::{ready, Ready}, diff --git a/primitives/runtime/src/multiaddress.rs b/primitives/runtime/src/multiaddress.rs index 46d80608352dc..629099d85d726 100644 --- a/primitives/runtime/src/multiaddress.rs +++ b/primitives/runtime/src/multiaddress.rs @@ -62,9 +62,3 @@ impl From for MultiAddress Default for MultiAddress { - fn default() -> Self { - Self::Id(Default::default()) - } -} From 915bf1c75bc3d234aa956d34848e50c475bcd3d1 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 10 Dec 2021 16:22:32 +0100 Subject: [PATCH 33/47] Formatting --- client/tracing/proc-macro/src/lib.rs | 8 ++++---- client/transaction-pool/benches/basics.rs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client/tracing/proc-macro/src/lib.rs b/client/tracing/proc-macro/src/lib.rs index e9a4f58705b41..005fcf4ba0f51 100644 --- a/client/tracing/proc-macro/src/lib.rs +++ b/client/tracing/proc-macro/src/lib.rs @@ -56,7 +56,7 @@ use syn::{Error, Expr, Ident, ItemFn}; /// 2020-10-16 08:03:14 ✌️ version 2.0.0-47f7d3f2e-x86_64-linux-gnu /// 2020-10-16 08:03:14 ❤️ by Anonymous, 2017-2020 /// 2020-10-16 08:03:14 📋 Chain specification: Local Testnet -/// 2020-10-16 08:03:14 🏷 Node name: nice-glove-1401 +/// 2020-10-16 08:03:14 🏷 Node name: nice-glove-1401 /// 2020-10-16 08:03:14 👤 Role: LIGHT /// 2020-10-16 08:03:14 💾 Database: RocksDb at /tmp/substrate95w2Dk/chains/local_testnet/db /// 2020-10-16 08:03:14 ⛓ Native runtime: node-template-1 (node-template-1.tx1.au1) @@ -64,7 +64,7 @@ use syn::{Error, Expr, Ident, ItemFn}; /// 2020-10-16 08:03:14 [light] Loading GRANDPA authorities from genesis on what appears to be first startup. /// 2020-10-16 08:03:15 [light] ⏱ Loaded block-time = 6000 milliseconds from genesis on first-launch /// 2020-10-16 08:03:15 [light] Using default protocol ID "sup" because none is configured in the chain specs -/// 2020-10-16 08:03:15 [light] 🏷 Local node identity is: 12D3KooWHX4rkWT6a6N55Km7ZnvenGdShSKPkzJ3yj9DU5nqDtWR +/// 2020-10-16 08:03:15 [light] 🏷 Local node identity is: 12D3KooWHX4rkWT6a6N55Km7ZnvenGdShSKPkzJ3yj9DU5nqDtWR /// 2020-10-16 08:03:15 [light] 📦 Highest known block at #0 /// 2020-10-16 08:03:15 [light] 〽️ Prometheus server started at 127.0.0.1:9615 /// 2020-10-16 08:03:15 [light] Listening for new connections on 127.0.0.1:9944. @@ -90,7 +90,7 @@ use syn::{Error, Expr, Ident, ItemFn}; /// 2020-10-16 08:12:57 ✌️ version 2.0.0-efb9b822a-x86_64-linux-gnu /// 2020-10-16 08:12:57 ❤️ by Anonymous, 2017-2020 /// 2020-10-16 08:12:57 📋 Chain specification: Local Testnet -/// 2020-10-16 08:12:57 🏷 Node name: open-harbor-1619 +/// 2020-10-16 08:12:57 🏷 Node name: open-harbor-1619 /// 2020-10-16 08:12:57 👤 Role: LIGHT /// 2020-10-16 08:12:57 💾 Database: RocksDb at /tmp/substrate9T9Mtb/chains/local_testnet/db /// 2020-10-16 08:12:57 ⛓ Native runtime: node-template-1 (node-template-1.tx1.au1) @@ -98,7 +98,7 @@ use syn::{Error, Expr, Ident, ItemFn}; /// 2020-10-16 08:12:58 [open-harbor-1619] Loading GRANDPA authorities from genesis on what appears to be first startup. /// 2020-10-16 08:12:58 [open-harbor-1619] ⏱ Loaded block-time = 6000 milliseconds from genesis on first-launch /// 2020-10-16 08:12:58 [open-harbor-1619] Using default protocol ID "sup" because none is configured in the chain specs -/// 2020-10-16 08:12:58 [open-harbor-1619] 🏷 Local node identity is: 12D3KooWRzmYC8QTK1Pm8Cfvid3skTS4Hn54jc4AUtje8Rqbfgtp +/// 2020-10-16 08:12:58 [open-harbor-1619] 🏷 Local node identity is: 12D3KooWRzmYC8QTK1Pm8Cfvid3skTS4Hn54jc4AUtje8Rqbfgtp /// 2020-10-16 08:12:58 [open-harbor-1619] 📦 Highest known block at #0 /// 2020-10-16 08:12:58 [open-harbor-1619] 〽️ Prometheus server started at 127.0.0.1:9615 /// 2020-10-16 08:12:58 [open-harbor-1619] Listening for new connections on 127.0.0.1:9944. diff --git a/client/transaction-pool/benches/basics.rs b/client/transaction-pool/benches/basics.rs index ea1f0157c2666..cfb40c6cb2ab7 100644 --- a/client/transaction-pool/benches/basics.rs +++ b/client/transaction-pool/benches/basics.rs @@ -18,7 +18,7 @@ use criterion::{criterion_group, criterion_main, Criterion}; -use codec::{Encode, Decode}; +use codec::{Decode, Encode}; use futures::{ executor::block_on, future::{ready, Ready}, From cfb1418497e8201bdde872ed697625f38214558c Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 10 Dec 2021 16:27:30 +0100 Subject: [PATCH 34/47] Fixes --- Cargo.lock | 1 + bin/node/executor/Cargo.toml | 1 + bin/node/executor/tests/submit_transaction.rs | 13 +++++++------ 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0b5f58cecc643..23200d6918ed0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4613,6 +4613,7 @@ dependencies = [ "sp-consensus-babe", "sp-core", "sp-externalities", + "sp-keyring", "sp-keystore", "sp-runtime", "sp-state-machine", diff --git a/bin/node/executor/Cargo.toml b/bin/node/executor/Cargo.toml index 13ed4d313994c..f18616b1473b3 100644 --- a/bin/node/executor/Cargo.toml +++ b/bin/node/executor/Cargo.toml @@ -38,6 +38,7 @@ sp-application-crypto = { version = "4.0.0-dev", path = "../../../primitives/app sp-consensus-babe = { version = "0.10.0-dev", path = "../../../primitives/consensus/babe" } sp-runtime = { version = "4.0.0-dev", path = "../../../primitives/runtime" } sp-externalities = { version = "0.10.0", path = "../../../primitives/externalities" } +sp-keyring = { version = "4.0.0-dev", path = "../../../primitives/keyring" } wat = "1.0" futures = "0.3.9" diff --git a/bin/node/executor/tests/submit_transaction.rs b/bin/node/executor/tests/submit_transaction.rs index 77d5c6cc14365..e9689f9e70ff6 100644 --- a/bin/node/executor/tests/submit_transaction.rs +++ b/bin/node/executor/tests/submit_transaction.rs @@ -21,6 +21,7 @@ use node_runtime::{Executive, Indices, Runtime, UncheckedExtrinsic}; use sp_application_crypto::AppKey; use sp_core::offchain::{testing::TestTransactionPoolExt, TransactionPoolExt}; use sp_keystore::{testing::KeyStore, KeystoreExt, SyncCryptoStore}; +use sp_keyring::sr25519::Keyring::Alice; use std::sync::Arc; pub mod common; @@ -86,7 +87,7 @@ fn should_submit_signed_transaction() { let results = Signer::::all_accounts().send_signed_transaction(|_| { pallet_balances::Call::transfer { - dest: Default::default(), + dest: Alice.to_account_id().into(), value: Default::default(), } }); @@ -123,7 +124,7 @@ fn should_submit_signed_twice_from_the_same_account() { let result = Signer::::any_account().send_signed_transaction(|_| { pallet_balances::Call::transfer { - dest: Default::default(), + dest: Alice.to_account_id().into(), value: Default::default(), } }); @@ -135,7 +136,7 @@ fn should_submit_signed_twice_from_the_same_account() { let result = Signer::::any_account().send_signed_transaction(|_| { pallet_balances::Call::transfer { - dest: Default::default(), + dest: Alice.to_account_id().into(), value: Default::default(), } }); @@ -173,7 +174,7 @@ fn should_submit_signed_twice_from_all_accounts() { t.execute_with(|| { let results = Signer::::all_accounts() .send_signed_transaction(|_| { - pallet_balances::Call::transfer { dest: Default::default(), value: Default::default() } + pallet_balances::Call::transfer { dest: Alice.to_account_id().into(), value: Default::default() } }); let len = results.len(); @@ -184,7 +185,7 @@ fn should_submit_signed_twice_from_all_accounts() { // submit another one from the same account. The nonce should be incremented. let results = Signer::::all_accounts() .send_signed_transaction(|_| { - pallet_balances::Call::transfer { dest: Default::default(), value: Default::default() } + pallet_balances::Call::transfer { dest: Alice.to_account_id().into(), value: Default::default() } }); let len = results.len(); @@ -238,7 +239,7 @@ fn submitted_transaction_should_be_valid() { let results = Signer::::all_accounts().send_signed_transaction(|_| { pallet_balances::Call::transfer { - dest: Default::default(), + dest: Alice.to_account_id().into(), value: Default::default(), } }); From ed72cad1e8dd367a947587d6dc9a91ad1367316b Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 10 Dec 2021 16:28:19 +0100 Subject: [PATCH 35/47] Formatting --- bin/node/executor/tests/submit_transaction.rs | 2 +- client/cli/src/runner.rs | 4 ++-- client/network/src/service.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/node/executor/tests/submit_transaction.rs b/bin/node/executor/tests/submit_transaction.rs index e9689f9e70ff6..d561e08762dfa 100644 --- a/bin/node/executor/tests/submit_transaction.rs +++ b/bin/node/executor/tests/submit_transaction.rs @@ -20,8 +20,8 @@ use frame_system::offchain::{SendSignedTransaction, Signer, SubmitTransaction}; use node_runtime::{Executive, Indices, Runtime, UncheckedExtrinsic}; use sp_application_crypto::AppKey; use sp_core::offchain::{testing::TestTransactionPoolExt, TransactionPoolExt}; -use sp_keystore::{testing::KeyStore, KeystoreExt, SyncCryptoStore}; use sp_keyring::sr25519::Keyring::Alice; +use sp_keystore::{testing::KeyStore, KeystoreExt, SyncCryptoStore}; use std::sync::Arc; pub mod common; diff --git a/client/cli/src/runner.rs b/client/cli/src/runner.rs index 640b87584d4b6..34c1948012138 100644 --- a/client/cli/src/runner.rs +++ b/client/cli/src/runner.rs @@ -132,7 +132,7 @@ impl Runner { /// 2020-06-03 16:14:21 ✌️ version 2.0.0-rc3-f4940588c-x86_64-linux-gnu /// 2020-06-03 16:14:21 ❤️ by Parity Technologies , 2017-2020 /// 2020-06-03 16:14:21 📋 Chain specification: Flaming Fir - /// 2020-06-03 16:14:21 🏷 Node name: jolly-rod-7462 + /// 2020-06-03 16:14:21 🏷 Node name: jolly-rod-7462 /// 2020-06-03 16:14:21 👤 Role: FULL /// 2020-06-03 16:14:21 💾 Database: RocksDb at /tmp/c/chains/flamingfir7/db /// 2020-06-03 16:14:21 ⛓ Native runtime: node-251 (substrate-node-1.tx1.au10) @@ -199,7 +199,7 @@ pub fn print_node_infos(config: &Configuration) { info!("✌️ version {}", C::impl_version()); info!("❤️ by {}, {}-{}", C::author(), C::copyright_start_year(), Local::today().year()); info!("📋 Chain specification: {}", config.chain_spec.name()); - info!("🏷 Node name: {}", config.network.node_name); + info!("🏷 Node name: {}", config.network.node_name); info!("👤 Role: {}", config.display_role()); info!( "💾 Database: {} at {}", diff --git a/client/network/src/service.rs b/client/network/src/service.rs index e03bdcfa2f7ed..8b153bc4edf54 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -190,7 +190,7 @@ impl NetworkWorker { let local_peer_id = local_public.clone().to_peer_id(); info!( target: "sub-libp2p", - "🏷 Local node identity is: {}", + "🏷 Local node identity is: {}", local_peer_id.to_base58(), ); From 6e1b9e7f56c0900e71b022195c81794b0c7e7313 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 10 Dec 2021 17:42:56 +0100 Subject: [PATCH 36/47] Fixes --- frame/examples/basic/src/lib.rs | 10 +++ frame/system/src/extensions/check_genesis.rs | 12 +++- .../system/src/extensions/check_mortality.rs | 10 +++ .../src/extensions/check_non_zero_sender.rs | 10 +++ .../src/extensions/check_spec_version.rs | 13 +++- .../system/src/extensions/check_tx_version.rs | 11 ++- frame/system/src/extensions/check_weight.rs | 6 +- .../asset-tx-payment/src/lib.rs | 71 +++++++++---------- .../asset-tx-payment/src/tests.rs | 31 ++++---- frame/transaction-payment/src/lib.rs | 38 +++++----- .../runtime/src/generic/checked_extrinsic.rs | 10 +-- .../src/generic/unchecked_extrinsic.rs | 12 +++- primitives/runtime/src/traits.rs | 43 +++++++---- 13 files changed, 176 insertions(+), 101 deletions(-) diff --git a/frame/examples/basic/src/lib.rs b/frame/examples/basic/src/lib.rs index 25ff76f4d1514..2b443ff8e8dde 100644 --- a/frame/examples/basic/src/lib.rs +++ b/frame/examples/basic/src/lib.rs @@ -731,6 +731,16 @@ where Ok(()) } + fn pre_dispatch( + self, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result { + Ok(self.validate(who, call, info, len).map(|_| ())?) + } + fn validate( &self, _who: &Self::AccountId, diff --git a/frame/system/src/extensions/check_genesis.rs b/frame/system/src/extensions/check_genesis.rs index 9c5c890ee6098..d2b775b23cba9 100644 --- a/frame/system/src/extensions/check_genesis.rs +++ b/frame/system/src/extensions/check_genesis.rs @@ -19,7 +19,7 @@ use crate::{Config, Pallet}; use codec::{Decode, Encode}; use scale_info::TypeInfo; use sp_runtime::{ - traits::{SignedExtension, Zero}, + traits::{SignedExtension, Zero, DispatchInfoOf}, transaction_validity::TransactionValidityError, }; @@ -62,4 +62,14 @@ impl SignedExtension for CheckGenesis { fn additional_signed(&self) -> Result { Ok(>::block_hash(T::BlockNumber::zero())) } + + fn pre_dispatch( + self, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result { + Ok(self.validate(who, call, info, len).map(|_| ())?) + } } diff --git a/frame/system/src/extensions/check_mortality.rs b/frame/system/src/extensions/check_mortality.rs index 941f28dc6fc63..140a06298df33 100644 --- a/frame/system/src/extensions/check_mortality.rs +++ b/frame/system/src/extensions/check_mortality.rs @@ -85,6 +85,16 @@ impl SignedExtension for CheckMortality { Ok(>::block_hash(n)) } } + + fn pre_dispatch( + self, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result { + Ok(self.validate(who, call, info, len).map(|_| ())?) + } } #[cfg(test)] diff --git a/frame/system/src/extensions/check_non_zero_sender.rs b/frame/system/src/extensions/check_non_zero_sender.rs index 1d45ae17cb7ac..349bc0bede0d8 100644 --- a/frame/system/src/extensions/check_non_zero_sender.rs +++ b/frame/system/src/extensions/check_non_zero_sender.rs @@ -65,6 +65,16 @@ where Ok(()) } + fn pre_dispatch( + self, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result { + Ok(self.validate(who, call, info, len).map(|_| ())?) + } + fn validate( &self, who: &Self::AccountId, diff --git a/frame/system/src/extensions/check_spec_version.rs b/frame/system/src/extensions/check_spec_version.rs index 688abe99763a2..82bba6ef1af42 100644 --- a/frame/system/src/extensions/check_spec_version.rs +++ b/frame/system/src/extensions/check_spec_version.rs @@ -18,7 +18,8 @@ use crate::{Config, Pallet}; use codec::{Decode, Encode}; use scale_info::TypeInfo; -use sp_runtime::{traits::SignedExtension, transaction_validity::TransactionValidityError}; +use sp_runtime::traits::{SignedExtension, DispatchInfoOf}; +use sp_runtime::transaction_validity::TransactionValidityError; /// Ensure the runtime version registered in the transaction is the same as at present. /// @@ -59,4 +60,14 @@ impl SignedExtension for CheckSpecVersion { fn additional_signed(&self) -> Result { Ok(>::runtime_version().spec_version) } + + fn pre_dispatch( + self, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result { + Ok(self.validate(who, call, info, len).map(|_| ())?) + } } diff --git a/frame/system/src/extensions/check_tx_version.rs b/frame/system/src/extensions/check_tx_version.rs index f6bb53e1cba34..0efb0800bd720 100644 --- a/frame/system/src/extensions/check_tx_version.rs +++ b/frame/system/src/extensions/check_tx_version.rs @@ -18,7 +18,7 @@ use crate::{Config, Pallet}; use codec::{Decode, Encode}; use scale_info::TypeInfo; -use sp_runtime::{traits::SignedExtension, transaction_validity::TransactionValidityError}; +use sp_runtime::{traits::{SignedExtension, DispatchInfoOf}, transaction_validity::TransactionValidityError}; /// Ensure the transaction version registered in the transaction is the same as at present. /// @@ -59,4 +59,13 @@ impl SignedExtension for CheckTxVersion { fn additional_signed(&self) -> Result { Ok(>::runtime_version().transaction_version) } + fn pre_dispatch( + self, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result { + Ok(self.validate(who, call, info, len).map(|_| ())?) + } } diff --git a/frame/system/src/extensions/check_weight.rs b/frame/system/src/extensions/check_weight.rs index ca885accd660f..e4edd82567499 100644 --- a/frame/system/src/extensions/check_weight.rs +++ b/frame/system/src/extensions/check_weight.rs @@ -223,7 +223,7 @@ where } fn post_dispatch( - _pre: Self::Pre, + _pre: Option, info: &DispatchInfoOf, post_info: &PostDispatchInfoOf, _len: usize, @@ -563,7 +563,7 @@ mod tests { let pre = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &info, len).unwrap(); assert_eq!(BlockWeight::::get().total(), info.weight + 256); - assert_ok!(CheckWeight::::post_dispatch(pre, &info, &post_info, len, &Ok(()))); + assert_ok!(CheckWeight::::post_dispatch(Some(pre), &info, &post_info, len, &Ok(()))); assert_eq!(BlockWeight::::get().total(), post_info.actual_weight.unwrap() + 256); }) } @@ -587,7 +587,7 @@ mod tests { info.weight + 128 + block_weights().get(DispatchClass::Normal).base_extrinsic, ); - assert_ok!(CheckWeight::::post_dispatch(pre, &info, &post_info, len, &Ok(()))); + assert_ok!(CheckWeight::::post_dispatch(Some(pre), &info, &post_info, len, &Ok(()))); assert_eq!( BlockWeight::::get().total(), info.weight + 128 + block_weights().get(DispatchClass::Normal).base_extrinsic, diff --git a/frame/transaction-payment/asset-tx-payment/src/lib.rs b/frame/transaction-payment/asset-tx-payment/src/lib.rs index 49fac2a382778..ba3e24483779f 100644 --- a/frame/transaction-payment/asset-tx-payment/src/lib.rs +++ b/frame/transaction-payment/asset-tx-payment/src/lib.rs @@ -210,7 +210,7 @@ where // tip BalanceOf, // who paid the fee - Option, + Self::AccountId, // imbalance resulting from withdrawing the fee InitialPayment, ); @@ -240,49 +240,48 @@ where len: usize, ) -> Result { let (_fee, initial_payment) = self.withdraw_fee(who, call, info, len)?; - Ok((self.tip, Some(who.clone()), initial_payment)) + Ok((self.tip, who.clone(), initial_payment)) } fn post_dispatch( - pre: Self::Pre, + pre: Option, info: &DispatchInfoOf, post_info: &PostDispatchInfoOf, len: usize, result: &DispatchResult, ) -> Result<(), TransactionValidityError> { - let (tip, who, initial_payment) = pre; - match initial_payment { - InitialPayment::Native(already_withdrawn) => { - pallet_transaction_payment::ChargeTransactionPayment::::post_dispatch( - (tip, who, already_withdrawn), - info, - post_info, - len, - result, - )?; - }, - InitialPayment::Asset(already_withdrawn) => { - let actual_fee = pallet_transaction_payment::Pallet::::compute_actual_fee( - len as u32, info, post_info, tip, - ); - let who = - who.ok_or(TransactionValidityError::Invalid(InvalidTransaction::Custom(255)))?; - T::OnChargeAssetTransaction::correct_and_deposit_fee( - &who, - info, - post_info, - actual_fee.into(), - tip.into(), - already_withdrawn.into(), - )?; - }, - InitialPayment::Nothing => { - // `actual_fee` should be zero here for any signed extrinsic. It would be non-zero - // here in case of unsigned extrinsics as they don't pay fees but - // `compute_actual_fee` is not aware of them. In both cases it's fine to just move - // ahead without adjusting the fee, though, so we do nothing. - debug_assert!(tip.is_zero(), "tip should be zero if initial fee was zero."); - }, + if let Some((tip, who, initial_payment)) = pre { + match initial_payment { + InitialPayment::Native(already_withdrawn) => { + pallet_transaction_payment::ChargeTransactionPayment::::post_dispatch( + Some((tip, who, already_withdrawn)), + info, + post_info, + len, + result, + )?; + }, + InitialPayment::Asset(already_withdrawn) => { + let actual_fee = pallet_transaction_payment::Pallet::::compute_actual_fee( + len as u32, info, post_info, tip, + ); + T::OnChargeAssetTransaction::correct_and_deposit_fee( + &who, + info, + post_info, + actual_fee.into(), + tip.into(), + already_withdrawn.into(), + )?; + }, + InitialPayment::Nothing => { + // `actual_fee` should be zero here for any signed extrinsic. It would be non-zero + // here in case of unsigned extrinsics as they don't pay fees but + // `compute_actual_fee` is not aware of them. In both cases it's fine to just move + // ahead without adjusting the fee, though, so we do nothing. + debug_assert!(tip.is_zero(), "tip should be zero if initial fee was zero."); + }, + } } Ok(()) diff --git a/frame/transaction-payment/asset-tx-payment/src/tests.rs b/frame/transaction-payment/asset-tx-payment/src/tests.rs index 289bb820953f8..791929dd16c92 100644 --- a/frame/transaction-payment/asset-tx-payment/src/tests.rs +++ b/frame/transaction-payment/asset-tx-payment/src/tests.rs @@ -305,7 +305,7 @@ fn transaction_payment_in_native_possible() { assert_eq!(Balances::free_balance(1), initial_balance - 5 - 5 - 10); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + Some(pre), &info_from_weight(5), &default_post_info(), len, @@ -320,7 +320,7 @@ fn transaction_payment_in_native_possible() { assert_eq!(Balances::free_balance(2), initial_balance_for_2 - 5 - 10 - 100 - 5); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + Some(pre), &info_from_weight(100), &post_info_from_weight(50), len, @@ -371,7 +371,7 @@ fn transaction_payment_in_asset_possible() { assert_eq!(Assets::balance(asset_id, BLOCK_AUTHOR), 0); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + Some(pre), &info_from_weight(weight), &default_post_info(), len, @@ -424,7 +424,7 @@ fn transaction_payment_without_fee() { assert_eq!(Assets::balance(asset_id, BLOCK_AUTHOR), 0); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + Some(pre), &info_from_weight(weight), &post_info_from_pays(Pays::No), len, @@ -476,7 +476,7 @@ fn asset_transaction_payment_with_tip_and_refund() { let final_weight = 50; assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + Some(pre), &info_from_weight(weight), &post_info_from_weight(final_weight), len, @@ -529,7 +529,7 @@ fn payment_from_account_with_only_assets() { assert_eq!(Assets::balance(asset_id, caller), balance - fee); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + Some(pre), &info_from_weight(weight), &default_post_info(), len, @@ -613,7 +613,7 @@ fn converted_fee_is_never_zero_if_input_fee_is_not() { assert_eq!(Assets::balance(asset_id, caller), balance); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + Some(pre), &info_from_pays(Pays::No), &post_info_from_pays(Pays::No), len, @@ -628,7 +628,7 @@ fn converted_fee_is_never_zero_if_input_fee_is_not() { assert_eq!(Assets::balance(asset_id, caller), balance - 1); assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + Some(pre), &info_from_weight(weight), &default_post_info(), len, @@ -685,7 +685,7 @@ fn post_dispatch_fee_is_zero_if_pre_dispatch_fee_is_zero() { // `Pays::Yes` on post-dispatch does not mean we pay (we never charge more than the // initial fee) assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + Some(pre), &info_from_pays(Pays::No), &post_info_from_pays(Pays::Yes), len, @@ -722,25 +722,18 @@ fn post_dispatch_fee_is_zero_if_unsigned_pre_dispatch_fee_is_zero() { assert_eq!(Assets::balance(asset_id, caller), balance); let weight = 1; let len = 1; - let pre = ChargeAssetTxPayment::::pre_dispatch_unsigned( + ChargeAssetTxPayment::::pre_dispatch_unsigned( CALL, &info_from_weight(weight), len, - ) - .unwrap(); + ).unwrap(); assert_eq!(Assets::balance(asset_id, caller), balance); - let (_tip, _who, initial_payment) = ⪯ - let not_paying = match initial_payment { - &InitialPayment::Nothing => true, - _ => false, - }; - assert!(not_paying, "initial payment is Nothing for unsigned extrinsics"); // `Pays::Yes` on post-dispatch does not mean we pay (we never charge more than the // initial fee) assert_ok!(ChargeAssetTxPayment::::post_dispatch( - pre, + None, &info_from_weight(weight), &post_info_from_pays(Pays::Yes), len, diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index 30a1c26e5e8be..c7ccdafc78283 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -56,8 +56,7 @@ use sp_runtime::{ Saturating, SignedExtension, Zero, }, transaction_validity::{ - InvalidTransaction, TransactionPriority, TransactionValidity, TransactionValidityError, - ValidTransaction, + TransactionPriority, TransactionValidity, TransactionValidityError, ValidTransaction, }, FixedPointNumber, FixedPointOperand, FixedU128, Perquintill, RuntimeDebug, }; @@ -706,7 +705,7 @@ where // tip BalanceOf, // who paid the fee - this is an option to allow for a Default impl. - Option, + Self::AccountId, // imbalance resulting from withdrawing the fee <::OnChargeTransaction as OnChargeTransaction>::LiquidityInfo, ); @@ -737,23 +736,22 @@ where len: usize, ) -> Result { let (_fee, imbalance) = self.withdraw_fee(who, call, info, len)?; - Ok((self.0, Some(who.clone()), imbalance)) + Ok((self.0, who.clone(), imbalance)) } fn post_dispatch( - pre: Self::Pre, + maybe_pre: Option, info: &DispatchInfoOf, post_info: &PostDispatchInfoOf, len: usize, _result: &DispatchResult, ) -> Result<(), TransactionValidityError> { - let (tip, who, imbalance) = pre; - let actual_fee = Pallet::::compute_actual_fee(len as u32, info, post_info, tip); - let e = TransactionValidityError::Invalid(InvalidTransaction::Custom(255)); - let who = who.clone().ok_or(e)?; - T::OnChargeTransaction::correct_and_deposit_fee( - &who, info, post_info, actual_fee, tip, imbalance, - )?; + if let Some((tip, who, imbalance)) = maybe_pre { + let actual_fee = Pallet::::compute_actual_fee(len as u32, info, post_info, tip); + T::OnChargeTransaction::correct_and_deposit_fee( + &who, info, post_info, actual_fee, tip, imbalance, + )?; + } Ok(()) } } @@ -1017,7 +1015,7 @@ mod tests { assert_eq!(Balances::free_balance(1), 100 - 5 - 5 - 10); assert_ok!(ChargeTransactionPayment::::post_dispatch( - pre, + Some(pre), &info_from_weight(5), &default_post_info(), len, @@ -1035,7 +1033,7 @@ mod tests { assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5); assert_ok!(ChargeTransactionPayment::::post_dispatch( - pre, + Some(pre), &info_from_weight(100), &post_info_from_weight(50), len, @@ -1064,7 +1062,7 @@ mod tests { assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 150 - 5); assert_ok!(ChargeTransactionPayment::::post_dispatch( - pre, + Some(pre), &info_from_weight(100), &post_info_from_weight(50), len, @@ -1359,7 +1357,7 @@ mod tests { assert_eq!(Balances::free_balance(2), 0); assert_ok!(ChargeTransactionPayment::::post_dispatch( - pre, + Some(pre), &info_from_weight(100), &post_info_from_weight(50), len, @@ -1393,7 +1391,7 @@ mod tests { assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5); assert_ok!(ChargeTransactionPayment::::post_dispatch( - pre, + Some(pre), &info_from_weight(100), &post_info_from_weight(101), len, @@ -1421,7 +1419,7 @@ mod tests { .unwrap(); assert_eq!(Balances::total_balance(&user), 0); assert_ok!(ChargeTransactionPayment::::post_dispatch( - pre, + Some(pre), &dispatch_info, &default_post_info(), len, @@ -1453,7 +1451,7 @@ mod tests { .unwrap(); ChargeTransactionPayment::::post_dispatch( - pre, + Some(pre), &info, &post_info, len, @@ -1604,7 +1602,7 @@ mod tests { .unwrap(); ChargeTransactionPayment::::post_dispatch( - pre, + Some(pre), &info, &post_info, len, diff --git a/primitives/runtime/src/generic/checked_extrinsic.rs b/primitives/runtime/src/generic/checked_extrinsic.rs index b2044a6cf74fd..816d4a164b004 100644 --- a/primitives/runtime/src/generic/checked_extrinsic.rs +++ b/primitives/runtime/src/generic/checked_extrinsic.rs @@ -70,20 +70,20 @@ where info: &DispatchInfoOf, len: usize, ) -> crate::ApplyExtrinsicResultWithInfo> { - let (maybe_who, pre) = if let Some((id, extra)) = self.signed { + let (maybe_who, maybe_pre) = if let Some((id, extra)) = self.signed { let pre = Extra::pre_dispatch(extra, &id, &self.function, info, len)?; - (Some(id), pre) + (Some(id), Some(pre)) } else { - let pre = Extra::pre_dispatch_unsigned(&self.function, info, len)?; + Extra::pre_dispatch_unsigned(&self.function, info, len)?; U::pre_dispatch(&self.function)?; - (None, pre) + (None, None) }; let res = self.function.dispatch(Origin::from(maybe_who)); let post_info = match res { Ok(info) => info, Err(err) => err.post_info, }; - Extra::post_dispatch(pre, info, &post_info, len, &res.map(|_| ()).map_err(|e| e.error))?; + Extra::post_dispatch(maybe_pre, info, &post_info, len, &res.map(|_| ()).map_err(|e| e.error))?; Ok(res) } } diff --git a/primitives/runtime/src/generic/unchecked_extrinsic.rs b/primitives/runtime/src/generic/unchecked_extrinsic.rs index 95f4f2f3584d9..3837eeeeeb077 100644 --- a/primitives/runtime/src/generic/unchecked_extrinsic.rs +++ b/primitives/runtime/src/generic/unchecked_extrinsic.rs @@ -364,7 +364,7 @@ mod tests { use crate::{ codec::{Decode, Encode}, testing::TestSignature as TestSig, - traits::{IdentityLookup, SignedExtension}, + traits::{IdentityLookup, SignedExtension, DispatchInfoOf}, }; use sp_io::hashing::blake2_256; @@ -387,6 +387,16 @@ mod tests { fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) } + + fn pre_dispatch( + self, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result { + Ok(self.validate(who, call, info, len).map(|_| ())?) + } } type Ex = UncheckedExtrinsic; diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 547fdb6d254ac..9097860bd1877 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -850,9 +850,8 @@ pub trait SignedExtension: /// from the transaction using the `additional_signed` function. type AdditionalSigned: Encode + TypeInfo; - // TODO: Refactor to remove the Default bound. /// The type that encodes information that can be passed from pre_dispatch to post-dispatch. - type Pre: Default; + type Pre; /// Construct any additional data that should be in the signed payload of the transaction. Can /// also perform any pre-signature-verification checks and return an error if needed. @@ -891,11 +890,7 @@ pub trait SignedExtension: call: &Self::Call, info: &DispatchInfoOf, len: usize, - ) -> Result { - self.validate(who, call, info, len) - .map(|_| Self::Pre::default()) - .map_err(Into::into) - } + ) -> Result; /// Validate an unsigned transaction for the transaction queue. /// @@ -925,14 +920,17 @@ pub trait SignedExtension: call: &Self::Call, info: &DispatchInfoOf, len: usize, - ) -> Result { + ) -> Result<(), TransactionValidityError> { Self::validate_unsigned(call, info, len) - .map(|_| Self::Pre::default()) + .map(|_| ()) .map_err(Into::into) } /// Do any post-flight stuff for an extrinsic. /// + /// If the transaction is signed, then `_pre` will contain the output of `validate_unsigned`, + /// and `None` otherwise. + /// /// This gets given the `DispatchResult` `_result` from the extrinsic and can, if desired, /// introduce a `TransactionValidityError`, causing the block to become invalid for including /// it. @@ -945,7 +943,7 @@ pub trait SignedExtension: /// introduced by the current block author; generally this implies that it is an inherent and /// will come from either an offchain-worker or via `InherentData`. fn post_dispatch( - _pre: Self::Pre, + _pre: Option, _info: &DispatchInfoOf, _post_info: &PostDispatchInfoOf, _len: usize, @@ -1030,18 +1028,26 @@ impl SignedExtension for Tuple { call: &Self::Call, info: &DispatchInfoOf, len: usize, - ) -> Result { - Ok(for_tuples!( ( #( Tuple::pre_dispatch_unsigned(call, info, len)? ),* ) )) + ) -> Result<(), TransactionValidityError> { + for_tuples!( #( Tuple::pre_dispatch_unsigned(call, info, len)?; )* ); + Ok(()) } fn post_dispatch( - pre: Self::Pre, + pre: Option, info: &DispatchInfoOf, post_info: &PostDispatchInfoOf, len: usize, result: &DispatchResult, ) -> Result<(), TransactionValidityError> { - for_tuples!( #( Tuple::post_dispatch(pre.Tuple, info, post_info, len, result)?; )* ); + match pre { + Some(x) => { + for_tuples!( #( Tuple::post_dispatch(Some(x.Tuple), info, post_info, len, result)?; )* ); + }, + None => { + for_tuples!( #( Tuple::post_dispatch(None, info, post_info, len, result)?; )* ); + }, + } Ok(()) } @@ -1063,6 +1069,15 @@ impl SignedExtension for () { fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) } + fn pre_dispatch( + self, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result { + Ok(self.validate(who, call, info, len).map(|_| ())?) + } } /// An "executable" piece of information, used by the standard Substrate Executive in order to From 5fab98c2844487427437bdaba196a442cac3deda Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 10 Dec 2021 17:43:04 +0100 Subject: [PATCH 37/47] Formatting --- frame/system/src/extensions/check_genesis.rs | 2 +- .../system/src/extensions/check_spec_version.rs | 6 ++++-- frame/system/src/extensions/check_tx_version.rs | 5 ++++- frame/system/src/extensions/check_weight.rs | 16 ++++++++++++++-- .../asset-tx-payment/src/lib.rs | 8 ++++---- .../asset-tx-payment/src/tests.rs | 3 ++- .../runtime/src/generic/checked_extrinsic.rs | 8 +++++++- .../runtime/src/generic/unchecked_extrinsic.rs | 2 +- primitives/runtime/src/traits.rs | 4 +--- 9 files changed, 38 insertions(+), 16 deletions(-) diff --git a/frame/system/src/extensions/check_genesis.rs b/frame/system/src/extensions/check_genesis.rs index d2b775b23cba9..c758f9b6cb6ee 100644 --- a/frame/system/src/extensions/check_genesis.rs +++ b/frame/system/src/extensions/check_genesis.rs @@ -19,7 +19,7 @@ use crate::{Config, Pallet}; use codec::{Decode, Encode}; use scale_info::TypeInfo; use sp_runtime::{ - traits::{SignedExtension, Zero, DispatchInfoOf}, + traits::{DispatchInfoOf, SignedExtension, Zero}, transaction_validity::TransactionValidityError, }; diff --git a/frame/system/src/extensions/check_spec_version.rs b/frame/system/src/extensions/check_spec_version.rs index 82bba6ef1af42..1e1a31d4d870d 100644 --- a/frame/system/src/extensions/check_spec_version.rs +++ b/frame/system/src/extensions/check_spec_version.rs @@ -18,8 +18,10 @@ use crate::{Config, Pallet}; use codec::{Decode, Encode}; use scale_info::TypeInfo; -use sp_runtime::traits::{SignedExtension, DispatchInfoOf}; -use sp_runtime::transaction_validity::TransactionValidityError; +use sp_runtime::{ + traits::{DispatchInfoOf, SignedExtension}, + transaction_validity::TransactionValidityError, +}; /// Ensure the runtime version registered in the transaction is the same as at present. /// diff --git a/frame/system/src/extensions/check_tx_version.rs b/frame/system/src/extensions/check_tx_version.rs index 0efb0800bd720..e1e7b070e831d 100644 --- a/frame/system/src/extensions/check_tx_version.rs +++ b/frame/system/src/extensions/check_tx_version.rs @@ -18,7 +18,10 @@ use crate::{Config, Pallet}; use codec::{Decode, Encode}; use scale_info::TypeInfo; -use sp_runtime::{traits::{SignedExtension, DispatchInfoOf}, transaction_validity::TransactionValidityError}; +use sp_runtime::{ + traits::{DispatchInfoOf, SignedExtension}, + transaction_validity::TransactionValidityError, +}; /// Ensure the transaction version registered in the transaction is the same as at present. /// diff --git a/frame/system/src/extensions/check_weight.rs b/frame/system/src/extensions/check_weight.rs index e4edd82567499..8f83b7594cb5b 100644 --- a/frame/system/src/extensions/check_weight.rs +++ b/frame/system/src/extensions/check_weight.rs @@ -563,7 +563,13 @@ mod tests { let pre = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &info, len).unwrap(); assert_eq!(BlockWeight::::get().total(), info.weight + 256); - assert_ok!(CheckWeight::::post_dispatch(Some(pre), &info, &post_info, len, &Ok(()))); + assert_ok!(CheckWeight::::post_dispatch( + Some(pre), + &info, + &post_info, + len, + &Ok(()) + )); assert_eq!(BlockWeight::::get().total(), post_info.actual_weight.unwrap() + 256); }) } @@ -587,7 +593,13 @@ mod tests { info.weight + 128 + block_weights().get(DispatchClass::Normal).base_extrinsic, ); - assert_ok!(CheckWeight::::post_dispatch(Some(pre), &info, &post_info, len, &Ok(()))); + assert_ok!(CheckWeight::::post_dispatch( + Some(pre), + &info, + &post_info, + len, + &Ok(()) + )); assert_eq!( BlockWeight::::get().total(), info.weight + 128 + block_weights().get(DispatchClass::Normal).base_extrinsic, diff --git a/frame/transaction-payment/asset-tx-payment/src/lib.rs b/frame/transaction-payment/asset-tx-payment/src/lib.rs index ba3e24483779f..be16fa45f9534 100644 --- a/frame/transaction-payment/asset-tx-payment/src/lib.rs +++ b/frame/transaction-payment/asset-tx-payment/src/lib.rs @@ -275,10 +275,10 @@ where )?; }, InitialPayment::Nothing => { - // `actual_fee` should be zero here for any signed extrinsic. It would be non-zero - // here in case of unsigned extrinsics as they don't pay fees but - // `compute_actual_fee` is not aware of them. In both cases it's fine to just move - // ahead without adjusting the fee, though, so we do nothing. + // `actual_fee` should be zero here for any signed extrinsic. It would be + // non-zero here in case of unsigned extrinsics as they don't pay fees but + // `compute_actual_fee` is not aware of them. In both cases it's fine to just + // move ahead without adjusting the fee, though, so we do nothing. debug_assert!(tip.is_zero(), "tip should be zero if initial fee was zero."); }, } diff --git a/frame/transaction-payment/asset-tx-payment/src/tests.rs b/frame/transaction-payment/asset-tx-payment/src/tests.rs index 791929dd16c92..c6c60cfe237d5 100644 --- a/frame/transaction-payment/asset-tx-payment/src/tests.rs +++ b/frame/transaction-payment/asset-tx-payment/src/tests.rs @@ -726,7 +726,8 @@ fn post_dispatch_fee_is_zero_if_unsigned_pre_dispatch_fee_is_zero() { CALL, &info_from_weight(weight), len, - ).unwrap(); + ) + .unwrap(); assert_eq!(Assets::balance(asset_id, caller), balance); diff --git a/primitives/runtime/src/generic/checked_extrinsic.rs b/primitives/runtime/src/generic/checked_extrinsic.rs index 816d4a164b004..f65e4ead089fe 100644 --- a/primitives/runtime/src/generic/checked_extrinsic.rs +++ b/primitives/runtime/src/generic/checked_extrinsic.rs @@ -83,7 +83,13 @@ where Ok(info) => info, Err(err) => err.post_info, }; - Extra::post_dispatch(maybe_pre, info, &post_info, len, &res.map(|_| ()).map_err(|e| e.error))?; + Extra::post_dispatch( + maybe_pre, + info, + &post_info, + len, + &res.map(|_| ()).map_err(|e| e.error), + )?; Ok(res) } } diff --git a/primitives/runtime/src/generic/unchecked_extrinsic.rs b/primitives/runtime/src/generic/unchecked_extrinsic.rs index 3837eeeeeb077..53e7c349f2a76 100644 --- a/primitives/runtime/src/generic/unchecked_extrinsic.rs +++ b/primitives/runtime/src/generic/unchecked_extrinsic.rs @@ -364,7 +364,7 @@ mod tests { use crate::{ codec::{Decode, Encode}, testing::TestSignature as TestSig, - traits::{IdentityLookup, SignedExtension, DispatchInfoOf}, + traits::{DispatchInfoOf, IdentityLookup, SignedExtension}, }; use sp_io::hashing::blake2_256; diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 9097860bd1877..52f41c3da988f 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -921,9 +921,7 @@ pub trait SignedExtension: info: &DispatchInfoOf, len: usize, ) -> Result<(), TransactionValidityError> { - Self::validate_unsigned(call, info, len) - .map(|_| ()) - .map_err(Into::into) + Self::validate_unsigned(call, info, len).map(|_| ()).map_err(Into::into) } /// Do any post-flight stuff for an extrinsic. From 67492d15466ed784843a1ecad75a13ff02cc7b47 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 11 Dec 2021 12:15:43 +0100 Subject: [PATCH 38/47] Fixes --- client/cli/src/commands/inspect_key.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cli/src/commands/inspect_key.rs b/client/cli/src/commands/inspect_key.rs index 48b045f4cbaf3..f6d856e589cb9 100644 --- a/client/cli/src/commands/inspect_key.rs +++ b/client/cli/src/commands/inspect_key.rs @@ -156,7 +156,7 @@ fn expect_public_from_phrase( #[cfg(test)] mod tests { use super::*; - use sp_core::crypto::{Pair, Public}; + use sp_core::crypto::{Pair, ByteArray}; use sp_runtime::traits::IdentifyAccount; use structopt::StructOpt; From b465b2d9e8ce9f04b72187dd4cada4891e8ac088 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 11 Dec 2021 12:21:08 +0100 Subject: [PATCH 39/47] Formatting --- client/cli/src/commands/inspect_key.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cli/src/commands/inspect_key.rs b/client/cli/src/commands/inspect_key.rs index f6d856e589cb9..55dd5dfe80d81 100644 --- a/client/cli/src/commands/inspect_key.rs +++ b/client/cli/src/commands/inspect_key.rs @@ -156,7 +156,7 @@ fn expect_public_from_phrase( #[cfg(test)] mod tests { use super::*; - use sp_core::crypto::{Pair, ByteArray}; + use sp_core::crypto::{ByteArray, Pair}; use sp_runtime::traits::IdentifyAccount; use structopt::StructOpt; From 87351bb5337b4e9873fcfb9f39eb495d5a804492 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Sun, 12 Dec 2021 10:50:35 +0100 Subject: [PATCH 40/47] Update client/keystore/src/local.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- client/keystore/src/local.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/keystore/src/local.rs b/client/keystore/src/local.rs index f83b3e75f4ed4..97bd410a15088 100644 --- a/client/keystore/src/local.rs +++ b/client/keystore/src/local.rs @@ -192,7 +192,7 @@ impl SyncCryptoStore for LocalKeystore { match key.0 { ed25519::CRYPTO_ID => { let pub_key = ed25519::Public::from_slice(key.1.as_slice()) - .map_err(|()| TraitError::Other("Corrupted key - Invalid size".into()))?; + .map_err(|()| TraitError::Other("Corrupted public key - Invalid size".into()))?; let key_pair = self .0 .read() From f7939bb8261d3c65f31102a8252e1da97775eff5 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Sun, 12 Dec 2021 10:50:44 +0100 Subject: [PATCH 41/47] Update client/finality-grandpa/src/lib.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- client/finality-grandpa/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/finality-grandpa/src/lib.rs b/client/finality-grandpa/src/lib.rs index 277e9459bfd60..656d8ea434349 100644 --- a/client/finality-grandpa/src/lib.rs +++ b/client/finality-grandpa/src/lib.rs @@ -942,7 +942,7 @@ where let maybe_authority_id = local_authority_id(&self.env.voters, self.env.config.keystore.as_ref()); - let authority_id = maybe_authority_id.map_or("".into(), |s| s.to_string()); + let authority_id = maybe_authority_id.map_or("".into(), |s| s.to_string()); telemetry!( self.telemetry; From 5e157c97f8351ef3ace554a3c310d5542dd17f9f Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Sun, 12 Dec 2021 10:50:59 +0100 Subject: [PATCH 42/47] Update client/keystore/src/local.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- client/keystore/src/local.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/keystore/src/local.rs b/client/keystore/src/local.rs index 97bd410a15088..6f41c62a39460 100644 --- a/client/keystore/src/local.rs +++ b/client/keystore/src/local.rs @@ -202,7 +202,7 @@ impl SyncCryptoStore for LocalKeystore { }, sr25519::CRYPTO_ID => { let pub_key = sr25519::Public::from_slice(key.1.as_slice()) - .map_err(|()| TraitError::Other("Corrupted key - Invalid size".into()))?; + .map_err(|()| TraitError::Other("Corrupted public key - Invalid size".into()))?; let key_pair = self .0 .read() From 3557e1341c1732d1b9020046fc25629a847e9be2 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Sun, 12 Dec 2021 10:51:08 +0100 Subject: [PATCH 43/47] Update client/keystore/src/local.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- client/keystore/src/local.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/keystore/src/local.rs b/client/keystore/src/local.rs index 6f41c62a39460..8089faa15b02e 100644 --- a/client/keystore/src/local.rs +++ b/client/keystore/src/local.rs @@ -212,7 +212,7 @@ impl SyncCryptoStore for LocalKeystore { }, ecdsa::CRYPTO_ID => { let pub_key = ecdsa::Public::from_slice(key.1.as_slice()) - .map_err(|()| TraitError::Other("Corrupted key - Invalid size".into()))?; + .map_err(|()| TraitError::Other("Corrupted public key - Invalid size".into()))?; let key_pair = self .0 .read() From c147de9d555fd1458be1fa668f993ae4b6e7312f Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Sun, 12 Dec 2021 10:51:20 +0100 Subject: [PATCH 44/47] Update frame/staking/src/lib.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- frame/staking/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 9354f2ab654cb..2a4f73f57a6fd 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -643,6 +643,7 @@ pub struct UnappliedSlash { } impl UnappliedSlash { + /// Initializes the default object using the given `validator`. pub fn default_from(validator: AccountId) -> Self { Self { validator, From fa596c1a6919b4d0073ebe77cb4c300004ab0e6c Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Sun, 12 Dec 2021 10:51:27 +0100 Subject: [PATCH 45/47] Update frame/staking/src/lib.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- frame/staking/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 2a4f73f57a6fd..7bc3ac8aa7075 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -465,6 +465,7 @@ pub struct StakingLedger { impl StakingLedger { + /// Initializes the default object using the given `validator`. pub fn default_from(stash: AccountId) -> Self { Self { stash, From aa7ac285478d2e1c5556f98653a42eb837ea88bb Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Sun, 12 Dec 2021 10:52:52 +0100 Subject: [PATCH 46/47] Update primitives/runtime/src/traits.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- primitives/runtime/src/traits.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 52f41c3da988f..0ddd8cae93ea7 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -926,7 +926,7 @@ pub trait SignedExtension: /// Do any post-flight stuff for an extrinsic. /// - /// If the transaction is signed, then `_pre` will contain the output of `validate_unsigned`, + /// If the transaction is signed, then `_pre` will contain the output of `pre_dispatch`, /// and `None` otherwise. /// /// This gets given the `DispatchResult` `_result` from the extrinsic and can, if desired, From 175596a9453cb5b7380b14ea0b3004007c6e9a38 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 13 Dec 2021 11:44:00 +0100 Subject: [PATCH 47/47] Formatting --- client/keystore/src/local.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/client/keystore/src/local.rs b/client/keystore/src/local.rs index 8089faa15b02e..be9bb5e145977 100644 --- a/client/keystore/src/local.rs +++ b/client/keystore/src/local.rs @@ -191,8 +191,9 @@ impl SyncCryptoStore for LocalKeystore { ) -> std::result::Result>, TraitError> { match key.0 { ed25519::CRYPTO_ID => { - let pub_key = ed25519::Public::from_slice(key.1.as_slice()) - .map_err(|()| TraitError::Other("Corrupted public key - Invalid size".into()))?; + let pub_key = ed25519::Public::from_slice(key.1.as_slice()).map_err(|()| { + TraitError::Other("Corrupted public key - Invalid size".into()) + })?; let key_pair = self .0 .read() @@ -201,8 +202,9 @@ impl SyncCryptoStore for LocalKeystore { key_pair.map(|k| k.sign(msg).encode()).map(Ok).transpose() }, sr25519::CRYPTO_ID => { - let pub_key = sr25519::Public::from_slice(key.1.as_slice()) - .map_err(|()| TraitError::Other("Corrupted public key - Invalid size".into()))?; + let pub_key = sr25519::Public::from_slice(key.1.as_slice()).map_err(|()| { + TraitError::Other("Corrupted public key - Invalid size".into()) + })?; let key_pair = self .0 .read() @@ -211,8 +213,9 @@ impl SyncCryptoStore for LocalKeystore { key_pair.map(|k| k.sign(msg).encode()).map(Ok).transpose() }, ecdsa::CRYPTO_ID => { - let pub_key = ecdsa::Public::from_slice(key.1.as_slice()) - .map_err(|()| TraitError::Other("Corrupted public key - Invalid size".into()))?; + let pub_key = ecdsa::Public::from_slice(key.1.as_slice()).map_err(|()| { + TraitError::Other("Corrupted public key - Invalid size".into()) + })?; let key_pair = self .0 .read()