Remove Default bound for AccountId (#10403)

* Remove Default for AccountId

* More removals of default

* Update frame/authorship/src/lib.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Update frame/authorship/src/lib.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Update frame/authorship/src/lib.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Update frame/authorship/src/lib.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* More work

* More work

* Remove old code

* More work

* pallet-asset-tx-payment

* tips

* sc-consensus-babe

* sc-finality-grandpa

* sc-consensus-babe-rpc

* sc-cli

* make npos crates accept non-default account (#10420)

* minimal changes to make npos pallets all work

* make this pesky reduce.rs a bit cleaner

* more work

* more work

* Tests build

* Fix imonline tests

* Formatting

* Fixes

* Fixes

* Fix bench

* Fixes

* Fixes

* Fixes

* Fixes

* Fixes

* Formatting

* Fixes

* Formatting

* Fixes

* Formatting

* Fixes

* Formatting

* Fixes

* Formatting

* Update client/keystore/src/local.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Update client/finality-grandpa/src/lib.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Update client/keystore/src/local.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Update client/keystore/src/local.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Update frame/staking/src/lib.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Update frame/staking/src/lib.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Update primitives/runtime/src/traits.rs

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Formatting

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
Co-authored-by: kianenigma <kian@parity.io>
This commit is contained in:
Gavin Wood
2021-12-13 15:03:59 +01:00
committed by GitHub
parent a4ccc26e33
commit 1e24e45ea1
118 changed files with 998 additions and 4181 deletions
@@ -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();
@@ -57,6 +57,6 @@ impl RuntimePublic for Public {
}
fn to_raw_vec(&self) -> Vec<u8> {
sp_core::crypto::Public::to_raw_vec(self)
sp_core::crypto::ByteArray::to_raw_vec(self)
}
}
@@ -57,6 +57,6 @@ impl RuntimePublic for Public {
}
fn to_raw_vec(&self) -> Vec<u8> {
sp_core::crypto::Public::to_raw_vec(self)
sp_core::crypto::ByteArray::to_raw_vec(self)
}
}
@@ -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},
crypto::{
ByteArray, CryptoType, CryptoTypePublicPair, Derive, IsWrappedBy, Public, UncheckedFrom,
Wraps,
},
RuntimeDebug,
};
@@ -221,7 +224,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 +261,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 +304,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 +359,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 +437,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 +472,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,
@@ -516,11 +518,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<Self, Self::Error> {
<$sig>::try_from(data).map(Into::into)
}
}
impl $crate::TryFrom<$crate::Vec<u8>> for Signature {
type Error = ();
fn try_from(data: $crate::Vec<u8>) -> Result<Self, Self::Error> {
Ok(<$sig>::try_from(data.as_slice())?.into())
Self::try_from(&data[..])
}
}
};
@@ -57,6 +57,6 @@ impl RuntimePublic for Public {
}
fn to_raw_vec(&self) -> Vec<u8> {
sp_core::crypto::Public::to_raw_vec(self)
sp_core::crypto::ByteArray::to_raw_vec(self)
}
}
+43 -43
View File
@@ -222,7 +222,7 @@ pub enum PublicError {
/// See <https://docs.substrate.io/v3/advanced/ss58/>
/// 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,10 @@ 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 +390,13 @@ lazy_static::lazy_static! {
}
#[cfg(feature = "std")]
impl<T: Sized + AsMut<[u8]> + AsRef<[u8]> + Default + Derive> Ss58Codec for T {
impl<T: Sized + AsMut<[u8]> + AsRef<[u8]> + Public + Derive> Ss58Codec for T {
fn from_string(s: &str) -> Result<Self, PublicError> {
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 +424,15 @@ impl<T: Sized + AsMut<[u8]> + 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, ()> {
Self::try_from(data)
}
/// Return a `Vec<u8>` filled with raw data.
fn to_raw_vec(&self) -> Vec<u8> {
@@ -460,7 +443,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;
}
@@ -488,6 +474,10 @@ impl UncheckedFrom<crate::hash::H256> for AccountId32 {
}
}
impl ByteArray for AccountId32 {
const LEN: usize = 32;
}
#[cfg(feature = "std")]
impl Ss58Codec for AccountId32 {}
@@ -650,9 +640,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<Self, ()> {
Ok(Self)
}
#[cfg(feature = "std")]
fn to_raw_vec(&self) -> Vec<u8> {
@@ -661,8 +652,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"), <Self as ByteArray>::to_raw_vec(self))
}
}
@@ -1146,17 +1139,22 @@ mod tests {
impl<'a> TryFrom<&'a [u8]> for TestPublic {
type Error = ();
fn try_from(_: &'a [u8]) -> Result<Self, ()> {
Ok(Self)
fn try_from(data: &'a [u8]) -> Result<Self, ()> {
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<Self, ()> {
if bytes.len() == 0 {
Ok(Self)
} else {
Err(())
}
}
fn as_slice(&self) -> &[u8] {
&[]
@@ -1164,6 +1162,8 @@ mod tests {
fn to_raw_vec(&self) -> Vec<u8> {
vec![]
}
}
impl Public for TestPublic {
fn to_public_crypto_pair(&self) -> CryptoTypePublicPair {
CryptoTypePublicPair(CryptoTypeId(*b"dumm"), self.to_raw_vec())
}
+17 -21
View File
@@ -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, CryptoType, CryptoTypeId, CryptoTypePublicPair, Derive, Public as TraitPublic,
UncheckedFrom,
};
#[cfg(feature = "full_crypto")]
use crate::{
@@ -113,17 +114,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 +138,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 +154,12 @@ impl sp_std::convert::TryFrom<&[u8]> for Public {
type Error = ();
fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
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))
}
}
@@ -340,6 +330,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`.
///
+19 -24
View File
@@ -22,7 +22,10 @@
#[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 +69,6 @@ type Seed = [u8; 32];
Copy,
Encode,
Decode,
Default,
PassByInner,
MaxEncodedLen,
TypeInfo,
@@ -118,13 +120,12 @@ impl sp_std::convert::TryFrom<&[u8]> for Public {
type Error = ();
fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
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 +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[..]
@@ -321,6 +316,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`.
///
@@ -400,17 +401,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())
}
+1 -1
View File
@@ -76,7 +76,7 @@ pub use self::{
uint::{U256, U512},
};
#[cfg(feature = "full_crypto")]
pub use crypto::{DeriveJunction, Pair, Public};
pub use crypto::{ByteArray, DeriveJunction, Pair, Public};
#[cfg(feature = "std")]
pub use self::hasher::blake2::Blake2Hasher;
+16 -24
View File
@@ -41,7 +41,7 @@ use substrate_bip39::mini_secret_from_entropy;
use crate::{
crypto::{
CryptoType, CryptoTypeId, CryptoTypePublicPair, Derive, Public as TraitPublic,
ByteArray, CryptoType, CryptoTypeId, CryptoTypePublicPair, Derive, Public as TraitPublic,
UncheckedFrom,
},
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<Self, Self::Error> {
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[..]
@@ -342,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`.
///
@@ -412,17 +410,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())
}
+25 -5
View File
@@ -1543,7 +1543,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, map, storage::Storage, testing::TaskExecutor,
traits::TaskExecutorExt,
};
use sp_state_machine::BasicExternalities;
use std::any::TypeId;
@@ -1644,7 +1647,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();
@@ -1657,14 +1660,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
@@ -1690,7 +1710,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());
@@ -1722,7 +1742,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());
});
+1 -1
View File
@@ -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,
ByteArray, Pair as PairT, H256,
};
use sp_runtime::AccountId32;
use std::{collections::HashMap, ops::Deref};
+1 -1
View File
@@ -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,
ByteArray, Pair as PairT, H256,
};
use sp_runtime::AccountId32;
use std::{collections::HashMap, ops::Deref};
+6 -6
View File
@@ -18,7 +18,7 @@
//! Types that should only be used for testing!
use sp_core::{
crypto::{CryptoTypePublicPair, KeyTypeId, Pair, Public},
crypto::{ByteArray, CryptoTypePublicPair, KeyTypeId, Pair},
ecdsa, ed25519, sr25519,
};
@@ -340,20 +340,20 @@ 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()));
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()));
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()
},
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()
},
+34 -5
View File
@@ -178,7 +178,7 @@ impl<AccountId> Candidate<AccountId> {
}
/// A vote being casted by a [`Voter`] to a [`Candidate`] is an `Edge`.
#[derive(Clone, Default)]
#[derive(Clone)]
pub struct Edge<AccountId> {
/// Identifier of the target.
///
@@ -193,6 +193,15 @@ pub struct Edge<AccountId> {
weight: ExtendedBalance,
}
#[cfg(test)]
impl<AccountId: Clone> Edge<AccountId> {
fn new(candidate: Candidate<AccountId>, 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<A: IdentifierT> sp_std::fmt::Debug for Edge<A> {
fn fmt(&self, f: &mut sp_std::fmt::Formatter<'_>) -> sp_std::fmt::Result {
@@ -223,7 +232,12 @@ impl<A: IdentifierT> std::fmt::Debug for Voter<A> {
impl<AccountId: IdentifierT> Voter<AccountId> {
/// 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 +353,7 @@ pub struct ElectionResult<AccountId, P: PerThing> {
///
/// 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<AccountId> {
/// Total support.
@@ -348,6 +362,12 @@ pub struct Support<AccountId> {
pub voters: Vec<(AccountId, ExtendedBalance)>,
}
impl<AccountId> Default for Support<AccountId> {
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 +481,15 @@ pub fn setup_inputs<AccountId: IdentifierT>(
.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::<Vec<CandidatePtr<AccountId>>>();
@@ -482,7 +510,8 @@ pub fn setup_inputs<AccountId: IdentifierT>(
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.
}
+29 -6
View File
@@ -287,7 +287,15 @@ fn prepare_pjr_input<AccountId: IdentifierT>(
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::<Vec<_>>();
@@ -315,14 +323,14 @@ fn prepare_pjr_input<AccountId: IdentifierT>(
who: t,
candidate: Rc::clone(&candidates[*idx]),
weight,
..Default::default()
load: Default::default(),
});
}
}
let who = v;
let budget: ExtendedBalance = w.into();
Voter { who, budget, edges, ..Default::default() }
Voter { who, budget, edges, load: Default::default() }
})
.collect::<Vec<_>>();
@@ -387,7 +395,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::<Vec<_>>();
let edges = candidates
@@ -396,7 +411,7 @@ mod tests {
who: c.who,
weight: c.backed_stake,
candidate: c.to_ptr(),
..Default::default()
load: Default::default(),
})
.collect::<Vec<_>>();
voter.edges = edges;
@@ -432,7 +447,15 @@ 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);
@@ -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.
@@ -356,7 +355,7 @@ fn reduce_all<A: IdentifierT>(assignments: &mut Vec<StakedAssignment<A>>) -> 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) {
@@ -390,39 +389,44 @@ fn reduce_all<A: IdentifierT>(assignments: &mut Vec<StakedAssignment<A>>) -> 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());
//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
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::<Vec<NodeRef<A>>>();
// 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: A = Default::default();
let mut min_voter: A = Default::default();
// 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<A> = None;
let mut maybe_min_voter: Option<A> = None;
// The index of the min in opaque cycle list.
let mut min_index = 0usize;
let mut maybe_min_index: Option<usize> = None;
// 1 -> next // 0 -> prev
let mut min_direction = 0u32;
let mut maybe_min_direction: Option<u32> = None;
// helpers
let next_index = |i| {
if i < (cycle.len() - 1) {
@@ -438,6 +442,7 @@ fn reduce_all<A: IdentifierT>(assignments: &mut Vec<StakedAssignment<A>>) -> 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
@@ -448,10 +453,10 @@ fn reduce_all<A: IdentifierT>(assignments: &mut Vec<StakedAssignment<A>>) -> 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_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);
}
})
});
@@ -459,16 +464,39 @@ fn reduce_all<A: IdentifierT>(assignments: &mut Vec<StakedAssignment<A>>) -> 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_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;
@@ -624,8 +652,8 @@ fn reduce_all<A: IdentifierT>(assignments: &mut Vec<StakedAssignment<A>>) -> u32
num_changed
}
/// Reduce the given [`Vec<StakedAssignment<IdentifierT>>`]. This removes redundant edges from
/// without changing the overall backing of any of the elected candidates.
/// Reduce the given [`Vec<StakedAssignment<IdentifierT>>`]. This removes redundant edges without
/// changing the overall backing of any of the elected candidates.
///
/// Returns the number of edges removed.
///
@@ -192,16 +192,15 @@ 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() };
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 +213,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() };
@@ -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<T: Clone + Eq + Default + Ord + Debug + codec::Codec> IdentifierT for T {}
pub trait IdentifierT: Clone + Eq + Ord + Debug + codec::Codec {}
impl<T: Clone + Eq + Ord + Debug + codec::Codec> IdentifierT for T {}
/// Aggregator trait for a PerThing that can be multiplied by u128 (ExtendedBalance).
pub trait PerThing128: PerThing + Mul<ExtendedBalance, Output = ExtendedBalance> {}
@@ -70,20 +70,26 @@ where
info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> crate::ApplyExtrinsicResultWithInfo<PostDispatchInfoOf<Self::Call>> {
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)
}
}
@@ -364,7 +364,7 @@ mod tests {
use crate::{
codec::{Decode, Encode},
testing::TestSignature as TestSig,
traits::{IdentityLookup, SignedExtension},
traits::{DispatchInfoOf, IdentityLookup, SignedExtension},
};
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<Self::Call>,
len: usize,
) -> Result<Self::Pre, TransactionValidityError> {
Ok(self.validate(who, call, info, len).map(|_| ())?)
}
}
type Ex = UncheckedExtrinsic<TestAccountId, TestCall, TestSig, TestExtra>;
+17 -20
View File
@@ -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<MultiSignature> 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<T: Into<H256>> crypto::UncheckedFrom<T> for MultiSigner {
@@ -403,10 +391,14 @@ impl Verify for MultiSignature {
type Signer = MultiSigner;
fn verify<L: Lazy<[u8]>>(&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)
}
}
@@ -924,7 +919,7 @@ mod tests {
use super::*;
use codec::{Decode, Encode};
use sp_core::crypto::Pair;
use sp_core::crypto::{Pair, UncheckedFrom};
use sp_io::TestExternalities;
use sp_state_machine::create_proof_check_backend;
@@ -1010,7 +1005,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);
});
}
@@ -62,9 +62,3 @@ impl<AccountId, AccountIndex> From<AccountId> for MultiAddress<AccountId, Accoun
Self::Id(a)
}
}
impl<AccountId: Default, AccountIndex> Default for MultiAddress<AccountId, AccountIndex> {
fn default() -> Self {
Self::Id(Default::default())
}
}
+4 -4
View File
@@ -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, ByteArray, CryptoType, Dummy},
U256,
};
pub use sp_core::{sr25519, H256};
@@ -77,10 +77,10 @@ impl From<UintAuthorityId> for u64 {
}
impl UintAuthorityId {
/// Convert this authority id into a public key.
pub fn to_public_key<T: Public>(&self) -> T {
/// Convert this authority ID into a public key.
pub fn to_public_key<T: ByteArray>(&self) -> T {
let bytes: [u8; 32] = U256::from(self.0).into();
T::from_slice(&bytes)
T::from_slice(&bytes).unwrap()
}
}
+43 -21
View File
@@ -851,7 +851,7 @@ pub trait SignedExtension:
type AdditionalSigned: Encode + TypeInfo;
/// 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.
@@ -890,11 +890,7 @@ pub trait SignedExtension:
call: &Self::Call,
info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> Result<Self::Pre, TransactionValidityError> {
self.validate(who, call, info, len)
.map(|_| Self::Pre::default())
.map_err(Into::into)
}
) -> Result<Self::Pre, TransactionValidityError>;
/// Validate an unsigned transaction for the transaction queue.
///
@@ -924,14 +920,15 @@ pub trait SignedExtension:
call: &Self::Call,
info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> Result<Self::Pre, TransactionValidityError> {
Self::validate_unsigned(call, info, len)
.map(|_| Self::Pre::default())
.map_err(Into::into)
) -> Result<(), TransactionValidityError> {
Self::validate_unsigned(call, info, len).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 `pre_dispatch`,
/// 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.
@@ -944,7 +941,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<Self::Pre>,
_info: &DispatchInfoOf<Self::Call>,
_post_info: &PostDispatchInfoOf<Self::Call>,
_len: usize,
@@ -1029,18 +1026,26 @@ impl<AccountId, Call: Dispatchable> SignedExtension for Tuple {
call: &Self::Call,
info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> Result<Self::Pre, TransactionValidityError> {
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<Self::Pre>,
info: &DispatchInfoOf<Self::Call>,
post_info: &PostDispatchInfoOf<Self::Call>,
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(())
}
@@ -1062,6 +1067,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<Self::Call>,
len: usize,
) -> Result<Self::Pre, TransactionValidityError> {
Ok(self.validate(who, call, info, len).map(|_| ())?)
}
}
/// An "executable" piece of information, used by the standard Substrate Executive in order to
@@ -1212,6 +1226,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> {
@@ -1260,11 +1279,11 @@ pub trait AccountIdConversion<AccountId>: Sized {
/// Format is TYPE_ID ++ encode(parachain ID) ++ 00.... where 00... is indefinite trailing zeroes to
/// fill AccountId.
impl<T: Encode + Decode + Default, Id: Encode + Decode + TypeId> AccountIdConversion<T> for Id {
impl<T: Encode + Decode, Id: Encode + Decode + TypeId> AccountIdConversion<T> for Id {
fn into_sub_account<S: Encode>(&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<S: Decode>(x: &T) -> Option<(Self, S)> {
@@ -1317,7 +1336,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,
@@ -1616,7 +1635,10 @@ 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};
@@ -1629,8 +1651,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)]