mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-25 11:45:47 +00:00
Add Authorize Upgrade Pattern to Frame System (#2682)
Adds the `authorize_upgrade` -> `enact_authorized_upgrade` pattern to `frame-system`. This will be useful for upgrading bridged chains that are under the governance of Polkadot without passing entire runtime Wasm blobs over a bridge. Notes: - Changed `enact_authorized_upgrade` to `apply_authorized_upgrade`. Personal opinion, "apply" more accurately expresses what it's doing. Can change back if outvoted. - Remove `check_version` in favor of two extrinsics, so as to make _checked_ the default. - Left calls in `parachain-system` and marked as deprecated to prevent breaking the API. They just call into the `frame-system` functions. - Updated `frame-system` benchmarks to v2 syntax. --------- Co-authored-by: command-bot <>
This commit is contained in:
@@ -27,7 +27,7 @@
|
|||||||
//!
|
//!
|
||||||
//! Users must ensure that they register this pallet as an inherent provider.
|
//! Users must ensure that they register this pallet as an inherent provider.
|
||||||
|
|
||||||
use codec::{Decode, Encode, MaxEncodedLen};
|
use codec::{Decode, Encode};
|
||||||
use cumulus_primitives_core::{
|
use cumulus_primitives_core::{
|
||||||
relay_chain, AbridgedHostConfiguration, ChannelInfo, ChannelStatus, CollationInfo,
|
relay_chain, AbridgedHostConfiguration, ChannelInfo, ChannelStatus, CollationInfo,
|
||||||
GetChannelInfo, InboundDownwardMessage, InboundHrmpMessage, MessageSendError,
|
GetChannelInfo, InboundDownwardMessage, InboundHrmpMessage, MessageSendError,
|
||||||
@@ -50,10 +50,9 @@ use scale_info::TypeInfo;
|
|||||||
use sp_runtime::{
|
use sp_runtime::{
|
||||||
traits::{Block as BlockT, BlockNumberProvider, Hash},
|
traits::{Block as BlockT, BlockNumberProvider, Hash},
|
||||||
transaction_validity::{
|
transaction_validity::{
|
||||||
InvalidTransaction, TransactionLongevity, TransactionSource, TransactionValidity,
|
InvalidTransaction, TransactionSource, TransactionValidity, ValidTransaction,
|
||||||
ValidTransaction,
|
|
||||||
},
|
},
|
||||||
BoundedSlice, DispatchError, FixedU128, RuntimeDebug, Saturating,
|
BoundedSlice, FixedU128, RuntimeDebug, Saturating,
|
||||||
};
|
};
|
||||||
use sp_std::{cmp, collections::btree_map::BTreeMap, prelude::*};
|
use sp_std::{cmp, collections::btree_map::BTreeMap, prelude::*};
|
||||||
use xcm::latest::XcmHash;
|
use xcm::latest::XcmHash;
|
||||||
@@ -169,20 +168,6 @@ impl CheckAssociatedRelayNumber for RelayNumberMonotonicallyIncreases {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Information needed when a new runtime binary is submitted and needs to be authorized before
|
|
||||||
/// replacing the current runtime.
|
|
||||||
#[derive(Decode, Encode, Default, PartialEq, Eq, MaxEncodedLen, TypeInfo)]
|
|
||||||
#[scale_info(skip_type_params(T))]
|
|
||||||
struct CodeUpgradeAuthorization<T>
|
|
||||||
where
|
|
||||||
T: Config,
|
|
||||||
{
|
|
||||||
/// Hash of the new runtime binary.
|
|
||||||
code_hash: T::Hash,
|
|
||||||
/// Whether or not to carry out version checks.
|
|
||||||
check_version: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The max length of a DMP message.
|
/// The max length of a DMP message.
|
||||||
pub type MaxDmpMessageLenOf<T> = <<T as Config>::DmpQueue as HandleMessage>::MaxMessageLen;
|
pub type MaxDmpMessageLenOf<T> = <<T as Config>::DmpQueue as HandleMessage>::MaxMessageLen;
|
||||||
|
|
||||||
@@ -204,7 +189,7 @@ pub mod ump_constants {
|
|||||||
pub mod pallet {
|
pub mod pallet {
|
||||||
use super::*;
|
use super::*;
|
||||||
use frame_support::pallet_prelude::*;
|
use frame_support::pallet_prelude::*;
|
||||||
use frame_system::pallet_prelude::*;
|
use frame_system::{pallet_prelude::*, WeightInfo as SystemWeightInfo};
|
||||||
|
|
||||||
#[pallet::pallet]
|
#[pallet::pallet]
|
||||||
#[pallet::storage_version(migration::STORAGE_VERSION)]
|
#[pallet::storage_version(migration::STORAGE_VERSION)]
|
||||||
@@ -677,16 +662,18 @@ pub mod pallet {
|
|||||||
///
|
///
|
||||||
/// This call requires Root origin.
|
/// This call requires Root origin.
|
||||||
#[pallet::call_index(2)]
|
#[pallet::call_index(2)]
|
||||||
#[pallet::weight((1_000_000, DispatchClass::Operational))]
|
#[pallet::weight(<T as frame_system::Config>::SystemWeightInfo::authorize_upgrade())]
|
||||||
|
#[allow(deprecated)]
|
||||||
|
#[deprecated(
|
||||||
|
note = "To be removed after June 2024. Migrate to `frame_system::authorize_upgrade`."
|
||||||
|
)]
|
||||||
pub fn authorize_upgrade(
|
pub fn authorize_upgrade(
|
||||||
origin: OriginFor<T>,
|
origin: OriginFor<T>,
|
||||||
code_hash: T::Hash,
|
code_hash: T::Hash,
|
||||||
check_version: bool,
|
check_version: bool,
|
||||||
) -> DispatchResult {
|
) -> DispatchResult {
|
||||||
ensure_root(origin)?;
|
ensure_root(origin)?;
|
||||||
AuthorizedUpgrade::<T>::put(CodeUpgradeAuthorization { code_hash, check_version });
|
frame_system::Pallet::<T>::do_authorize_upgrade(code_hash, check_version);
|
||||||
|
|
||||||
Self::deposit_event(Event::UpgradeAuthorized { code_hash });
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -700,15 +687,17 @@ pub mod pallet {
|
|||||||
///
|
///
|
||||||
/// All origins are allowed.
|
/// All origins are allowed.
|
||||||
#[pallet::call_index(3)]
|
#[pallet::call_index(3)]
|
||||||
#[pallet::weight({1_000_000})]
|
#[pallet::weight(<T as frame_system::Config>::SystemWeightInfo::apply_authorized_upgrade())]
|
||||||
|
#[allow(deprecated)]
|
||||||
|
#[deprecated(
|
||||||
|
note = "To be removed after June 2024. Migrate to `frame_system::apply_authorized_upgrade`."
|
||||||
|
)]
|
||||||
pub fn enact_authorized_upgrade(
|
pub fn enact_authorized_upgrade(
|
||||||
_: OriginFor<T>,
|
_: OriginFor<T>,
|
||||||
code: Vec<u8>,
|
code: Vec<u8>,
|
||||||
) -> DispatchResultWithPostInfo {
|
) -> DispatchResultWithPostInfo {
|
||||||
Self::validate_authorized_upgrade(&code[..])?;
|
let post = frame_system::Pallet::<T>::do_apply_authorize_upgrade(code)?;
|
||||||
Self::schedule_code_upgrade(code)?;
|
Ok(post)
|
||||||
AuthorizedUpgrade::<T>::kill();
|
|
||||||
Ok(Pays::No.into())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -721,8 +710,6 @@ pub mod pallet {
|
|||||||
ValidationFunctionApplied { relay_chain_block_num: RelayChainBlockNumber },
|
ValidationFunctionApplied { relay_chain_block_num: RelayChainBlockNumber },
|
||||||
/// The relay-chain aborted the upgrade process.
|
/// The relay-chain aborted the upgrade process.
|
||||||
ValidationFunctionDiscarded,
|
ValidationFunctionDiscarded,
|
||||||
/// An upgrade has been authorized.
|
|
||||||
UpgradeAuthorized { code_hash: T::Hash },
|
|
||||||
/// Some downward messages have been received and will be processed.
|
/// Some downward messages have been received and will be processed.
|
||||||
DownwardMessagesReceived { count: u32 },
|
DownwardMessagesReceived { count: u32 },
|
||||||
/// Downward messages were processed using the given weight.
|
/// Downward messages were processed using the given weight.
|
||||||
@@ -928,10 +915,6 @@ pub mod pallet {
|
|||||||
#[pallet::storage]
|
#[pallet::storage]
|
||||||
pub(super) type ReservedDmpWeightOverride<T: Config> = StorageValue<_, Weight>;
|
pub(super) type ReservedDmpWeightOverride<T: Config> = StorageValue<_, Weight>;
|
||||||
|
|
||||||
/// The next authorized upgrade, if there is one.
|
|
||||||
#[pallet::storage]
|
|
||||||
pub(super) type AuthorizedUpgrade<T: Config> = StorageValue<_, CodeUpgradeAuthorization<T>>;
|
|
||||||
|
|
||||||
/// A custom head data that should be returned as result of `validate_block`.
|
/// A custom head data that should be returned as result of `validate_block`.
|
||||||
///
|
///
|
||||||
/// See `Pallet::set_custom_validation_head_data` for more information.
|
/// See `Pallet::set_custom_validation_head_data` for more information.
|
||||||
@@ -982,7 +965,8 @@ pub mod pallet {
|
|||||||
|
|
||||||
fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity {
|
fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity {
|
||||||
if let Call::enact_authorized_upgrade { ref code } = call {
|
if let Call::enact_authorized_upgrade { ref code } = call {
|
||||||
if let Ok(hash) = Self::validate_authorized_upgrade(code) {
|
if let Ok(hash) = frame_system::Pallet::<T>::validate_authorized_upgrade(&code[..])
|
||||||
|
{
|
||||||
return Ok(ValidTransaction {
|
return Ok(ValidTransaction {
|
||||||
priority: 100,
|
priority: 100,
|
||||||
requires: Vec::new(),
|
requires: Vec::new(),
|
||||||
@@ -1001,21 +985,6 @@ pub mod pallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Config> Pallet<T> {
|
impl<T: Config> Pallet<T> {
|
||||||
fn validate_authorized_upgrade(code: &[u8]) -> Result<T::Hash, DispatchError> {
|
|
||||||
let authorization = AuthorizedUpgrade::<T>::get().ok_or(Error::<T>::NothingAuthorized)?;
|
|
||||||
|
|
||||||
// ensure that the actual hash matches the authorized hash
|
|
||||||
let actual_hash = T::Hashing::hash(code);
|
|
||||||
ensure!(actual_hash == authorization.code_hash, Error::<T>::Unauthorized);
|
|
||||||
|
|
||||||
// check versions if required as part of the authorization
|
|
||||||
if authorization.check_version {
|
|
||||||
frame_system::Pallet::<T>::can_set_code(code)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(actual_hash)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the unincluded segment size after the given hash.
|
/// Get the unincluded segment size after the given hash.
|
||||||
///
|
///
|
||||||
/// If the unincluded segment doesn't contain the given hash, this returns the
|
/// If the unincluded segment doesn't contain the given hash, this returns the
|
||||||
@@ -1563,8 +1532,8 @@ impl<T: Config> Pallet<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Type that implements `SetCode`.
|
||||||
pub struct ParachainSetCode<T>(sp_std::marker::PhantomData<T>);
|
pub struct ParachainSetCode<T>(sp_std::marker::PhantomData<T>);
|
||||||
|
|
||||||
impl<T: Config> frame_system::SetCode<T> for ParachainSetCode<T> {
|
impl<T: Config> frame_system::SetCode<T> for ParachainSetCode<T> {
|
||||||
fn set_code(code: Vec<u8>) -> DispatchResult {
|
fn set_code(code: Vec<u8>) -> DispatchResult {
|
||||||
Pallet::<T>::schedule_code_upgrade(code)
|
Pallet::<T>::schedule_code_upgrade(code)
|
||||||
|
|||||||
@@ -1127,8 +1127,9 @@ fn upgrade_version_checks_should_work() {
|
|||||||
let new_code = vec![1, 2, 3, 4];
|
let new_code = vec![1, 2, 3, 4];
|
||||||
let new_code_hash = H256(sp_core::blake2_256(&new_code));
|
let new_code_hash = H256(sp_core::blake2_256(&new_code));
|
||||||
|
|
||||||
let _authorize =
|
#[allow(deprecated)]
|
||||||
ParachainSystem::authorize_upgrade(RawOrigin::Root.into(), new_code_hash, true);
|
let _authorize = ParachainSystem::authorize_upgrade(RawOrigin::Root.into(), new_code_hash, true);
|
||||||
|
#[allow(deprecated)]
|
||||||
let res = ParachainSystem::enact_authorized_upgrade(RawOrigin::None.into(), new_code);
|
let res = ParachainSystem::enact_authorized_upgrade(RawOrigin::None.into(), new_code);
|
||||||
|
|
||||||
assert_eq!(expected.map_err(DispatchErrorWithPostInfo::from), res);
|
assert_eq!(expected.map_err(DispatchErrorWithPostInfo::from), res);
|
||||||
|
|||||||
@@ -152,4 +152,31 @@ impl<T: frame_system::Config> frame_system::WeightInfo for WeightInfo<T> {
|
|||||||
.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into())))
|
.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into())))
|
||||||
.saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into()))
|
.saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into()))
|
||||||
}
|
}
|
||||||
|
/// Storage: `System::AuthorizedUpgrade` (r:0 w:1)
|
||||||
|
/// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`)
|
||||||
|
fn authorize_upgrade() -> Weight {
|
||||||
|
// Proof Size summary in bytes:
|
||||||
|
// Measured: `0`
|
||||||
|
// Estimated: `0`
|
||||||
|
// Minimum execution time: 33_027_000 picoseconds.
|
||||||
|
Weight::from_parts(33_027_000, 0)
|
||||||
|
.saturating_add(Weight::from_parts(0, 0))
|
||||||
|
.saturating_add(T::DbWeight::get().writes(1))
|
||||||
|
}
|
||||||
|
/// Storage: `System::AuthorizedUpgrade` (r:1 w:1)
|
||||||
|
/// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`)
|
||||||
|
/// Storage: `System::Digest` (r:1 w:1)
|
||||||
|
/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||||
|
/// Storage: UNKNOWN KEY `0x3a636f6465` (r:0 w:1)
|
||||||
|
/// Proof: UNKNOWN KEY `0x3a636f6465` (r:0 w:1)
|
||||||
|
fn apply_authorized_upgrade() -> Weight {
|
||||||
|
// Proof Size summary in bytes:
|
||||||
|
// Measured: `22`
|
||||||
|
// Estimated: `1518`
|
||||||
|
// Minimum execution time: 118_101_992_000 picoseconds.
|
||||||
|
Weight::from_parts(118_101_992_000, 0)
|
||||||
|
.saturating_add(Weight::from_parts(0, 1518))
|
||||||
|
.saturating_add(T::DbWeight::get().reads(2))
|
||||||
|
.saturating_add(T::DbWeight::get().writes(3))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,4 +151,31 @@ impl<T: frame_system::Config> frame_system::WeightInfo for WeightInfo<T> {
|
|||||||
.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into())))
|
.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into())))
|
||||||
.saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into()))
|
.saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into()))
|
||||||
}
|
}
|
||||||
|
/// Storage: `System::AuthorizedUpgrade` (r:0 w:1)
|
||||||
|
/// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`)
|
||||||
|
fn authorize_upgrade() -> Weight {
|
||||||
|
// Proof Size summary in bytes:
|
||||||
|
// Measured: `0`
|
||||||
|
// Estimated: `0`
|
||||||
|
// Minimum execution time: 33_027_000 picoseconds.
|
||||||
|
Weight::from_parts(33_027_000, 0)
|
||||||
|
.saturating_add(Weight::from_parts(0, 0))
|
||||||
|
.saturating_add(T::DbWeight::get().writes(1))
|
||||||
|
}
|
||||||
|
/// Storage: `System::AuthorizedUpgrade` (r:1 w:1)
|
||||||
|
/// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`)
|
||||||
|
/// Storage: `System::Digest` (r:1 w:1)
|
||||||
|
/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||||
|
/// Storage: UNKNOWN KEY `0x3a636f6465` (r:0 w:1)
|
||||||
|
/// Proof: UNKNOWN KEY `0x3a636f6465` (r:0 w:1)
|
||||||
|
fn apply_authorized_upgrade() -> Weight {
|
||||||
|
// Proof Size summary in bytes:
|
||||||
|
// Measured: `22`
|
||||||
|
// Estimated: `1518`
|
||||||
|
// Minimum execution time: 118_101_992_000 picoseconds.
|
||||||
|
Weight::from_parts(118_101_992_000, 0)
|
||||||
|
.saturating_add(Weight::from_parts(0, 1518))
|
||||||
|
.saturating_add(T::DbWeight::get().reads(2))
|
||||||
|
.saturating_add(T::DbWeight::get().writes(3))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,4 +151,31 @@ impl<T: frame_system::Config> frame_system::WeightInfo for WeightInfo<T> {
|
|||||||
.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into())))
|
.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into())))
|
||||||
.saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into()))
|
.saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into()))
|
||||||
}
|
}
|
||||||
|
/// Storage: `System::AuthorizedUpgrade` (r:0 w:1)
|
||||||
|
/// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`)
|
||||||
|
fn authorize_upgrade() -> Weight {
|
||||||
|
// Proof Size summary in bytes:
|
||||||
|
// Measured: `0`
|
||||||
|
// Estimated: `0`
|
||||||
|
// Minimum execution time: 33_027_000 picoseconds.
|
||||||
|
Weight::from_parts(33_027_000, 0)
|
||||||
|
.saturating_add(Weight::from_parts(0, 0))
|
||||||
|
.saturating_add(T::DbWeight::get().writes(1))
|
||||||
|
}
|
||||||
|
/// Storage: `System::AuthorizedUpgrade` (r:1 w:1)
|
||||||
|
/// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`)
|
||||||
|
/// Storage: `System::Digest` (r:1 w:1)
|
||||||
|
/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||||
|
/// Storage: UNKNOWN KEY `0x3a636f6465` (r:0 w:1)
|
||||||
|
/// Proof: UNKNOWN KEY `0x3a636f6465` (r:0 w:1)
|
||||||
|
fn apply_authorized_upgrade() -> Weight {
|
||||||
|
// Proof Size summary in bytes:
|
||||||
|
// Measured: `22`
|
||||||
|
// Estimated: `1518`
|
||||||
|
// Minimum execution time: 118_101_992_000 picoseconds.
|
||||||
|
Weight::from_parts(118_101_992_000, 0)
|
||||||
|
.saturating_add(Weight::from_parts(0, 1518))
|
||||||
|
.saturating_add(T::DbWeight::get().reads(2))
|
||||||
|
.saturating_add(T::DbWeight::get().writes(3))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+27
@@ -152,4 +152,31 @@ impl<T: frame_system::Config> frame_system::WeightInfo for WeightInfo<T> {
|
|||||||
.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into())))
|
.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into())))
|
||||||
.saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into()))
|
.saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into()))
|
||||||
}
|
}
|
||||||
|
/// Storage: `System::AuthorizedUpgrade` (r:0 w:1)
|
||||||
|
/// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`)
|
||||||
|
fn authorize_upgrade() -> Weight {
|
||||||
|
// Proof Size summary in bytes:
|
||||||
|
// Measured: `0`
|
||||||
|
// Estimated: `0`
|
||||||
|
// Minimum execution time: 33_027_000 picoseconds.
|
||||||
|
Weight::from_parts(33_027_000, 0)
|
||||||
|
.saturating_add(Weight::from_parts(0, 0))
|
||||||
|
.saturating_add(T::DbWeight::get().writes(1))
|
||||||
|
}
|
||||||
|
/// Storage: `System::AuthorizedUpgrade` (r:1 w:1)
|
||||||
|
/// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`)
|
||||||
|
/// Storage: `System::Digest` (r:1 w:1)
|
||||||
|
/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||||
|
/// Storage: UNKNOWN KEY `0x3a636f6465` (r:0 w:1)
|
||||||
|
/// Proof: UNKNOWN KEY `0x3a636f6465` (r:0 w:1)
|
||||||
|
fn apply_authorized_upgrade() -> Weight {
|
||||||
|
// Proof Size summary in bytes:
|
||||||
|
// Measured: `22`
|
||||||
|
// Estimated: `1518`
|
||||||
|
// Minimum execution time: 118_101_992_000 picoseconds.
|
||||||
|
Weight::from_parts(118_101_992_000, 0)
|
||||||
|
.saturating_add(Weight::from_parts(0, 1518))
|
||||||
|
.saturating_add(T::DbWeight::get().reads(2))
|
||||||
|
.saturating_add(T::DbWeight::get().writes(3))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+27
@@ -151,4 +151,31 @@ impl<T: frame_system::Config> frame_system::WeightInfo for WeightInfo<T> {
|
|||||||
.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into())))
|
.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into())))
|
||||||
.saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into()))
|
.saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into()))
|
||||||
}
|
}
|
||||||
|
/// Storage: `System::AuthorizedUpgrade` (r:0 w:1)
|
||||||
|
/// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`)
|
||||||
|
fn authorize_upgrade() -> Weight {
|
||||||
|
// Proof Size summary in bytes:
|
||||||
|
// Measured: `0`
|
||||||
|
// Estimated: `0`
|
||||||
|
// Minimum execution time: 33_027_000 picoseconds.
|
||||||
|
Weight::from_parts(33_027_000, 0)
|
||||||
|
.saturating_add(Weight::from_parts(0, 0))
|
||||||
|
.saturating_add(T::DbWeight::get().writes(1))
|
||||||
|
}
|
||||||
|
/// Storage: `System::AuthorizedUpgrade` (r:1 w:1)
|
||||||
|
/// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`)
|
||||||
|
/// Storage: `System::Digest` (r:1 w:1)
|
||||||
|
/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||||
|
/// Storage: UNKNOWN KEY `0x3a636f6465` (r:0 w:1)
|
||||||
|
/// Proof: UNKNOWN KEY `0x3a636f6465` (r:0 w:1)
|
||||||
|
fn apply_authorized_upgrade() -> Weight {
|
||||||
|
// Proof Size summary in bytes:
|
||||||
|
// Measured: `22`
|
||||||
|
// Estimated: `1518`
|
||||||
|
// Minimum execution time: 118_101_992_000 picoseconds.
|
||||||
|
Weight::from_parts(118_101_992_000, 0)
|
||||||
|
.saturating_add(Weight::from_parts(0, 1518))
|
||||||
|
.saturating_add(T::DbWeight::get().reads(2))
|
||||||
|
.saturating_add(T::DbWeight::get().writes(3))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,4 +150,31 @@ impl<T: frame_system::Config> frame_system::WeightInfo for WeightInfo<T> {
|
|||||||
.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into())))
|
.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into())))
|
||||||
.saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into()))
|
.saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into()))
|
||||||
}
|
}
|
||||||
|
/// Storage: `System::AuthorizedUpgrade` (r:0 w:1)
|
||||||
|
/// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`)
|
||||||
|
fn authorize_upgrade() -> Weight {
|
||||||
|
// Proof Size summary in bytes:
|
||||||
|
// Measured: `0`
|
||||||
|
// Estimated: `0`
|
||||||
|
// Minimum execution time: 33_027_000 picoseconds.
|
||||||
|
Weight::from_parts(33_027_000, 0)
|
||||||
|
.saturating_add(Weight::from_parts(0, 0))
|
||||||
|
.saturating_add(T::DbWeight::get().writes(1))
|
||||||
|
}
|
||||||
|
/// Storage: `System::AuthorizedUpgrade` (r:1 w:1)
|
||||||
|
/// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`)
|
||||||
|
/// Storage: `System::Digest` (r:1 w:1)
|
||||||
|
/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||||
|
/// Storage: UNKNOWN KEY `0x3a636f6465` (r:0 w:1)
|
||||||
|
/// Proof: UNKNOWN KEY `0x3a636f6465` (r:0 w:1)
|
||||||
|
fn apply_authorized_upgrade() -> Weight {
|
||||||
|
// Proof Size summary in bytes:
|
||||||
|
// Measured: `22`
|
||||||
|
// Estimated: `1518`
|
||||||
|
// Minimum execution time: 118_101_992_000 picoseconds.
|
||||||
|
Weight::from_parts(118_101_992_000, 0)
|
||||||
|
.saturating_add(Weight::from_parts(0, 1518))
|
||||||
|
.saturating_add(T::DbWeight::get().reads(2))
|
||||||
|
.saturating_add(T::DbWeight::get().writes(3))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,4 +141,31 @@ impl<T: frame_system::Config> frame_system::WeightInfo for WeightInfo<T> {
|
|||||||
.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into())))
|
.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into())))
|
||||||
.saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into()))
|
.saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into()))
|
||||||
}
|
}
|
||||||
|
/// Storage: `System::AuthorizedUpgrade` (r:0 w:1)
|
||||||
|
/// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`)
|
||||||
|
fn authorize_upgrade() -> Weight {
|
||||||
|
// Proof Size summary in bytes:
|
||||||
|
// Measured: `0`
|
||||||
|
// Estimated: `0`
|
||||||
|
// Minimum execution time: 33_027_000 picoseconds.
|
||||||
|
Weight::from_parts(33_027_000, 0)
|
||||||
|
.saturating_add(Weight::from_parts(0, 0))
|
||||||
|
.saturating_add(T::DbWeight::get().writes(1))
|
||||||
|
}
|
||||||
|
/// Storage: `System::AuthorizedUpgrade` (r:1 w:1)
|
||||||
|
/// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`)
|
||||||
|
/// Storage: `System::Digest` (r:1 w:1)
|
||||||
|
/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||||
|
/// Storage: UNKNOWN KEY `0x3a636f6465` (r:0 w:1)
|
||||||
|
/// Proof: UNKNOWN KEY `0x3a636f6465` (r:0 w:1)
|
||||||
|
fn apply_authorized_upgrade() -> Weight {
|
||||||
|
// Proof Size summary in bytes:
|
||||||
|
// Measured: `22`
|
||||||
|
// Estimated: `1518`
|
||||||
|
// Minimum execution time: 118_101_992_000 picoseconds.
|
||||||
|
Weight::from_parts(118_101_992_000, 0)
|
||||||
|
.saturating_add(Weight::from_parts(0, 1518))
|
||||||
|
.saturating_add(T::DbWeight::get().reads(2))
|
||||||
|
.saturating_add(T::DbWeight::get().writes(3))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,4 +144,31 @@ impl<T: frame_system::Config> frame_system::WeightInfo for WeightInfo<T> {
|
|||||||
.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into())))
|
.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into())))
|
||||||
.saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into()))
|
.saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into()))
|
||||||
}
|
}
|
||||||
|
/// Storage: `System::AuthorizedUpgrade` (r:0 w:1)
|
||||||
|
/// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`)
|
||||||
|
fn authorize_upgrade() -> Weight {
|
||||||
|
// Proof Size summary in bytes:
|
||||||
|
// Measured: `0`
|
||||||
|
// Estimated: `0`
|
||||||
|
// Minimum execution time: 33_027_000 picoseconds.
|
||||||
|
Weight::from_parts(33_027_000, 0)
|
||||||
|
.saturating_add(Weight::from_parts(0, 0))
|
||||||
|
.saturating_add(T::DbWeight::get().writes(1))
|
||||||
|
}
|
||||||
|
/// Storage: `System::AuthorizedUpgrade` (r:1 w:1)
|
||||||
|
/// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`)
|
||||||
|
/// Storage: `System::Digest` (r:1 w:1)
|
||||||
|
/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||||
|
/// Storage: UNKNOWN KEY `0x3a636f6465` (r:0 w:1)
|
||||||
|
/// Proof: UNKNOWN KEY `0x3a636f6465` (r:0 w:1)
|
||||||
|
fn apply_authorized_upgrade() -> Weight {
|
||||||
|
// Proof Size summary in bytes:
|
||||||
|
// Measured: `22`
|
||||||
|
// Estimated: `1518`
|
||||||
|
// Minimum execution time: 118_101_992_000 picoseconds.
|
||||||
|
Weight::from_parts(118_101_992_000, 0)
|
||||||
|
.saturating_add(Weight::from_parts(0, 1518))
|
||||||
|
.saturating_add(T::DbWeight::get().reads(2))
|
||||||
|
.saturating_add(T::DbWeight::get().writes(3))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0
|
||||||
|
# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json
|
||||||
|
|
||||||
|
title: "Add Authorize Upgrade Pattern to Frame System"
|
||||||
|
|
||||||
|
doc:
|
||||||
|
- audience: Runtime User
|
||||||
|
description: |
|
||||||
|
Adds the `authorize_upgrade` -> `enact_authorized_upgrade` pattern to `frame-system`. This
|
||||||
|
will be useful for upgrading bridged chains that are under the governance of Polkadot without
|
||||||
|
passing entire runtime Wasm blobs over a bridge.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
- Changed `enact_authorized_upgrade` to `apply_authorized_upgrade`.
|
||||||
|
- Left calls in `parachain-system` and marked as deprecated to prevent breaking the API. They
|
||||||
|
just call into the `frame-system` functions.
|
||||||
|
- Deprecated calls will be removed no earlier than June 2024.
|
||||||
|
- Updated `frame-system` benchmarks to v2 syntax.
|
||||||
|
|
||||||
|
crates: [ ]
|
||||||
@@ -94,6 +94,8 @@ fn module_error_outer_enum_expand_explicit() {
|
|||||||
frame_system::Error::InvalidTask => (),
|
frame_system::Error::InvalidTask => (),
|
||||||
#[cfg(feature = "experimental")]
|
#[cfg(feature = "experimental")]
|
||||||
frame_system::Error::FailedTask => (),
|
frame_system::Error::FailedTask => (),
|
||||||
|
frame_system::Error::NothingAuthorized => (),
|
||||||
|
frame_system::Error::Unauthorized => (),
|
||||||
frame_system::Error::__Ignore(_, _) => (),
|
frame_system::Error::__Ignore(_, _) => (),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -94,6 +94,8 @@ fn module_error_outer_enum_expand_implicit() {
|
|||||||
frame_system::Error::InvalidTask => (),
|
frame_system::Error::InvalidTask => (),
|
||||||
#[cfg(feature = "experimental")]
|
#[cfg(feature = "experimental")]
|
||||||
frame_system::Error::FailedTask => (),
|
frame_system::Error::FailedTask => (),
|
||||||
|
frame_system::Error::NothingAuthorized => (),
|
||||||
|
frame_system::Error::Unauthorized => (),
|
||||||
frame_system::Error::__Ignore(_, _) => (),
|
frame_system::Error::__Ignore(_, _) => (),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -21,10 +21,7 @@
|
|||||||
#![cfg(feature = "runtime-benchmarks")]
|
#![cfg(feature = "runtime-benchmarks")]
|
||||||
|
|
||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
use frame_benchmarking::{
|
use frame_benchmarking::{impl_benchmark_test_suite, v2::*};
|
||||||
v1::{benchmarks, whitelisted_caller},
|
|
||||||
BenchmarkError,
|
|
||||||
};
|
|
||||||
use frame_support::{dispatch::DispatchClass, storage, traits::Get};
|
use frame_support::{dispatch::DispatchClass, storage, traits::Get};
|
||||||
use frame_system::{Call, Pallet as System, RawOrigin};
|
use frame_system::{Call, Pallet as System, RawOrigin};
|
||||||
use sp_core::storage::well_known_keys;
|
use sp_core::storage::well_known_keys;
|
||||||
@@ -55,69 +52,104 @@ pub trait Config: frame_system::Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
benchmarks! {
|
#[benchmarks]
|
||||||
remark {
|
mod benchmarks {
|
||||||
let b in 0 .. *T::BlockLength::get().max.get(DispatchClass::Normal) as u32;
|
use super::*;
|
||||||
|
|
||||||
|
#[benchmark]
|
||||||
|
fn remark(
|
||||||
|
b: Linear<0, { *T::BlockLength::get().max.get(DispatchClass::Normal) as u32 }>,
|
||||||
|
) -> Result<(), BenchmarkError> {
|
||||||
let remark_message = vec![1; b as usize];
|
let remark_message = vec![1; b as usize];
|
||||||
let caller = whitelisted_caller();
|
let caller = whitelisted_caller();
|
||||||
}: _(RawOrigin::Signed(caller), remark_message)
|
|
||||||
|
|
||||||
remark_with_event {
|
#[extrinsic_call]
|
||||||
let b in 0 .. *T::BlockLength::get().max.get(DispatchClass::Normal) as u32;
|
remark(RawOrigin::Signed(caller), remark_message);
|
||||||
let remark_message = vec![1; b as usize];
|
|
||||||
let caller = whitelisted_caller();
|
|
||||||
}: _(RawOrigin::Signed(caller), remark_message)
|
|
||||||
|
|
||||||
set_heap_pages {
|
Ok(())
|
||||||
}: _(RawOrigin::Root, Default::default())
|
|
||||||
|
|
||||||
set_code {
|
|
||||||
let runtime_blob = T::prepare_set_code_data();
|
|
||||||
T::setup_set_code_requirements(&runtime_blob)?;
|
|
||||||
}: _(RawOrigin::Root, runtime_blob)
|
|
||||||
verify {
|
|
||||||
T::verify_set_code()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[extra]
|
#[benchmark]
|
||||||
set_code_without_checks {
|
fn remark_with_event(
|
||||||
|
b: Linear<0, { *T::BlockLength::get().max.get(DispatchClass::Normal) as u32 }>,
|
||||||
|
) -> Result<(), BenchmarkError> {
|
||||||
|
let remark_message = vec![1; b as usize];
|
||||||
|
let caller: T::AccountId = whitelisted_caller();
|
||||||
|
let hash = T::Hashing::hash(&remark_message[..]);
|
||||||
|
|
||||||
|
#[extrinsic_call]
|
||||||
|
remark_with_event(RawOrigin::Signed(caller.clone()), remark_message);
|
||||||
|
|
||||||
|
System::<T>::assert_last_event(
|
||||||
|
frame_system::Event::<T>::Remarked { sender: caller, hash }.into(),
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[benchmark]
|
||||||
|
fn set_heap_pages() -> Result<(), BenchmarkError> {
|
||||||
|
#[extrinsic_call]
|
||||||
|
set_heap_pages(RawOrigin::Root, Default::default());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[benchmark]
|
||||||
|
fn set_code() -> Result<(), BenchmarkError> {
|
||||||
|
let runtime_blob = T::prepare_set_code_data();
|
||||||
|
T::setup_set_code_requirements(&runtime_blob)?;
|
||||||
|
|
||||||
|
#[extrinsic_call]
|
||||||
|
set_code(RawOrigin::Root, runtime_blob);
|
||||||
|
|
||||||
|
T::verify_set_code();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[benchmark(extra)]
|
||||||
|
fn set_code_without_checks() -> Result<(), BenchmarkError> {
|
||||||
// Assume Wasm ~4MB
|
// Assume Wasm ~4MB
|
||||||
let code = vec![1; 4_000_000 as usize];
|
let code = vec![1; 4_000_000 as usize];
|
||||||
T::setup_set_code_requirements(&code)?;
|
T::setup_set_code_requirements(&code)?;
|
||||||
}: _(RawOrigin::Root, code)
|
|
||||||
verify {
|
#[block]
|
||||||
let current_code = storage::unhashed::get_raw(well_known_keys::CODE).ok_or("Code not stored.")?;
|
{
|
||||||
|
System::<T>::set_code_without_checks(RawOrigin::Root.into(), code)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let current_code =
|
||||||
|
storage::unhashed::get_raw(well_known_keys::CODE).ok_or("Code not stored.")?;
|
||||||
assert_eq!(current_code.len(), 4_000_000 as usize);
|
assert_eq!(current_code.len(), 4_000_000 as usize);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[skip_meta]
|
#[benchmark(skip_meta)]
|
||||||
set_storage {
|
fn set_storage(i: Linear<0, { 1_000 }>) -> Result<(), BenchmarkError> {
|
||||||
let i in 0 .. 1000;
|
|
||||||
|
|
||||||
// Set up i items to add
|
// Set up i items to add
|
||||||
let mut items = Vec::new();
|
let mut items = Vec::new();
|
||||||
for j in 0 .. i {
|
for j in 0..i {
|
||||||
let hash = (i, j).using_encoded(T::Hashing::hash).as_ref().to_vec();
|
let hash = (i, j).using_encoded(T::Hashing::hash).as_ref().to_vec();
|
||||||
items.push((hash.clone(), hash.clone()));
|
items.push((hash.clone(), hash.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let items_to_verify = items.clone();
|
let items_to_verify = items.clone();
|
||||||
}: _(RawOrigin::Root, items)
|
|
||||||
verify {
|
#[extrinsic_call]
|
||||||
|
set_storage(RawOrigin::Root, items);
|
||||||
|
|
||||||
// Verify that they're actually in the storage.
|
// Verify that they're actually in the storage.
|
||||||
for (item, _) in items_to_verify {
|
for (item, _) in items_to_verify {
|
||||||
let value = storage::unhashed::get_raw(&item).ok_or("No value stored")?;
|
let value = storage::unhashed::get_raw(&item).ok_or("No value stored")?;
|
||||||
assert_eq!(value, *item);
|
assert_eq!(value, *item);
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[skip_meta]
|
#[benchmark(skip_meta)]
|
||||||
kill_storage {
|
fn kill_storage(i: Linear<0, { 1_000 }>) -> Result<(), BenchmarkError> {
|
||||||
let i in 0 .. 1000;
|
|
||||||
|
|
||||||
// Add i items to storage
|
// Add i items to storage
|
||||||
let mut items = Vec::with_capacity(i as usize);
|
let mut items = Vec::with_capacity(i as usize);
|
||||||
for j in 0 .. i {
|
for j in 0..i {
|
||||||
let hash = (i, j).using_encoded(T::Hashing::hash).as_ref().to_vec();
|
let hash = (i, j).using_encoded(T::Hashing::hash).as_ref().to_vec();
|
||||||
storage::unhashed::put_raw(&hash, &hash);
|
storage::unhashed::put_raw(&hash, &hash);
|
||||||
items.push(hash);
|
items.push(hash);
|
||||||
@@ -130,22 +162,23 @@ benchmarks! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let items_to_verify = items.clone();
|
let items_to_verify = items.clone();
|
||||||
}: _(RawOrigin::Root, items)
|
|
||||||
verify {
|
#[extrinsic_call]
|
||||||
|
kill_storage(RawOrigin::Root, items);
|
||||||
|
|
||||||
// Verify that they're not in the storage anymore.
|
// Verify that they're not in the storage anymore.
|
||||||
for item in items_to_verify {
|
for item in items_to_verify {
|
||||||
assert!(storage::unhashed::get_raw(&item).is_none());
|
assert!(storage::unhashed::get_raw(&item).is_none());
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[skip_meta]
|
#[benchmark(skip_meta)]
|
||||||
kill_prefix {
|
fn kill_prefix(p: Linear<0, { 1_000 }>) -> Result<(), BenchmarkError> {
|
||||||
let p in 0 .. 1000;
|
|
||||||
|
|
||||||
let prefix = p.using_encoded(T::Hashing::hash).as_ref().to_vec();
|
let prefix = p.using_encoded(T::Hashing::hash).as_ref().to_vec();
|
||||||
let mut items = Vec::with_capacity(p as usize);
|
let mut items = Vec::with_capacity(p as usize);
|
||||||
// add p items that share a prefix
|
// add p items that share a prefix
|
||||||
for i in 0 .. p {
|
for i in 0..p {
|
||||||
let hash = (p, i).using_encoded(T::Hashing::hash).as_ref().to_vec();
|
let hash = (p, i).using_encoded(T::Hashing::hash).as_ref().to_vec();
|
||||||
let key = [&prefix[..], &hash[..]].concat();
|
let key = [&prefix[..], &hash[..]].concat();
|
||||||
storage::unhashed::put_raw(&key, &key);
|
storage::unhashed::put_raw(&key, &key);
|
||||||
@@ -157,12 +190,45 @@ benchmarks! {
|
|||||||
let value = storage::unhashed::get_raw(item).ok_or("No value stored")?;
|
let value = storage::unhashed::get_raw(item).ok_or("No value stored")?;
|
||||||
assert_eq!(value, *item);
|
assert_eq!(value, *item);
|
||||||
}
|
}
|
||||||
}: _(RawOrigin::Root, prefix, p)
|
|
||||||
verify {
|
#[extrinsic_call]
|
||||||
|
kill_prefix(RawOrigin::Root, prefix, p);
|
||||||
|
|
||||||
// Verify that they're not in the storage anymore.
|
// Verify that they're not in the storage anymore.
|
||||||
for item in items {
|
for item in items {
|
||||||
assert!(storage::unhashed::get_raw(&item).is_none());
|
assert!(storage::unhashed::get_raw(&item).is_none());
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[benchmark]
|
||||||
|
fn authorize_upgrade() -> Result<(), BenchmarkError> {
|
||||||
|
let runtime_blob = T::prepare_set_code_data();
|
||||||
|
T::setup_set_code_requirements(&runtime_blob)?;
|
||||||
|
let hash = T::Hashing::hash(&runtime_blob);
|
||||||
|
|
||||||
|
#[extrinsic_call]
|
||||||
|
authorize_upgrade(RawOrigin::Root, hash);
|
||||||
|
|
||||||
|
assert!(System::<T>::authorized_upgrade().is_some());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[benchmark]
|
||||||
|
fn apply_authorized_upgrade() -> Result<(), BenchmarkError> {
|
||||||
|
let runtime_blob = T::prepare_set_code_data();
|
||||||
|
T::setup_set_code_requirements(&runtime_blob)?;
|
||||||
|
let hash = T::Hashing::hash(&runtime_blob);
|
||||||
|
// Will be heavier when it needs to do verification (i.e. don't use `...without_checks`).
|
||||||
|
System::<T>::authorize_upgrade(RawOrigin::Root.into(), hash)?;
|
||||||
|
|
||||||
|
#[extrinsic_call]
|
||||||
|
apply_authorized_upgrade(RawOrigin::Root, runtime_blob);
|
||||||
|
|
||||||
|
// Can't check for `CodeUpdated` in parachain upgrades. Just check that the authorization is
|
||||||
|
// gone.
|
||||||
|
assert!(System::<T>::authorized_upgrade().is_none());
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test);
|
impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test);
|
||||||
|
|||||||
@@ -17,27 +17,60 @@
|
|||||||
|
|
||||||
//! # System Pallet
|
//! # System Pallet
|
||||||
//!
|
//!
|
||||||
//! The System pallet provides low-level access to core types and cross-cutting utilities.
|
//! The System pallet provides low-level access to core types and cross-cutting utilities. It acts
|
||||||
//! It acts as the base layer for other pallets to interact with the Substrate framework components.
|
//! as the base layer for other pallets to interact with the Substrate framework components.
|
||||||
//!
|
//!
|
||||||
//! - [`Config`]
|
//! - [`Config`]
|
||||||
//!
|
//!
|
||||||
//! ## Overview
|
//! ## Overview
|
||||||
//!
|
//!
|
||||||
//! The System pallet defines the core data types used in a Substrate runtime.
|
//! The System pallet defines the core data types used in a Substrate runtime. It also provides
|
||||||
//! It also provides several utility functions (see [`Pallet`]) for other FRAME pallets.
|
//! several utility functions (see [`Pallet`]) for other FRAME pallets.
|
||||||
//!
|
//!
|
||||||
//! In addition, it manages the storage items for extrinsics data, indexes, event records, and
|
//! In addition, it manages the storage items for extrinsic data, indices, event records, and digest
|
||||||
//! digest items, among other things that support the execution of the current block.
|
//! items, among other things that support the execution of the current block.
|
||||||
//!
|
//!
|
||||||
//! It also handles low-level tasks like depositing logs, basic set up and take down of
|
//! It also handles low-level tasks like depositing logs, basic set up and take down of temporary
|
||||||
//! temporary storage entries, and access to previous block hashes.
|
//! storage entries, and access to previous block hashes.
|
||||||
//!
|
//!
|
||||||
//! ## Interface
|
//! ## Interface
|
||||||
//!
|
//!
|
||||||
//! ### Dispatchable Functions
|
//! ### Dispatchable Functions
|
||||||
//!
|
//!
|
||||||
//! The System pallet does not implement any dispatchable functions.
|
//! The System pallet provides dispatchable functions that, with the exception of `remark`, manage
|
||||||
|
//! low-level or privileged functionality of a Substrate-based runtime.
|
||||||
|
//!
|
||||||
|
//! - `remark`: Make some on-chain remark.
|
||||||
|
//! - `set_heap_pages`: Set the number of pages in the WebAssembly environment's heap.
|
||||||
|
//! - `set_code`: Set the new runtime code.
|
||||||
|
//! - `set_code_without_checks`: Set the new runtime code without any checks.
|
||||||
|
//! - `set_storage`: Set some items of storage.
|
||||||
|
//! - `kill_storage`: Kill some items from storage.
|
||||||
|
//! - `kill_prefix`: Kill all storage items with a key that starts with the given prefix.
|
||||||
|
//! - `remark_with_event`: Make some on-chain remark and emit an event.
|
||||||
|
//! - `do_task`: Do some specified task.
|
||||||
|
//! - `authorize_upgrade`: Authorize new runtime code.
|
||||||
|
//! - `authorize_upgrade_without_checks`: Authorize new runtime code and an upgrade sans
|
||||||
|
//! verification.
|
||||||
|
//! - `apply_authorized_upgrade`: Provide new, already-authorized runtime code.
|
||||||
|
//!
|
||||||
|
//! #### A Note on Upgrades
|
||||||
|
//!
|
||||||
|
//! The pallet provides two primary means of upgrading the runtime, a single-phase means using
|
||||||
|
//! `set_code` and a two-phase means using `authorize_upgrade` followed by
|
||||||
|
//! `apply_authorized_upgrade`. The first will directly attempt to apply the provided `code`
|
||||||
|
//! (application may have to be scheduled, depending on the context and implementation of the
|
||||||
|
//! `OnSetCode` trait).
|
||||||
|
//!
|
||||||
|
//! The `authorize_upgrade` route allows the authorization of a runtime's code hash. Once
|
||||||
|
//! authorized, anyone may upload the correct runtime to apply the code. This pattern is useful when
|
||||||
|
//! providing the runtime ahead of time may be unwieldy, for example when a large preimage (the
|
||||||
|
//! code) would need to be stored on-chain or sent over a message transport protocol such as a
|
||||||
|
//! bridge.
|
||||||
|
//!
|
||||||
|
//! The `*_without_checks` variants do not perform any version checks, so using them runs the risk
|
||||||
|
//! of applying a downgrade or entirely other chain specification. They will still validate that the
|
||||||
|
//! `code` meets the authorized hash.
|
||||||
//!
|
//!
|
||||||
//! ### Public Functions
|
//! ### Public Functions
|
||||||
//!
|
//!
|
||||||
@@ -59,7 +92,7 @@
|
|||||||
//! - [`CheckTxVersion`]: Checks that the transaction version is the same as the one used to sign
|
//! - [`CheckTxVersion`]: Checks that the transaction version is the same as the one used to sign
|
||||||
//! the transaction.
|
//! the transaction.
|
||||||
//!
|
//!
|
||||||
//! Lookup the runtime aggregator file (e.g. `node/runtime`) to see the full list of signed
|
//! Look up the runtime aggregator file (e.g. `node/runtime`) to see the full list of signed
|
||||||
//! extensions included in a chain.
|
//! extensions included in a chain.
|
||||||
|
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
@@ -77,6 +110,10 @@ use sp_runtime::{
|
|||||||
Hash, Header, Lookup, LookupError, MaybeDisplay, MaybeSerializeDeserialize, Member, One,
|
Hash, Header, Lookup, LookupError, MaybeDisplay, MaybeSerializeDeserialize, Member, One,
|
||||||
Saturating, SimpleBitOps, StaticLookup, Zero,
|
Saturating, SimpleBitOps, StaticLookup, Zero,
|
||||||
},
|
},
|
||||||
|
transaction_validity::{
|
||||||
|
InvalidTransaction, TransactionLongevity, TransactionSource, TransactionValidity,
|
||||||
|
ValidTransaction,
|
||||||
|
},
|
||||||
DispatchError, RuntimeDebug,
|
DispatchError, RuntimeDebug,
|
||||||
};
|
};
|
||||||
#[cfg(any(feature = "std", test))]
|
#[cfg(any(feature = "std", test))]
|
||||||
@@ -90,9 +127,10 @@ use frame_support::traits::BuildGenesisConfig;
|
|||||||
use frame_support::{
|
use frame_support::{
|
||||||
dispatch::{
|
dispatch::{
|
||||||
extract_actual_pays_fee, extract_actual_weight, DispatchClass, DispatchInfo,
|
extract_actual_pays_fee, extract_actual_weight, DispatchClass, DispatchInfo,
|
||||||
DispatchResult, DispatchResultWithPostInfo, PerDispatchClass,
|
DispatchResult, DispatchResultWithPostInfo, PerDispatchClass, PostDispatchInfo,
|
||||||
},
|
},
|
||||||
impl_ensure_origin_with_arg_ignoring_arg,
|
ensure, impl_ensure_origin_with_arg_ignoring_arg,
|
||||||
|
pallet_prelude::Pays,
|
||||||
storage::{self, StorageStreamIter},
|
storage::{self, StorageStreamIter},
|
||||||
traits::{
|
traits::{
|
||||||
ConstU32, Contains, EnsureOrigin, EnsureOriginWithArg, Get, HandleLifetime,
|
ConstU32, Contains, EnsureOrigin, EnsureOriginWithArg, Get, HandleLifetime,
|
||||||
@@ -198,6 +236,20 @@ impl<MaxNormal: Get<u32>, MaxOverflow: Get<u32>> ConsumerLimits for (MaxNormal,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Information needed when a new runtime binary is submitted and needs to be authorized before
|
||||||
|
/// replacing the current runtime.
|
||||||
|
#[derive(Decode, Encode, Default, PartialEq, Eq, MaxEncodedLen, TypeInfo)]
|
||||||
|
#[scale_info(skip_type_params(T))]
|
||||||
|
pub struct CodeUpgradeAuthorization<T>
|
||||||
|
where
|
||||||
|
T: Config,
|
||||||
|
{
|
||||||
|
/// Hash of the new runtime binary.
|
||||||
|
code_hash: T::Hash,
|
||||||
|
/// Whether or not to carry out version checks.
|
||||||
|
check_version: bool,
|
||||||
|
}
|
||||||
|
|
||||||
#[frame_support::pallet]
|
#[frame_support::pallet]
|
||||||
pub mod pallet {
|
pub mod pallet {
|
||||||
use crate::{self as frame_system, pallet_prelude::*, *};
|
use crate::{self as frame_system, pallet_prelude::*, *};
|
||||||
@@ -661,6 +713,56 @@ pub mod pallet {
|
|||||||
// Return success.
|
// Return success.
|
||||||
Ok(().into())
|
Ok(().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Authorize an upgrade to a given `code_hash` for the runtime. The runtime can be supplied
|
||||||
|
/// later.
|
||||||
|
///
|
||||||
|
/// This call requires Root origin.
|
||||||
|
#[pallet::call_index(9)]
|
||||||
|
#[pallet::weight((T::SystemWeightInfo::authorize_upgrade(), DispatchClass::Operational))]
|
||||||
|
pub fn authorize_upgrade(origin: OriginFor<T>, code_hash: T::Hash) -> DispatchResult {
|
||||||
|
ensure_root(origin)?;
|
||||||
|
Self::do_authorize_upgrade(code_hash, true);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Authorize an upgrade to a given `code_hash` for the runtime. The runtime can be supplied
|
||||||
|
/// later.
|
||||||
|
///
|
||||||
|
/// WARNING: This authorizes an upgrade that will take place without any safety checks, for
|
||||||
|
/// example that the spec name remains the same and that the version number increases. Not
|
||||||
|
/// recommended for normal use. Use `authorize_upgrade` instead.
|
||||||
|
///
|
||||||
|
/// This call requires Root origin.
|
||||||
|
#[pallet::call_index(10)]
|
||||||
|
#[pallet::weight((T::SystemWeightInfo::authorize_upgrade(), DispatchClass::Operational))]
|
||||||
|
pub fn authorize_upgrade_without_checks(
|
||||||
|
origin: OriginFor<T>,
|
||||||
|
code_hash: T::Hash,
|
||||||
|
) -> DispatchResult {
|
||||||
|
ensure_root(origin)?;
|
||||||
|
Self::do_authorize_upgrade(code_hash, false);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Provide the preimage (runtime binary) `code` for an upgrade that has been authorized.
|
||||||
|
///
|
||||||
|
/// If the authorization required a version check, this call will ensure the spec name
|
||||||
|
/// remains unchanged and that the spec version has increased.
|
||||||
|
///
|
||||||
|
/// Depending on the runtime's `OnSetCode` configuration, this function may directly apply
|
||||||
|
/// the new `code` in the same block or attempt to schedule the upgrade.
|
||||||
|
///
|
||||||
|
/// All origins are allowed.
|
||||||
|
#[pallet::call_index(11)]
|
||||||
|
#[pallet::weight((T::SystemWeightInfo::apply_authorized_upgrade(), DispatchClass::Operational))]
|
||||||
|
pub fn apply_authorized_upgrade(
|
||||||
|
_: OriginFor<T>,
|
||||||
|
code: Vec<u8>,
|
||||||
|
) -> DispatchResultWithPostInfo {
|
||||||
|
let post = Self::do_apply_authorize_upgrade(code)?;
|
||||||
|
Ok(post)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Event for the System pallet.
|
/// Event for the System pallet.
|
||||||
@@ -687,6 +789,8 @@ pub mod pallet {
|
|||||||
#[cfg(feature = "experimental")]
|
#[cfg(feature = "experimental")]
|
||||||
/// A [`Task`] failed during execution.
|
/// A [`Task`] failed during execution.
|
||||||
TaskFailed { task: T::RuntimeTask, err: DispatchError },
|
TaskFailed { task: T::RuntimeTask, err: DispatchError },
|
||||||
|
/// An upgrade was authorized.
|
||||||
|
UpgradeAuthorized { code_hash: T::Hash, check_version: bool },
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Error for the System pallet
|
/// Error for the System pallet
|
||||||
@@ -714,6 +818,10 @@ pub mod pallet {
|
|||||||
#[cfg(feature = "experimental")]
|
#[cfg(feature = "experimental")]
|
||||||
/// The specified [`Task`] failed during execution.
|
/// The specified [`Task`] failed during execution.
|
||||||
FailedTask,
|
FailedTask,
|
||||||
|
/// No upgrade authorized.
|
||||||
|
NothingAuthorized,
|
||||||
|
/// The submitted code is not authorized.
|
||||||
|
Unauthorized,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Exposed trait-generic origin type.
|
/// Exposed trait-generic origin type.
|
||||||
@@ -829,6 +937,12 @@ pub mod pallet {
|
|||||||
#[pallet::whitelist_storage]
|
#[pallet::whitelist_storage]
|
||||||
pub(super) type ExecutionPhase<T: Config> = StorageValue<_, Phase>;
|
pub(super) type ExecutionPhase<T: Config> = StorageValue<_, Phase>;
|
||||||
|
|
||||||
|
/// `Some` if a code upgrade has been authorized.
|
||||||
|
#[pallet::storage]
|
||||||
|
#[pallet::getter(fn authorized_upgrade)]
|
||||||
|
pub(super) type AuthorizedUpgrade<T: Config> =
|
||||||
|
StorageValue<_, CodeUpgradeAuthorization<T>, OptionQuery>;
|
||||||
|
|
||||||
#[derive(frame_support::DefaultNoBound)]
|
#[derive(frame_support::DefaultNoBound)]
|
||||||
#[pallet::genesis_config]
|
#[pallet::genesis_config]
|
||||||
pub struct GenesisConfig<T: Config> {
|
pub struct GenesisConfig<T: Config> {
|
||||||
@@ -848,6 +962,25 @@ pub mod pallet {
|
|||||||
sp_io::storage::set(well_known_keys::EXTRINSIC_INDEX, &0u32.encode());
|
sp_io::storage::set(well_known_keys::EXTRINSIC_INDEX, &0u32.encode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pallet::validate_unsigned]
|
||||||
|
impl<T: Config> sp_runtime::traits::ValidateUnsigned for Pallet<T> {
|
||||||
|
type Call = Call<T>;
|
||||||
|
fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity {
|
||||||
|
if let Call::apply_authorized_upgrade { ref code } = call {
|
||||||
|
if let Ok(hash) = Self::validate_authorized_upgrade(&code[..]) {
|
||||||
|
return Ok(ValidTransaction {
|
||||||
|
priority: 100,
|
||||||
|
requires: Vec::new(),
|
||||||
|
provides: vec![hash.as_ref().to_vec()],
|
||||||
|
longevity: TransactionLongevity::max_value(),
|
||||||
|
propagate: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(InvalidTransaction::Call.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Key = Vec<u8>;
|
pub type Key = Vec<u8>;
|
||||||
@@ -1872,6 +2005,41 @@ impl<T: Config> Pallet<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// To be called after any origin/privilege checks. Put the code upgrade authorization into
|
||||||
|
/// storage and emit an event. Infallible.
|
||||||
|
pub fn do_authorize_upgrade(code_hash: T::Hash, check_version: bool) {
|
||||||
|
AuthorizedUpgrade::<T>::put(CodeUpgradeAuthorization { code_hash, check_version });
|
||||||
|
Self::deposit_event(Event::UpgradeAuthorized { code_hash, check_version });
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Apply an authorized upgrade, performing any validation checks, and remove the authorization.
|
||||||
|
/// Whether or not the code is set directly depends on the `OnSetCode` configuration of the
|
||||||
|
/// runtime.
|
||||||
|
pub fn do_apply_authorize_upgrade(code: Vec<u8>) -> Result<PostDispatchInfo, DispatchError> {
|
||||||
|
Self::validate_authorized_upgrade(&code[..])?;
|
||||||
|
T::OnSetCode::set_code(code)?;
|
||||||
|
AuthorizedUpgrade::<T>::kill();
|
||||||
|
let post = PostDispatchInfo {
|
||||||
|
// consume the rest of the block to prevent further transactions
|
||||||
|
actual_weight: Some(T::BlockWeights::get().max_block),
|
||||||
|
// no fee for valid upgrade
|
||||||
|
pays_fee: Pays::No,
|
||||||
|
};
|
||||||
|
Ok(post)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check that provided `code` can be upgraded to. Namely, check that its hash matches an
|
||||||
|
/// existing authorization and that it meets the specification requirements of `can_set_code`.
|
||||||
|
pub fn validate_authorized_upgrade(code: &[u8]) -> Result<T::Hash, DispatchError> {
|
||||||
|
let authorization = AuthorizedUpgrade::<T>::get().ok_or(Error::<T>::NothingAuthorized)?;
|
||||||
|
let actual_hash = T::Hashing::hash(code);
|
||||||
|
ensure!(actual_hash == authorization.code_hash, Error::<T>::Unauthorized);
|
||||||
|
if authorization.check_version {
|
||||||
|
Self::can_set_code(code)?
|
||||||
|
}
|
||||||
|
Ok(actual_hash)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a 32 byte datum which is guaranteed to be universally unique. `entropy` is provided
|
/// Returns a 32 byte datum which is guaranteed to be universally unique. `entropy` is provided
|
||||||
|
|||||||
@@ -675,6 +675,46 @@ fn set_code_with_real_wasm_blob() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn set_code_via_authorization_works() {
|
||||||
|
let executor = substrate_test_runtime_client::new_native_or_wasm_executor();
|
||||||
|
let mut ext = new_test_ext();
|
||||||
|
ext.register_extension(sp_core::traits::ReadRuntimeVersionExt::new(executor));
|
||||||
|
ext.execute_with(|| {
|
||||||
|
System::set_block_number(1);
|
||||||
|
assert!(System::authorized_upgrade().is_none());
|
||||||
|
|
||||||
|
let runtime = substrate_test_runtime_client::runtime::wasm_binary_unwrap().to_vec();
|
||||||
|
let hash = <mock::Test as pallet::Config>::Hashing::hash(&runtime);
|
||||||
|
|
||||||
|
// Can't apply before authorization
|
||||||
|
assert_noop!(
|
||||||
|
System::apply_authorized_upgrade(RawOrigin::None.into(), runtime.clone()),
|
||||||
|
Error::<Test>::NothingAuthorized,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Can authorize
|
||||||
|
assert_ok!(System::authorize_upgrade(RawOrigin::Root.into(), hash));
|
||||||
|
System::assert_has_event(
|
||||||
|
SysEvent::UpgradeAuthorized { code_hash: hash, check_version: true }.into(),
|
||||||
|
);
|
||||||
|
assert!(System::authorized_upgrade().is_some());
|
||||||
|
|
||||||
|
// Can't be sneaky
|
||||||
|
let mut bad_runtime = substrate_test_runtime_client::runtime::wasm_binary_unwrap().to_vec();
|
||||||
|
bad_runtime.extend(b"sneaky");
|
||||||
|
assert_noop!(
|
||||||
|
System::apply_authorized_upgrade(RawOrigin::None.into(), bad_runtime),
|
||||||
|
Error::<Test>::Unauthorized,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Can apply correct runtime
|
||||||
|
assert_ok!(System::apply_authorized_upgrade(RawOrigin::None.into(), runtime));
|
||||||
|
System::assert_has_event(SysEvent::CodeUpdated.into());
|
||||||
|
assert!(System::authorized_upgrade().is_none());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn runtime_upgraded_with_set_storage() {
|
fn runtime_upgraded_with_set_storage() {
|
||||||
let executor = substrate_test_runtime_client::new_native_or_wasm_executor();
|
let executor = substrate_test_runtime_client::new_native_or_wasm_executor();
|
||||||
|
|||||||
Generated
+56
@@ -57,6 +57,8 @@ pub trait WeightInfo {
|
|||||||
fn set_storage(i: u32, ) -> Weight;
|
fn set_storage(i: u32, ) -> Weight;
|
||||||
fn kill_storage(i: u32, ) -> Weight;
|
fn kill_storage(i: u32, ) -> Weight;
|
||||||
fn kill_prefix(p: u32, ) -> Weight;
|
fn kill_prefix(p: u32, ) -> Weight;
|
||||||
|
fn authorize_upgrade() -> Weight;
|
||||||
|
fn apply_authorized_upgrade() -> Weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Weights for frame_system using the Substrate node and recommended hardware.
|
/// Weights for frame_system using the Substrate node and recommended hardware.
|
||||||
@@ -149,6 +151,33 @@ impl<T: crate::Config> WeightInfo for SubstrateWeight<T> {
|
|||||||
.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into())))
|
.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into())))
|
||||||
.saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into()))
|
.saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into()))
|
||||||
}
|
}
|
||||||
|
/// Storage: `System::AuthorizedUpgrade` (r:0 w:1)
|
||||||
|
/// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`)
|
||||||
|
fn authorize_upgrade() -> Weight {
|
||||||
|
// Proof Size summary in bytes:
|
||||||
|
// Measured: `0`
|
||||||
|
// Estimated: `0`
|
||||||
|
// Minimum execution time: 33_027_000 picoseconds.
|
||||||
|
Weight::from_parts(33_027_000, 0)
|
||||||
|
.saturating_add(Weight::from_parts(0, 0))
|
||||||
|
.saturating_add(T::DbWeight::get().writes(1))
|
||||||
|
}
|
||||||
|
/// Storage: `System::AuthorizedUpgrade` (r:1 w:1)
|
||||||
|
/// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`)
|
||||||
|
/// Storage: `System::Digest` (r:1 w:1)
|
||||||
|
/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||||
|
/// Storage: UNKNOWN KEY `0x3a636f6465` (r:0 w:1)
|
||||||
|
/// Proof: UNKNOWN KEY `0x3a636f6465` (r:0 w:1)
|
||||||
|
fn apply_authorized_upgrade() -> Weight {
|
||||||
|
// Proof Size summary in bytes:
|
||||||
|
// Measured: `22`
|
||||||
|
// Estimated: `1518`
|
||||||
|
// Minimum execution time: 118_101_992_000 picoseconds.
|
||||||
|
Weight::from_parts(118_101_992_000, 0)
|
||||||
|
.saturating_add(Weight::from_parts(0, 1518))
|
||||||
|
.saturating_add(T::DbWeight::get().reads(2))
|
||||||
|
.saturating_add(T::DbWeight::get().writes(3))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// For backwards compatibility and tests
|
// For backwards compatibility and tests
|
||||||
@@ -240,4 +269,31 @@ impl WeightInfo for () {
|
|||||||
.saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(p.into())))
|
.saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(p.into())))
|
||||||
.saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into()))
|
.saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into()))
|
||||||
}
|
}
|
||||||
|
/// Storage: `System::AuthorizedUpgrade` (r:0 w:1)
|
||||||
|
/// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`)
|
||||||
|
fn authorize_upgrade() -> Weight {
|
||||||
|
// Proof Size summary in bytes:
|
||||||
|
// Measured: `0`
|
||||||
|
// Estimated: `0`
|
||||||
|
// Minimum execution time: 33_027_000 picoseconds.
|
||||||
|
Weight::from_parts(33_027_000, 0)
|
||||||
|
.saturating_add(Weight::from_parts(0, 0))
|
||||||
|
.saturating_add(RocksDbWeight::get().writes(1))
|
||||||
|
}
|
||||||
|
/// Storage: `System::AuthorizedUpgrade` (r:1 w:1)
|
||||||
|
/// Proof: `System::AuthorizedUpgrade` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`)
|
||||||
|
/// Storage: `System::Digest` (r:1 w:1)
|
||||||
|
/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
|
||||||
|
/// Storage: UNKNOWN KEY `0x3a636f6465` (r:0 w:1)
|
||||||
|
/// Proof: UNKNOWN KEY `0x3a636f6465` (r:0 w:1)
|
||||||
|
fn apply_authorized_upgrade() -> Weight {
|
||||||
|
// Proof Size summary in bytes:
|
||||||
|
// Measured: `22`
|
||||||
|
// Estimated: `1518`
|
||||||
|
// Minimum execution time: 118_101_992_000 picoseconds.
|
||||||
|
Weight::from_parts(118_101_992_000, 0)
|
||||||
|
.saturating_add(Weight::from_parts(0, 1518))
|
||||||
|
.saturating_add(RocksDbWeight::get().reads(2))
|
||||||
|
.saturating_add(RocksDbWeight::get().writes(3))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user