Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Create benchmark for the system::set_code instrisic #13373

Merged
merged 33 commits into from
May 11, 2023
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
1fe4c80
Still WIP
hirschenberger Feb 13, 2023
9546674
Still WIP
hirschenberger Jan 26, 2023
fbe6aff
Add benchmark for system::set_code intrinsic
hirschenberger Feb 13, 2023
053c682
Fix format
hirschenberger Feb 13, 2023
e413564
Add missing benchmark runtime
hirschenberger Feb 13, 2023
c069a65
Fix lint warning
hirschenberger Feb 13, 2023
6406281
Consume the rest of the block and add test verification after the ben…
hirschenberger Feb 14, 2023
c480343
Rewrite set_code function
hirschenberger Feb 17, 2023
3f8b72a
Try to fix benchmarks and tests
hirschenberger Feb 18, 2023
f21ccc0
Remove weight tags
hirschenberger Feb 22, 2023
34f66a5
Update frame/system/src/tests.rs
hirschenberger Feb 22, 2023
a1f901d
Register ReadRuntimeVersionExt for benches
ggwpez Mar 11, 2023
8617622
Merge remote-tracking branch 'origin/master' into issue_13192
hirschenberger Apr 11, 2023
0317a8b
Fix tests
hirschenberger Apr 11, 2023
5bfdb2d
Fix deprecations
hirschenberger Apr 12, 2023
ee261b5
Fix deprecations
hirschenberger Apr 12, 2023
e4ab3af
Merge branch 'master' of https://github.com/paritytech/substrate into…
Apr 13, 2023
6eb79f4
".git/.scripts/commands/bench/bench.sh" pallet dev frame_system
Apr 13, 2023
6c4cd80
Merge branch 'issue_13192' of https://github.com/hirschenberger/subst…
hirschenberger Apr 14, 2023
eca7ea7
Add update info and remove obsolete complexity comments.
hirschenberger Apr 14, 2023
f0806b0
".git/.scripts/commands/fmt/fmt.sh"
Apr 17, 2023
a4b0817
Update frame/system/src/lib.rs
hirschenberger Apr 21, 2023
117434b
Update frame/system/src/lib.rs
hirschenberger Apr 21, 2023
80c6fd2
Update frame/system/src/lib.rs
hirschenberger Apr 21, 2023
400474f
Update frame/system/src/lib.rs
hirschenberger Apr 21, 2023
058c8e6
Update frame/system/benchmarking/src/lib.rs
hirschenberger Apr 21, 2023
134672f
".git/.scripts/commands/fmt/fmt.sh"
Apr 21, 2023
ec6a01f
Merge branch 'master' of https://github.com/paritytech/substrate into…
hirschenberger Apr 27, 2023
9db0abd
Merge remote-tracking branch 'origin/master' into issue_13192
hirschenberger May 8, 2023
5a3d6f9
Merge branch 'issue_13192' of https://github.com/hirschenberger/subst…
hirschenberger May 8, 2023
96f08f9
Update README.md
hirschenberger May 8, 2023
03fef0b
Update README.md
hirschenberger May 8, 2023
719d26a
Merge remote-tracking branch 'origin/master' into issue_13192
May 11, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frame/system/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ readme = "README.md"
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
cfg-if = "1.0"
codec = { package = "parity-scale-codec", version = "3.2.2", default-features = false, features = ["derive"] }
log = { version = "0.4.17", default-features = false }
scale-info = { version = "2.5.0", default-features = false, features = ["derive"] }
Expand Down
2 changes: 2 additions & 0 deletions frame/system/benchmarking/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ sp-std = { version = "5.0.0", default-features = false, path = "../../../primiti

[dev-dependencies]
sp-io = { version = "7.0.0", path = "../../../primitives/io" }
sp-externalities = { version = "0.13.0", path = "../../../primitives/externalities" }
sp-version = { version = "5.0.0", path = "../../../primitives/version" }

[features]
default = ["std"]
Expand Down
5 changes: 5 additions & 0 deletions frame/system/benchmarking/res/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
These runtimes are used for benchmarking the `set_code` intrinsic.

**Don't use them in production environments!**
hirschenberger marked this conversation as resolved.
Show resolved Hide resolved

To update the just copy the new runtime from `target/release/wbuild/kitchensink-runtime/kitchensink_runtime.compact.compressed.wasm` to here.
Binary file not shown.
9 changes: 6 additions & 3 deletions frame/system/benchmarking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,12 @@ benchmarks! {
set_heap_pages {
}: _(RawOrigin::Root, Default::default())

// `set_code` was not benchmarked because it is pretty hard to come up with a real
// Wasm runtime to test the upgrade with. But this is okay because we will make
// `set_code` take a full block anyway.
set_code {
let runtime_blob = include_bytes!("../res/kitchensink_runtime.compact.compressed.wasm");
}: _(RawOrigin::Root, runtime_blob.to_vec())
hirschenberger marked this conversation as resolved.
Show resolved Hide resolved
verify {
System::<T>::assert_last_event(frame_system::Event::<T>::CodeUpdated.into());
}

#[extra]
set_code_without_checks {
Expand Down
25 changes: 24 additions & 1 deletion frame/system/benchmarking/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#![cfg(test)]

use codec::Encode;
use sp_runtime::traits::IdentityLookup;

type AccountId = u64;
Expand Down Expand Up @@ -67,7 +68,29 @@ impl frame_system::Config for Test {

impl crate::Config for Test {}

struct MockedReadRuntimeVersion(Vec<u8>);

impl sp_core::traits::ReadRuntimeVersion for MockedReadRuntimeVersion {
fn read_runtime_version(
&self,
_wasm_code: &[u8],
_ext: &mut dyn sp_externalities::Externalities,
) -> Result<Vec<u8>, String> {
Ok(self.0.clone())
}
}

pub fn new_test_ext() -> sp_io::TestExternalities {
let t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
sp_io::TestExternalities::new(t)

let version = sp_version::RuntimeVersion {
spec_name: "spec_name".into(),
spec_version: 123,
impl_version: 456,
..Default::default()
};
let read_runtime_version = MockedReadRuntimeVersion(version.encode());
let mut ext = sp_io::TestExternalities::new(t);
ext.register_extension(sp_core::traits::ReadRuntimeVersionExt::new(read_runtime_version));
ext
}
40 changes: 25 additions & 15 deletions frame/system/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,6 @@ pub mod pallet {
impl<T: Config> Pallet<T> {
/// Make some on-chain remark.
///
/// ## Complexity
/// - `O(1)`
#[pallet::call_index(0)]
#[pallet::weight(T::SystemWeightInfo::remark(_remark.len() as u32))]
Expand All @@ -394,30 +393,34 @@ pub mod pallet {

/// Set the new runtime code.
///
/// ## Complexity
/// - `O(C + S)` where `C` length of `code` and `S` complexity of `can_set_code`
/// - 1 call to `can_set_code`: `O(S)` (calls `sp_io::misc::runtime_version` which is
/// expensive).
/// The weight of this function is dependent on the runtime, but generally this is very
/// expensive.
hirschenberger marked this conversation as resolved.
Show resolved Hide resolved
#[pallet::call_index(2)]
#[pallet::weight((T::BlockWeights::get().max_block, DispatchClass::Operational))]
#[pallet::weight((T::SystemWeightInfo::set_code(), DispatchClass::Operational))]
hirschenberger marked this conversation as resolved.
Show resolved Hide resolved
pub fn set_code(origin: OriginFor<T>, code: Vec<u8>) -> DispatchResultWithPostInfo {
ensure_root(origin)?;
Self::can_set_code(&code)?;
T::OnSetCode::set_code(code)?;
Ok(().into())
// consume the rest of the block to prevent further transactions
Ok(Some(T::BlockWeights::get().max_block).into())
}

/// Set the new runtime code without doing any checks of the given `code`.
///
/// ## Complexity
/// - `O(C)` where `C` length of `code`
/// The weight of this function is dependent on the runtime.
hirschenberger marked this conversation as resolved.
Show resolved Hide resolved
#[pallet::call_index(3)]
#[pallet::weight((T::BlockWeights::get().max_block, DispatchClass::Operational))]
#[pallet::weight((T::SystemWeightInfo::set_code(), DispatchClass::Operational))]
pub fn set_code_without_checks(
origin: OriginFor<T>,
code: Vec<u8>,
) -> DispatchResultWithPostInfo {
ensure_root(origin)?;
T::OnSetCode::set_code(code)?;
Ok(().into())
Ok(Some(T::BlockWeights::get().max_block).into())
}

/// Set some items of storage.
Expand Down Expand Up @@ -1405,7 +1408,6 @@ impl<T: Config> Pallet<T> {

/// Deposits a log and ensures it matches the block's log data.
///
hirschenberger marked this conversation as resolved.
Show resolved Hide resolved
/// ## Complexity
/// - `O(1)`
hirschenberger marked this conversation as resolved.
Show resolved Hide resolved
pub fn deposit_log(item: generic::DigestItem) {
<Digest<T>>::append(item);
Expand Down Expand Up @@ -1604,15 +1606,23 @@ impl<T: Config> Pallet<T> {
.and_then(|v| RuntimeVersion::decode(&mut &v[..]).ok())
.ok_or(Error::<T>::FailedToExtractRuntimeVersion)?;

if new_version.spec_name != current_version.spec_name {
return Err(Error::<T>::InvalidSpecName.into())
}
cfg_if::cfg_if! {
if #[cfg(all(feature = "runtime-benchmarks", not(test)))] {
// Let's ensure the compiler doesn't optimize our fetching of the runtime version away.
core::hint::black_box((new_version, current_version));
Ok(())
} else {
if new_version.spec_name != current_version.spec_name {
return Err(Error::<T>::InvalidSpecName.into())
}

if new_version.spec_version <= current_version.spec_version {
return Err(Error::<T>::SpecVersionNeedsToIncrease.into())
}
if new_version.spec_version <= current_version.spec_version {
return Err(Error::<T>::SpecVersionNeedsToIncrease.into())
}

Ok(())
Ok(())
}
}
}
}

Expand Down
7 changes: 6 additions & 1 deletion frame/system/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,12 @@ fn set_code_checks_works() {
("test", 1, 2, Err(Error::<Test>::SpecVersionNeedsToIncrease)),
("test", 1, 1, Err(Error::<Test>::SpecVersionNeedsToIncrease)),
("test2", 1, 1, Err(Error::<Test>::InvalidSpecName)),
("test", 2, 1, Ok(PostDispatchInfo::default())),
(
"test",
2,
1,
Ok(Some(<mock::Test as pallet::Config>::BlockWeights::get().max_block).into()),
),
("test", 0, 1, Err(Error::<Test>::SpecVersionNeedsToIncrease)),
("test", 1, 0, Err(Error::<Test>::SpecVersionNeedsToIncrease)),
];
Expand Down
Loading