mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-11 10:41:09 +00:00
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:
committed by
GitHub
parent
27d4177f93
commit
38db14089b
@@ -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.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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!(
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
));
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -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!(
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user