Run cargo fmt on the whole code base (#9394)

* Run cargo fmt on the whole code base

* Second run

* Add CI check

* Fix compilation

* More unnecessary braces

* Handle weights

* Use --all

* Use correct attributes...

* Fix UI tests

* AHHHHHHHHH

* 🤦

* Docs

* Fix compilation

* 🤷

* Please stop

* 🤦 x 2

* More

* make rustfmt.toml consistent with polkadot

Co-authored-by: André Silva <andrerfosilva@gmail.com>
This commit is contained in:
Bastian Köcher
2021-07-21 16:32:32 +02:00
committed by GitHub
parent d451c38c1c
commit 7b56ab15b4
1010 changed files with 53339 additions and 51208 deletions
@@ -15,8 +15,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use codec::{Encode, Decode};
use crate::{Config, Pallet};
use codec::{Decode, Encode};
use sp_runtime::{
traits::{SignedExtension, Zero},
transaction_validity::TransactionValidityError,
@@ -15,13 +15,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use codec::{Encode, Decode};
use crate::{Config, Pallet, BlockHash};
use crate::{BlockHash, Config, Pallet};
use codec::{Decode, Encode};
use sp_runtime::{
generic::Era,
traits::{SignedExtension, DispatchInfoOf, SaturatedConversion},
traits::{DispatchInfoOf, SaturatedConversion, SignedExtension},
transaction_validity::{
ValidTransaction, TransactionValidityError, InvalidTransaction, TransactionValidity,
InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction,
},
};
@@ -84,7 +84,7 @@ impl<T: Config + Send + Sync> SignedExtension for CheckMortality<T> {
#[cfg(test)]
mod tests {
use super::*;
use crate::mock::{Test, new_test_ext, System, CALL};
use crate::mock::{new_test_ext, System, Test, CALL};
use frame_support::weights::{DispatchClass, DispatchInfo, Pays};
use sp_core::H256;
@@ -93,7 +93,10 @@ mod tests {
new_test_ext().execute_with(|| {
// future
assert_eq!(
CheckMortality::<Test>::from(Era::mortal(4, 2)).additional_signed().err().unwrap(),
CheckMortality::<Test>::from(Era::mortal(4, 2))
.additional_signed()
.err()
.unwrap(),
InvalidTransaction::AncientBirthBlock.into(),
);
@@ -107,7 +110,8 @@ mod tests {
#[test]
fn signed_ext_check_era_should_change_longevity() {
new_test_ext().execute_with(|| {
let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal, pays_fee: Pays::Yes };
let normal =
DispatchInfo { weight: 100, class: DispatchClass::Normal, pays_fee: Pays::Yes };
let len = 0_usize;
let ext = (
crate::CheckWeight::<Test>::new(),
@@ -15,14 +15,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use codec::{Encode, Decode};
use crate::Config;
use codec::{Decode, Encode};
use frame_support::weights::DispatchInfo;
use sp_runtime::{
traits::{SignedExtension, DispatchInfoOf, Dispatchable, One},
traits::{DispatchInfoOf, Dispatchable, One, SignedExtension},
transaction_validity::{
ValidTransaction, TransactionValidityError, InvalidTransaction, TransactionValidity,
TransactionLongevity,
InvalidTransaction, TransactionLongevity, TransactionValidity, TransactionValidityError,
ValidTransaction,
},
};
use sp_std::vec;
@@ -53,8 +53,9 @@ impl<T: Config> sp_std::fmt::Debug for CheckNonce<T> {
}
}
impl<T: Config> SignedExtension for CheckNonce<T> where
T::Call: Dispatchable<Info=DispatchInfo>
impl<T: Config> SignedExtension for CheckNonce<T>
where
T::Call: Dispatchable<Info = DispatchInfo>,
{
type AccountId = T::AccountId;
type Call = T::Call;
@@ -62,7 +63,9 @@ impl<T: Config> SignedExtension for CheckNonce<T> where
type Pre = ();
const IDENTIFIER: &'static str = "CheckNonce";
fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) }
fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> {
Ok(())
}
fn pre_dispatch(
self,
@@ -73,13 +76,12 @@ impl<T: Config> SignedExtension for CheckNonce<T> where
) -> Result<(), TransactionValidityError> {
let mut account = crate::Account::<T>::get(who);
if self.0 != account.nonce {
return Err(
if self.0 < account.nonce {
InvalidTransaction::Stale
} else {
InvalidTransaction::Future
}.into()
)
return Err(if self.0 < account.nonce {
InvalidTransaction::Stale
} else {
InvalidTransaction::Future
}
.into())
}
account.nonce += T::Index::one();
crate::Account::<T>::insert(who, account);
@@ -119,19 +121,22 @@ impl<T: Config> SignedExtension for CheckNonce<T> where
#[cfg(test)]
mod tests {
use super::*;
use crate::mock::{Test, new_test_ext, CALL};
use crate::mock::{new_test_ext, Test, CALL};
use frame_support::{assert_noop, assert_ok};
#[test]
fn signed_ext_check_nonce_works() {
new_test_ext().execute_with(|| {
crate::Account::<Test>::insert(1, crate::AccountInfo {
nonce: 1,
consumers: 0,
providers: 0,
sufficients: 0,
data: 0,
});
crate::Account::<Test>::insert(
1,
crate::AccountInfo {
nonce: 1,
consumers: 0,
providers: 0,
sufficients: 0,
data: 0,
},
);
let info = DispatchInfo::default();
let len = 0_usize;
// stale
@@ -16,11 +16,8 @@
// limitations under the License.
use crate::{Config, Pallet};
use codec::{Encode, Decode};
use sp_runtime::{
traits::SignedExtension,
transaction_validity::TransactionValidityError,
};
use codec::{Decode, Encode};
use sp_runtime::{traits::SignedExtension, transaction_validity::TransactionValidityError};
/// Ensure the runtime version registered in the transaction is the same as at present.
#[derive(Encode, Decode, Clone, Eq, PartialEq)]
@@ -16,11 +16,8 @@
// limitations under the License.
use crate::{Config, Pallet};
use codec::{Encode, Decode};
use sp_runtime::{
traits::SignedExtension,
transaction_validity::TransactionValidityError,
};
use codec::{Decode, Encode};
use sp_runtime::{traits::SignedExtension, transaction_validity::TransactionValidityError};
/// Ensure the transaction version registered in the transaction is the same as at present.
#[derive(Encode, Decode, Clone, Eq, PartialEq)]
@@ -16,26 +16,27 @@
// limitations under the License.
use crate::{limits::BlockWeights, Config, Pallet};
use codec::{Encode, Decode};
use sp_runtime::{
traits::{SignedExtension, DispatchInfoOf, Dispatchable, PostDispatchInfoOf},
transaction_validity::{
ValidTransaction, TransactionValidityError, InvalidTransaction, TransactionValidity,
TransactionPriority,
},
DispatchResult,
};
use codec::{Decode, Encode};
use frame_support::{
traits::Get,
weights::{PostDispatchInfo, DispatchInfo, DispatchClass, priority::FrameTransactionPriority},
weights::{priority::FrameTransactionPriority, DispatchClass, DispatchInfo, PostDispatchInfo},
};
use sp_runtime::{
traits::{DispatchInfoOf, Dispatchable, PostDispatchInfoOf, SignedExtension},
transaction_validity::{
InvalidTransaction, TransactionPriority, TransactionValidity, TransactionValidityError,
ValidTransaction,
},
DispatchResult,
};
/// Block resource (weight) limit check.
#[derive(Encode, Decode, Clone, Eq, PartialEq, Default)]
pub struct CheckWeight<T: Config + Send + Sync>(sp_std::marker::PhantomData<T>);
impl<T: Config + Send + Sync> CheckWeight<T> where
T::Call: Dispatchable<Info=DispatchInfo, PostInfo=PostDispatchInfo>,
impl<T: Config + Send + Sync> CheckWeight<T>
where
T::Call: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
{
/// Checks if the current extrinsic does not exceed the maximum weight a single extrinsic
/// with given `DispatchClass` can have.
@@ -44,9 +45,7 @@ impl<T: Config + Send + Sync> CheckWeight<T> where
) -> Result<(), TransactionValidityError> {
let max = T::BlockWeights::get().get(info.class).max_extrinsic;
match max {
Some(max) if info.weight > max => {
Err(InvalidTransaction::ExhaustsResources.into())
},
Some(max) if info.weight > max => Err(InvalidTransaction::ExhaustsResources.into()),
_ => Ok(()),
}
}
@@ -87,8 +86,7 @@ impl<T: Config + Send + Sync> CheckWeight<T> where
fn get_priority(info: &DispatchInfoOf<T::Call>) -> TransactionPriority {
match info.class {
// Normal transaction.
DispatchClass::Normal =>
FrameTransactionPriority::Normal(info.weight.into()).into(),
DispatchClass::Normal => FrameTransactionPriority::Normal(info.weight.into()).into(),
// Don't use up the whole priority space, to allow things like `tip` to be taken into
// account as well.
DispatchClass::Operational =>
@@ -122,10 +120,7 @@ impl<T: Config + Send + Sync> CheckWeight<T> where
/// Do the validate checks. This can be applied to both signed and unsigned.
///
/// It only checks that the block weight and length limit will not exceed.
pub fn do_validate(
info: &DispatchInfoOf<T::Call>,
len: usize,
) -> TransactionValidity {
pub fn do_validate(info: &DispatchInfoOf<T::Call>, len: usize) -> TransactionValidity {
// ignore the next length. If they return `Ok`, then it is below the limit.
let _ = Self::check_block_length(info, len)?;
// during validation we skip block limit check. Since the `validate_transaction`
@@ -141,17 +136,20 @@ pub fn calculate_consumed_weight<Call>(
maximum_weight: BlockWeights,
mut all_weight: crate::ConsumedWeight,
info: &DispatchInfoOf<Call>,
) -> Result<crate::ConsumedWeight, TransactionValidityError> where
Call: Dispatchable<Info=DispatchInfo, PostInfo=PostDispatchInfo>,
) -> Result<crate::ConsumedWeight, TransactionValidityError>
where
Call: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
{
let extrinsic_weight = info.weight.saturating_add(maximum_weight.get(info.class).base_extrinsic);
let extrinsic_weight =
info.weight.saturating_add(maximum_weight.get(info.class).base_extrinsic);
let limit_per_class = maximum_weight.get(info.class);
// add the weight. If class is unlimited, use saturating add instead of checked one.
if limit_per_class.max_total.is_none() && limit_per_class.reserved.is_none() {
all_weight.add(extrinsic_weight, info.class)
} else {
all_weight.checked_add(extrinsic_weight, info.class)
all_weight
.checked_add(extrinsic_weight, info.class)
.map_err(|_| InvalidTransaction::ExhaustsResources)?;
}
@@ -159,9 +157,7 @@ pub fn calculate_consumed_weight<Call>(
// Check if we don't exceed per-class allowance
match limit_per_class.max_total {
Some(max) if per_class > max => {
return Err(InvalidTransaction::ExhaustsResources.into());
},
Some(max) if per_class > max => return Err(InvalidTransaction::ExhaustsResources.into()),
// There is no `max_total` limit (`None`),
// or we are below the limit.
_ => {},
@@ -172,9 +168,8 @@ pub fn calculate_consumed_weight<Call>(
if all_weight.total() > maximum_weight.max_block {
match limit_per_class.reserved {
// We are over the limit in reserved pool.
Some(reserved) if per_class > reserved => {
return Err(InvalidTransaction::ExhaustsResources.into());
}
Some(reserved) if per_class > reserved =>
return Err(InvalidTransaction::ExhaustsResources.into()),
// There is either no limit in reserved pool (`None`),
// or we are below the limit.
_ => {},
@@ -184,8 +179,9 @@ pub fn calculate_consumed_weight<Call>(
Ok(all_weight)
}
impl<T: Config + Send + Sync> SignedExtension for CheckWeight<T> where
T::Call: Dispatchable<Info=DispatchInfo, PostInfo=PostDispatchInfo>
impl<T: Config + Send + Sync> SignedExtension for CheckWeight<T>
where
T::Call: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
{
type AccountId = T::AccountId;
type Call = T::Call;
@@ -193,7 +189,9 @@ impl<T: Config + Send + Sync> SignedExtension for CheckWeight<T> where
type Pre = ();
const IDENTIFIER: &'static str = "CheckWeight";
fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) }
fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> {
Ok(())
}
fn pre_dispatch(
self,
@@ -278,17 +276,24 @@ impl<T: Config + Send + Sync> sp_std::fmt::Debug for CheckWeight<T> {
#[cfg(test)]
mod tests {
use super::*;
use crate::{BlockWeight, AllExtrinsicsLen};
use crate::mock::{Test, CALL, new_test_ext, System};
use crate::{
mock::{new_test_ext, System, Test, CALL},
AllExtrinsicsLen, BlockWeight,
};
use frame_support::{
assert_err, assert_ok,
weights::{Pays, Weight},
};
use sp_std::marker::PhantomData;
use frame_support::{assert_err, assert_ok, weights::{Weight, Pays}};
fn block_weights() -> crate::limits::BlockWeights {
<Test as crate::Config>::BlockWeights::get()
}
fn normal_weight_limit() -> Weight {
block_weights().get(DispatchClass::Normal).max_total
block_weights()
.get(DispatchClass::Normal)
.max_total
.unwrap_or_else(|| block_weights().max_block)
}
@@ -334,7 +339,10 @@ mod tests {
..Default::default()
};
let len = 0_usize;
assert_err!(CheckWeight::<Test>::do_validate(&max, len), InvalidTransaction::ExhaustsResources);
assert_err!(
CheckWeight::<Test>::do_validate(&max, len),
InvalidTransaction::ExhaustsResources
);
});
}
@@ -342,16 +350,15 @@ mod tests {
fn operational_extrinsic_limited_by_operational_space_limit() {
new_test_ext().execute_with(|| {
let weights = block_weights();
let operational_limit = weights.get(DispatchClass::Operational).max_total
let operational_limit = weights
.get(DispatchClass::Operational)
.max_total
.unwrap_or_else(|| weights.max_block);
let base_weight = weights.get(DispatchClass::Normal).base_extrinsic;
let weight = operational_limit - base_weight;
let okay = DispatchInfo {
weight,
class: DispatchClass::Operational,
..Default::default()
};
let okay =
DispatchInfo { weight, class: DispatchClass::Operational, ..Default::default() };
let max = DispatchInfo {
weight: weight + 1,
class: DispatchClass::Operational,
@@ -366,7 +373,10 @@ mod tests {
..Default::default()
})
);
assert_err!(CheckWeight::<Test>::do_validate(&max, len), InvalidTransaction::ExhaustsResources);
assert_err!(
CheckWeight::<Test>::do_validate(&max, len),
InvalidTransaction::ExhaustsResources
);
});
}
@@ -388,7 +398,11 @@ mod tests {
// So normal extrinsic can be 758 weight (-5 for base extrinsic weight)
// And Operational can be 256 to produce a full block (-5 for base)
let max_normal = DispatchInfo { weight: 753, ..Default::default() };
let rest_operational = DispatchInfo { weight: 251, class: DispatchClass::Operational, ..Default::default() };
let rest_operational = DispatchInfo {
weight: 251,
class: DispatchClass::Operational,
..Default::default()
};
let len = 0_usize;
@@ -407,7 +421,11 @@ mod tests {
new_test_ext().execute_with(|| {
// We switch the order of `full_block_with_normal_and_operational`
let max_normal = DispatchInfo { weight: 753, ..Default::default() };
let rest_operational = DispatchInfo { weight: 251, class: DispatchClass::Operational, ..Default::default() };
let rest_operational = DispatchInfo {
weight: 251,
class: DispatchClass::Operational,
..Default::default()
};
let len = 0_usize;
@@ -425,17 +443,24 @@ mod tests {
new_test_ext().execute_with(|| {
// An on_initialize takes up the whole block! (Every time!)
System::register_extra_weight_unchecked(Weight::max_value(), DispatchClass::Mandatory);
let dispatch_normal = DispatchInfo { weight: 251, class: DispatchClass::Normal, ..Default::default() };
let dispatch_operational = DispatchInfo { weight: 251, class: DispatchClass::Operational, ..Default::default() };
let dispatch_normal =
DispatchInfo { weight: 251, class: DispatchClass::Normal, ..Default::default() };
let dispatch_operational = DispatchInfo {
weight: 251,
class: DispatchClass::Operational,
..Default::default()
};
let len = 0_usize;
assert_err!( CheckWeight::<Test>::do_pre_dispatch(&dispatch_normal, len),
assert_err!(
CheckWeight::<Test>::do_pre_dispatch(&dispatch_normal, len),
InvalidTransaction::ExhaustsResources
);
// Thank goodness we can still do an operational transaction to possibly save the blockchain.
assert_ok!(CheckWeight::<Test>::do_pre_dispatch(&dispatch_operational, len));
// Not too much though
assert_err!(CheckWeight::<Test>::do_pre_dispatch(&dispatch_operational, len),
assert_err!(
CheckWeight::<Test>::do_pre_dispatch(&dispatch_operational, len),
InvalidTransaction::ExhaustsResources
);
// Even with full block, validity of single transaction should be correct.
@@ -447,7 +472,11 @@ mod tests {
fn signed_ext_check_weight_works_operational_tx() {
new_test_ext().execute_with(|| {
let normal = DispatchInfo { weight: 100, ..Default::default() };
let op = DispatchInfo { weight: 100, class: DispatchClass::Operational, pays_fee: Pays::Yes };
let op = DispatchInfo {
weight: 100,
class: DispatchClass::Operational,
pays_fee: Pays::Yes,
};
let len = 0_usize;
let normal_limit = normal_weight_limit();
@@ -456,7 +485,8 @@ mod tests {
current_weight.set(normal_limit, DispatchClass::Normal)
});
// will not fit.
assert_err!(CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, &normal, len),
assert_err!(
CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, &normal, len),
InvalidTransaction::ExhaustsResources
);
// will fit.
@@ -465,7 +495,8 @@ mod tests {
// likewise for length limit.
let len = 100_usize;
AllExtrinsicsLen::<Test>::put(normal_length_limit());
assert_err!(CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, &normal, len),
assert_err!(
CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, &normal, len),
InvalidTransaction::ExhaustsResources
);
assert_ok!(CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, &op, len));
@@ -475,8 +506,13 @@ mod tests {
#[test]
fn signed_ext_check_weight_works() {
new_test_ext().execute_with(|| {
let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal, pays_fee: Pays::Yes };
let op = DispatchInfo { weight: 100, class: DispatchClass::Operational, pays_fee: Pays::Yes };
let normal =
DispatchInfo { weight: 100, class: DispatchClass::Normal, pays_fee: Pays::Yes };
let op = DispatchInfo {
weight: 100,
class: DispatchClass::Operational,
pays_fee: Pays::Yes,
};
let len = 0_usize;
let priority = CheckWeight::<Test>(PhantomData)
@@ -485,10 +521,8 @@ mod tests {
.priority;
assert_eq!(priority, 100);
let priority = CheckWeight::<Test>(PhantomData)
.validate(&1, CALL, &op, len)
.unwrap()
.priority;
let priority =
CheckWeight::<Test>(PhantomData).validate(&1, CALL, &op, len).unwrap().priority;
assert_eq!(priority, frame_support::weights::priority::LIMIT + 100);
})
}
@@ -501,7 +535,11 @@ mod tests {
let reset_check_weight = |tx, s, f| {
AllExtrinsicsLen::<Test>::put(0);
let r = CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, tx, s);
if f { assert!(r.is_err()) } else { assert!(r.is_ok()) }
if f {
assert!(r.is_err())
} else {
assert!(r.is_ok())
}
};
reset_check_weight(&normal, normal_limit - 1, false);
@@ -509,7 +547,8 @@ mod tests {
reset_check_weight(&normal, normal_limit + 1, true);
// Operational ones don't have this limit.
let op = DispatchInfo { weight: 0, class: DispatchClass::Operational, pays_fee: Pays::Yes };
let op =
DispatchInfo { weight: 0, class: DispatchClass::Operational, pays_fee: Pays::Yes };
reset_check_weight(&op, normal_limit, false);
reset_check_weight(&op, normal_limit + 100, false);
reset_check_weight(&op, 1024, false);
@@ -517,21 +556,16 @@ mod tests {
})
}
#[test]
fn signed_ext_check_weight_works_normal_tx() {
new_test_ext().execute_with(|| {
let normal_limit = normal_weight_limit();
let small = DispatchInfo { weight: 100, ..Default::default() };
let base_extrinsic = block_weights().get(DispatchClass::Normal).base_extrinsic;
let medium = DispatchInfo {
weight: normal_limit - base_extrinsic,
..Default::default()
};
let big = DispatchInfo {
weight: normal_limit - base_extrinsic + 1,
..Default::default()
};
let medium =
DispatchInfo { weight: normal_limit - base_extrinsic, ..Default::default() };
let big =
DispatchInfo { weight: normal_limit - base_extrinsic + 1, ..Default::default() };
let len = 0_usize;
let reset_check_weight = |i, f, s| {
@@ -539,7 +573,11 @@ mod tests {
current_weight.set(s, DispatchClass::Normal)
});
let r = CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, i, len);
if f { assert!(r.is_err()) } else { assert!(r.is_ok()) }
if f {
assert!(r.is_err())
} else {
assert!(r.is_ok())
}
};
reset_check_weight(&small, false, 0);
@@ -553,10 +591,8 @@ mod tests {
new_test_ext().execute_with(|| {
// This is half of the max block weight
let info = DispatchInfo { weight: 512, ..Default::default() };
let post_info = PostDispatchInfo {
actual_weight: Some(128),
pays_fee: Default::default(),
};
let post_info =
PostDispatchInfo { actual_weight: Some(128), pays_fee: Default::default() };
let len = 0_usize;
let base_extrinsic = block_weights().get(DispatchClass::Normal).base_extrinsic;
@@ -569,11 +605,8 @@ mod tests {
let pre = CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, &info, len).unwrap();
assert_eq!(BlockWeight::<Test>::get().total(), info.weight + 256);
assert_ok!( CheckWeight::<Test>::post_dispatch(pre, &info, &post_info, len, &Ok(())));
assert_eq!(
BlockWeight::<Test>::get().total(),
post_info.actual_weight.unwrap() + 256,
);
assert_ok!(CheckWeight::<Test>::post_dispatch(pre, &info, &post_info, len, &Ok(())));
assert_eq!(BlockWeight::<Test>::get().total(), post_info.actual_weight.unwrap() + 256,);
})
}
@@ -581,10 +614,8 @@ mod tests {
fn signed_ext_check_weight_actual_weight_higher_than_max_is_capped() {
new_test_ext().execute_with(|| {
let info = DispatchInfo { weight: 512, ..Default::default() };
let post_info = PostDispatchInfo {
actual_weight: Some(700),
pays_fee: Default::default(),
};
let post_info =
PostDispatchInfo { actual_weight: Some(700), pays_fee: Default::default() };
let len = 0_usize;
BlockWeight::<Test>::mutate(|current_weight| {
@@ -614,10 +645,7 @@ mod tests {
let len = 0_usize;
// Initial weight from `weights.base_block`
assert_eq!(
System::block_weight().total(),
weights.base_block
);
assert_eq!(System::block_weight().total(), weights.base_block);
assert_ok!(CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, &free, len));
assert_eq!(
System::block_weight().total(),
@@ -633,7 +661,11 @@ mod tests {
// Max normal is 768 (75%)
// Max mandatory is unlimited
let max_normal = DispatchInfo { weight: 753, ..Default::default() };
let mandatory = DispatchInfo { weight: 1019, class: DispatchClass::Mandatory, ..Default::default() };
let mandatory = DispatchInfo {
weight: 1019,
class: DispatchClass::Mandatory,
..Default::default()
};
let len = 0_usize;
@@ -669,18 +701,24 @@ mod tests {
assert_eq!(maximum_weight.max_block, all_weight.total());
// fits into reserved
let mandatory1 = DispatchInfo { weight: 5, class: DispatchClass::Mandatory, ..Default::default() };
let mandatory1 =
DispatchInfo { weight: 5, class: DispatchClass::Mandatory, ..Default::default() };
// does not fit into reserved and the block is full.
let mandatory2 = DispatchInfo { weight: 6, class: DispatchClass::Mandatory, ..Default::default() };
let mandatory2 =
DispatchInfo { weight: 6, class: DispatchClass::Mandatory, ..Default::default() };
// when
assert_ok!(
calculate_consumed_weight::<<Test as Config>::Call>(
maximum_weight.clone(), all_weight.clone(), &mandatory1
)
);
assert_ok!(calculate_consumed_weight::<<Test as Config>::Call>(
maximum_weight.clone(),
all_weight.clone(),
&mandatory1
));
assert_err!(
calculate_consumed_weight::<<Test as Config>::Call>( maximum_weight, all_weight, &mandatory2),
calculate_consumed_weight::<<Test as Config>::Call>(
maximum_weight,
all_weight,
&mandatory2
),
InvalidTransaction::ExhaustsResources
);
}
@@ -21,4 +21,3 @@ pub mod check_nonce;
pub mod check_spec_version;
pub mod check_tx_version;
pub mod check_weight;
+216 -166
View File
@@ -66,57 +66,55 @@
#[cfg(feature = "std")]
use serde::Serialize;
use sp_std::prelude::*;
use sp_runtime::{
generic,
traits::{
self, AtLeast32Bit, AtLeast32BitUnsigned, BadOrigin, BlockNumberProvider, Bounded,
CheckEqual, Dispatchable, Hash, Lookup, LookupError, MaybeDisplay, MaybeMallocSizeOf,
MaybeSerializeDeserialize, Member, One, Saturating, SimpleBitOps, StaticLookup, Zero,
},
DispatchError, Either, Perbill, RuntimeDebug,
};
#[cfg(any(feature = "std", test))]
use sp_std::map;
use sp_std::marker::PhantomData;
use sp_std::fmt::Debug;
use sp_std::{fmt::Debug, marker::PhantomData, prelude::*};
use sp_version::RuntimeVersion;
use sp_runtime::{
RuntimeDebug, Perbill, DispatchError, Either, generic,
traits::{
self, CheckEqual, AtLeast32Bit, Zero, Lookup, LookupError,
SimpleBitOps, Hash, Member, MaybeDisplay, BadOrigin,
MaybeSerializeDeserialize, MaybeMallocSizeOf, StaticLookup, One, Bounded,
Dispatchable, AtLeast32BitUnsigned, Saturating, BlockNumberProvider,
},
};
use sp_core::{ChangesTrieConfiguration, storage::well_known_keys};
use codec::{Decode, Encode, EncodeLike, FullCodec, MaxEncodedLen};
use frame_support::{
Parameter, storage,
dispatch::{DispatchResult, DispatchResultWithPostInfo},
storage,
traits::{
SortedMembers, Get, PalletInfo, OnNewAccount, OnKilledAccount, HandleLifetime,
StoredMap, EnsureOrigin, OriginTrait, Filter,
EnsureOrigin, Filter, Get, HandleLifetime, OnKilledAccount, OnNewAccount, OriginTrait,
PalletInfo, SortedMembers, StoredMap,
},
weights::{
Weight, RuntimeDbWeight, DispatchInfo, DispatchClass,
extract_actual_weight, PerDispatchClass,
extract_actual_weight, DispatchClass, DispatchInfo, PerDispatchClass, RuntimeDbWeight,
Weight,
},
dispatch::{DispatchResultWithPostInfo, DispatchResult},
Parameter,
};
use codec::{Encode, Decode, FullCodec, EncodeLike, MaxEncodedLen};
use sp_core::{storage::well_known_keys, ChangesTrieConfiguration};
#[cfg(feature = "std")]
use frame_support::traits::GenesisBuild;
#[cfg(any(feature = "std", test))]
use sp_io::TestExternalities;
pub mod offchain;
pub mod limits;
#[cfg(test)]
pub(crate) mod mock;
pub mod offchain;
mod extensions;
pub mod weights;
#[cfg(test)]
mod tests;
#[cfg(feature = "std")]
pub mod mocking;
#[cfg(test)]
mod tests;
pub mod weights;
pub use extensions::{
check_mortality::CheckMortality, check_genesis::CheckGenesis, check_nonce::CheckNonce,
check_genesis::CheckGenesis, check_mortality::CheckMortality, check_nonce::CheckNonce,
check_spec_version::CheckSpecVersion, check_tx_version::CheckTxVersion,
check_weight::CheckWeight,
};
@@ -154,7 +152,7 @@ impl SetCode for () {
#[frame_support::pallet]
pub mod pallet {
use crate::{*, pallet_prelude::*, self as frame_system};
use crate::{self as frame_system, pallet_prelude::*, *};
use frame_support::pallet_prelude::*;
/// System configuration trait. Implemented by runtime.
@@ -174,39 +172,69 @@ pub mod pallet {
type BlockLength: Get<limits::BlockLength>;
/// The `Origin` type used by dispatchable calls.
type Origin:
Into<Result<RawOrigin<Self::AccountId>, Self::Origin>>
type Origin: Into<Result<RawOrigin<Self::AccountId>, Self::Origin>>
+ From<RawOrigin<Self::AccountId>>
+ Clone
+ OriginTrait<Call=Self::Call>;
+ OriginTrait<Call = Self::Call>;
/// The aggregated `Call` type.
type Call: Dispatchable + Debug;
/// Account index (aka nonce) type. This stores the number of previous transactions associated
/// with a sender account.
type Index:
Parameter + Member + MaybeSerializeDeserialize + Debug + Default + MaybeDisplay + AtLeast32Bit
type Index: Parameter
+ Member
+ MaybeSerializeDeserialize
+ Debug
+ Default
+ MaybeDisplay
+ AtLeast32Bit
+ Copy;
/// The block number type used by the runtime.
type BlockNumber:
Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay +
AtLeast32BitUnsigned + Default + Bounded + Copy + sp_std::hash::Hash +
sp_std::str::FromStr + MaybeMallocSizeOf + MaxEncodedLen;
type BlockNumber: Parameter
+ Member
+ MaybeSerializeDeserialize
+ Debug
+ MaybeDisplay
+ AtLeast32BitUnsigned
+ Default
+ Bounded
+ Copy
+ sp_std::hash::Hash
+ sp_std::str::FromStr
+ MaybeMallocSizeOf
+ MaxEncodedLen;
/// The output of the `Hashing` function.
type Hash:
Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + SimpleBitOps + Ord
+ Default + Copy + CheckEqual + sp_std::hash::Hash + AsRef<[u8]> + AsMut<[u8]>
+ MaybeMallocSizeOf + MaxEncodedLen;
type Hash: Parameter
+ Member
+ MaybeSerializeDeserialize
+ Debug
+ MaybeDisplay
+ SimpleBitOps
+ Ord
+ Default
+ Copy
+ CheckEqual
+ sp_std::hash::Hash
+ AsRef<[u8]>
+ AsMut<[u8]>
+ MaybeMallocSizeOf
+ MaxEncodedLen;
/// The hashing system (algorithm) being used in the runtime (e.g. Blake2).
type Hashing: Hash<Output=Self::Hash>;
type Hashing: Hash<Output = Self::Hash>;
/// The user account identifier type for the runtime.
type AccountId: Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + Ord
+ Default + MaxEncodedLen;
type AccountId: Parameter
+ Member
+ MaybeSerializeDeserialize
+ Debug
+ MaybeDisplay
+ Ord
+ Default
+ MaxEncodedLen;
/// Converting trait to take a source type and convert to `AccountId`.
///
@@ -214,16 +242,17 @@ pub mod pallet {
/// It's perfectly reasonable for this to be an identity conversion (with the source type being
/// `AccountId`), but other pallets (e.g. Indices pallet) may provide more functional/efficient
/// alternatives.
type Lookup: StaticLookup<Target=Self::AccountId>;
type Lookup: StaticLookup<Target = Self::AccountId>;
/// The block header.
type Header: Parameter + traits::Header<
Number=Self::BlockNumber,
Hash=Self::Hash,
>;
type Header: Parameter + traits::Header<Number = Self::BlockNumber, Hash = Self::Hash>;
/// The aggregated event type of the runtime.
type Event: Parameter + Member + From<Event<Self>> + Debug + IsType<<Self as frame_system::Config>::Event>;
type Event: Parameter
+ Member
+ From<Event<Self>>
+ Debug
+ IsType<<Self as frame_system::Config>::Event>;
/// Maximum number of block number to block hash mappings to keep (oldest pruned first).
#[pallet::constant]
@@ -288,9 +317,7 @@ pub mod pallet {
}
fn integrity_test() {
T::BlockWeights::get()
.validate()
.expect("The weights are invalid.");
T::BlockWeights::get().validate().expect("The weights are invalid.");
}
}
@@ -413,7 +440,10 @@ pub mod pallet {
T::SystemWeightInfo::set_storage(items.len() as u32),
DispatchClass::Operational,
))]
pub fn set_storage(origin: OriginFor<T>, items: Vec<KeyValue>) -> DispatchResultWithPostInfo {
pub fn set_storage(
origin: OriginFor<T>,
items: Vec<KeyValue>,
) -> DispatchResultWithPostInfo {
ensure_root(origin)?;
for i in &items {
storage::unhashed::put_raw(&i.0, &i.1);
@@ -473,7 +503,10 @@ pub mod pallet {
/// - 1 event.
/// # </weight>
#[pallet::weight(T::SystemWeightInfo::remark_with_event(remark.len() as u32))]
pub fn remark_with_event(origin: OriginFor<T>, remark: Vec<u8>) -> DispatchResultWithPostInfo {
pub fn remark_with_event(
origin: OriginFor<T>,
remark: Vec<u8>,
) -> DispatchResultWithPostInfo {
let who = ensure_signed(origin)?;
let hash = T::Hashing::hash(&remark[..]);
Self::deposit_event(Event::Remarked(who, hash));
@@ -580,8 +613,7 @@ pub mod pallet {
/// Events deposited for the current block.
#[pallet::storage]
#[pallet::getter(fn events)]
pub type Events<T: Config> =
StorageValue<_, Vec<EventRecord<T::Event, T::Hash>>, ValueQuery>;
pub type Events<T: Config> = StorageValue<_, Vec<EventRecord<T::Event, T::Hash>>, ValueQuery>;
/// The number of events in the `Events<T>` list.
#[pallet::storage]
@@ -630,10 +662,7 @@ pub mod pallet {
#[cfg(feature = "std")]
impl Default for GenesisConfig {
fn default() -> Self {
Self {
changes_trie_config: Default::default(),
code: Default::default(),
}
Self { changes_trie_config: Default::default(), code: Default::default() }
}
}
@@ -649,7 +678,10 @@ pub mod pallet {
sp_io::storage::set(well_known_keys::CODE, &self.code);
sp_io::storage::set(well_known_keys::EXTRINSIC_INDEX, &0u32.encode());
if let Some(ref changes_trie_config) = self.changes_trie_config {
sp_io::storage::set(well_known_keys::CHANGES_TRIE_CONFIG, &changes_trie_config.encode());
sp_io::storage::set(
well_known_keys::CHANGES_TRIE_CONFIG,
&changes_trie_config.encode(),
);
}
}
}
@@ -661,17 +693,25 @@ pub mod migrations {
#[allow(dead_code)]
/// Migrate from unique `u8` reference counting to triple `u32` reference counting.
pub fn migrate_all<T: Config>() -> frame_support::weights::Weight {
Account::<T>::translate::<(T::Index, u8, T::AccountData), _>(|_key, (nonce, rc, data)|
Some(AccountInfo { nonce, consumers: rc as RefCount, providers: 1, sufficients: 0, data })
);
Account::<T>::translate::<(T::Index, u8, T::AccountData), _>(|_key, (nonce, rc, data)| {
Some(AccountInfo {
nonce,
consumers: rc as RefCount,
providers: 1,
sufficients: 0,
data,
})
});
T::BlockWeights::get().max_block
}
#[allow(dead_code)]
/// Migrate from unique `u32` reference counting to triple `u32` reference counting.
pub fn migrate_to_dual_ref_count<T: Config>() -> frame_support::weights::Weight {
Account::<T>::translate::<(T::Index, RefCount, T::AccountData), _>(|_key, (nonce, consumers, data)|
Some(AccountInfo { nonce, consumers, providers: 1, sufficients: 0, data })
Account::<T>::translate::<(T::Index, RefCount, T::AccountData), _>(
|_key, (nonce, consumers, data)| {
Some(AccountInfo { nonce, consumers, providers: 1, sufficients: 0, data })
},
);
T::BlockWeights::get().max_block
}
@@ -681,7 +721,7 @@ pub mod migrations {
Account::<T>::translate::<(T::Index, RefCount, RefCount, T::AccountData), _>(
|_key, (nonce, consumers, providers, data)| {
Some(AccountInfo { nonce, consumers, providers, sufficients: 0, data })
}
},
);
T::BlockWeights::get().max_block
}
@@ -701,7 +741,7 @@ impl GenesisConfig {
/// Kept in order not to break dependency.
pub fn assimilate_storage<T: Config>(
&self,
storage: &mut sp_runtime::Storage
storage: &mut sp_runtime::Storage,
) -> Result<(), String> {
<Self as GenesisBuild<T>>::assimilate_storage(self, storage)
}
@@ -822,18 +862,14 @@ impl LastRuntimeUpgradeInfo {
impl From<sp_version::RuntimeVersion> for LastRuntimeUpgradeInfo {
fn from(version: sp_version::RuntimeVersion) -> Self {
Self {
spec_version: version.spec_version.into(),
spec_name: version.spec_name,
}
Self { spec_version: version.spec_version.into(), spec_name: version.spec_name }
}
}
pub struct EnsureRoot<AccountId>(sp_std::marker::PhantomData<AccountId>);
impl<
O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>,
AccountId,
> EnsureOrigin<O> for EnsureRoot<AccountId> {
impl<O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>, AccountId>
EnsureOrigin<O> for EnsureRoot<AccountId>
{
type Success = ();
fn try_origin(o: O) -> Result<Self::Success, O> {
o.into().and_then(|o| match o {
@@ -849,10 +885,9 @@ impl<
}
pub struct EnsureSigned<AccountId>(sp_std::marker::PhantomData<AccountId>);
impl<
O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>,
AccountId: Default,
> EnsureOrigin<O> for EnsureSigned<AccountId> {
impl<O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>, AccountId: Default>
EnsureOrigin<O> for EnsureSigned<AccountId>
{
type Success = AccountId;
fn try_origin(o: O) -> Result<Self::Success, O> {
o.into().and_then(|o| match o {
@@ -869,10 +904,11 @@ impl<
pub struct EnsureSignedBy<Who, AccountId>(sp_std::marker::PhantomData<(Who, AccountId)>);
impl<
O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>,
Who: SortedMembers<AccountId>,
AccountId: PartialEq + Clone + Ord + Default,
> EnsureOrigin<O> for EnsureSignedBy<Who, AccountId> {
O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>,
Who: SortedMembers<AccountId>,
AccountId: PartialEq + Clone + Ord + Default,
> EnsureOrigin<O> for EnsureSignedBy<Who, AccountId>
{
type Success = AccountId;
fn try_origin(o: O) -> Result<Self::Success, O> {
o.into().and_then(|o| match o {
@@ -893,10 +929,9 @@ impl<
}
pub struct EnsureNone<AccountId>(sp_std::marker::PhantomData<AccountId>);
impl<
O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>,
AccountId,
> EnsureOrigin<O> for EnsureNone<AccountId> {
impl<O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>, AccountId>
EnsureOrigin<O> for EnsureNone<AccountId>
{
type Success = ();
fn try_origin(o: O) -> Result<Self::Success, O> {
o.into().and_then(|o| match o {
@@ -929,17 +964,16 @@ impl<O, T> EnsureOrigin<O> for EnsureNever<T> {
/// Origin check will pass if `L` or `R` origin check passes. `L` is tested first.
pub struct EnsureOneOf<AccountId, L, R>(sp_std::marker::PhantomData<(AccountId, L, R)>);
impl<
AccountId,
O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>,
L: EnsureOrigin<O>,
R: EnsureOrigin<O>,
> EnsureOrigin<O> for EnsureOneOf<AccountId, L, R> {
AccountId,
O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>,
L: EnsureOrigin<O>,
R: EnsureOrigin<O>,
> EnsureOrigin<O> for EnsureOneOf<AccountId, L, R>
{
type Success = Either<L::Success, R::Success>;
fn try_origin(o: O) -> Result<Self::Success, O> {
L::try_origin(o).map_or_else(
|o| R::try_origin(o).map(|o| Either::Right(o)),
|o| Ok(Either::Left(o)),
)
L::try_origin(o)
.map_or_else(|o| R::try_origin(o).map(|o| Either::Right(o)), |o| Ok(Either::Left(o)))
}
#[cfg(feature = "runtime-benchmarks")]
@@ -951,7 +985,8 @@ impl<
/// Ensure that the origin `o` represents a signed extrinsic (i.e. transaction).
/// Returns `Ok` with the account that signed the extrinsic or an `Err` otherwise.
pub fn ensure_signed<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<AccountId, BadOrigin>
where OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>
where
OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>,
{
match o.into() {
Ok(RawOrigin::Signed(t)) => Ok(t),
@@ -961,7 +996,8 @@ pub fn ensure_signed<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<AccountId
/// Ensure that the origin `o` represents the root. Returns `Ok` or an `Err` otherwise.
pub fn ensure_root<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<(), BadOrigin>
where OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>
where
OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>,
{
match o.into() {
Ok(RawOrigin::Root) => Ok(()),
@@ -971,7 +1007,8 @@ pub fn ensure_root<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<(), BadOrig
/// Ensure that the origin `o` represents an unsigned extrinsic. Returns `Ok` or an `Err` otherwise.
pub fn ensure_none<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<(), BadOrigin>
where OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>
where
OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>,
{
match o.into() {
Ok(RawOrigin::None) => Ok(()),
@@ -1057,14 +1094,16 @@ impl<T: Config> Pallet<T> {
/// Increment the provider reference counter on an account.
pub fn inc_providers(who: &T::AccountId) -> IncRefStatus {
Account::<T>::mutate(who, |a| if a.providers == 0 && a.sufficients == 0 {
// Account is being created.
a.providers = 1;
Self::on_created_account(who.clone(), a);
IncRefStatus::Created
} else {
a.providers = a.providers.saturating_add(1);
IncRefStatus::Existed
Account::<T>::mutate(who, |a| {
if a.providers == 0 && a.sufficients == 0 {
// Account is being created.
a.providers = 1;
Self::on_created_account(who.clone(), a);
IncRefStatus::Created
} else {
a.providers = a.providers.saturating_add(1);
IncRefStatus::Existed
}
})
}
@@ -1088,18 +1127,18 @@ impl<T: Config> Pallet<T> {
Pallet::<T>::on_killed_account(who.clone());
Ok(DecRefStatus::Reaped)
}
},
(1, c, _) if c > 0 => {
// Cannot remove last provider if there are consumers.
Err(DispatchError::ConsumerRemaining)
}
},
(x, _, _) => {
// Account will continue to exist as there is either > 1 provider or
// > 0 sufficients.
account.providers = x - 1;
*maybe_account = Some(account);
Ok(DecRefStatus::Exists)
}
},
}
} else {
log::error!(
@@ -1113,14 +1152,16 @@ impl<T: Config> Pallet<T> {
/// Increment the self-sufficient reference counter on an account.
pub fn inc_sufficients(who: &T::AccountId) -> IncRefStatus {
Account::<T>::mutate(who, |a| if a.providers + a.sufficients == 0 {
// Account is being created.
a.sufficients = 1;
Self::on_created_account(who.clone(), a);
IncRefStatus::Created
} else {
a.sufficients = a.sufficients.saturating_add(1);
IncRefStatus::Existed
Account::<T>::mutate(who, |a| {
if a.providers + a.sufficients == 0 {
// Account is being created.
a.sufficients = 1;
Self::on_created_account(who.clone(), a);
IncRefStatus::Created
} else {
a.sufficients = a.sufficients.saturating_add(1);
IncRefStatus::Existed
}
})
}
@@ -1141,12 +1182,12 @@ impl<T: Config> Pallet<T> {
(0, 0) | (1, 0) => {
Pallet::<T>::on_killed_account(who.clone());
DecRefStatus::Reaped
}
},
(x, _) => {
account.sufficients = x - 1;
*maybe_account = Some(account);
DecRefStatus::Exists
}
},
}
} else {
log::error!(
@@ -1178,24 +1219,28 @@ impl<T: Config> Pallet<T> {
///
/// The account `who`'s `providers` must be non-zero or this will return an error.
pub fn inc_consumers(who: &T::AccountId) -> Result<(), DispatchError> {
Account::<T>::try_mutate(who, |a| if a.providers > 0 {
a.consumers = a.consumers.saturating_add(1);
Ok(())
} else {
Err(DispatchError::NoProviders)
Account::<T>::try_mutate(who, |a| {
if a.providers > 0 {
a.consumers = a.consumers.saturating_add(1);
Ok(())
} else {
Err(DispatchError::NoProviders)
}
})
}
/// Decrement the reference counter on an account. This *MUST* only be done once for every time
/// you called `inc_consumers` on `who`.
pub fn dec_consumers(who: &T::AccountId) {
Account::<T>::mutate(who, |a| if a.consumers > 0 {
a.consumers -= 1;
} else {
log::error!(
target: "runtime::system",
"Logic error: Unexpected underflow in reducing consumer",
);
Account::<T>::mutate(who, |a| {
if a.consumers > 0 {
a.consumers -= 1;
} else {
log::error!(
target: "runtime::system",
"Logic error: Unexpected underflow in reducing consumer",
);
}
})
}
@@ -1233,14 +1278,13 @@ impl<T: Config> Pallet<T> {
pub fn deposit_event_indexed(topics: &[T::Hash], event: T::Event) {
let block_number = Self::block_number();
// Don't populate events on genesis.
if block_number.is_zero() { return }
if block_number.is_zero() {
return
}
let phase = ExecutionPhase::<T>::get().unwrap_or_default();
let event = EventRecord {
phase,
event,
topics: topics.iter().cloned().collect::<Vec<_>>(),
};
let event =
EventRecord { phase, event, topics: topics.iter().cloned().collect::<Vec<_>>() };
// Index of the to be added event.
let event_idx = {
@@ -1366,12 +1410,18 @@ impl<T: Config> Pallet<T> {
if let Some(storage_changes_root) = storage_changes_root {
let item = generic::DigestItem::ChangesTrieRoot(
T::Hash::decode(&mut &storage_changes_root[..])
.expect("Node is configured to use the same hash; qed")
.expect("Node is configured to use the same hash; qed"),
);
digest.push(item);
}
<T::Header as traits::Header>::new(number, extrinsics_root, storage_root, parent_hash, digest)
<T::Header as traits::Header>::new(
number,
extrinsics_root,
storage_root,
parent_hash,
digest,
)
}
/// Deposits a log and ensures it matches the block's log data.
@@ -1448,7 +1498,9 @@ impl<T: Config> Pallet<T> {
}
/// Return the chain's current runtime version.
pub fn runtime_version() -> RuntimeVersion { T::Version::get() }
pub fn runtime_version() -> RuntimeVersion {
T::Version::get()
}
/// Retrieve the account transaction counter from storage.
pub fn account_nonce(who: impl EncodeLike<T::AccountId>) -> T::Index {
@@ -1471,20 +1523,18 @@ impl<T: Config> Pallet<T> {
/// To be called immediately after an extrinsic has been applied.
pub fn note_applied_extrinsic(r: &DispatchResultWithPostInfo, mut info: DispatchInfo) {
info.weight = extract_actual_weight(r, &info);
Self::deposit_event(
match r {
Ok(_) => Event::ExtrinsicSuccess(info),
Err(err) => {
log::trace!(
target: "runtime::system",
"Extrinsic failed at block({:?}): {:?}",
Self::block_number(),
err,
);
Event::ExtrinsicFailed(err.error, info)
},
}
);
Self::deposit_event(match r {
Ok(_) => Event::ExtrinsicSuccess(info),
Err(err) => {
log::trace!(
target: "runtime::system",
"Extrinsic failed at block({:?}): {:?}",
Self::block_number(),
err,
);
Event::ExtrinsicFailed(err.error, info)
},
});
let next_extrinsic_index = Self::extrinsic_index().unwrap_or_default() + 1u32;
@@ -1495,8 +1545,8 @@ impl<T: Config> Pallet<T> {
/// To be called immediately after `note_applied_extrinsic` of the last extrinsic of the block
/// has been called.
pub fn note_finished_extrinsics() {
let extrinsic_index: u32 = storage::unhashed::take(well_known_keys::EXTRINSIC_INDEX)
.unwrap_or_default();
let extrinsic_index: u32 =
storage::unhashed::take(well_known_keys::EXTRINSIC_INDEX).unwrap_or_default();
ExtrinsicCount::<T>::put(extrinsic_index);
ExecutionPhase::<T>::put(Phase::Finalization);
}
@@ -1579,8 +1629,7 @@ impl<T: Config> HandleLifetime<T::AccountId> for Consumer<T> {
}
}
impl<T: Config> BlockNumberProvider for Pallet<T>
{
impl<T: Config> BlockNumberProvider for Pallet<T> {
type BlockNumber = <T as Config>::BlockNumber;
fn current_block_number() -> Self::BlockNumber {
@@ -1618,7 +1667,7 @@ impl<T: Config> StoredMap<T::AccountId, T::AccountData> for Pallet<T> {
DecRefStatus::Reaped => return Ok(result),
DecRefStatus::Exists => {
// Update value as normal...
}
},
}
} else if !was_providing && !is_providing {
return Ok(result)
@@ -1629,14 +1678,15 @@ impl<T: Config> StoredMap<T::AccountId, T::AccountData> for Pallet<T> {
}
/// Split an `option` into two constituent options, as defined by a `splitter` function.
pub fn split_inner<T, R, S>(option: Option<T>, splitter: impl FnOnce(T) -> (R, S))
-> (Option<R>, Option<S>)
{
pub fn split_inner<T, R, S>(
option: Option<T>,
splitter: impl FnOnce(T) -> (R, S),
) -> (Option<R>, Option<S>) {
match option {
Some(inner) => {
let (r, s) = splitter(inner);
(Some(r), Some(s))
}
},
None => (None, None),
}
}
@@ -1659,7 +1709,7 @@ impl<T: Config> Lookup for ChainContext<T> {
/// Prelude to be used alongside pallet macro, for ease of use.
pub mod pallet_prelude {
pub use crate::{ensure_signed, ensure_none, ensure_root};
pub use crate::{ensure_none, ensure_root, ensure_signed};
/// Type alias for the `Origin` associated type of system config.
pub type OriginFor<T> = <T as crate::Config>::Origin;
+27 -30
View File
@@ -25,8 +25,8 @@
//! `DispatchClass`. This module contains configuration object for both resources,
//! which should be passed to `frame_system` configuration when runtime is being set up.
use frame_support::weights::{Weight, DispatchClass, constants, PerDispatchClass, OneOrMany};
use sp_runtime::{RuntimeDebug, Perbill};
use frame_support::weights::{constants, DispatchClass, OneOrMany, PerDispatchClass, Weight};
use sp_runtime::{Perbill, RuntimeDebug};
/// Block length limit configuration.
#[derive(RuntimeDebug, Clone, codec::Encode, codec::Decode)]
@@ -40,29 +40,26 @@ pub struct BlockLength {
impl Default for BlockLength {
fn default() -> Self {
BlockLength::max_with_normal_ratio(
5 * 1024 * 1024,
DEFAULT_NORMAL_RATIO,
)
BlockLength::max_with_normal_ratio(5 * 1024 * 1024, DEFAULT_NORMAL_RATIO)
}
}
impl BlockLength {
/// Create new `BlockLength` with `max` for every class.
pub fn max(max: u32) -> Self {
Self {
max: PerDispatchClass::new(|_| max),
}
Self { max: PerDispatchClass::new(|_| max) }
}
/// Create new `BlockLength` with `max` for `Operational` & `Mandatory`
/// and `normal * max` for `Normal`.
pub fn max_with_normal_ratio(max: u32, normal: Perbill) -> Self {
Self {
max: PerDispatchClass::new(|class| if class == DispatchClass::Normal {
normal * max
} else {
max
max: PerDispatchClass::new(|class| {
if class == DispatchClass::Normal {
normal * max
} else {
max
}
}),
}
}
@@ -206,10 +203,7 @@ pub struct BlockWeights {
impl Default for BlockWeights {
fn default() -> Self {
Self::with_sensible_defaults(
1 * constants::WEIGHT_PER_SECOND,
DEFAULT_NORMAL_RATIO,
)
Self::with_sensible_defaults(1 * constants::WEIGHT_PER_SECOND, DEFAULT_NORMAL_RATIO)
}
}
@@ -245,7 +239,8 @@ impl BlockWeights {
weights.max_extrinsic.unwrap_or(0) <= max_for_class.saturating_sub(base_for_class),
&mut error,
"[{:?}] {:?} (max_extrinsic) can't be greater than {:?} (max for class)",
class, weights.max_extrinsic,
class,
weights.max_extrinsic,
max_for_class.saturating_sub(base_for_class),
);
// Max extrinsic should not be 0
@@ -260,21 +255,27 @@ impl BlockWeights {
reserved > base_for_class || reserved == 0,
&mut error,
"[{:?}] {:?} (reserved) has to be greater than {:?} (base extrinsic) if set",
class, reserved, base_for_class,
class,
reserved,
base_for_class,
);
// Make sure max block is greater than max_total if it's set.
error_assert!(
self.max_block >= weights.max_total.unwrap_or(0),
&mut error,
"[{:?}] {:?} (max block) has to be greater than {:?} (max for class)",
class, self.max_block, weights.max_total,
class,
self.max_block,
weights.max_total,
);
// Make sure we can fit at least one extrinsic.
error_assert!(
self.max_block > base_for_class + self.base_block,
&mut error,
"[{:?}] {:?} (max block) must fit at least one extrinsic {:?} (base weight)",
class, self.max_block, base_for_class + self.base_block,
class,
self.max_block,
base_for_class + self.base_block,
);
}
@@ -309,10 +310,7 @@ impl BlockWeights {
/// Assumptions:
/// - Average block initialization is assumed to be `10%`.
/// - `Operational` transactions have reserved allowance (`1.0 - normal_ratio`)
pub fn with_sensible_defaults(
expected_block_weight: Weight,
normal_ratio: Perbill,
) -> Self {
pub fn with_sensible_defaults(expected_block_weight: Weight, normal_ratio: Perbill) -> Self {
let normal_weight = normal_ratio * expected_block_weight;
Self::builder()
.for_class(DispatchClass::Normal, |weights| {
@@ -388,7 +386,7 @@ impl BlockWeightsBuilder {
for class in class.into_iter() {
action(self.weights.per_class.get_mut(class));
}
self
self
}
/// Construct the `BlockWeights` object.
@@ -408,7 +406,8 @@ impl BlockWeightsBuilder {
for class in DispatchClass::all() {
let per_class = weights.per_class.get_mut(*class);
if per_class.max_extrinsic.is_none() && init_cost.is_some() {
per_class.max_extrinsic = per_class.max_total
per_class.max_extrinsic = per_class
.max_total
.map(|x| x.saturating_sub(init_weight))
.map(|x| x.saturating_sub(per_class.base_extrinsic));
}
@@ -435,8 +434,6 @@ mod tests {
#[test]
fn default_weights_are_valid() {
BlockWeights::default()
.validate()
.unwrap();
BlockWeights::default().validate().unwrap();
}
}
+16 -11
View File
@@ -16,13 +16,14 @@
// limitations under the License.
use crate::{self as frame_system, *};
use sp_std::cell::RefCell;
use frame_support::parameter_types;
use sp_core::H256;
use sp_runtime::{
testing::Header,
traits::{BlakeTwo256, IdentityLookup},
testing::Header, BuildStorage,
BuildStorage,
};
use frame_support::parameter_types;
use sp_std::cell::RefCell;
type UncheckedExtrinsic = mocking::MockUncheckedExtrinsic<Test>;
type Block = mocking::MockBlock<Test>;
@@ -75,13 +76,15 @@ parameter_types! {
limits::BlockLength::max_with_normal_ratio(1024, NORMAL_DISPATCH_RATIO);
}
thread_local!{
thread_local! {
pub static KILLED: RefCell<Vec<u64>> = RefCell::new(vec![]);
}
pub struct RecordKilled;
impl OnKilledAccount<u64> for RecordKilled {
fn on_killed_account(who: &u64) { KILLED.with(|r| r.borrow_mut().push(*who)) }
fn on_killed_account(who: &u64) {
KILLED.with(|r| r.borrow_mut().push(*who))
}
}
impl Config for Test {
@@ -117,12 +120,14 @@ pub const CALL: &<Test as Config>::Call = &Call::System(frame_system::Call::set_
/// Create new externalities for `System` module tests.
pub fn new_test_ext() -> sp_io::TestExternalities {
let mut ext: sp_io::TestExternalities = GenesisConfig::default()
.build_storage().unwrap().into();
let mut ext: sp_io::TestExternalities =
GenesisConfig::default().build_storage().unwrap().into();
// Add to each test the initial weight of a block
ext.execute_with(|| System::register_extra_weight_unchecked(
<Test as crate::Config>::BlockWeights::get().base_block,
DispatchClass::Mandatory
));
ext.execute_with(|| {
System::register_extra_weight_unchecked(
<Test as crate::Config>::BlockWeights::get().base_block,
DispatchClass::Mandatory,
)
});
ext
}
+4 -1
View File
@@ -21,7 +21,10 @@ use sp_runtime::generic;
/// An unchecked extrinsic type to be used in tests.
pub type MockUncheckedExtrinsic<T, Signature = (), Extra = ()> = generic::UncheckedExtrinsic<
<T as crate::Config>::AccountId, <T as crate::Config>::Call, Signature, Extra,
<T as crate::Config>::AccountId,
<T as crate::Config>::Call,
Signature,
Extra,
>;
/// An implementation of `sp_runtime::traits::Block` to be used in tests.
+115 -163
View File
@@ -57,12 +57,16 @@
#![warn(missing_docs)]
use codec::Encode;
use sp_std::collections::btree_set::BTreeSet;
use sp_std::convert::{TryInto, TryFrom};
use sp_std::prelude::{Box, Vec};
use sp_runtime::app_crypto::RuntimeAppPublic;
use sp_runtime::traits::{Extrinsic as ExtrinsicT, IdentifyAccount, One};
use frame_support::RuntimeDebug;
use sp_runtime::{
app_crypto::RuntimeAppPublic,
traits::{Extrinsic as ExtrinsicT, IdentifyAccount, One},
};
use sp_std::{
collections::btree_set::BTreeSet,
convert::{TryFrom, TryInto},
prelude::{Box, Vec},
};
/// Marker struct used to flag using all supported keys to sign a payload.
pub struct ForAll {}
@@ -76,7 +80,7 @@ pub struct ForAny {}
/// utility function can be used. However, this struct is used by `Signer`
/// to submit a signed transactions providing the signature along with the call.
pub struct SubmitTransaction<T: SendTransactionTypes<OverarchingCall>, OverarchingCall> {
_phantom: sp_std::marker::PhantomData<(T, OverarchingCall)>
_phantom: sp_std::marker::PhantomData<(T, OverarchingCall)>,
}
impl<T, LocalCall> SubmitTransaction<T, LocalCall>
@@ -120,10 +124,7 @@ pub struct Signer<T: SigningTypes, C: AppCrypto<T::Public, T::Signature>, X = Fo
impl<T: SigningTypes, C: AppCrypto<T::Public, T::Signature>, X> Default for Signer<T, C, X> {
fn default() -> Self {
Self {
accounts: Default::default(),
_phantom: Default::default(),
}
Self { accounts: Default::default(), _phantom: Default::default() }
}
}
@@ -161,72 +162,73 @@ impl<T: SigningTypes, C: AppCrypto<T::Public, T::Signature>, X> Signer<T, C, X>
let keystore_accounts = self.keystore_accounts();
match self.accounts {
None => Box::new(keystore_accounts),
Some(ref keys) => {
let keystore_lookup: BTreeSet<<T as SigningTypes>::Public> = keystore_accounts
.map(|account| account.public).collect();
Some(ref keys) => {
let keystore_lookup: BTreeSet<<T as SigningTypes>::Public> =
keystore_accounts.map(|account| account.public).collect();
Box::new(keys.into_iter()
.enumerate()
.map(|(index, key)| {
let account_id = key.clone().into_account();
Account::new(index, account_id, key.clone())
})
.filter(move |account| keystore_lookup.contains(&account.public)))
}
Box::new(
keys.into_iter()
.enumerate()
.map(|(index, key)| {
let account_id = key.clone().into_account();
Account::new(index, account_id, key.clone())
})
.filter(move |account| keystore_lookup.contains(&account.public)),
)
},
}
}
fn keystore_accounts(&self) -> impl Iterator<Item = Account<T>> {
C::RuntimeAppPublic::all()
.into_iter()
.enumerate()
.map(|(index, key)| {
let generic_public = C::GenericPublic::from(key);
let public: T::Public = generic_public.into();
let account_id = public.clone().into_account();
Account::new(index, account_id, public)
})
C::RuntimeAppPublic::all().into_iter().enumerate().map(|(index, key)| {
let generic_public = C::GenericPublic::from(key);
let public: T::Public = generic_public.into();
let account_id = public.clone().into_account();
Account::new(index, account_id, public)
})
}
}
impl<T: SigningTypes, C: AppCrypto<T::Public, T::Signature>> Signer<T, C, ForAll> {
fn for_all<F, R>(&self, f: F) -> Vec<(Account<T>, R)> where
fn for_all<F, R>(&self, f: F) -> Vec<(Account<T>, R)>
where
F: Fn(&Account<T>) -> Option<R>,
{
let accounts = self.accounts_from_keys();
accounts
.into_iter()
.filter_map(|account| {
f(&account).map(|res| (account, res))
})
.filter_map(|account| f(&account).map(|res| (account, res)))
.collect()
}
}
impl<T: SigningTypes, C: AppCrypto<T::Public, T::Signature>> Signer<T, C, ForAny> {
fn for_any<F, R>(&self, f: F) -> Option<(Account<T>, R)> where
fn for_any<F, R>(&self, f: F) -> Option<(Account<T>, R)>
where
F: Fn(&Account<T>) -> Option<R>,
{
let accounts = self.accounts_from_keys();
for account in accounts.into_iter() {
let res = f(&account);
if let Some(res) = res {
return Some((account, res));
return Some((account, res))
}
}
None
}
}
impl<T: SigningTypes, C: AppCrypto<T::Public, T::Signature>> SignMessage<T> for Signer<T, C, ForAll> {
impl<T: SigningTypes, C: AppCrypto<T::Public, T::Signature>> SignMessage<T>
for Signer<T, C, ForAll>
{
type SignatureData = Vec<(Account<T>, T::Signature)>;
fn sign_message(&self, message: &[u8]) -> Self::SignatureData {
self.for_all(|account| C::sign(message, account.public.clone()))
}
fn sign<TPayload, F>(&self, f: F) -> Self::SignatureData where
fn sign<TPayload, F>(&self, f: F) -> Self::SignatureData
where
F: Fn(&Account<T>) -> TPayload,
TPayload: SignedPayload<T>,
{
@@ -234,14 +236,17 @@ impl<T: SigningTypes, C: AppCrypto<T::Public, T::Signature>> SignMessage<T> for
}
}
impl<T: SigningTypes, C: AppCrypto<T::Public, T::Signature>> SignMessage<T> for Signer<T, C, ForAny> {
impl<T: SigningTypes, C: AppCrypto<T::Public, T::Signature>> SignMessage<T>
for Signer<T, C, ForAny>
{
type SignatureData = Option<(Account<T>, T::Signature)>;
fn sign_message(&self, message: &[u8]) -> Self::SignatureData {
self.for_any(|account| C::sign(message, account.public.clone()))
}
fn sign<TPayload, F>(&self, f: F) -> Self::SignatureData where
fn sign<TPayload, F>(&self, f: F) -> Self::SignatureData
where
F: Fn(&Account<T>) -> TPayload,
TPayload: SignedPayload<T>,
{
@@ -250,16 +255,14 @@ impl<T: SigningTypes, C: AppCrypto<T::Public, T::Signature>> SignMessage<T> for
}
impl<
T: CreateSignedTransaction<LocalCall> + SigningTypes,
C: AppCrypto<T::Public, T::Signature>,
LocalCall,
> SendSignedTransaction<T, C, LocalCall> for Signer<T, C, ForAny> {
T: CreateSignedTransaction<LocalCall> + SigningTypes,
C: AppCrypto<T::Public, T::Signature>,
LocalCall,
> SendSignedTransaction<T, C, LocalCall> for Signer<T, C, ForAny>
{
type Result = Option<(Account<T>, Result<(), ()>)>;
fn send_signed_transaction(
&self,
f: impl Fn(&Account<T>) -> LocalCall,
) -> Self::Result {
fn send_signed_transaction(&self, f: impl Fn(&Account<T>) -> LocalCall) -> Self::Result {
self.for_any(|account| {
let call = f(account);
self.send_single_signed_transaction(account, call)
@@ -268,16 +271,14 @@ impl<
}
impl<
T: SigningTypes + CreateSignedTransaction<LocalCall>,
C: AppCrypto<T::Public, T::Signature>,
LocalCall,
> SendSignedTransaction<T, C, LocalCall> for Signer<T, C, ForAll> {
T: SigningTypes + CreateSignedTransaction<LocalCall>,
C: AppCrypto<T::Public, T::Signature>,
LocalCall,
> SendSignedTransaction<T, C, LocalCall> for Signer<T, C, ForAll>
{
type Result = Vec<(Account<T>, Result<(), ()>)>;
fn send_signed_transaction(
&self,
f: impl Fn(&Account<T>) -> LocalCall,
) -> Self::Result {
fn send_signed_transaction(&self, f: impl Fn(&Account<T>) -> LocalCall) -> Self::Result {
self.for_all(|account| {
let call = f(account);
self.send_single_signed_transaction(account, call)
@@ -286,10 +287,11 @@ impl<
}
impl<
T: SigningTypes + SendTransactionTypes<LocalCall>,
C: AppCrypto<T::Public, T::Signature>,
LocalCall,
> SendUnsignedTransaction<T, LocalCall> for Signer<T, C, ForAny> {
T: SigningTypes + SendTransactionTypes<LocalCall>,
C: AppCrypto<T::Public, T::Signature>,
LocalCall,
> SendUnsignedTransaction<T, LocalCall> for Signer<T, C, ForAny>
{
type Result = Option<(Account<T>, Result<(), ()>)>;
fn send_unsigned_transaction<TPayload, F>(
@@ -303,7 +305,7 @@ impl<
{
self.for_any(|account| {
let payload = f(account);
let signature= payload.sign::<C>()?;
let signature = payload.sign::<C>()?;
let call = f2(payload, signature);
self.submit_unsigned_transaction(call)
})
@@ -311,10 +313,11 @@ impl<
}
impl<
T: SigningTypes + SendTransactionTypes<LocalCall>,
C: AppCrypto<T::Public, T::Signature>,
LocalCall,
> SendUnsignedTransaction<T, LocalCall> for Signer<T, C, ForAll> {
T: SigningTypes + SendTransactionTypes<LocalCall>,
C: AppCrypto<T::Public, T::Signature>,
LocalCall,
> SendUnsignedTransaction<T, LocalCall> for Signer<T, C, ForAll>
{
type Result = Vec<(Account<T>, Result<(), ()>)>;
fn send_unsigned_transaction<TPayload, F>(
@@ -324,7 +327,8 @@ impl<
) -> Self::Result
where
F: Fn(&Account<T>) -> TPayload,
TPayload: SignedPayload<T> {
TPayload: SignedPayload<T>,
{
self.for_all(|account| {
let payload = f(account);
let signature = payload.sign::<C>()?;
@@ -352,16 +356,13 @@ impl<T: SigningTypes> Account<T> {
}
}
impl<T: SigningTypes> Clone for Account<T> where
impl<T: SigningTypes> Clone for Account<T>
where
T::AccountId: Clone,
T::Public: Clone,
{
fn clone(&self) -> Self {
Self {
index: self.index,
id: self.id.clone(),
public: self.public.clone(),
}
Self { index: self.index, id: self.id.clone(), public: self.public.clone() }
}
}
@@ -375,9 +376,9 @@ impl<T: SigningTypes> Clone for Account<T> where
/// The point of this trait is to be able to easily convert between `RuntimeAppPublic`, the wrapped
/// (generic = non application-specific) crypto types and the `Public` type required by the runtime.
///
/// Example (pseudo-)implementation:
/// Example (pseudo-)implementation:
/// ```ignore
/// // im-online specific crypto
/// // im-online specific crypto
/// type RuntimeAppPublic = ImOnline(sr25519::Public);
///
/// // wrapped "raw" crypto
@@ -395,15 +396,13 @@ pub trait AppCrypto<Public, Signature> {
type RuntimeAppPublic: RuntimeAppPublic;
/// A raw crypto public key wrapped by `RuntimeAppPublic`.
type GenericPublic:
From<Self::RuntimeAppPublic>
type GenericPublic: From<Self::RuntimeAppPublic>
+ Into<Self::RuntimeAppPublic>
+ TryFrom<Public>
+ Into<Public>;
/// A matching raw crypto `Signature` type.
type GenericSignature:
From<<Self::RuntimeAppPublic as RuntimeAppPublic>::Signature>
type GenericSignature: From<<Self::RuntimeAppPublic as RuntimeAppPublic>::Signature>
+ Into<<Self::RuntimeAppPublic as RuntimeAppPublic>::Signature>
+ TryFrom<Signature>
+ Into<Signature>;
@@ -424,16 +423,15 @@ pub trait AppCrypto<Public, Signature> {
fn verify(payload: &[u8], public: Public, signature: Signature) -> bool {
let p: Self::GenericPublic = match public.try_into() {
Ok(a) => a,
_ => return false
_ => return false,
};
let x = Into::<Self::RuntimeAppPublic>::into(p);
let signature: Self::GenericSignature = match signature.try_into() {
Ok(a) => a,
_ => return false
_ => return false,
};
let signature = Into::<<
Self::RuntimeAppPublic as RuntimeAppPublic
>::Signature>::into(signature);
let signature =
Into::<<Self::RuntimeAppPublic as RuntimeAppPublic>::Signature>::into(signature);
x.verify(&payload, &signature)
}
@@ -443,7 +441,6 @@ pub trait AppCrypto<Public, Signature> {
///
/// This trait adds extra bounds to `Public` and `Signature` types of the runtime
/// that are necessary to use these types for signing.
///
// TODO [#5663] Could this be just `T::Signature as traits::Verify>::Signer`?
// Seems that this may cause issues with bounds resolution.
pub trait SigningTypes: crate::Config {
@@ -459,16 +456,13 @@ pub trait SigningTypes: crate::Config {
+ Ord;
/// A matching `Signature` type.
type Signature: Clone
+ PartialEq
+ core::fmt::Debug
+ codec::Codec;
type Signature: Clone + PartialEq + core::fmt::Debug + codec::Codec;
}
/// A definition of types required to submit transactions from within the runtime.
pub trait SendTransactionTypes<LocalCall> {
/// The extrinsic type expected by the runtime.
type Extrinsic: ExtrinsicT<Call=Self::OverarchingCall> + codec::Encode;
type Extrinsic: ExtrinsicT<Call = Self::OverarchingCall> + codec::Encode;
/// The runtime's call type.
///
/// This has additional bound to be able to be created from pallet-local `Call` types.
@@ -482,7 +476,9 @@ pub trait SendTransactionTypes<LocalCall> {
/// This will most likely include creation of `SignedExtra` (a set of `SignedExtensions`).
/// Note that the result can be altered by inspecting the `Call` (for instance adjusting
/// fees, or mortality depending on the `pallet` being called).
pub trait CreateSignedTransaction<LocalCall>: SendTransactionTypes<LocalCall> + SigningTypes {
pub trait CreateSignedTransaction<LocalCall>:
SendTransactionTypes<LocalCall> + SigningTypes
{
/// Attempt to create signed extrinsic data that encodes call from given account.
///
/// Runtime implementation is free to construct the payload to sign and the signature
@@ -514,18 +510,19 @@ pub trait SignMessage<T: SigningTypes> {
///
/// This method expects `f` to return a `SignedPayload`
/// object which is then used for signing.
fn sign<TPayload, F>(&self, f: F) -> Self::SignatureData where
fn sign<TPayload, F>(&self, f: F) -> Self::SignatureData
where
F: Fn(&Account<T>) -> TPayload,
TPayload: SignedPayload<T>,
;
TPayload: SignedPayload<T>;
}
/// Submit a signed transaction to the transaction pool.
pub trait SendSignedTransaction<
T: SigningTypes + CreateSignedTransaction<LocalCall>,
C: AppCrypto<T::Public, T::Signature>,
LocalCall
> {
LocalCall,
>
{
/// A submission result.
///
/// This should contain an indication of success and the account that was used for signing.
@@ -537,10 +534,7 @@ pub trait SendSignedTransaction<
/// to be returned.
/// The call is then wrapped into a transaction (see `#CreateSignedTransaction`), signed and
/// submitted to the pool.
fn send_signed_transaction(
&self,
f: impl Fn(&Account<T>) -> LocalCall,
) -> Self::Result;
fn send_signed_transaction(&self, f: impl Fn(&Account<T>) -> LocalCall) -> Self::Result;
/// Wraps the call into transaction, signs using given account and submits to the pool.
fn send_single_signed_transaction(
@@ -559,10 +553,9 @@ pub trait SendSignedTransaction<
call.into(),
account.public.clone(),
account.id.clone(),
account_data.nonce
account_data.nonce,
)?;
let res = SubmitTransaction::<T, LocalCall>
::submit_transaction(call, Some(signature));
let res = SubmitTransaction::<T, LocalCall>::submit_transaction(call, Some(signature));
if res.is_ok() {
// increment the nonce. This is fine, since the code should always
@@ -576,10 +569,7 @@ pub trait SendSignedTransaction<
}
/// Submit an unsigned transaction onchain with a signed payload
pub trait SendUnsignedTransaction<
T: SigningTypes + SendTransactionTypes<LocalCall>,
LocalCall,
> {
pub trait SendUnsignedTransaction<T: SigningTypes + SendTransactionTypes<LocalCall>, LocalCall> {
/// A submission result.
///
/// Should contain the submission result and the account(s) that signed the payload.
@@ -601,12 +591,8 @@ pub trait SendUnsignedTransaction<
TPayload: SignedPayload<T>;
/// Submits an unsigned call to the transaction pool.
fn submit_unsigned_transaction(
&self,
call: LocalCall
) -> Option<Result<(), ()>> {
Some(SubmitTransaction::<T, LocalCall>
::submit_unsigned_transaction(call.into()))
fn submit_unsigned_transaction(&self, call: LocalCall) -> Option<Result<(), ()>> {
Some(SubmitTransaction::<T, LocalCall>::submit_unsigned_transaction(call.into()))
}
}
@@ -631,14 +617,13 @@ pub trait SignedPayload<T: SigningTypes>: Encode {
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::mock::{Call, Test as TestRuntime, CALL};
use codec::Decode;
use crate::mock::{Test as TestRuntime, Call, CALL};
use sp_core::offchain::{testing, TransactionPoolExt};
use sp_runtime::testing::{UintAuthorityId, TestSignature, TestXt};
use sp_runtime::testing::{TestSignature, TestXt, UintAuthorityId};
impl SigningTypes for TestRuntime {
type Public = UintAuthorityId;
@@ -675,16 +660,8 @@ mod tests {
type GenericSignature = TestSignature;
}
fn assert_account(
next: Option<(Account<TestRuntime>, Result<(), ()>)>,
index: usize,
id: u64,
) {
assert_eq!(next, Some((Account {
index,
id,
public: id.into(),
}, Ok(()))));
fn assert_account(next: Option<(Account<TestRuntime>, Result<(), ()>)>, index: usize, id: u64) {
assert_eq!(next, Some((Account { index, id, public: id.into() }, Ok(()))));
}
#[test]
@@ -699,16 +676,10 @@ mod tests {
t.execute_with(|| {
// when
let result = Signer::<TestRuntime, DummyAppCrypto>
::all_accounts()
let result = Signer::<TestRuntime, DummyAppCrypto>::all_accounts()
.send_unsigned_transaction(
|account| SimplePayload {
data: vec![1, 2, 3],
public: account.public.clone()
},
|_payload, _signature| {
CALL.clone()
}
|account| SimplePayload { data: vec![1, 2, 3], public: account.public.clone() },
|_payload, _signature| CALL.clone(),
);
// then
@@ -740,16 +711,10 @@ mod tests {
t.execute_with(|| {
// when
let result = Signer::<TestRuntime, DummyAppCrypto>
::any_account()
let result = Signer::<TestRuntime, DummyAppCrypto>::any_account()
.send_unsigned_transaction(
|account| SimplePayload {
data: vec![1, 2, 3],
public: account.public.clone()
},
|_payload, _signature| {
CALL.clone()
}
|account| SimplePayload { data: vec![1, 2, 3], public: account.public.clone() },
|_payload, _signature| CALL.clone(),
);
// then
@@ -777,17 +742,11 @@ mod tests {
t.execute_with(|| {
// when
let result = Signer::<TestRuntime, DummyAppCrypto>
::all_accounts()
let result = Signer::<TestRuntime, DummyAppCrypto>::all_accounts()
.with_filter(vec![0xf2.into(), 0xf1.into()])
.send_unsigned_transaction(
|account| SimplePayload {
data: vec![1, 2, 3],
public: account.public.clone()
},
|_payload, _signature| {
CALL.clone()
}
|account| SimplePayload { data: vec![1, 2, 3], public: account.public.clone() },
|_payload, _signature| CALL.clone(),
);
// then
@@ -817,17 +776,11 @@ mod tests {
t.execute_with(|| {
// when
let result = Signer::<TestRuntime, DummyAppCrypto>
::any_account()
let result = Signer::<TestRuntime, DummyAppCrypto>::any_account()
.with_filter(vec![0xf2.into(), 0xf1.into()])
.send_unsigned_transaction(
|account| SimplePayload {
data: vec![1, 2, 3],
public: account.public.clone()
},
|_payload, _signature| {
CALL.clone()
}
|account| SimplePayload { data: vec![1, 2, 3], public: account.public.clone() },
|_payload, _signature| CALL.clone(),
);
// then
@@ -842,5 +795,4 @@ mod tests {
assert_eq!(tx1.signature, None);
});
}
}
+60 -134
View File
@@ -16,11 +16,14 @@
// limitations under the License.
use crate::*;
use mock::{*, Origin};
use sp_core::H256;
use sp_runtime::{DispatchError, DispatchErrorWithPostInfo, traits::{Header, BlakeTwo256}};
use frame_support::{
assert_noop, assert_ok, weights::WithPostDispatchInfo, dispatch::PostDispatchInfo
assert_noop, assert_ok, dispatch::PostDispatchInfo, weights::WithPostDispatchInfo,
};
use mock::{Origin, *};
use sp_core::H256;
use sp_runtime::{
traits::{BlakeTwo256, Header},
DispatchError, DispatchErrorWithPostInfo,
};
#[test]
@@ -36,13 +39,10 @@ fn stored_map_works() {
assert_ok!(System::insert(&0, 42));
assert!(!System::is_provider_required(&0));
assert_eq!(Account::<Test>::get(0), AccountInfo {
nonce: 0,
providers: 1,
consumers: 0,
sufficients: 0,
data: 42,
});
assert_eq!(
Account::<Test>::get(0),
AccountInfo { nonce: 0, providers: 1, consumers: 0, sufficients: 0, data: 42 }
);
assert_ok!(System::inc_consumers(&0));
assert!(System::is_provider_required(&0));
@@ -154,40 +154,25 @@ fn provider_required_to_support_consumer() {
#[test]
fn deposit_event_should_work() {
new_test_ext().execute_with(|| {
System::initialize(
&1,
&[0u8; 32].into(),
&Default::default(),
InitKind::Full,
);
System::initialize(&1, &[0u8; 32].into(), &Default::default(), InitKind::Full);
System::note_finished_extrinsics();
System::deposit_event(SysEvent::CodeUpdated);
System::finalize();
assert_eq!(
System::events(),
vec![
EventRecord {
phase: Phase::Finalization,
event: SysEvent::CodeUpdated.into(),
topics: vec![],
}
]
vec![EventRecord {
phase: Phase::Finalization,
event: SysEvent::CodeUpdated.into(),
topics: vec![],
}]
);
System::initialize(
&2,
&[0u8; 32].into(),
&Default::default(),
InitKind::Full,
);
System::initialize(&2, &[0u8; 32].into(), &Default::default(), InitKind::Full);
System::deposit_event(SysEvent::NewAccount(32));
System::note_finished_initialize();
System::deposit_event(SysEvent::KilledAccount(42));
System::note_applied_extrinsic(&Ok(().into()), Default::default());
System::note_applied_extrinsic(
&Err(DispatchError::BadOrigin.into()),
Default::default()
);
System::note_applied_extrinsic(&Err(DispatchError::BadOrigin.into()), Default::default());
System::note_finished_extrinsics();
System::deposit_event(SysEvent::NewAccount(3));
System::finalize();
@@ -214,7 +199,8 @@ fn deposit_event_should_work() {
event: SysEvent::ExtrinsicFailed(
DispatchError::BadOrigin.into(),
Default::default()
).into(),
)
.into(),
topics: vec![]
},
EventRecord {
@@ -230,78 +216,56 @@ fn deposit_event_should_work() {
#[test]
fn deposit_event_uses_actual_weight() {
new_test_ext().execute_with(|| {
System::initialize(
&1,
&[0u8; 32].into(),
&Default::default(),
InitKind::Full,
);
System::initialize(&1, &[0u8; 32].into(), &Default::default(), InitKind::Full);
System::note_finished_initialize();
let pre_info = DispatchInfo {
weight: 1000,
.. Default::default()
};
System::note_applied_extrinsic(
&Ok(Some(300).into()),
pre_info,
);
System::note_applied_extrinsic(
&Ok(Some(1000).into()),
pre_info,
);
let pre_info = DispatchInfo { weight: 1000, ..Default::default() };
System::note_applied_extrinsic(&Ok(Some(300).into()), pre_info);
System::note_applied_extrinsic(&Ok(Some(1000).into()), pre_info);
System::note_applied_extrinsic(
// values over the pre info should be capped at pre dispatch value
&Ok(Some(1200).into()),
pre_info,
);
System::note_applied_extrinsic(
&Err(DispatchError::BadOrigin.with_weight(999)),
pre_info,
);
System::note_applied_extrinsic(&Err(DispatchError::BadOrigin.with_weight(999)), pre_info);
assert_eq!(
System::events(),
vec![
EventRecord {
phase: Phase::ApplyExtrinsic(0),
event: SysEvent::ExtrinsicSuccess(
DispatchInfo {
weight: 300,
.. Default::default()
},
).into(),
event: SysEvent::ExtrinsicSuccess(DispatchInfo {
weight: 300,
..Default::default()
},)
.into(),
topics: vec![]
},
EventRecord {
phase: Phase::ApplyExtrinsic(1),
event: SysEvent::ExtrinsicSuccess(
DispatchInfo {
weight: 1000,
.. Default::default()
},
).into(),
event: SysEvent::ExtrinsicSuccess(DispatchInfo {
weight: 1000,
..Default::default()
},)
.into(),
topics: vec![]
},
EventRecord {
phase: Phase::ApplyExtrinsic(2),
event: SysEvent::ExtrinsicSuccess(
DispatchInfo {
weight: 1000,
.. Default::default()
},
).into(),
event: SysEvent::ExtrinsicSuccess(DispatchInfo {
weight: 1000,
..Default::default()
},)
.into(),
topics: vec![]
},
EventRecord {
phase: Phase::ApplyExtrinsic(3),
event: SysEvent::ExtrinsicFailed(
DispatchError::BadOrigin.into(),
DispatchInfo {
weight: 999,
.. Default::default()
},
).into(),
DispatchInfo { weight: 999, ..Default::default() },
)
.into(),
topics: vec![]
},
]
@@ -314,19 +278,10 @@ fn deposit_event_topics() {
new_test_ext().execute_with(|| {
const BLOCK_NUMBER: u64 = 1;
System::initialize(
&BLOCK_NUMBER,
&[0u8; 32].into(),
&Default::default(),
InitKind::Full,
);
System::initialize(&BLOCK_NUMBER, &[0u8; 32].into(), &Default::default(), InitKind::Full);
System::note_finished_extrinsics();
let topics = vec![
H256::repeat_byte(1),
H256::repeat_byte(2),
H256::repeat_byte(3),
];
let topics = vec![H256::repeat_byte(1), H256::repeat_byte(2), H256::repeat_byte(3)];
// We deposit a few events with different sets of topics.
System::deposit_event_indexed(&topics[0..3], SysEvent::NewAccount(1).into());
@@ -359,18 +314,9 @@ fn deposit_event_topics() {
// Check that the topic-events mapping reflects the deposited topics.
// Note that these are indexes of the events.
assert_eq!(
System::event_topics(&topics[0]),
vec![(BLOCK_NUMBER, 0), (BLOCK_NUMBER, 1)],
);
assert_eq!(
System::event_topics(&topics[1]),
vec![(BLOCK_NUMBER, 0), (BLOCK_NUMBER, 2)],
);
assert_eq!(
System::event_topics(&topics[2]),
vec![(BLOCK_NUMBER, 0)],
);
assert_eq!(System::event_topics(&topics[0]), vec![(BLOCK_NUMBER, 0), (BLOCK_NUMBER, 1)],);
assert_eq!(System::event_topics(&topics[1]), vec![(BLOCK_NUMBER, 0), (BLOCK_NUMBER, 2)],);
assert_eq!(System::event_topics(&topics[2]), vec![(BLOCK_NUMBER, 0)],);
});
}
@@ -390,30 +336,19 @@ fn prunes_block_hash_mappings() {
new_test_ext().execute_with(|| {
// simulate import of 15 blocks
for n in 1..=15 {
System::initialize(
&n,
&[n as u8 - 1; 32].into(),
&Default::default(),
InitKind::Full,
);
System::initialize(&n, &[n as u8 - 1; 32].into(), &Default::default(), InitKind::Full);
System::finalize();
}
// first 5 block hashes are pruned
for n in 0..5 {
assert_eq!(
System::block_hash(n),
H256::zero(),
);
assert_eq!(System::block_hash(n), H256::zero(),);
}
// the remaining 10 are kept
for n in 5..15 {
assert_eq!(
System::block_hash(n),
[n as u8; 32].into(),
);
assert_eq!(System::block_hash(n), [n as u8; 32].into(),);
}
})
}
@@ -453,10 +388,7 @@ fn set_code_checks_works() {
let mut ext = new_test_ext();
ext.register_extension(sp_core::traits::ReadRuntimeVersionExt::new(read_runtime_version));
ext.execute_with(|| {
let res = System::set_code(
RawOrigin::Root.into(),
vec![1, 2, 3, 4],
);
let res = System::set_code(RawOrigin::Root.into(), vec![1, 2, 3, 4]);
assert_eq!(expected.map_err(DispatchErrorWithPostInfo::from), res);
});
@@ -473,7 +405,8 @@ fn set_code_with_real_wasm_blob() {
System::set_code(
RawOrigin::Root.into(),
substrate_test_runtime_client::runtime::wasm_binary_unwrap().to_vec(),
).unwrap();
)
.unwrap();
assert_eq!(
System::events(),
@@ -496,9 +429,10 @@ fn runtime_upgraded_with_set_storage() {
RawOrigin::Root.into(),
vec![(
well_known_keys::CODE.to_vec(),
substrate_test_runtime_client::runtime::wasm_binary_unwrap().to_vec()
substrate_test_runtime_client::runtime::wasm_binary_unwrap().to_vec(),
)],
).unwrap();
)
.unwrap();
});
}
@@ -531,20 +465,12 @@ fn ensure_one_of_works() {
#[test]
fn extrinsics_root_is_calculated_correctly() {
new_test_ext().execute_with(|| {
System::initialize(
&1,
&[0u8; 32].into(),
&Default::default(),
InitKind::Full,
);
System::initialize(&1, &[0u8; 32].into(), &Default::default(), InitKind::Full);
System::note_finished_initialize();
System::note_extrinsic(vec![1]);
System::note_applied_extrinsic(&Ok(().into()), Default::default());
System::note_extrinsic(vec![2]);
System::note_applied_extrinsic(
&Err(DispatchError::BadOrigin.into()),
Default::default()
);
System::note_applied_extrinsic(&Err(DispatchError::BadOrigin.into()), Default::default());
System::note_finished_extrinsics();
let header = System::finalize();
+1
View File
@@ -36,6 +36,7 @@
// --template=./.maintain/frame-weight-template.hbs
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)]
#![allow(unused_imports)]