mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 17:28:00 +00:00
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:
@@ -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
@@ -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;
|
||||
|
||||
@@ -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,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
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
// --template=./.maintain/frame-weight-template.hbs
|
||||
|
||||
|
||||
#![cfg_attr(rustfmt, rustfmt_skip)]
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user