Improve call, and usage in pallet utility (#9418)

* WIP

* WIP

* WIP

* add some tests and limit

* remove wip test

* fmt

* Update bin/node/runtime/src/lib.rs

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

* fmt

* use primitives allocation limit

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
Guillaume Thiolliere
2021-08-07 11:34:25 +02:00
committed by GitHub
parent 27d4177f93
commit 38db14089b
17 changed files with 197 additions and 92 deletions
+10
View File
@@ -1679,4 +1679,14 @@ mod tests {
is_submit_signed_transaction::<Runtime>();
}
#[test]
fn call_size() {
assert!(
core::mem::size_of::<Call>() <= 200,
"size of Call is more than 200 bytes: some calls have too big arguments, use Box to reduce the
size of Call.
If the limit is too strong, maybe consider increase the limit to 300.",
);
}
}
+2 -1
View File
@@ -155,7 +155,8 @@ where
) -> DispatchResult {
use frame_system::offchain::SubmitTransaction;
let call = Call::report_equivocation_unsigned(equivocation_proof, key_owner_proof);
let call =
Call::report_equivocation_unsigned(Box::new(equivocation_proof), key_owner_proof);
match SubmitTransaction::<T, Call<T>>::submit_unsigned_transaction(call.into()) {
Ok(()) => log::info!(
+4 -4
View File
@@ -349,12 +349,12 @@ pub mod pallet {
))]
pub fn report_equivocation(
origin: OriginFor<T>,
equivocation_proof: EquivocationProof<T::Header>,
equivocation_proof: Box<EquivocationProof<T::Header>>,
key_owner_proof: T::KeyOwnerProof,
) -> DispatchResultWithPostInfo {
let reporter = ensure_signed(origin)?;
Self::do_report_equivocation(Some(reporter), equivocation_proof, key_owner_proof)
Self::do_report_equivocation(Some(reporter), *equivocation_proof, key_owner_proof)
}
/// Report authority equivocation/misbehavior. This method will verify
@@ -370,14 +370,14 @@ pub mod pallet {
))]
pub fn report_equivocation_unsigned(
origin: OriginFor<T>,
equivocation_proof: EquivocationProof<T::Header>,
equivocation_proof: Box<EquivocationProof<T::Header>>,
key_owner_proof: T::KeyOwnerProof,
) -> DispatchResultWithPostInfo {
ensure_none(origin)?;
Self::do_report_equivocation(
T::HandleEquivocation::block_author(),
equivocation_proof,
*equivocation_proof,
key_owner_proof,
)
}
+39 -18
View File
@@ -440,8 +440,12 @@ fn report_equivocation_current_session_works() {
let key_owner_proof = Historical::prove(key).unwrap();
// report the equivocation
Babe::report_equivocation_unsigned(Origin::none(), equivocation_proof, key_owner_proof)
.unwrap();
Babe::report_equivocation_unsigned(
Origin::none(),
Box::new(equivocation_proof),
key_owner_proof,
)
.unwrap();
// start a new era so that the results of the offence report
// are applied at era end
@@ -508,8 +512,12 @@ fn report_equivocation_old_session_works() {
assert_eq!(Staking::slashable_balance_of(&offending_validator_id), 10_000);
// report the equivocation
Babe::report_equivocation_unsigned(Origin::none(), equivocation_proof, key_owner_proof)
.unwrap();
Babe::report_equivocation_unsigned(
Origin::none(),
Box::new(equivocation_proof),
key_owner_proof,
)
.unwrap();
// start a new era so that the results of the offence report
// are applied at era end
@@ -558,7 +566,7 @@ fn report_equivocation_invalid_key_owner_proof() {
assert_err!(
Babe::report_equivocation_unsigned(
Origin::none(),
equivocation_proof.clone(),
Box::new(equivocation_proof.clone()),
key_owner_proof
),
Error::<Test>::InvalidKeyOwnershipProof,
@@ -576,7 +584,11 @@ fn report_equivocation_invalid_key_owner_proof() {
start_era(2);
assert_err!(
Babe::report_equivocation_unsigned(Origin::none(), equivocation_proof, key_owner_proof),
Babe::report_equivocation_unsigned(
Origin::none(),
Box::new(equivocation_proof),
key_owner_proof,
),
Error::<Test>::InvalidKeyOwnershipProof,
);
})
@@ -608,7 +620,7 @@ fn report_equivocation_invalid_equivocation_proof() {
assert_err!(
Babe::report_equivocation_unsigned(
Origin::none(),
equivocation_proof,
Box::new(equivocation_proof),
key_owner_proof.clone(),
),
Error::<Test>::InvalidEquivocationProof,
@@ -714,8 +726,10 @@ fn report_equivocation_validate_unsigned_prevents_duplicates() {
let key = (sp_consensus_babe::KEY_TYPE, &offending_authority_pair.public());
let key_owner_proof = Historical::prove(key).unwrap();
let inner =
Call::report_equivocation_unsigned(equivocation_proof.clone(), key_owner_proof.clone());
let inner = Call::report_equivocation_unsigned(
Box::new(equivocation_proof.clone()),
key_owner_proof.clone(),
);
// only local/inblock reports are allowed
assert_eq!(
@@ -746,8 +760,12 @@ fn report_equivocation_validate_unsigned_prevents_duplicates() {
assert_ok!(<Babe as sp_runtime::traits::ValidateUnsigned>::pre_dispatch(&inner));
// we submit the report
Babe::report_equivocation_unsigned(Origin::none(), equivocation_proof, key_owner_proof)
.unwrap();
Babe::report_equivocation_unsigned(
Origin::none(),
Box::new(equivocation_proof),
key_owner_proof,
)
.unwrap();
// the report should now be considered stale and the transaction is invalid.
// the check for staleness should be done on both `validate_unsigned` and on `pre_dispatch`
@@ -805,7 +823,7 @@ fn valid_equivocation_reports_dont_pay_fees() {
// check the dispatch info for the call.
let info = Call::<Test>::report_equivocation_unsigned(
equivocation_proof.clone(),
Box::new(equivocation_proof.clone()),
key_owner_proof.clone(),
)
.get_dispatch_info();
@@ -817,7 +835,7 @@ fn valid_equivocation_reports_dont_pay_fees() {
// report the equivocation.
let post_info = Babe::report_equivocation_unsigned(
Origin::none(),
equivocation_proof.clone(),
Box::new(equivocation_proof.clone()),
key_owner_proof.clone(),
)
.unwrap();
@@ -829,11 +847,14 @@ fn valid_equivocation_reports_dont_pay_fees() {
// report the equivocation again which is invalid now since it is
// duplicate.
let post_info =
Babe::report_equivocation_unsigned(Origin::none(), equivocation_proof, key_owner_proof)
.err()
.unwrap()
.post_info;
let post_info = Babe::report_equivocation_unsigned(
Origin::none(),
Box::new(equivocation_proof),
key_owner_proof,
)
.err()
.unwrap()
.post_info;
// the fee is not waived and the original weight is kept.
assert!(post_info.actual_weight.is_none());
@@ -26,7 +26,10 @@ use rand::{prelude::SliceRandom, rngs::SmallRng, SeedableRng};
use sp_arithmetic::{per_things::Percent, traits::One};
use sp_npos_elections::IndexAssignment;
use sp_runtime::InnerOf;
use sp_std::convert::{TryFrom, TryInto};
use sp_std::{
boxed::Box,
convert::{TryFrom, TryInto},
};
const SEED: u32 = 999;
@@ -317,7 +320,7 @@ frame_benchmarking::benchmarks! {
let caller = frame_benchmarking::whitelisted_caller();
T::Currency::make_free_balance_be(&caller, T::Currency::minimum_balance() * 10u32.into());
}: _(RawOrigin::Signed(caller), solution, c)
}: _(RawOrigin::Signed(caller), Box::new(solution), c)
verify {
assert!(<MultiPhase<T>>::signed_submissions().len() as u32 == c + 1);
}
@@ -344,9 +347,15 @@ frame_benchmarking::benchmarks! {
// encode the most significant storage item that needs to be decoded in the dispatch.
let encoded_snapshot = <MultiPhase<T>>::snapshot().unwrap().encode();
let encoded_call = <Call<T>>::submit_unsigned(raw_solution.clone(), witness).encode();
let encoded_call = <Call<T>>::submit_unsigned(Box::new(raw_solution.clone()), witness).encode();
}: {
assert_ok!(<MultiPhase<T>>::submit_unsigned(RawOrigin::None.into(), raw_solution, witness));
assert_ok!(
<MultiPhase<T>>::submit_unsigned(
RawOrigin::None.into(),
Box::new(raw_solution),
witness,
)
);
let _decoded_snap = <RoundSnapshot<T::AccountId> as Decode>::decode(&mut &*encoded_snapshot)
.unwrap();
let _decoded_call = <Call<T> as Decode>::decode(&mut &*encoded_call).unwrap();
@@ -857,7 +857,7 @@ pub mod pallet {
))]
pub fn submit_unsigned(
origin: OriginFor<T>,
solution: RawSolution<CompactOf<T>>,
solution: Box<RawSolution<CompactOf<T>>>,
witness: SolutionOrSnapshotSize,
) -> DispatchResultWithPostInfo {
ensure_none(origin)?;
@@ -876,7 +876,7 @@ pub mod pallet {
assert!(targets as u32 == witness.targets, "{}", error_message);
let ready =
Self::feasibility_check(solution, ElectionCompute::Unsigned).expect(error_message);
Self::feasibility_check(*solution, ElectionCompute::Unsigned).expect(error_message);
// Store the newly received solution.
log!(info, "queued unsigned solution with score {:?}", ready.score);
@@ -947,7 +947,7 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::submit(*num_signed_submissions))]
pub fn submit(
origin: OriginFor<T>,
solution: RawSolution<CompactOf<T>>,
solution: Box<RawSolution<CompactOf<T>>>,
num_signed_submissions: u32,
) -> DispatchResult {
let who = ensure_signed(origin)?;
@@ -982,7 +982,8 @@ pub mod pallet {
T::SignedRewardBase::get().saturating_add(call_fee)
};
let submission = SignedSubmission { who: who.clone(), deposit, solution, reward };
let submission =
SignedSubmission { who: who.clone(), deposit, solution: *solution, reward };
// insert the submission if the queue has space or it's better than the weakest
// eject the weakest if the queue was full
@@ -1927,7 +1928,7 @@ mod tests {
let solution = RawSolution { score: [(5 + s).into(), 0, 0], ..Default::default() };
assert_ok!(MultiPhase::submit(
crate::mock::Origin::signed(99),
solution,
Box::new(solution),
MultiPhase::signed_submissions().len() as u32
));
}
@@ -499,7 +499,11 @@ mod tests {
origin: Origin,
solution: RawSolution<CompactOf<Runtime>>,
) -> DispatchResult {
MultiPhase::submit(origin, solution, MultiPhase::signed_submissions().len() as u32)
MultiPhase::submit(
origin,
Box::new(solution),
MultiPhase::signed_submissions().len() as u32,
)
}
#[test]
@@ -532,7 +536,7 @@ mod tests {
// now try and cheat by passing a lower queue length
assert_noop!(
MultiPhase::submit(Origin::signed(99), solution, 0),
MultiPhase::submit(Origin::signed(99), Box::new(solution), 0),
Error::<Runtime>::SignedInvalidWitness,
);
})
@@ -34,7 +34,7 @@ use sp_runtime::{
traits::TrailingZeroInput,
DispatchError, SaturatedConversion,
};
use sp_std::{cmp::Ordering, convert::TryFrom, vec::Vec};
use sp_std::{boxed::Box, cmp::Ordering, convert::TryFrom, vec::Vec};
/// Storage key used to store the last block number at which offchain worker ran.
pub(crate) const OFFCHAIN_LAST_BLOCK: &[u8] = b"parity/multi-phase-unsigned-election";
@@ -208,7 +208,7 @@ impl<T: Config> Pallet<T> {
let (raw_solution, witness) = Self::mine_and_check(iters)?;
let score = raw_solution.score.clone();
let call: Call<T> = Call::submit_unsigned(raw_solution, witness).into();
let call: Call<T> = Call::submit_unsigned(Box::new(raw_solution), witness).into();
log!(
debug,
@@ -773,7 +773,7 @@ mod tests {
fn validate_unsigned_retracts_wrong_phase() {
ExtBuilder::default().desired_targets(0).build_and_execute(|| {
let solution = RawSolution::<TestCompact> { score: [5, 0, 0], ..Default::default() };
let call = Call::submit_unsigned(solution.clone(), witness());
let call = Call::submit_unsigned(Box::new(solution.clone()), witness());
// initial
assert_eq!(MultiPhase::current_phase(), Phase::Off);
@@ -842,7 +842,7 @@ mod tests {
assert!(MultiPhase::current_phase().is_unsigned());
let solution = RawSolution::<TestCompact> { score: [5, 0, 0], ..Default::default() };
let call = Call::submit_unsigned(solution.clone(), witness());
let call = Call::submit_unsigned(Box::new(solution.clone()), witness());
// initial
assert!(<MultiPhase as ValidateUnsigned>::validate_unsigned(
@@ -879,7 +879,7 @@ mod tests {
assert!(MultiPhase::current_phase().is_unsigned());
let solution = RawSolution::<TestCompact> { score: [5, 0, 0], ..Default::default() };
let call = Call::submit_unsigned(solution.clone(), witness());
let call = Call::submit_unsigned(Box::new(solution.clone()), witness());
assert_eq!(solution.compact.unique_targets().len(), 0);
// won't work anymore.
@@ -905,7 +905,7 @@ mod tests {
let solution =
RawSolution::<TestCompact> { score: [5, 0, 0], ..Default::default() };
let call = Call::submit_unsigned(solution.clone(), witness());
let call = Call::submit_unsigned(Box::new(solution.clone()), witness());
assert_eq!(
<MultiPhase as ValidateUnsigned>::validate_unsigned(
@@ -931,7 +931,7 @@ mod tests {
// This is in itself an invalid BS solution.
let solution = RawSolution::<TestCompact> { score: [5, 0, 0], ..Default::default() };
let call = Call::submit_unsigned(solution.clone(), witness());
let call = Call::submit_unsigned(Box::new(solution.clone()), witness());
let outer_call: OuterCall = call.into();
let _ = outer_call.dispatch(Origin::none());
})
@@ -951,7 +951,7 @@ mod tests {
let mut correct_witness = witness();
correct_witness.voters += 1;
correct_witness.targets -= 1;
let call = Call::submit_unsigned(solution.clone(), correct_witness);
let call = Call::submit_unsigned(Box::new(solution.clone()), correct_witness);
let outer_call: OuterCall = call.into();
let _ = outer_call.dispatch(Origin::none());
})
@@ -972,7 +972,7 @@ mod tests {
// ensure this solution is valid.
assert!(MultiPhase::queued_solution().is_none());
assert_ok!(MultiPhase::submit_unsigned(Origin::none(), solution, witness));
assert_ok!(MultiPhase::submit_unsigned(Origin::none(), Box::new(solution), witness));
assert!(MultiPhase::queued_solution().is_some());
})
}
@@ -1054,7 +1054,11 @@ mod tests {
};
let (solution, witness) = MultiPhase::prepare_election_result(result).unwrap();
assert_ok!(MultiPhase::unsigned_pre_dispatch_checks(&solution));
assert_ok!(MultiPhase::submit_unsigned(Origin::none(), solution, witness));
assert_ok!(MultiPhase::submit_unsigned(
Origin::none(),
Box::new(solution),
witness
));
assert_eq!(MultiPhase::queued_solution().unwrap().score[0], 10);
// trial 1: a solution who's score is only 2, i.e. 20% better in the first element.
@@ -1096,7 +1100,11 @@ mod tests {
// and it is fine
assert_ok!(MultiPhase::unsigned_pre_dispatch_checks(&solution));
assert_ok!(MultiPhase::submit_unsigned(Origin::none(), solution, witness));
assert_ok!(MultiPhase::submit_unsigned(
Origin::none(),
Box::new(solution),
witness
));
})
}
+2 -1
View File
@@ -164,7 +164,8 @@ where
) -> DispatchResult {
use frame_system::offchain::SubmitTransaction;
let call = Call::report_equivocation_unsigned(equivocation_proof, key_owner_proof);
let call =
Call::report_equivocation_unsigned(Box::new(equivocation_proof), key_owner_proof);
match SubmitTransaction::<T, Call<T>>::submit_unsigned_transaction(call.into()) {
Ok(()) => log::info!(
+4 -4
View File
@@ -190,12 +190,12 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::report_equivocation(key_owner_proof.validator_count()))]
pub fn report_equivocation(
origin: OriginFor<T>,
equivocation_proof: EquivocationProof<T::Hash, T::BlockNumber>,
equivocation_proof: Box<EquivocationProof<T::Hash, T::BlockNumber>>,
key_owner_proof: T::KeyOwnerProof,
) -> DispatchResultWithPostInfo {
let reporter = ensure_signed(origin)?;
Self::do_report_equivocation(Some(reporter), equivocation_proof, key_owner_proof)
Self::do_report_equivocation(Some(reporter), *equivocation_proof, key_owner_proof)
}
/// Report voter equivocation/misbehavior. This method will verify the
@@ -210,14 +210,14 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::report_equivocation(key_owner_proof.validator_count()))]
pub fn report_equivocation_unsigned(
origin: OriginFor<T>,
equivocation_proof: EquivocationProof<T::Hash, T::BlockNumber>,
equivocation_proof: Box<EquivocationProof<T::Hash, T::BlockNumber>>,
key_owner_proof: T::KeyOwnerProof,
) -> DispatchResultWithPostInfo {
ensure_none(origin)?;
Self::do_report_equivocation(
T::HandleEquivocation::block_author(),
equivocation_proof,
*equivocation_proof,
key_owner_proof,
)
}
+19 -13
View File
@@ -354,7 +354,7 @@ fn report_equivocation_current_set_works() {
// report the equivocation and the tx should be dispatched successfully
assert_ok!(Grandpa::report_equivocation_unsigned(
Origin::none(),
equivocation_proof,
Box::new(equivocation_proof),
key_owner_proof,
),);
@@ -432,7 +432,7 @@ fn report_equivocation_old_set_works() {
// the old set, the tx should be dispatched successfully
assert_ok!(Grandpa::report_equivocation_unsigned(
Origin::none(),
equivocation_proof,
Box::new(equivocation_proof),
key_owner_proof,
),);
@@ -495,7 +495,7 @@ fn report_equivocation_invalid_set_id() {
assert_err!(
Grandpa::report_equivocation_unsigned(
Origin::none(),
equivocation_proof,
Box::new(equivocation_proof),
key_owner_proof,
),
Error::<Test>::InvalidEquivocationProof,
@@ -536,7 +536,7 @@ fn report_equivocation_invalid_session() {
assert_err!(
Grandpa::report_equivocation_unsigned(
Origin::none(),
equivocation_proof,
Box::new(equivocation_proof),
key_owner_proof,
),
Error::<Test>::InvalidEquivocationProof,
@@ -581,7 +581,7 @@ fn report_equivocation_invalid_key_owner_proof() {
assert_err!(
Grandpa::report_equivocation_unsigned(
Origin::none(),
equivocation_proof,
Box::new(equivocation_proof),
invalid_key_owner_proof,
),
Error::<Test>::InvalidKeyOwnershipProof,
@@ -612,7 +612,7 @@ fn report_equivocation_invalid_equivocation_proof() {
assert_err!(
Grandpa::report_equivocation_unsigned(
Origin::none(),
equivocation_proof,
Box::new(equivocation_proof),
key_owner_proof.clone(),
),
Error::<Test>::InvalidEquivocationProof,
@@ -681,8 +681,10 @@ fn report_equivocation_validate_unsigned_prevents_duplicates() {
let key_owner_proof =
Historical::prove((sp_finality_grandpa::KEY_TYPE, &equivocation_key)).unwrap();
let call =
Call::report_equivocation_unsigned(equivocation_proof.clone(), key_owner_proof.clone());
let call = Call::report_equivocation_unsigned(
Box::new(equivocation_proof.clone()),
key_owner_proof.clone(),
);
// only local/inblock reports are allowed
assert_eq!(
@@ -714,8 +716,12 @@ fn report_equivocation_validate_unsigned_prevents_duplicates() {
assert_ok!(<Grandpa as sp_runtime::traits::ValidateUnsigned>::pre_dispatch(&call));
// we submit the report
Grandpa::report_equivocation_unsigned(Origin::none(), equivocation_proof, key_owner_proof)
.unwrap();
Grandpa::report_equivocation_unsigned(
Origin::none(),
Box::new(equivocation_proof),
key_owner_proof,
)
.unwrap();
// the report should now be considered stale and the transaction is invalid
// the check for staleness should be done on both `validate_unsigned` and on `pre_dispatch`
@@ -838,7 +844,7 @@ fn valid_equivocation_reports_dont_pay_fees() {
// check the dispatch info for the call.
let info = Call::<Test>::report_equivocation_unsigned(
equivocation_proof.clone(),
Box::new(equivocation_proof.clone()),
key_owner_proof.clone(),
)
.get_dispatch_info();
@@ -850,7 +856,7 @@ fn valid_equivocation_reports_dont_pay_fees() {
// report the equivocation.
let post_info = Grandpa::report_equivocation_unsigned(
Origin::none(),
equivocation_proof.clone(),
Box::new(equivocation_proof.clone()),
key_owner_proof.clone(),
)
.unwrap();
@@ -864,7 +870,7 @@ fn valid_equivocation_reports_dont_pay_fees() {
// duplicate.
let post_info = Grandpa::report_equivocation_unsigned(
Origin::none(),
equivocation_proof,
Box::new(equivocation_proof),
key_owner_proof,
)
.err()
+5 -1
View File
@@ -37,5 +37,9 @@ std = [
"frame-support/std",
"frame-system/std",
]
runtime-benchmarks = ["frame-benchmarking"]
runtime-benchmarks = [
"frame-benchmarking",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
]
try-runtime = ["frame-support/try-runtime"]
+8 -8
View File
@@ -77,7 +77,7 @@ fn create_sub_accounts<T: Config>(
// Set identity so `set_subs` does not fail.
let _ = T::Currency::make_free_balance_be(&who, BalanceOf::<T>::max_value());
let info = create_identity_info::<T>(1);
Identity::<T>::set_identity(who_origin.clone().into(), info)?;
Identity::<T>::set_identity(who_origin.clone().into(), Box::new(info))?;
Ok(subs)
}
@@ -137,7 +137,7 @@ benchmarks! {
// Add an initial identity
let initial_info = create_identity_info::<T>(1);
Identity::<T>::set_identity(caller_origin.clone(), initial_info)?;
Identity::<T>::set_identity(caller_origin.clone(), Box::new(initial_info))?;
// User requests judgement from all the registrars, and they approve
for i in 0..r {
@@ -151,7 +151,7 @@ benchmarks! {
}
caller
};
}: _(RawOrigin::Signed(caller.clone()), create_identity_info::<T>(x))
}: _(RawOrigin::Signed(caller.clone()), Box::new(create_identity_info::<T>(x)))
verify {
assert_last_event::<T>(Event::<T>::IdentitySet(caller).into());
}
@@ -204,7 +204,7 @@ benchmarks! {
let info = create_identity_info::<T>(x);
let caller: T::AccountId = whitelisted_caller();
let caller_origin = <T as frame_system::Config>::Origin::from(RawOrigin::Signed(caller));
Identity::<T>::set_identity(caller_origin, info)?;
Identity::<T>::set_identity(caller_origin, Box::new(info))?;
};
// User requests judgement from all the registrars, and they approve
@@ -233,7 +233,7 @@ benchmarks! {
let info = create_identity_info::<T>(x);
let caller: T::AccountId = whitelisted_caller();
let caller_origin = <T as frame_system::Config>::Origin::from(RawOrigin::Signed(caller));
Identity::<T>::set_identity(caller_origin, info)?;
Identity::<T>::set_identity(caller_origin, Box::new(info))?;
};
}: _(RawOrigin::Signed(caller.clone()), r - 1, 10u32.into())
verify {
@@ -251,7 +251,7 @@ benchmarks! {
let info = create_identity_info::<T>(x);
let caller: T::AccountId = whitelisted_caller();
let caller_origin = <T as frame_system::Config>::Origin::from(RawOrigin::Signed(caller));
Identity::<T>::set_identity(caller_origin, info)?;
Identity::<T>::set_identity(caller_origin, Box::new(info))?;
};
Identity::<T>::request_judgement(caller_origin, r - 1, 10u32.into())?;
@@ -321,7 +321,7 @@ benchmarks! {
let r in 1 .. T::MaxRegistrars::get() - 1 => add_registrars::<T>(r)?;
let x in 1 .. T::MaxAdditionalFields::get() => {
let info = create_identity_info::<T>(x);
Identity::<T>::set_identity(user_origin.clone(), info)?;
Identity::<T>::set_identity(user_origin.clone(), Box::new(info))?;
};
Identity::<T>::add_registrar(RawOrigin::Root.into(), caller.clone())?;
@@ -342,7 +342,7 @@ benchmarks! {
let _ = T::Currency::make_free_balance_be(&target, BalanceOf::<T>::max_value());
let info = create_identity_info::<T>(x);
Identity::<T>::set_identity(target_origin.clone(), info)?;
Identity::<T>::set_identity(target_origin.clone(), Box::new(info))?;
let _ = add_sub_accounts::<T>(&target, s)?;
// User requests judgement from all the registrars, and they approve
+7 -4
View File
@@ -335,7 +335,7 @@ pub mod pallet {
))]
pub fn set_identity(
origin: OriginFor<T>,
info: IdentityInfo<T::MaxAdditionalFields>,
info: Box<IdentityInfo<T::MaxAdditionalFields>>,
) -> DispatchResultWithPostInfo {
let sender = ensure_signed(origin)?;
let extra_fields = info.additional.len() as u32;
@@ -346,11 +346,14 @@ pub mod pallet {
Some(mut id) => {
// Only keep non-positive judgements.
id.judgements.retain(|j| j.1.is_sticky());
id.info = info;
id.info = *info;
id
},
None =>
Registration { info, judgements: BoundedVec::default(), deposit: Zero::zero() },
None => Registration {
info: *info,
judgements: BoundedVec::default(),
deposit: Zero::zero(),
},
};
let old_deposit = id.deposit;
+14 -14
View File
@@ -150,7 +150,7 @@ fn editing_subaccounts_should_work() {
assert_noop!(Identity::add_sub(Origin::signed(10), 20, data(1)), Error::<Test>::NoIdentity);
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_ok!(Identity::set_identity(Origin::signed(10), Box::new(ten())));
// first sub account
assert_ok!(Identity::add_sub(Origin::signed(10), 1, data(1)));
@@ -195,8 +195,8 @@ fn resolving_subaccount_ownership_works() {
new_test_ext().execute_with(|| {
let data = |x| Data::Raw(vec![x; 1].try_into().unwrap());
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_ok!(Identity::set_identity(Origin::signed(20), twenty()));
assert_ok!(Identity::set_identity(Origin::signed(10), Box::new(ten())));
assert_ok!(Identity::set_identity(Origin::signed(20), Box::new(twenty())));
// 10 claims 1 as a subaccount
assert_ok!(Identity::add_sub(Origin::signed(10), 1, data(1)));
@@ -266,7 +266,7 @@ fn registration_should_work() {
three_fields.additional.try_push(Default::default()).unwrap();
three_fields.additional.try_push(Default::default()).unwrap();
assert_eq!(three_fields.additional.try_push(Default::default()), Err(()));
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_ok!(Identity::set_identity(Origin::signed(10), Box::new(ten())));
assert_eq!(Identity::identity(10).unwrap().info, ten());
assert_eq!(Balances::free_balance(10), 90);
assert_ok!(Identity::clear_identity(Origin::signed(10)));
@@ -289,7 +289,7 @@ fn uninvited_judgement_should_work() {
Error::<Test>::InvalidTarget
);
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_ok!(Identity::set_identity(Origin::signed(10), Box::new(ten())));
assert_noop!(
Identity::provide_judgement(Origin::signed(10), 0, 10, Judgement::Reasonable),
Error::<Test>::InvalidIndex
@@ -308,7 +308,7 @@ fn uninvited_judgement_should_work() {
fn clearing_judgement_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::add_registrar(Origin::signed(1), 3));
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_ok!(Identity::set_identity(Origin::signed(10), Box::new(ten())));
assert_ok!(Identity::provide_judgement(Origin::signed(3), 0, 10, Judgement::Reasonable));
assert_ok!(Identity::clear_identity(Origin::signed(10)));
assert_eq!(Identity::identity(10), None);
@@ -318,7 +318,7 @@ fn clearing_judgement_should_work() {
#[test]
fn killing_slashing_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_ok!(Identity::set_identity(Origin::signed(10), Box::new(ten())));
assert_noop!(Identity::kill_identity(Origin::signed(1), 10), BadOrigin);
assert_ok!(Identity::kill_identity(Origin::signed(2), 10));
assert_eq!(Identity::identity(10), None);
@@ -333,7 +333,7 @@ fn setting_subaccounts_should_work() {
let mut subs = vec![(20, Data::Raw(vec![40; 1].try_into().unwrap()))];
assert_noop!(Identity::set_subs(Origin::signed(10), subs.clone()), Error::<Test>::NotFound);
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_ok!(Identity::set_identity(Origin::signed(10), Box::new(ten())));
assert_ok!(Identity::set_subs(Origin::signed(10), subs.clone()));
assert_eq!(Balances::free_balance(10), 80);
assert_eq!(Identity::subs_of(10), (10, vec![20].try_into().unwrap()));
@@ -374,7 +374,7 @@ fn setting_subaccounts_should_work() {
#[test]
fn clearing_account_should_remove_subaccounts_and_refund() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_ok!(Identity::set_identity(Origin::signed(10), Box::new(ten())));
assert_ok!(Identity::set_subs(
Origin::signed(10),
vec![(20, Data::Raw(vec![40; 1].try_into().unwrap()))]
@@ -388,7 +388,7 @@ fn clearing_account_should_remove_subaccounts_and_refund() {
#[test]
fn killing_account_should_remove_subaccounts_and_not_refund() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_ok!(Identity::set_identity(Origin::signed(10), Box::new(ten())));
assert_ok!(Identity::set_subs(
Origin::signed(10),
vec![(20, Data::Raw(vec![40; 1].try_into().unwrap()))]
@@ -405,7 +405,7 @@ fn cancelling_requested_judgement_should_work() {
assert_ok!(Identity::add_registrar(Origin::signed(1), 3));
assert_ok!(Identity::set_fee(Origin::signed(3), 0, 10));
assert_noop!(Identity::cancel_request(Origin::signed(10), 0), Error::<Test>::NoIdentity);
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_ok!(Identity::set_identity(Origin::signed(10), Box::new(ten())));
assert_ok!(Identity::request_judgement(Origin::signed(10), 0, 10));
assert_ok!(Identity::cancel_request(Origin::signed(10), 0));
assert_eq!(Balances::free_balance(10), 90);
@@ -424,7 +424,7 @@ fn requesting_judgement_should_work() {
new_test_ext().execute_with(|| {
assert_ok!(Identity::add_registrar(Origin::signed(1), 3));
assert_ok!(Identity::set_fee(Origin::signed(3), 0, 10));
assert_ok!(Identity::set_identity(Origin::signed(10), ten()));
assert_ok!(Identity::set_identity(Origin::signed(10), Box::new(ten())));
assert_noop!(
Identity::request_judgement(Origin::signed(10), 0, 9),
Error::<Test>::FeeChanged
@@ -465,7 +465,7 @@ fn field_deposit_should_work() {
assert_ok!(Identity::set_fee(Origin::signed(3), 0, 10));
assert_ok!(Identity::set_identity(
Origin::signed(10),
IdentityInfo {
Box::new(IdentityInfo {
additional: vec![
(
Data::Raw(b"number".to_vec().try_into().unwrap()),
@@ -479,7 +479,7 @@ fn field_deposit_should_work() {
.try_into()
.unwrap(),
..Default::default()
}
})
));
assert_eq!(Balances::free_balance(10), 70);
});
+27 -2
View File
@@ -112,13 +112,33 @@ pub mod pallet {
ItemCompleted,
}
#[pallet::extra_constants]
impl<T: Config> Pallet<T> {
/// The limit on the number of batched calls.
fn batched_calls_limit() -> u32 {
let allocator_limit = sp_core::MAX_POSSIBLE_ALLOCATION;
let call_size = core::mem::size_of::<<T as Config>::Call>() as u32;
// The margin to take into account vec doubling capacity.
let margin_factor = 3;
allocator_limit / margin_factor / call_size
}
}
#[pallet::error]
pub enum Error<T> {
/// Too many calls batched.
TooManyCalls,
}
#[pallet::call]
impl<T: Config> Pallet<T> {
/// Send a batch of dispatch calls.
///
/// May be called from any origin.
///
/// - `calls`: The calls to be dispatched from the same origin.
/// - `calls`: The calls to be dispatched from the same origin. The number of call must not
/// exceed the constant: `batched_calls_limit` (available in constant metadata).
///
/// If origin is root then call are dispatch without checking origin filter. (This includes
/// bypassing `frame_system::Config::BaseCallFilter`).
@@ -156,6 +176,8 @@ pub mod pallet {
) -> DispatchResultWithPostInfo {
let is_root = ensure_root(origin.clone()).is_ok();
let calls_len = calls.len();
ensure!(calls_len <= Self::batched_calls_limit() as usize, Error::<T>::TooManyCalls);
// Track the actual weight of each of the batch calls.
let mut weight: Weight = 0;
for (index, call) in calls.into_iter().enumerate() {
@@ -234,7 +256,8 @@ pub mod pallet {
///
/// May be called from any origin.
///
/// - `calls`: The calls to be dispatched from the same origin.
/// - `calls`: The calls to be dispatched from the same origin. The number of call must not
/// exceed the constant: `batched_calls_limit` (available in constant metadata).
///
/// If origin is root then call are dispatch without checking origin filter. (This includes
/// bypassing `frame_system::Config::BaseCallFilter`).
@@ -267,6 +290,8 @@ pub mod pallet {
) -> DispatchResultWithPostInfo {
let is_root = ensure_root(origin.clone()).is_ok();
let calls_len = calls.len();
ensure!(calls_len <= Self::batched_calls_limit() as usize, Error::<T>::TooManyCalls);
// Track the actual weight of each of the batch calls.
let mut weight: Weight = 0;
for (index, call) in calls.into_iter().enumerate() {
+12
View File
@@ -66,6 +66,9 @@ pub mod example {
Ok(end_weight.into())
}
}
#[weight = 0]
fn big_variant(_origin, _arg: [u8; 400]) {}
}
}
}
@@ -588,3 +591,12 @@ fn batch_all_does_not_nest() {
assert_eq!(Balances::free_balance(2), 10);
});
}
#[test]
fn batch_limit() {
new_test_ext().execute_with(|| {
let calls = vec![Call::System(SystemCall::remark(vec![])); 40_000];
assert_noop!(Utility::batch(Origin::signed(1), calls.clone()), Error::<Test>::TooManyCalls);
assert_noop!(Utility::batch_all(Origin::signed(1), calls), Error::<Test>::TooManyCalls);
});
}