mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-09 21:21:11 +00:00
Bound uses of Call (#11649)
* Introduce preimages module in traits * Multisize Preimages * Len not actually necessary * Tweaks to the preimage API * Fixes * Get Scheduler building with new API * Scheduler tests pass * Bounded Scheduler 🎉 * Use Agenda holes and introduce IncompleteSince to avoid need to reschedule * Tests pass with new weight system * New benchmarks * Add missing file * Drop preimage when permenantly overeight * Drop preimage when permenantly overeight * Referenda uses latest preimage API * Testing ok * Adding tests Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * fmt Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add preimage migration Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Docs * Remove dbg * Refactor Democracy * Refactor Democracy * Add final MEL * Remove silly maps * Fixes * Minor refactor * Formatting * Fixes * Fixes * Fixes * Update frame/preimage/src/lib.rs Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com> * Add migrations to Democracy * WIP Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Resolve conflicts Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Revert "Resolve conflicts" This reverts commit 734d66d69e54553471ffa54fa52e3e304dc8f106. * Undo wrong resolves... Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * WIP Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Make compile Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * massage clippy Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * More clippy Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * clippy annoyance Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * clippy annoyance Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix benchmarks Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * add missing file * Test <Preimage as QueryPreimage> Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * More tests Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Clippy harassment Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add test Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * clippy Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fixup tests Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Remove old stuff Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * fmt Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Test <Scheduler as Anon> trait functions Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Update pallet-ui tests Why is this needed? Should not be the case unless master is broken... Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * More scheduler trait test Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * More tests Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Apply review suggestion Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Beauty fixes Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add Scheduler test migration_v3_to_v4_works Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Merge fixup Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Keep referenda benchmarks instantiatable Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Update weights Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Use new scheduler weight functions Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Use new democracy weight functions Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Use weight compare functions Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Update pallet-ui tests Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * More renaming… Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * More renaming… Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add comment Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Implement OnRuntimeUpgrade for scheduler::v3_to_v4 migration Put the migration into a proper `MigrateToV4` struct and implement the OnRuntimeUpgrade hooks for it. Also move the test to use that instead. This should make it easier for adding it to Polkadot. Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Clippy Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Handle undecodable Agendas Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Remove trash Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix test Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Use new OnRuntimeUpgrade functions Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * fix test Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix BoundedSlice::truncate_from Co-authored-by: jakoblell Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix pre_upgrade hook return values Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add more error logging Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Find too large preimages in the pre_upgrade hook Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Test that too large Calls in agendas are ignored Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Use new OnRuntimeUpgrade hooks Why did the CI not catch this?! Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * works fine - just more logs Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix staking migration Causing issues on Kusama... Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix UI tests No idea why this is needed. This is actually undoing an earlier change. Maybe the CI has different rustc versions!? Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Remove multisig's Calls (#12072) * Remove multisig's Calls * Multisig: Fix tests and re-introduce reserve logic (#12241) * Fix tests and re-introduce reserve logic * fix benches * add todo * remove irrelevant bench * [Feature] Add a migration that drains and refunds stored calls (#12313) * [Feature] Add a migration that drains and refunds stored calls * migration fixes * fixes * address review comments * consume the whole block weight * fix assertions * license header * fix interface Co-authored-by: parity-processbot <> Co-authored-by: parity-processbot <> Co-authored-by: Roman Useinov <roman.useinov@gmail.com> * Fix test Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix multisig benchmarks Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * ".git/.scripts/bench-bot.sh" pallet dev pallet_democracy * ".git/.scripts/bench-bot.sh" pallet dev pallet_scheduler * ".git/.scripts/bench-bot.sh" pallet dev pallet_preimage Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com> Co-authored-by: parity-processbot <> Co-authored-by: Roman Useinov <roman.useinov@gmail.com>
This commit is contained in:
@@ -35,7 +35,7 @@ fn funded_account<T: Config>(name: &'static str, index: u32) -> T::AccountId {
|
||||
}
|
||||
|
||||
fn preimage_and_hash<T: Config>() -> (Vec<u8>, T::Hash) {
|
||||
sized_preimage_and_hash::<T>(T::MaxSize::get())
|
||||
sized_preimage_and_hash::<T>(MAX_SIZE)
|
||||
}
|
||||
|
||||
fn sized_preimage_and_hash<T: Config>(size: u32) -> (Vec<u8>, T::Hash) {
|
||||
@@ -48,7 +48,7 @@ fn sized_preimage_and_hash<T: Config>(size: u32) -> (Vec<u8>, T::Hash) {
|
||||
benchmarks! {
|
||||
// Expensive note - will reserve.
|
||||
note_preimage {
|
||||
let s in 0 .. T::MaxSize::get();
|
||||
let s in 0 .. MAX_SIZE;
|
||||
let caller = funded_account::<T>("caller", 0);
|
||||
whitelist_account!(caller);
|
||||
let (preimage, hash) = sized_preimage_and_hash::<T>(s);
|
||||
@@ -58,7 +58,7 @@ benchmarks! {
|
||||
}
|
||||
// Cheap note - will not reserve since it was requested.
|
||||
note_requested_preimage {
|
||||
let s in 0 .. T::MaxSize::get();
|
||||
let s in 0 .. MAX_SIZE;
|
||||
let caller = funded_account::<T>("caller", 0);
|
||||
whitelist_account!(caller);
|
||||
let (preimage, hash) = sized_preimage_and_hash::<T>(s);
|
||||
@@ -69,7 +69,7 @@ benchmarks! {
|
||||
}
|
||||
// Cheap note - will not reserve since it's the manager.
|
||||
note_no_deposit_preimage {
|
||||
let s in 0 .. T::MaxSize::get();
|
||||
let s in 0 .. MAX_SIZE;
|
||||
let (preimage, hash) = sized_preimage_and_hash::<T>(s);
|
||||
assert_ok!(Preimage::<T>::request_preimage(T::ManagerOrigin::successful_origin(), hash));
|
||||
}: note_preimage<T::RuntimeOrigin>(T::ManagerOrigin::successful_origin(), preimage)
|
||||
@@ -101,10 +101,12 @@ benchmarks! {
|
||||
let (preimage, hash) = preimage_and_hash::<T>();
|
||||
let noter = funded_account::<T>("noter", 0);
|
||||
whitelist_account!(noter);
|
||||
assert_ok!(Preimage::<T>::note_preimage(RawOrigin::Signed(noter).into(), preimage));
|
||||
assert_ok!(Preimage::<T>::note_preimage(RawOrigin::Signed(noter.clone()).into(), preimage));
|
||||
}: _<T::RuntimeOrigin>(T::ManagerOrigin::successful_origin(), hash)
|
||||
verify {
|
||||
assert_eq!(StatusFor::<T>::get(&hash), Some(RequestStatus::Requested(1)));
|
||||
let deposit = T::BaseDeposit::get() + T::ByteDeposit::get() * MAX_SIZE.into();
|
||||
let s = RequestStatus::Requested { deposit: Some((noter, deposit)), count: 1, len: Some(MAX_SIZE) };
|
||||
assert_eq!(StatusFor::<T>::get(&hash), Some(s));
|
||||
}
|
||||
// Cheap request - would unreserve the deposit but none was held.
|
||||
request_no_deposit_preimage {
|
||||
@@ -112,14 +114,16 @@ benchmarks! {
|
||||
assert_ok!(Preimage::<T>::note_preimage(T::ManagerOrigin::successful_origin(), preimage));
|
||||
}: request_preimage<T::RuntimeOrigin>(T::ManagerOrigin::successful_origin(), hash)
|
||||
verify {
|
||||
assert_eq!(StatusFor::<T>::get(&hash), Some(RequestStatus::Requested(1)));
|
||||
let s = RequestStatus::Requested { deposit: None, count: 2, len: Some(MAX_SIZE) };
|
||||
assert_eq!(StatusFor::<T>::get(&hash), Some(s));
|
||||
}
|
||||
// Cheap request - the preimage is not yet noted, so deposit to unreserve.
|
||||
request_unnoted_preimage {
|
||||
let (_, hash) = preimage_and_hash::<T>();
|
||||
}: request_preimage<T::RuntimeOrigin>(T::ManagerOrigin::successful_origin(), hash)
|
||||
verify {
|
||||
assert_eq!(StatusFor::<T>::get(&hash), Some(RequestStatus::Requested(1)));
|
||||
let s = RequestStatus::Requested { deposit: None, count: 1, len: None };
|
||||
assert_eq!(StatusFor::<T>::get(&hash), Some(s));
|
||||
}
|
||||
// Cheap request - the preimage is already requested, so just a counter bump.
|
||||
request_requested_preimage {
|
||||
@@ -127,7 +131,8 @@ benchmarks! {
|
||||
assert_ok!(Preimage::<T>::request_preimage(T::ManagerOrigin::successful_origin(), hash));
|
||||
}: request_preimage<T::RuntimeOrigin>(T::ManagerOrigin::successful_origin(), hash)
|
||||
verify {
|
||||
assert_eq!(StatusFor::<T>::get(&hash), Some(RequestStatus::Requested(2)));
|
||||
let s = RequestStatus::Requested { deposit: None, count: 2, len: None };
|
||||
assert_eq!(StatusFor::<T>::get(&hash), Some(s));
|
||||
}
|
||||
|
||||
// Expensive unrequest - last reference and it's noted, so will destroy the preimage.
|
||||
@@ -154,7 +159,8 @@ benchmarks! {
|
||||
assert_ok!(Preimage::<T>::request_preimage(T::ManagerOrigin::successful_origin(), hash));
|
||||
}: unrequest_preimage<T::RuntimeOrigin>(T::ManagerOrigin::successful_origin(), hash)
|
||||
verify {
|
||||
assert_eq!(StatusFor::<T>::get(&hash), Some(RequestStatus::Requested(1)));
|
||||
let s = RequestStatus::Requested { deposit: None, count: 1, len: None };
|
||||
assert_eq!(StatusFor::<T>::get(&hash), Some(s));
|
||||
}
|
||||
|
||||
impl_benchmark_test_suite!(Preimage, crate::mock::new_test_ext(), crate::mock::Test);
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
mod benchmarking;
|
||||
pub mod migration;
|
||||
#[cfg(test)]
|
||||
mod mock;
|
||||
#[cfg(test)]
|
||||
@@ -37,15 +38,18 @@ mod tests;
|
||||
pub mod weights;
|
||||
|
||||
use sp_runtime::traits::{BadOrigin, Hash, Saturating};
|
||||
use sp_std::prelude::*;
|
||||
use sp_std::{borrow::Cow, prelude::*};
|
||||
|
||||
use codec::{Decode, Encode, MaxEncodedLen};
|
||||
use frame_support::{
|
||||
dispatch::Pays,
|
||||
ensure,
|
||||
pallet_prelude::Get,
|
||||
traits::{Currency, PreimageProvider, PreimageRecipient, ReservableCurrency},
|
||||
BoundedVec,
|
||||
traits::{
|
||||
Currency, Defensive, FetchResult, Hash as PreimageHash, PreimageProvider,
|
||||
PreimageRecipient, QueryPreimage, ReservableCurrency, StorePreimage,
|
||||
},
|
||||
BoundedSlice, BoundedVec,
|
||||
};
|
||||
use scale_info::TypeInfo;
|
||||
pub use weights::WeightInfo;
|
||||
@@ -59,20 +63,27 @@ pub use pallet::*;
|
||||
#[derive(Clone, Eq, PartialEq, Encode, Decode, TypeInfo, MaxEncodedLen, RuntimeDebug)]
|
||||
pub enum RequestStatus<AccountId, Balance> {
|
||||
/// The associated preimage has not yet been requested by the system. The given deposit (if
|
||||
/// some) is being held until either it becomes requested or the user retracts the primage.
|
||||
Unrequested(Option<(AccountId, Balance)>),
|
||||
/// some) is being held until either it becomes requested or the user retracts the preimage.
|
||||
Unrequested { deposit: (AccountId, Balance), len: u32 },
|
||||
/// There are a non-zero number of outstanding requests for this hash by this chain. If there
|
||||
/// is a preimage registered, then it may be removed iff this counter becomes zero.
|
||||
Requested(u32),
|
||||
/// is a preimage registered, then `len` is `Some` and it may be removed iff this counter
|
||||
/// becomes zero.
|
||||
Requested { deposit: Option<(AccountId, Balance)>, count: u32, len: Option<u32> },
|
||||
}
|
||||
|
||||
type BalanceOf<T> =
|
||||
<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
|
||||
|
||||
/// Maximum size of preimage we can store is 4mb.
|
||||
const MAX_SIZE: u32 = 4 * 1024 * 1024;
|
||||
|
||||
#[frame_support::pallet]
|
||||
pub mod pallet {
|
||||
use super::*;
|
||||
|
||||
/// The current storage version.
|
||||
const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
|
||||
|
||||
#[pallet::config]
|
||||
pub trait Config: frame_system::Config {
|
||||
/// The overarching event type.
|
||||
@@ -88,9 +99,6 @@ pub mod pallet {
|
||||
/// manage existing preimages.
|
||||
type ManagerOrigin: EnsureOrigin<Self::RuntimeOrigin>;
|
||||
|
||||
/// Max size allowed for a preimage.
|
||||
type MaxSize: Get<u32>;
|
||||
|
||||
/// The base deposit for placing a preimage on chain.
|
||||
type BaseDeposit: Get<BalanceOf<Self>>;
|
||||
|
||||
@@ -100,6 +108,7 @@ pub mod pallet {
|
||||
|
||||
#[pallet::pallet]
|
||||
#[pallet::generate_store(pub(super) trait Store)]
|
||||
#[pallet::storage_version(STORAGE_VERSION)]
|
||||
pub struct Pallet<T>(PhantomData<T>);
|
||||
|
||||
#[pallet::event]
|
||||
@@ -116,7 +125,7 @@ pub mod pallet {
|
||||
#[pallet::error]
|
||||
pub enum Error<T> {
|
||||
/// Preimage is too large to store on-chain.
|
||||
TooLarge,
|
||||
TooBig,
|
||||
/// Preimage has already been noted on-chain.
|
||||
AlreadyNoted,
|
||||
/// The user is not authorized to perform this action.
|
||||
@@ -134,10 +143,9 @@ pub mod pallet {
|
||||
pub(super) type StatusFor<T: Config> =
|
||||
StorageMap<_, Identity, T::Hash, RequestStatus<T::AccountId, BalanceOf<T>>>;
|
||||
|
||||
/// The preimages stored by this pallet.
|
||||
#[pallet::storage]
|
||||
pub(super) type PreimageFor<T: Config> =
|
||||
StorageMap<_, Identity, T::Hash, BoundedVec<u8, T::MaxSize>>;
|
||||
StorageMap<_, Identity, (T::Hash, u32), BoundedVec<u8, ConstU32<MAX_SIZE>>>;
|
||||
|
||||
#[pallet::call]
|
||||
impl<T: Config> Pallet<T> {
|
||||
@@ -150,9 +158,7 @@ pub mod pallet {
|
||||
// We accept a signed origin which will pay a deposit, or a root origin where a deposit
|
||||
// is not taken.
|
||||
let maybe_sender = Self::ensure_signed_or_manager(origin)?;
|
||||
let bounded_vec =
|
||||
BoundedVec::<u8, T::MaxSize>::try_from(bytes).map_err(|()| Error::<T>::TooLarge)?;
|
||||
let system_requested = Self::note_bytes(bounded_vec, maybe_sender.as_ref())?;
|
||||
let (system_requested, _) = Self::note_bytes(bytes.into(), maybe_sender.as_ref())?;
|
||||
if system_requested || maybe_sender.is_none() {
|
||||
Ok(Pays::No.into())
|
||||
} else {
|
||||
@@ -161,6 +167,11 @@ pub mod pallet {
|
||||
}
|
||||
|
||||
/// Clear an unrequested preimage from the runtime storage.
|
||||
///
|
||||
/// If `len` is provided, then it will be a much cheaper operation.
|
||||
///
|
||||
/// - `hash`: The hash of the preimage to be removed from the store.
|
||||
/// - `len`: The length of the preimage of `hash`.
|
||||
#[pallet::weight(T::WeightInfo::unnote_preimage())]
|
||||
pub fn unnote_preimage(origin: OriginFor<T>, hash: T::Hash) -> DispatchResult {
|
||||
let maybe_sender = Self::ensure_signed_or_manager(origin)?;
|
||||
@@ -203,41 +214,46 @@ impl<T: Config> Pallet<T> {
|
||||
|
||||
/// Store some preimage on chain.
|
||||
///
|
||||
/// If `maybe_depositor` is `None` then it is also requested. If `Some`, then it is not.
|
||||
///
|
||||
/// We verify that the preimage is within the bounds of what the pallet supports.
|
||||
///
|
||||
/// If the preimage was requested to be uploaded, then the user pays no deposits or tx fees.
|
||||
fn note_bytes(
|
||||
preimage: BoundedVec<u8, T::MaxSize>,
|
||||
preimage: Cow<[u8]>,
|
||||
maybe_depositor: Option<&T::AccountId>,
|
||||
) -> Result<bool, DispatchError> {
|
||||
) -> Result<(bool, T::Hash), DispatchError> {
|
||||
let hash = T::Hashing::hash(&preimage);
|
||||
ensure!(!PreimageFor::<T>::contains_key(hash), Error::<T>::AlreadyNoted);
|
||||
let len = preimage.len() as u32;
|
||||
ensure!(len <= MAX_SIZE, Error::<T>::TooBig);
|
||||
|
||||
// We take a deposit only if there is a provided depositor, and the preimage was not
|
||||
// We take a deposit only if there is a provided depositor and the preimage was not
|
||||
// previously requested. This also allows the tx to pay no fee.
|
||||
let was_requested = match (StatusFor::<T>::get(hash), maybe_depositor) {
|
||||
(Some(RequestStatus::Requested(..)), _) => true,
|
||||
(Some(RequestStatus::Unrequested(..)), _) =>
|
||||
let status = match (StatusFor::<T>::get(hash), maybe_depositor) {
|
||||
(Some(RequestStatus::Requested { count, deposit, .. }), _) =>
|
||||
RequestStatus::Requested { count, deposit, len: Some(len) },
|
||||
(Some(RequestStatus::Unrequested { .. }), Some(_)) =>
|
||||
return Err(Error::<T>::AlreadyNoted.into()),
|
||||
(None, None) => {
|
||||
StatusFor::<T>::insert(hash, RequestStatus::Unrequested(None));
|
||||
false
|
||||
},
|
||||
(Some(RequestStatus::Unrequested { len, deposit }), None) =>
|
||||
RequestStatus::Requested { deposit: Some(deposit), count: 1, len: Some(len) },
|
||||
(None, None) => RequestStatus::Requested { count: 1, len: Some(len), deposit: None },
|
||||
(None, Some(depositor)) => {
|
||||
let length = preimage.len() as u32;
|
||||
let deposit = T::BaseDeposit::get()
|
||||
.saturating_add(T::ByteDeposit::get().saturating_mul(length.into()));
|
||||
T::Currency::reserve(depositor, deposit)?;
|
||||
let status = RequestStatus::Unrequested(Some((depositor.clone(), deposit)));
|
||||
StatusFor::<T>::insert(hash, status);
|
||||
false
|
||||
RequestStatus::Unrequested { deposit: (depositor.clone(), deposit), len }
|
||||
},
|
||||
};
|
||||
let was_requested = matches!(status, RequestStatus::Requested { .. });
|
||||
StatusFor::<T>::insert(hash, status);
|
||||
|
||||
let _ = Self::insert(&hash, preimage)
|
||||
.defensive_proof("Unable to insert. Logic error in `note_bytes`?");
|
||||
|
||||
PreimageFor::<T>::insert(hash, preimage);
|
||||
Self::deposit_event(Event::Noted { hash });
|
||||
|
||||
Ok(was_requested)
|
||||
Ok((was_requested, hash))
|
||||
}
|
||||
|
||||
// This function will add a hash to the list of requested preimages.
|
||||
@@ -245,19 +261,15 @@ impl<T: Config> Pallet<T> {
|
||||
// If the preimage already exists before the request is made, the deposit for the preimage is
|
||||
// returned to the user, and removed from their management.
|
||||
fn do_request_preimage(hash: &T::Hash) {
|
||||
let count = StatusFor::<T>::get(hash).map_or(1, |x| match x {
|
||||
RequestStatus::Requested(mut count) => {
|
||||
count.saturating_inc();
|
||||
count
|
||||
},
|
||||
RequestStatus::Unrequested(None) => 1,
|
||||
RequestStatus::Unrequested(Some((owner, deposit))) => {
|
||||
// Return the deposit - the preimage now has outstanding requests.
|
||||
T::Currency::unreserve(&owner, deposit);
|
||||
1
|
||||
},
|
||||
});
|
||||
StatusFor::<T>::insert(hash, RequestStatus::Requested(count));
|
||||
let (count, len, deposit) =
|
||||
StatusFor::<T>::get(hash).map_or((1, None, None), |x| match x {
|
||||
RequestStatus::Requested { mut count, len, deposit } => {
|
||||
count.saturating_inc();
|
||||
(count, len, deposit)
|
||||
},
|
||||
RequestStatus::Unrequested { deposit, len } => (1, Some(len), Some(deposit)),
|
||||
});
|
||||
StatusFor::<T>::insert(hash, RequestStatus::Requested { count, len, deposit });
|
||||
if count == 1 {
|
||||
Self::deposit_event(Event::Requested { hash: *hash });
|
||||
}
|
||||
@@ -265,6 +277,8 @@ impl<T: Config> Pallet<T> {
|
||||
|
||||
// Clear a preimage from the storage of the chain, returning any deposit that may be reserved.
|
||||
//
|
||||
// If `len` is provided, it will be a much cheaper operation.
|
||||
//
|
||||
// If `maybe_owner` is provided, we verify that it is the correct owner before clearing the
|
||||
// data.
|
||||
fn do_unnote_preimage(
|
||||
@@ -272,51 +286,101 @@ impl<T: Config> Pallet<T> {
|
||||
maybe_check_owner: Option<T::AccountId>,
|
||||
) -> DispatchResult {
|
||||
match StatusFor::<T>::get(hash).ok_or(Error::<T>::NotNoted)? {
|
||||
RequestStatus::Unrequested(Some((owner, deposit))) => {
|
||||
RequestStatus::Requested { deposit: Some((owner, deposit)), count, len } => {
|
||||
ensure!(maybe_check_owner.map_or(true, |c| c == owner), Error::<T>::NotAuthorized);
|
||||
T::Currency::unreserve(&owner, deposit);
|
||||
StatusFor::<T>::insert(
|
||||
hash,
|
||||
RequestStatus::Requested { deposit: None, count, len },
|
||||
);
|
||||
Ok(())
|
||||
},
|
||||
RequestStatus::Unrequested(None) => {
|
||||
RequestStatus::Requested { deposit: None, .. } => {
|
||||
ensure!(maybe_check_owner.is_none(), Error::<T>::NotAuthorized);
|
||||
Self::do_unrequest_preimage(hash)
|
||||
},
|
||||
RequestStatus::Unrequested { deposit: (owner, deposit), len } => {
|
||||
ensure!(maybe_check_owner.map_or(true, |c| c == owner), Error::<T>::NotAuthorized);
|
||||
T::Currency::unreserve(&owner, deposit);
|
||||
StatusFor::<T>::remove(hash);
|
||||
|
||||
Self::remove(hash, len);
|
||||
Self::deposit_event(Event::Cleared { hash: *hash });
|
||||
Ok(())
|
||||
},
|
||||
RequestStatus::Requested(_) => return Err(Error::<T>::Requested.into()),
|
||||
}
|
||||
StatusFor::<T>::remove(hash);
|
||||
PreimageFor::<T>::remove(hash);
|
||||
Self::deposit_event(Event::Cleared { hash: *hash });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Clear a preimage request.
|
||||
fn do_unrequest_preimage(hash: &T::Hash) -> DispatchResult {
|
||||
match StatusFor::<T>::get(hash).ok_or(Error::<T>::NotRequested)? {
|
||||
RequestStatus::Requested(mut count) if count > 1 => {
|
||||
RequestStatus::Requested { mut count, len, deposit } if count > 1 => {
|
||||
count.saturating_dec();
|
||||
StatusFor::<T>::insert(hash, RequestStatus::Requested(count));
|
||||
StatusFor::<T>::insert(hash, RequestStatus::Requested { count, len, deposit });
|
||||
},
|
||||
RequestStatus::Requested(count) => {
|
||||
RequestStatus::Requested { count, len, deposit } => {
|
||||
debug_assert!(count == 1, "preimage request counter at zero?");
|
||||
PreimageFor::<T>::remove(hash);
|
||||
StatusFor::<T>::remove(hash);
|
||||
Self::deposit_event(Event::Cleared { hash: *hash });
|
||||
match (len, deposit) {
|
||||
// Preimage was never noted.
|
||||
(None, _) => StatusFor::<T>::remove(hash),
|
||||
// Preimage was noted without owner - just remove it.
|
||||
(Some(len), None) => {
|
||||
Self::remove(hash, len);
|
||||
StatusFor::<T>::remove(hash);
|
||||
Self::deposit_event(Event::Cleared { hash: *hash });
|
||||
},
|
||||
// Preimage was noted with owner - move to unrequested so they can get refund.
|
||||
(Some(len), Some(deposit)) => {
|
||||
StatusFor::<T>::insert(hash, RequestStatus::Unrequested { deposit, len });
|
||||
},
|
||||
}
|
||||
},
|
||||
RequestStatus::Unrequested(_) => return Err(Error::<T>::NotRequested.into()),
|
||||
RequestStatus::Unrequested { .. } => return Err(Error::<T>::NotRequested.into()),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn insert(hash: &T::Hash, preimage: Cow<[u8]>) -> Result<(), ()> {
|
||||
BoundedSlice::<u8, ConstU32<MAX_SIZE>>::try_from(preimage.as_ref())
|
||||
.map(|s| PreimageFor::<T>::insert((hash, s.len() as u32), s))
|
||||
}
|
||||
|
||||
fn remove(hash: &T::Hash, len: u32) {
|
||||
PreimageFor::<T>::remove((hash, len))
|
||||
}
|
||||
|
||||
fn have(hash: &T::Hash) -> bool {
|
||||
Self::len(hash).is_some()
|
||||
}
|
||||
|
||||
fn len(hash: &T::Hash) -> Option<u32> {
|
||||
use RequestStatus::*;
|
||||
match StatusFor::<T>::get(hash) {
|
||||
Some(Requested { len: Some(len), .. }) | Some(Unrequested { len, .. }) => Some(len),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn fetch(hash: &T::Hash, len: Option<u32>) -> FetchResult {
|
||||
let len = len.or_else(|| Self::len(hash)).ok_or(DispatchError::Unavailable)?;
|
||||
PreimageFor::<T>::get((hash, len))
|
||||
.map(|p| p.into_inner())
|
||||
.map(Into::into)
|
||||
.ok_or(DispatchError::Unavailable)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> PreimageProvider<T::Hash> for Pallet<T> {
|
||||
fn have_preimage(hash: &T::Hash) -> bool {
|
||||
PreimageFor::<T>::contains_key(hash)
|
||||
Self::have(hash)
|
||||
}
|
||||
|
||||
fn preimage_requested(hash: &T::Hash) -> bool {
|
||||
matches!(StatusFor::<T>::get(hash), Some(RequestStatus::Requested(..)))
|
||||
matches!(StatusFor::<T>::get(hash), Some(RequestStatus::Requested { .. }))
|
||||
}
|
||||
|
||||
fn get_preimage(hash: &T::Hash) -> Option<Vec<u8>> {
|
||||
PreimageFor::<T>::get(hash).map(|preimage| preimage.to_vec())
|
||||
Self::fetch(hash, None).ok().map(Cow::into_owned)
|
||||
}
|
||||
|
||||
fn request_preimage(hash: &T::Hash) {
|
||||
@@ -330,15 +394,60 @@ impl<T: Config> PreimageProvider<T::Hash> for Pallet<T> {
|
||||
}
|
||||
|
||||
impl<T: Config> PreimageRecipient<T::Hash> for Pallet<T> {
|
||||
type MaxSize = T::MaxSize;
|
||||
type MaxSize = ConstU32<MAX_SIZE>; // 2**22
|
||||
|
||||
fn note_preimage(bytes: BoundedVec<u8, Self::MaxSize>) {
|
||||
// We don't really care if this fails, since that's only the case if someone else has
|
||||
// already noted it.
|
||||
let _ = Self::note_bytes(bytes, None);
|
||||
let _ = Self::note_bytes(bytes.into_inner().into(), None);
|
||||
}
|
||||
|
||||
fn unnote_preimage(hash: &T::Hash) {
|
||||
// Should never fail if authorization check is skipped.
|
||||
let res = Self::do_unrequest_preimage(hash);
|
||||
debug_assert!(res.is_ok(), "unnote_preimage failed - request outstanding?");
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config<Hash = PreimageHash>> QueryPreimage for Pallet<T> {
|
||||
fn len(hash: &T::Hash) -> Option<u32> {
|
||||
Pallet::<T>::len(hash)
|
||||
}
|
||||
|
||||
fn fetch(hash: &T::Hash, len: Option<u32>) -> FetchResult {
|
||||
Pallet::<T>::fetch(hash, len)
|
||||
}
|
||||
|
||||
fn is_requested(hash: &T::Hash) -> bool {
|
||||
matches!(StatusFor::<T>::get(hash), Some(RequestStatus::Requested { .. }))
|
||||
}
|
||||
|
||||
fn request(hash: &T::Hash) {
|
||||
Self::do_request_preimage(hash)
|
||||
}
|
||||
|
||||
fn unrequest(hash: &T::Hash) {
|
||||
let res = Self::do_unrequest_preimage(hash);
|
||||
debug_assert!(res.is_ok(), "do_unrequest_preimage failed - counter underflow?");
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config<Hash = PreimageHash>> StorePreimage for Pallet<T> {
|
||||
const MAX_LENGTH: usize = MAX_SIZE as usize;
|
||||
|
||||
fn note(bytes: Cow<[u8]>) -> Result<T::Hash, DispatchError> {
|
||||
// We don't really care if this fails, since that's only the case if someone else has
|
||||
// already noted it.
|
||||
let maybe_hash = Self::note_bytes(bytes, None).map(|(_, h)| h);
|
||||
// Map to the correct trait error.
|
||||
if maybe_hash == Err(DispatchError::from(Error::<T>::TooBig)) {
|
||||
Err(DispatchError::Exhausted)
|
||||
} else {
|
||||
maybe_hash
|
||||
}
|
||||
}
|
||||
|
||||
fn unnote(hash: &T::Hash) {
|
||||
// Should never fail if authorization check is skipped.
|
||||
let res = Self::do_unnote_preimage(hash, None);
|
||||
debug_assert!(res.is_ok(), "unnote_preimage failed - request outstanding?");
|
||||
|
||||
@@ -0,0 +1,263 @@
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Copyright (C) 2022 Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Storage migrations for the preimage pallet.
|
||||
|
||||
use super::*;
|
||||
use frame_support::{
|
||||
storage_alias,
|
||||
traits::{ConstU32, OnRuntimeUpgrade},
|
||||
};
|
||||
use sp_std::collections::btree_map::BTreeMap;
|
||||
|
||||
/// The log target.
|
||||
const TARGET: &'static str = "runtime::preimage::migration::v1";
|
||||
|
||||
/// The original data layout of the preimage pallet without a specific version number.
|
||||
mod v0 {
|
||||
use super::*;
|
||||
|
||||
#[derive(Clone, Eq, PartialEq, Encode, Decode, TypeInfo, MaxEncodedLen, RuntimeDebug)]
|
||||
pub enum RequestStatus<AccountId, Balance> {
|
||||
Unrequested(Option<(AccountId, Balance)>),
|
||||
Requested(u32),
|
||||
}
|
||||
|
||||
#[storage_alias]
|
||||
pub type PreimageFor<T: Config> = StorageMap<
|
||||
Pallet<T>,
|
||||
Identity,
|
||||
<T as frame_system::Config>::Hash,
|
||||
BoundedVec<u8, ConstU32<MAX_SIZE>>,
|
||||
>;
|
||||
|
||||
#[storage_alias]
|
||||
pub type StatusFor<T: Config> = StorageMap<
|
||||
Pallet<T>,
|
||||
Identity,
|
||||
<T as frame_system::Config>::Hash,
|
||||
RequestStatus<<T as frame_system::Config>::AccountId, BalanceOf<T>>,
|
||||
>;
|
||||
|
||||
/// Returns the number of images or `None` if the storage is corrupted.
|
||||
#[cfg(feature = "try-runtime")]
|
||||
pub fn image_count<T: Config>() -> Option<u32> {
|
||||
let images = v0::PreimageFor::<T>::iter_values().count() as u32;
|
||||
let status = v0::StatusFor::<T>::iter_values().count() as u32;
|
||||
|
||||
if images == status {
|
||||
Some(images)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod v1 {
|
||||
use super::*;
|
||||
|
||||
/// Migration for moving preimage from V0 to V1 storage.
|
||||
///
|
||||
/// Note: This needs to be run with the same hashing algorithm as before
|
||||
/// since it is not re-hashing the preimages.
|
||||
pub struct Migration<T>(sp_std::marker::PhantomData<T>);
|
||||
|
||||
impl<T: Config> OnRuntimeUpgrade for Migration<T> {
|
||||
#[cfg(feature = "try-runtime")]
|
||||
fn pre_upgrade() -> Result<Vec<u8>, &'static str> {
|
||||
assert_eq!(StorageVersion::get::<Pallet<T>>(), 0, "can only upgrade from version 0");
|
||||
|
||||
let images = v0::image_count::<T>().expect("v0 storage corrupted");
|
||||
log::info!(target: TARGET, "Migrating {} images", &images);
|
||||
Ok((images as u32).encode())
|
||||
}
|
||||
|
||||
fn on_runtime_upgrade() -> Weight {
|
||||
let mut weight = T::DbWeight::get().reads(1);
|
||||
if StorageVersion::get::<Pallet<T>>() != 0 {
|
||||
log::warn!(
|
||||
target: TARGET,
|
||||
"skipping MovePreimagesIntoBuckets: executed on wrong storage version.\
|
||||
Expected version 0"
|
||||
);
|
||||
return weight
|
||||
}
|
||||
|
||||
let status = v0::StatusFor::<T>::drain().collect::<Vec<_>>();
|
||||
weight.saturating_accrue(T::DbWeight::get().reads(status.len() as u64));
|
||||
|
||||
let preimages = v0::PreimageFor::<T>::drain().collect::<BTreeMap<_, _>>();
|
||||
weight.saturating_accrue(T::DbWeight::get().reads(preimages.len() as u64));
|
||||
|
||||
for (hash, status) in status.into_iter() {
|
||||
let preimage = if let Some(preimage) = preimages.get(&hash) {
|
||||
preimage
|
||||
} else {
|
||||
log::error!(target: TARGET, "preimage not found for hash {:?}", &hash);
|
||||
continue
|
||||
};
|
||||
let len = preimage.len() as u32;
|
||||
if len > MAX_SIZE {
|
||||
log::error!(
|
||||
target: TARGET,
|
||||
"preimage too large for hash {:?}, len: {}",
|
||||
&hash,
|
||||
len
|
||||
);
|
||||
continue
|
||||
}
|
||||
|
||||
let status = match status {
|
||||
v0::RequestStatus::Unrequested(deposit) => match deposit {
|
||||
Some(deposit) => RequestStatus::Unrequested { deposit, len },
|
||||
// `None` depositor becomes system-requested.
|
||||
None =>
|
||||
RequestStatus::Requested { deposit: None, count: 1, len: Some(len) },
|
||||
},
|
||||
v0::RequestStatus::Requested(count) if count == 0 => {
|
||||
log::error!(target: TARGET, "preimage has counter of zero: {:?}", hash);
|
||||
continue
|
||||
},
|
||||
v0::RequestStatus::Requested(count) =>
|
||||
RequestStatus::Requested { deposit: None, count, len: Some(len) },
|
||||
};
|
||||
log::trace!(target: TARGET, "Moving preimage {:?} with len {}", hash, len);
|
||||
|
||||
crate::StatusFor::<T>::insert(hash, status);
|
||||
crate::PreimageFor::<T>::insert(&(hash, len), preimage);
|
||||
|
||||
weight.saturating_accrue(T::DbWeight::get().writes(2));
|
||||
}
|
||||
StorageVersion::new(1).put::<Pallet<T>>();
|
||||
|
||||
weight.saturating_add(T::DbWeight::get().writes(1))
|
||||
}
|
||||
|
||||
#[cfg(feature = "try-runtime")]
|
||||
fn post_upgrade(state: Vec<u8>) -> Result<(), &'static str> {
|
||||
let old_images: u32 =
|
||||
Decode::decode(&mut &state[..]).expect("pre_upgrade provides a valid state; qed");
|
||||
let new_images = image_count::<T>().expect("V1 storage corrupted");
|
||||
|
||||
if new_images != old_images {
|
||||
log::error!(
|
||||
target: TARGET,
|
||||
"migrated {} images, expected {}",
|
||||
new_images,
|
||||
old_images
|
||||
);
|
||||
}
|
||||
assert_eq!(StorageVersion::get::<Pallet<T>>(), 1, "must upgrade");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the number of images or `None` if the storage is corrupted.
|
||||
#[cfg(feature = "try-runtime")]
|
||||
pub fn image_count<T: Config>() -> Option<u32> {
|
||||
// Use iter_values() to ensure that the values are decodable.
|
||||
let images = crate::PreimageFor::<T>::iter_values().count() as u32;
|
||||
let status = crate::StatusFor::<T>::iter_values().count() as u32;
|
||||
|
||||
if images == status {
|
||||
Some(images)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg(feature = "try-runtime")]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::mock::{Test as T, *};
|
||||
|
||||
use frame_support::bounded_vec;
|
||||
|
||||
#[test]
|
||||
fn migration_works() {
|
||||
new_test_ext().execute_with(|| {
|
||||
assert_eq!(StorageVersion::get::<Pallet<T>>(), 0);
|
||||
// Insert some preimages into the v0 storage:
|
||||
|
||||
// Case 1: Unrequested without deposit
|
||||
let (p, h) = preimage::<T>(128);
|
||||
v0::PreimageFor::<T>::insert(h, p);
|
||||
v0::StatusFor::<T>::insert(h, v0::RequestStatus::Unrequested(None));
|
||||
// Case 2: Unrequested with deposit
|
||||
let (p, h) = preimage::<T>(1024);
|
||||
v0::PreimageFor::<T>::insert(h, p);
|
||||
v0::StatusFor::<T>::insert(h, v0::RequestStatus::Unrequested(Some((1, 1))));
|
||||
// Case 3: Requested by 0 (invalid)
|
||||
let (p, h) = preimage::<T>(8192);
|
||||
v0::PreimageFor::<T>::insert(h, p);
|
||||
v0::StatusFor::<T>::insert(h, v0::RequestStatus::Requested(0));
|
||||
// Case 4: Requested by 10
|
||||
let (p, h) = preimage::<T>(65536);
|
||||
v0::PreimageFor::<T>::insert(h, p);
|
||||
v0::StatusFor::<T>::insert(h, v0::RequestStatus::Requested(10));
|
||||
|
||||
assert_eq!(v0::image_count::<T>(), Some(4));
|
||||
assert_eq!(v1::image_count::<T>(), None, "V1 storage should be corrupted");
|
||||
|
||||
let state = v1::Migration::<T>::pre_upgrade().unwrap();
|
||||
let _w = v1::Migration::<T>::on_runtime_upgrade();
|
||||
v1::Migration::<T>::post_upgrade(state).unwrap();
|
||||
|
||||
// V0 and V1 share the same prefix, so `iter_values` still counts the same.
|
||||
assert_eq!(v0::image_count::<T>(), Some(3));
|
||||
assert_eq!(v1::image_count::<T>(), Some(3)); // One gets skipped therefore 3.
|
||||
assert_eq!(StorageVersion::get::<Pallet<T>>(), 1);
|
||||
|
||||
// Case 1: Unrequested without deposit becomes system-requested
|
||||
let (p, h) = preimage::<T>(128);
|
||||
assert_eq!(crate::PreimageFor::<T>::get(&(h, 128)), Some(p));
|
||||
assert_eq!(
|
||||
crate::StatusFor::<T>::get(h),
|
||||
Some(RequestStatus::Requested { deposit: None, count: 1, len: Some(128) })
|
||||
);
|
||||
// Case 2: Unrequested with deposit becomes unrequested
|
||||
let (p, h) = preimage::<T>(1024);
|
||||
assert_eq!(crate::PreimageFor::<T>::get(&(h, 1024)), Some(p));
|
||||
assert_eq!(
|
||||
crate::StatusFor::<T>::get(h),
|
||||
Some(RequestStatus::Unrequested { deposit: (1, 1), len: 1024 })
|
||||
);
|
||||
// Case 3: Requested by 0 should be skipped
|
||||
let (_, h) = preimage::<T>(8192);
|
||||
assert_eq!(crate::PreimageFor::<T>::get(&(h, 8192)), None);
|
||||
assert_eq!(crate::StatusFor::<T>::get(h), None);
|
||||
// Case 4: Requested by 10 becomes requested by 10
|
||||
let (p, h) = preimage::<T>(65536);
|
||||
assert_eq!(crate::PreimageFor::<T>::get(&(h, 65536)), Some(p));
|
||||
assert_eq!(
|
||||
crate::StatusFor::<T>::get(h),
|
||||
Some(RequestStatus::Requested { deposit: None, count: 10, len: Some(65536) })
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// Returns a preimage with a given size and its hash.
|
||||
fn preimage<T: Config>(
|
||||
len: usize,
|
||||
) -> (BoundedVec<u8, ConstU32<MAX_SIZE>>, <T as frame_system::Config>::Hash) {
|
||||
let p = bounded_vec![1; len];
|
||||
let h = <T as frame_system::Config>::Hashing::hash_of(&p);
|
||||
(p, h)
|
||||
}
|
||||
}
|
||||
@@ -105,7 +105,6 @@ impl Config for Test {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type Currency = Balances;
|
||||
type ManagerOrigin = EnsureSignedBy<One, u64>;
|
||||
type MaxSize = ConstU32<1024>;
|
||||
type BaseDeposit = ConstU64<2>;
|
||||
type ByteDeposit = ConstU64<1>;
|
||||
}
|
||||
|
||||
@@ -17,11 +17,35 @@
|
||||
|
||||
//! # Scheduler tests.
|
||||
|
||||
#![cfg(test)]
|
||||
|
||||
use super::*;
|
||||
use crate::mock::*;
|
||||
|
||||
use frame_support::{assert_noop, assert_ok};
|
||||
use frame_support::{
|
||||
assert_err, assert_noop, assert_ok, assert_storage_noop, bounded_vec,
|
||||
traits::{Bounded, BoundedInline, Hash as PreimageHash},
|
||||
StorageNoopGuard,
|
||||
};
|
||||
use pallet_balances::Error as BalancesError;
|
||||
use sp_core::{blake2_256, H256};
|
||||
|
||||
/// Returns one `Inline`, `Lookup` and `Legacy` item each with different data and hash.
|
||||
pub fn make_bounded_values() -> (Bounded<Vec<u8>>, Bounded<Vec<u8>>, Bounded<Vec<u8>>) {
|
||||
let data: BoundedInline = bounded_vec![1];
|
||||
let inline = Bounded::<Vec<u8>>::Inline(data);
|
||||
|
||||
let data = vec![1, 2];
|
||||
let hash: H256 = blake2_256(&data[..]).into();
|
||||
let len = data.len() as u32;
|
||||
let lookup = Bounded::<Vec<u8>>::unrequested(hash, len);
|
||||
|
||||
let data = vec![1, 2, 3];
|
||||
let hash: H256 = blake2_256(&data[..]).into();
|
||||
let legacy = Bounded::<Vec<u8>>::Legacy { hash, dummy: Default::default() };
|
||||
|
||||
(inline, lookup, legacy)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn user_note_preimage_works() {
|
||||
@@ -56,10 +80,7 @@ fn manager_note_preimage_works() {
|
||||
assert!(Preimage::have_preimage(&h));
|
||||
assert_eq!(Preimage::get_preimage(&h), Some(vec![1]));
|
||||
|
||||
assert_noop!(
|
||||
Preimage::note_preimage(RuntimeOrigin::signed(1), vec![1]),
|
||||
Error::<Test>::AlreadyNoted
|
||||
);
|
||||
assert_ok!(Preimage::note_preimage(RuntimeOrigin::signed(1), vec![1]));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -130,14 +151,16 @@ fn requested_then_noted_preimage_cannot_be_unnoted() {
|
||||
new_test_ext().execute_with(|| {
|
||||
assert_ok!(Preimage::note_preimage(RuntimeOrigin::signed(1), vec![1]));
|
||||
assert_ok!(Preimage::request_preimage(RuntimeOrigin::signed(1), hashed([1])));
|
||||
assert_noop!(
|
||||
Preimage::unnote_preimage(RuntimeOrigin::signed(1), hashed([1])),
|
||||
Error::<Test>::Requested
|
||||
);
|
||||
assert_ok!(Preimage::unnote_preimage(RuntimeOrigin::signed(1), hashed([1])));
|
||||
// it's still here.
|
||||
|
||||
let h = hashed([1]);
|
||||
assert!(Preimage::have_preimage(&h));
|
||||
assert_eq!(Preimage::get_preimage(&h), Some(vec![1]));
|
||||
|
||||
// now it's gone
|
||||
assert_ok!(Preimage::unrequest_preimage(RuntimeOrigin::signed(1), hashed([1])));
|
||||
assert!(!Preimage::have_preimage(&hashed([1])));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -145,15 +168,16 @@ fn requested_then_noted_preimage_cannot_be_unnoted() {
|
||||
fn request_note_order_makes_no_difference() {
|
||||
let one_way = new_test_ext().execute_with(|| {
|
||||
assert_ok!(Preimage::request_preimage(RuntimeOrigin::signed(1), hashed([1])));
|
||||
assert_ok!(Preimage::note_preimage(RuntimeOrigin::signed(1), vec![1]));
|
||||
assert_ok!(Preimage::note_preimage(RuntimeOrigin::signed(2), vec![1]));
|
||||
(
|
||||
StatusFor::<Test>::iter().collect::<Vec<_>>(),
|
||||
PreimageFor::<Test>::iter().collect::<Vec<_>>(),
|
||||
)
|
||||
});
|
||||
new_test_ext().execute_with(|| {
|
||||
assert_ok!(Preimage::note_preimage(RuntimeOrigin::signed(1), vec![1]));
|
||||
assert_ok!(Preimage::note_preimage(RuntimeOrigin::signed(2), vec![1]));
|
||||
assert_ok!(Preimage::request_preimage(RuntimeOrigin::signed(1), hashed([1])));
|
||||
assert_ok!(Preimage::unnote_preimage(RuntimeOrigin::signed(2), hashed([1])));
|
||||
let other_way = (
|
||||
StatusFor::<Test>::iter().collect::<Vec<_>>(),
|
||||
PreimageFor::<Test>::iter().collect::<Vec<_>>(),
|
||||
@@ -189,6 +213,7 @@ fn request_user_note_order_makes_no_difference() {
|
||||
new_test_ext().execute_with(|| {
|
||||
assert_ok!(Preimage::note_preimage(RuntimeOrigin::signed(2), vec![1]));
|
||||
assert_ok!(Preimage::request_preimage(RuntimeOrigin::signed(1), hashed([1])));
|
||||
assert_ok!(Preimage::unnote_preimage(RuntimeOrigin::signed(2), hashed([1])));
|
||||
let other_way = (
|
||||
StatusFor::<Test>::iter().collect::<Vec<_>>(),
|
||||
PreimageFor::<Test>::iter().collect::<Vec<_>>(),
|
||||
@@ -226,8 +251,240 @@ fn user_noted_then_requested_preimage_is_refunded_once_only() {
|
||||
assert_ok!(Preimage::note_preimage(RuntimeOrigin::signed(2), vec![1]));
|
||||
assert_ok!(Preimage::request_preimage(RuntimeOrigin::signed(1), hashed([1])));
|
||||
assert_ok!(Preimage::unrequest_preimage(RuntimeOrigin::signed(1), hashed([1])));
|
||||
assert_ok!(Preimage::unnote_preimage(RuntimeOrigin::signed(2), hashed([1])));
|
||||
// Still have reserve from `vec[1; 3]`.
|
||||
assert_eq!(Balances::reserved_balance(2), 5);
|
||||
assert_eq!(Balances::free_balance(2), 95);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn noted_preimage_use_correct_map() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// Add one preimage per bucket...
|
||||
for i in 0..7 {
|
||||
assert_ok!(Preimage::note_preimage(RuntimeOrigin::signed(1), vec![0; 128 << (i * 2)]));
|
||||
}
|
||||
assert_ok!(Preimage::note_preimage(RuntimeOrigin::signed(1), vec![0; MAX_SIZE as usize]));
|
||||
assert_eq!(PreimageFor::<Test>::iter().count(), 8);
|
||||
|
||||
// All are present
|
||||
assert_eq!(StatusFor::<Test>::iter().count(), 8);
|
||||
|
||||
// Now start removing them again...
|
||||
for i in 0..7 {
|
||||
assert_ok!(Preimage::unnote_preimage(
|
||||
RuntimeOrigin::signed(1),
|
||||
hashed(vec![0; 128 << (i * 2)])
|
||||
));
|
||||
}
|
||||
assert_eq!(PreimageFor::<Test>::iter().count(), 1);
|
||||
assert_ok!(Preimage::unnote_preimage(
|
||||
RuntimeOrigin::signed(1),
|
||||
hashed(vec![0; MAX_SIZE as usize])
|
||||
));
|
||||
assert_eq!(PreimageFor::<Test>::iter().count(), 0);
|
||||
|
||||
// All are gone
|
||||
assert_eq!(StatusFor::<Test>::iter().count(), 0);
|
||||
});
|
||||
}
|
||||
|
||||
/// The `StorePreimage` and `QueryPreimage` traits work together.
|
||||
#[test]
|
||||
fn query_and_store_preimage_workflow() {
|
||||
new_test_ext().execute_with(|| {
|
||||
let _guard = StorageNoopGuard::default();
|
||||
let data: Vec<u8> = vec![1; 512];
|
||||
let encoded = data.encode();
|
||||
|
||||
// Bound an unbound value.
|
||||
let bound = Preimage::bound(data.clone()).unwrap();
|
||||
let (len, hash) = (bound.len().unwrap(), bound.hash());
|
||||
|
||||
assert_eq!(hash, blake2_256(&encoded).into());
|
||||
assert_eq!(bound.len(), Some(len));
|
||||
assert!(bound.lookup_needed(), "Should not be Inlined");
|
||||
assert_eq!(bound.lookup_len(), Some(len));
|
||||
|
||||
// The value is requested and available.
|
||||
assert!(Preimage::is_requested(&hash));
|
||||
assert!(<Preimage as QueryPreimage>::have(&bound));
|
||||
assert_eq!(Preimage::len(&hash), Some(len));
|
||||
|
||||
// It can be fetched with length.
|
||||
assert_eq!(Preimage::fetch(&hash, Some(len)).unwrap(), encoded);
|
||||
// ... and without length.
|
||||
assert_eq!(Preimage::fetch(&hash, None).unwrap(), encoded);
|
||||
// ... but not with wrong length.
|
||||
assert_err!(Preimage::fetch(&hash, Some(0)), DispatchError::Unavailable);
|
||||
|
||||
// It can be peeked and decoded correctly.
|
||||
assert_eq!(Preimage::peek::<Vec<u8>>(&bound).unwrap(), (data.clone(), Some(len)));
|
||||
// Request it two more times.
|
||||
assert_eq!(Preimage::pick::<Vec<u8>>(hash, len), bound);
|
||||
Preimage::request(&hash);
|
||||
// It is requested thrice.
|
||||
assert!(matches!(
|
||||
StatusFor::<Test>::get(&hash).unwrap(),
|
||||
RequestStatus::Requested { count: 3, .. }
|
||||
));
|
||||
|
||||
// It can be realized and decoded correctly.
|
||||
assert_eq!(Preimage::realize::<Vec<u8>>(&bound).unwrap(), (data.clone(), Some(len)));
|
||||
assert!(matches!(
|
||||
StatusFor::<Test>::get(&hash).unwrap(),
|
||||
RequestStatus::Requested { count: 2, .. }
|
||||
));
|
||||
// Dropping should unrequest.
|
||||
Preimage::drop(&bound);
|
||||
assert!(matches!(
|
||||
StatusFor::<Test>::get(&hash).unwrap(),
|
||||
RequestStatus::Requested { count: 1, .. }
|
||||
));
|
||||
|
||||
// Is still available.
|
||||
assert!(<Preimage as QueryPreimage>::have(&bound));
|
||||
// Manually unnote it.
|
||||
Preimage::unnote(&hash);
|
||||
// Is not available anymore.
|
||||
assert!(!<Preimage as QueryPreimage>::have(&bound));
|
||||
assert_err!(Preimage::fetch(&hash, Some(len)), DispatchError::Unavailable);
|
||||
// And not requested since the traits assume permissioned origin.
|
||||
assert!(!Preimage::is_requested(&hash));
|
||||
|
||||
// No storage changes remain. Checked by `StorageNoopGuard`.
|
||||
});
|
||||
}
|
||||
|
||||
/// The request function behaves as expected.
|
||||
#[test]
|
||||
fn query_preimage_request_works() {
|
||||
new_test_ext().execute_with(|| {
|
||||
let _guard = StorageNoopGuard::default();
|
||||
let data: Vec<u8> = vec![1; 10];
|
||||
let hash: PreimageHash = blake2_256(&data[..]).into();
|
||||
|
||||
// Request the preimage.
|
||||
<Preimage as QueryPreimage>::request(&hash);
|
||||
|
||||
// The preimage is requested with unknown length and cannot be fetched.
|
||||
assert!(<Preimage as QueryPreimage>::is_requested(&hash));
|
||||
assert!(<Preimage as QueryPreimage>::len(&hash).is_none());
|
||||
assert_noop!(<Preimage as QueryPreimage>::fetch(&hash, None), DispatchError::Unavailable);
|
||||
|
||||
// Request again.
|
||||
<Preimage as QueryPreimage>::request(&hash);
|
||||
// The preimage is still requested.
|
||||
assert!(<Preimage as QueryPreimage>::is_requested(&hash));
|
||||
assert!(<Preimage as QueryPreimage>::len(&hash).is_none());
|
||||
assert_noop!(<Preimage as QueryPreimage>::fetch(&hash, None), DispatchError::Unavailable);
|
||||
// But there is only one entry in the map.
|
||||
assert_eq!(StatusFor::<Test>::iter().count(), 1);
|
||||
|
||||
// Un-request the preimage.
|
||||
<Preimage as QueryPreimage>::unrequest(&hash);
|
||||
// It is still requested.
|
||||
assert!(<Preimage as QueryPreimage>::is_requested(&hash));
|
||||
// Un-request twice.
|
||||
<Preimage as QueryPreimage>::unrequest(&hash);
|
||||
// It is not requested anymore.
|
||||
assert!(!<Preimage as QueryPreimage>::is_requested(&hash));
|
||||
// And there is no entry in the map.
|
||||
assert_eq!(StatusFor::<Test>::iter().count(), 0);
|
||||
});
|
||||
}
|
||||
|
||||
/// The `QueryPreimage` functions can be used together with `Bounded` values.
|
||||
#[test]
|
||||
fn query_preimage_hold_and_drop_work() {
|
||||
new_test_ext().execute_with(|| {
|
||||
let _guard = StorageNoopGuard::default();
|
||||
let (inline, lookup, legacy) = make_bounded_values();
|
||||
|
||||
// `hold` does nothing for `Inline` values.
|
||||
assert_storage_noop!(<Preimage as QueryPreimage>::hold(&inline));
|
||||
// `hold` requests `Lookup` values.
|
||||
<Preimage as QueryPreimage>::hold(&lookup);
|
||||
assert!(<Preimage as QueryPreimage>::is_requested(&lookup.hash()));
|
||||
// `hold` requests `Legacy` values.
|
||||
<Preimage as QueryPreimage>::hold(&legacy);
|
||||
assert!(<Preimage as QueryPreimage>::is_requested(&legacy.hash()));
|
||||
|
||||
// There are two values requested in total.
|
||||
assert_eq!(StatusFor::<Test>::iter().count(), 2);
|
||||
|
||||
// Cleanup by dropping both.
|
||||
<Preimage as QueryPreimage>::drop(&lookup);
|
||||
assert!(!<Preimage as QueryPreimage>::is_requested(&lookup.hash()));
|
||||
<Preimage as QueryPreimage>::drop(&legacy);
|
||||
assert!(!<Preimage as QueryPreimage>::is_requested(&legacy.hash()));
|
||||
|
||||
// There are no values requested anymore.
|
||||
assert_eq!(StatusFor::<Test>::iter().count(), 0);
|
||||
});
|
||||
}
|
||||
|
||||
/// The `StorePreimage` trait works as expected.
|
||||
#[test]
|
||||
fn store_preimage_basic_works() {
|
||||
new_test_ext().execute_with(|| {
|
||||
let _guard = StorageNoopGuard::default();
|
||||
let data: Vec<u8> = vec![1; 512]; // Too large to inline.
|
||||
let encoded = Cow::from(data.encode());
|
||||
|
||||
// Bound the data.
|
||||
let bound = <Preimage as StorePreimage>::bound(data.clone()).unwrap();
|
||||
// The preimage can be peeked.
|
||||
assert_ok!(<Preimage as QueryPreimage>::peek(&bound));
|
||||
// Un-note the preimage.
|
||||
<Preimage as StorePreimage>::unnote(&bound.hash());
|
||||
// The preimage cannot be peeked anymore.
|
||||
assert_err!(<Preimage as QueryPreimage>::peek(&bound), DispatchError::Unavailable);
|
||||
// Noting the wrong pre-image does not make it peek-able.
|
||||
assert_ok!(<Preimage as StorePreimage>::note(Cow::Borrowed(&data)));
|
||||
assert_err!(<Preimage as QueryPreimage>::peek(&bound), DispatchError::Unavailable);
|
||||
|
||||
// Manually note the preimage makes it peek-able again.
|
||||
assert_ok!(<Preimage as StorePreimage>::note(encoded.clone()));
|
||||
// Noting again works.
|
||||
assert_ok!(<Preimage as StorePreimage>::note(encoded));
|
||||
assert_ok!(<Preimage as QueryPreimage>::peek(&bound));
|
||||
|
||||
// Cleanup.
|
||||
<Preimage as StorePreimage>::unnote(&bound.hash());
|
||||
let data_hash = blake2_256(&data);
|
||||
<Preimage as StorePreimage>::unnote(&data_hash.into());
|
||||
|
||||
// No storage changes remain. Checked by `StorageNoopGuard`.
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn store_preimage_note_too_large_errors() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// Works with `MAX_LENGTH`.
|
||||
let len = <Preimage as StorePreimage>::MAX_LENGTH;
|
||||
let data = vec![0u8; len];
|
||||
assert_ok!(<Preimage as StorePreimage>::note(data.into()));
|
||||
|
||||
// Errors with `MAX_LENGTH+1`.
|
||||
let data = vec![0u8; len + 1];
|
||||
assert_err!(<Preimage as StorePreimage>::note(data.into()), DispatchError::Exhausted);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn store_preimage_bound_too_large_errors() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// Using `MAX_LENGTH` number of bytes in a vector does not work
|
||||
// since SCALE prepends the length.
|
||||
let len = <Preimage as StorePreimage>::MAX_LENGTH;
|
||||
let data: Vec<u8> = vec![0; len];
|
||||
assert_err!(<Preimage as StorePreimage>::bound(data.clone()), DispatchError::Exhausted);
|
||||
|
||||
// Works with `MAX_LENGTH-4`.
|
||||
let data: Vec<u8> = vec![0; len - 4];
|
||||
assert_ok!(<Preimage as StorePreimage>::bound(data.clone()));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -18,22 +18,24 @@
|
||||
//! Autogenerated weights for pallet_preimage
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
|
||||
//! DATE: 2022-05-23, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! DATE: 2022-10-03, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! HOSTNAME: `bm3`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
|
||||
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024
|
||||
|
||||
// Executed Command:
|
||||
// ./target/production/substrate
|
||||
// /home/benchbot/cargo_target_dir/production/substrate
|
||||
// benchmark
|
||||
// pallet
|
||||
// --chain=dev
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --pallet=pallet_preimage
|
||||
// --extrinsic=*
|
||||
// --execution=wasm
|
||||
// --wasm-execution=compiled
|
||||
// --template=./.maintain/frame-weight-template.hbs
|
||||
// --heap-pages=4096
|
||||
// --pallet=pallet_preimage
|
||||
// --chain=dev
|
||||
// --output=./frame/preimage/src/weights.rs
|
||||
// --template=./.maintain/frame-weight-template.hbs
|
||||
|
||||
#![cfg_attr(rustfmt, rustfmt_skip)]
|
||||
#![allow(unused_parens)]
|
||||
@@ -61,88 +63,90 @@ pub trait WeightInfo {
|
||||
/// Weights for pallet_preimage using the Substrate node and recommended hardware.
|
||||
pub struct SubstrateWeight<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
|
||||
// Storage: Preimage PreimageFor (r:1 w:1)
|
||||
// Storage: Preimage StatusFor (r:1 w:1)
|
||||
// Storage: Preimage PreimageFor (r:0 w:1)
|
||||
/// The range of component `s` is `[0, 4194304]`.
|
||||
fn note_preimage(s: u32, ) -> Weight {
|
||||
Weight::from_ref_time(0 as u64)
|
||||
Weight::from_ref_time(32_591_000 as u64)
|
||||
// Standard Error: 0
|
||||
.saturating_add(Weight::from_ref_time(2_000 as u64).saturating_mul(s as u64))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as u64))
|
||||
.saturating_add(Weight::from_ref_time(1_680 as u64).saturating_mul(s as u64))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as u64))
|
||||
}
|
||||
// Storage: Preimage PreimageFor (r:1 w:1)
|
||||
// Storage: Preimage StatusFor (r:1 w:0)
|
||||
// Storage: Preimage StatusFor (r:1 w:1)
|
||||
// Storage: Preimage PreimageFor (r:0 w:1)
|
||||
/// The range of component `s` is `[0, 4194304]`.
|
||||
fn note_requested_preimage(s: u32, ) -> Weight {
|
||||
Weight::from_ref_time(0 as u64)
|
||||
Weight::from_ref_time(23_350_000 as u64)
|
||||
// Standard Error: 0
|
||||
.saturating_add(Weight::from_ref_time(2_000 as u64).saturating_mul(s as u64))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as u64))
|
||||
.saturating_add(Weight::from_ref_time(1_681 as u64).saturating_mul(s as u64))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as u64))
|
||||
}
|
||||
// Storage: Preimage PreimageFor (r:1 w:1)
|
||||
// Storage: Preimage StatusFor (r:1 w:0)
|
||||
// Storage: Preimage StatusFor (r:1 w:1)
|
||||
// Storage: Preimage PreimageFor (r:0 w:1)
|
||||
/// The range of component `s` is `[0, 4194304]`.
|
||||
fn note_no_deposit_preimage(s: u32, ) -> Weight {
|
||||
Weight::from_ref_time(0 as u64)
|
||||
Weight::from_ref_time(21_436_000 as u64)
|
||||
// Standard Error: 0
|
||||
.saturating_add(Weight::from_ref_time(2_000 as u64).saturating_mul(s as u64))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as u64))
|
||||
.saturating_add(Weight::from_ref_time(1_680 as u64).saturating_mul(s as u64))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as u64))
|
||||
}
|
||||
// Storage: Preimage StatusFor (r:1 w:1)
|
||||
// Storage: Preimage PreimageFor (r:0 w:1)
|
||||
fn unnote_preimage() -> Weight {
|
||||
Weight::from_ref_time(44_380_000 as u64)
|
||||
Weight::from_ref_time(44_567_000 as u64)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as u64))
|
||||
}
|
||||
// Storage: Preimage StatusFor (r:1 w:1)
|
||||
// Storage: Preimage PreimageFor (r:0 w:1)
|
||||
fn unnote_no_deposit_preimage() -> Weight {
|
||||
Weight::from_ref_time(30_280_000 as u64)
|
||||
Weight::from_ref_time(30_065_000 as u64)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as u64))
|
||||
}
|
||||
// Storage: Preimage StatusFor (r:1 w:1)
|
||||
fn request_preimage() -> Weight {
|
||||
Weight::from_ref_time(42_809_000 as u64)
|
||||
Weight::from_ref_time(28_470_000 as u64)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as u64))
|
||||
}
|
||||
// Storage: Preimage StatusFor (r:1 w:1)
|
||||
fn request_no_deposit_preimage() -> Weight {
|
||||
Weight::from_ref_time(28_964_000 as u64)
|
||||
Weight::from_ref_time(14_601_000 as u64)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as u64))
|
||||
}
|
||||
// Storage: Preimage StatusFor (r:1 w:1)
|
||||
fn request_unnoted_preimage() -> Weight {
|
||||
Weight::from_ref_time(17_555_000 as u64)
|
||||
Weight::from_ref_time(20_121_000 as u64)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as u64))
|
||||
}
|
||||
// Storage: Preimage StatusFor (r:1 w:1)
|
||||
fn request_requested_preimage() -> Weight {
|
||||
Weight::from_ref_time(7_745_000 as u64)
|
||||
Weight::from_ref_time(9_440_000 as u64)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as u64))
|
||||
}
|
||||
// Storage: Preimage StatusFor (r:1 w:1)
|
||||
// Storage: Preimage PreimageFor (r:0 w:1)
|
||||
fn unrequest_preimage() -> Weight {
|
||||
Weight::from_ref_time(29_758_000 as u64)
|
||||
Weight::from_ref_time(29_013_000 as u64)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as u64))
|
||||
}
|
||||
// Storage: Preimage StatusFor (r:1 w:1)
|
||||
// Storage: Preimage PreimageFor (r:0 w:1)
|
||||
fn unrequest_unnoted_preimage() -> Weight {
|
||||
Weight::from_ref_time(18_360_000 as u64)
|
||||
Weight::from_ref_time(9_223_000 as u64)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as u64))
|
||||
}
|
||||
// Storage: Preimage StatusFor (r:1 w:1)
|
||||
fn unrequest_multi_referenced_preimage() -> Weight {
|
||||
Weight::from_ref_time(7_439_000 as u64)
|
||||
Weight::from_ref_time(9_252_000 as u64)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as u64))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as u64))
|
||||
}
|
||||
@@ -150,88 +154,90 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
|
||||
|
||||
// For backwards compatibility and tests
|
||||
impl WeightInfo for () {
|
||||
// Storage: Preimage PreimageFor (r:1 w:1)
|
||||
// Storage: Preimage StatusFor (r:1 w:1)
|
||||
// Storage: Preimage PreimageFor (r:0 w:1)
|
||||
/// The range of component `s` is `[0, 4194304]`.
|
||||
fn note_preimage(s: u32, ) -> Weight {
|
||||
Weight::from_ref_time(0 as u64)
|
||||
Weight::from_ref_time(32_591_000 as u64)
|
||||
// Standard Error: 0
|
||||
.saturating_add(Weight::from_ref_time(2_000 as u64).saturating_mul(s as u64))
|
||||
.saturating_add(RocksDbWeight::get().reads(2 as u64))
|
||||
.saturating_add(Weight::from_ref_time(1_680 as u64).saturating_mul(s as u64))
|
||||
.saturating_add(RocksDbWeight::get().reads(1 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(2 as u64))
|
||||
}
|
||||
// Storage: Preimage PreimageFor (r:1 w:1)
|
||||
// Storage: Preimage StatusFor (r:1 w:0)
|
||||
// Storage: Preimage StatusFor (r:1 w:1)
|
||||
// Storage: Preimage PreimageFor (r:0 w:1)
|
||||
/// The range of component `s` is `[0, 4194304]`.
|
||||
fn note_requested_preimage(s: u32, ) -> Weight {
|
||||
Weight::from_ref_time(0 as u64)
|
||||
Weight::from_ref_time(23_350_000 as u64)
|
||||
// Standard Error: 0
|
||||
.saturating_add(Weight::from_ref_time(2_000 as u64).saturating_mul(s as u64))
|
||||
.saturating_add(RocksDbWeight::get().reads(2 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(1 as u64))
|
||||
.saturating_add(Weight::from_ref_time(1_681 as u64).saturating_mul(s as u64))
|
||||
.saturating_add(RocksDbWeight::get().reads(1 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(2 as u64))
|
||||
}
|
||||
// Storage: Preimage PreimageFor (r:1 w:1)
|
||||
// Storage: Preimage StatusFor (r:1 w:0)
|
||||
// Storage: Preimage StatusFor (r:1 w:1)
|
||||
// Storage: Preimage PreimageFor (r:0 w:1)
|
||||
/// The range of component `s` is `[0, 4194304]`.
|
||||
fn note_no_deposit_preimage(s: u32, ) -> Weight {
|
||||
Weight::from_ref_time(0 as u64)
|
||||
Weight::from_ref_time(21_436_000 as u64)
|
||||
// Standard Error: 0
|
||||
.saturating_add(Weight::from_ref_time(2_000 as u64).saturating_mul(s as u64))
|
||||
.saturating_add(RocksDbWeight::get().reads(2 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(1 as u64))
|
||||
.saturating_add(Weight::from_ref_time(1_680 as u64).saturating_mul(s as u64))
|
||||
.saturating_add(RocksDbWeight::get().reads(1 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(2 as u64))
|
||||
}
|
||||
// Storage: Preimage StatusFor (r:1 w:1)
|
||||
// Storage: Preimage PreimageFor (r:0 w:1)
|
||||
fn unnote_preimage() -> Weight {
|
||||
Weight::from_ref_time(44_380_000 as u64)
|
||||
Weight::from_ref_time(44_567_000 as u64)
|
||||
.saturating_add(RocksDbWeight::get().reads(1 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(2 as u64))
|
||||
}
|
||||
// Storage: Preimage StatusFor (r:1 w:1)
|
||||
// Storage: Preimage PreimageFor (r:0 w:1)
|
||||
fn unnote_no_deposit_preimage() -> Weight {
|
||||
Weight::from_ref_time(30_280_000 as u64)
|
||||
Weight::from_ref_time(30_065_000 as u64)
|
||||
.saturating_add(RocksDbWeight::get().reads(1 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(2 as u64))
|
||||
}
|
||||
// Storage: Preimage StatusFor (r:1 w:1)
|
||||
fn request_preimage() -> Weight {
|
||||
Weight::from_ref_time(42_809_000 as u64)
|
||||
Weight::from_ref_time(28_470_000 as u64)
|
||||
.saturating_add(RocksDbWeight::get().reads(1 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(1 as u64))
|
||||
}
|
||||
// Storage: Preimage StatusFor (r:1 w:1)
|
||||
fn request_no_deposit_preimage() -> Weight {
|
||||
Weight::from_ref_time(28_964_000 as u64)
|
||||
Weight::from_ref_time(14_601_000 as u64)
|
||||
.saturating_add(RocksDbWeight::get().reads(1 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(1 as u64))
|
||||
}
|
||||
// Storage: Preimage StatusFor (r:1 w:1)
|
||||
fn request_unnoted_preimage() -> Weight {
|
||||
Weight::from_ref_time(17_555_000 as u64)
|
||||
Weight::from_ref_time(20_121_000 as u64)
|
||||
.saturating_add(RocksDbWeight::get().reads(1 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(1 as u64))
|
||||
}
|
||||
// Storage: Preimage StatusFor (r:1 w:1)
|
||||
fn request_requested_preimage() -> Weight {
|
||||
Weight::from_ref_time(7_745_000 as u64)
|
||||
Weight::from_ref_time(9_440_000 as u64)
|
||||
.saturating_add(RocksDbWeight::get().reads(1 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(1 as u64))
|
||||
}
|
||||
// Storage: Preimage StatusFor (r:1 w:1)
|
||||
// Storage: Preimage PreimageFor (r:0 w:1)
|
||||
fn unrequest_preimage() -> Weight {
|
||||
Weight::from_ref_time(29_758_000 as u64)
|
||||
Weight::from_ref_time(29_013_000 as u64)
|
||||
.saturating_add(RocksDbWeight::get().reads(1 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(2 as u64))
|
||||
}
|
||||
// Storage: Preimage StatusFor (r:1 w:1)
|
||||
// Storage: Preimage PreimageFor (r:0 w:1)
|
||||
fn unrequest_unnoted_preimage() -> Weight {
|
||||
Weight::from_ref_time(18_360_000 as u64)
|
||||
Weight::from_ref_time(9_223_000 as u64)
|
||||
.saturating_add(RocksDbWeight::get().reads(1 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(2 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(1 as u64))
|
||||
}
|
||||
// Storage: Preimage StatusFor (r:1 w:1)
|
||||
fn unrequest_multi_referenced_preimage() -> Weight {
|
||||
Weight::from_ref_time(7_439_000 as u64)
|
||||
Weight::from_ref_time(9_252_000 as u64)
|
||||
.saturating_add(RocksDbWeight::get().reads(1 as u64))
|
||||
.saturating_add(RocksDbWeight::get().writes(1 as u64))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user