Skip to content

Commit

Permalink
Preimage registrar and Scheduler integration (paritytech#10356)
Browse files Browse the repository at this point in the history
* initial idea

* more

* fix compile

* add clear and request logic

* improve some docs

* Add and implement trait

* continuing to improve

* refcount type

* infallible system preimage upload

* fmt

* fix requests

* Make it simple

* Make it simple

* Formatting

* Initial draft

* request when scheduled

* Docs

* Scheduler good

* Scheduler good

* Scheduler tests working

* Add new files

* Missing stuff

* Repotting, add weights.

* Add some tests to preimage pallet

* More tests

* Fix benchmarks

* preimage benchmarks

* All preimage benchmarks

* Tidy cargo

* Update weights.rs

* Allow hash provision in benchmarks

* Initial work on new benchmarks for Scheduler

* Tests working, refactor looks good

* Tests for new Scheduler functionality

* Use real weight, make tests work with runtimes without Preimage

* Rename

* Update benchmarks

* Formatting

* Formatting

* Fix weird formatting

* Update frame/preimage/src/lib.rs

* Fix try-runtime build

* Fixes

* Fixes

* Update frame/support/src/traits/tokens/currency.rs

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

* Update frame/support/src/traits/tokens/currency/reservable.rs

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

* Update frame/support/src/traits/tokens/imbalance.rs

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

* Update frame/preimage/src/mock.rs

Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com>

* Update frame/scheduler/src/lib.rs

Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com>

* Update frame/preimage/src/lib.rs

* Fixes

* Fixes

* Formatting

* Fixes

* Fixes

* cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_scheduler --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/scheduler/src/weights.rs --template=./.maintain/frame-weight-template.hbs

* cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_preimage --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/preimage/src/weights.rs --template=./.maintain/frame-weight-template.hbs

Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com>
Co-authored-by: Parity Bot <admin@parity.io>
  • Loading branch information
5 people authored and seunlanlege committed Dec 17, 2021
1 parent d40b4be commit 54e714b
Show file tree
Hide file tree
Showing 24 changed files with 3,593 additions and 1,288 deletions.
18 changes: 18 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 Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ members = [
"frame/nicks",
"frame/node-authorization",
"frame/offences",
"frame/preimage",
"frame/proxy",
"frame/randomness-collective-flip",
"frame/recovery",
Expand Down
4 changes: 4 additions & 0 deletions bin/node/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ pallet-mmr = { version = "4.0.0-dev", default-features = false, path = "../../..
pallet-multisig = { version = "4.0.0-dev", default-features = false, path = "../../../frame/multisig" }
pallet-offences = { version = "4.0.0-dev", default-features = false, path = "../../../frame/offences" }
pallet-offences-benchmarking = { version = "4.0.0-dev", path = "../../../frame/offences/benchmarking", default-features = false, optional = true }
pallet-preimage = { version = "4.0.0-dev", default-features = false, path = "../../../frame/preimage" }
pallet-proxy = { version = "4.0.0-dev", default-features = false, path = "../../../frame/proxy" }
pallet-randomness-collective-flip = { version = "4.0.0-dev", default-features = false, path = "../../../frame/randomness-collective-flip" }
pallet-recovery = { version = "4.0.0-dev", default-features = false, path = "../../../frame/recovery" }
Expand Down Expand Up @@ -141,6 +142,7 @@ std = [
"node-primitives/std",
"sp-offchain/std",
"pallet-offences/std",
"pallet-preimage/std",
"pallet-proxy/std",
"sp-core/std",
"pallet-randomness-collective-flip/std",
Expand Down Expand Up @@ -202,6 +204,7 @@ runtime-benchmarks = [
"pallet-membership/runtime-benchmarks",
"pallet-mmr/runtime-benchmarks",
"pallet-multisig/runtime-benchmarks",
"pallet-preimage/runtime-benchmarks",
"pallet-proxy/runtime-benchmarks",
"pallet-scheduler/runtime-benchmarks",
"pallet-society/runtime-benchmarks",
Expand Down Expand Up @@ -243,6 +246,7 @@ try-runtime = [
"pallet-identity/try-runtime",
"pallet-scheduler/try-runtime",
"pallet-offences/try-runtime",
"pallet-preimage/try-runtime",
"pallet-proxy/try-runtime",
"pallet-randomness-collective-flip/try-runtime",
"pallet-session/try-runtime",
Expand Down
32 changes: 28 additions & 4 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,8 @@ parameter_types! {
pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) *
RuntimeBlockWeights::get().max_block;
pub const MaxScheduledPerBlock: u32 = 50;
// Retry a scheduled item every 10 blocks (1 minute) until the preimage exists.
pub const NoPreimagePostponement: Option<u32> = Some(10);
}

impl pallet_scheduler::Config for Runtime {
Expand All @@ -349,6 +351,25 @@ impl pallet_scheduler::Config for Runtime {
type MaxScheduledPerBlock = MaxScheduledPerBlock;
type WeightInfo = pallet_scheduler::weights::SubstrateWeight<Runtime>;
type OriginPrivilegeCmp = EqualPrivilegeOnly;
type PreimageProvider = Preimage;
type NoPreimagePostponement = NoPreimagePostponement;
}

parameter_types! {
pub const PreimageMaxSize: u32 = 4096 * 1024;
pub const PreimageBaseDeposit: Balance = 1 * DOLLARS;
// One cent: $10,000 / MB
pub const PreimageByteDeposit: Balance = 1 * CENTS;
}

impl pallet_preimage::Config for Runtime {
type WeightInfo = pallet_preimage::weights::SubstrateWeight<Runtime>;
type Event = Event;
type Currency = Balances;
type ManagerOrigin = EnsureRoot<AccountId>;
type MaxSize = PreimageMaxSize;
type BaseDeposit = PreimageBaseDeposit;
type ByteDeposit = PreimageByteDeposit;
}

parameter_types! {
Expand Down Expand Up @@ -688,8 +709,6 @@ parameter_types! {
pub const MinimumDeposit: Balance = 100 * DOLLARS;
pub const EnactmentPeriod: BlockNumber = 30 * 24 * 60 * MINUTES;
pub const CooloffPeriod: BlockNumber = 28 * 24 * 60 * MINUTES;
// One cent: $10,000 / MB
pub const PreimageByteDeposit: Balance = 1 * CENTS;
pub const MaxVotes: u32 = 100;
pub const MaxProposals: u32 = 100;
}
Expand Down Expand Up @@ -1307,6 +1326,7 @@ construct_runtime!(
Recovery: pallet_recovery,
Vesting: pallet_vesting,
Scheduler: pallet_scheduler,
Preimage: pallet_preimage,
Proxy: pallet_proxy,
Multisig: pallet_multisig,
Bounties: pallet_bounties,
Expand Down Expand Up @@ -1686,6 +1706,7 @@ impl_runtime_apis! {
list_benchmark!(list, extra, pallet_mmr, Mmr);
list_benchmark!(list, extra, pallet_multisig, Multisig);
list_benchmark!(list, extra, pallet_offences, OffencesBench::<Runtime>);
list_benchmark!(list, extra, pallet_preimage, Preimage);
list_benchmark!(list, extra, pallet_proxy, Proxy);
list_benchmark!(list, extra, pallet_scheduler, Scheduler);
list_benchmark!(list, extra, pallet_session, SessionBench::<Runtime>);
Expand Down Expand Up @@ -1764,6 +1785,7 @@ impl_runtime_apis! {
add_benchmark!(params, batches, pallet_mmr, Mmr);
add_benchmark!(params, batches, pallet_multisig, Multisig);
add_benchmark!(params, batches, pallet_offences, OffencesBench::<Runtime>);
add_benchmark!(params, batches, pallet_preimage, Preimage);
add_benchmark!(params, batches, pallet_proxy, Proxy);
add_benchmark!(params, batches, pallet_scheduler, Scheduler);
add_benchmark!(params, batches, pallet_session, SessionBench::<Runtime>);
Expand Down Expand Up @@ -1811,11 +1833,13 @@ mod tests {

#[test]
fn call_size() {
let size = core::mem::size_of::<Call>();
assert!(
core::mem::size_of::<Call>() <= 200,
"size of Call is more than 200 bytes: some calls have too big arguments, use Box to reduce the
size <= 200,
"size of Call {} is more than 200 bytes: some calls have too big arguments, use Box to reduce the
size of Call.
If the limit is too strong, maybe consider increase the limit to 300.",
size,
);
}
}
2 changes: 2 additions & 0 deletions frame/democracy/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ impl pallet_scheduler::Config for Test {
type MaxScheduledPerBlock = ();
type WeightInfo = ();
type OriginPrivilegeCmp = EqualPrivilegeOnly;
type PreimageProvider = ();
type NoPreimagePostponement = ();
}
parameter_types! {
pub const ExistentialDeposit: u64 = 1;
Expand Down
46 changes: 46 additions & 0 deletions frame/preimage/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
[package]
name = "pallet-preimage"
version = "4.0.0-dev"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2021"
license = "Apache-2.0"
homepage = "https://substrate.io"
repository = "https://github.com/paritytech/substrate/"
description = "FRAME pallet for storing preimages of hashes"
readme = "README.md"

[dependencies]
codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive"] }
scale-info = { version = "1.0", default-features = false, features = ["derive"] }

sp-std = { version = "4.0.0", default-features = false, path = "../../primitives/std" }
sp-io = { version = "4.0.0-dev", default-features = false, path = "../../primitives/io" }
sp-core = { version = "4.1.0-dev", default-features = false, optional = true, path = "../../primitives/core" }
sp-runtime = { version = "4.0.0-dev", default-features = false, path = "../../primitives/runtime" }
frame-system = { version = "4.0.0-dev", default-features = false, path = "../system" }
frame-support = { version = "4.0.0-dev", default-features = false, path = "../support" }
frame-benchmarking = { version = "4.0.0-dev", default-features = false, path = "../benchmarking", optional = true }

[dev-dependencies]
sp-core = { version = "4.1.0-dev", path = "../../primitives/core", default-features = false }
pallet-balances = { version = "4.0.0-dev", path = "../balances" }

[features]
default = ["std"]
runtime-benchmarks = [
"frame-benchmarking",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
]
std = [
"codec/std",
"scale-info/std",
"sp-std/std",
"sp-io/std",
"sp-core/std",
"sp-runtime/std",
"frame-system/std",
"frame-support/std",
"frame-benchmarking/std",
]
try-runtime = ["frame-support/try-runtime"]
161 changes: 161 additions & 0 deletions frame/preimage/src/benchmarking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
// This file is part of Substrate.

// Copyright (C) 2020-2021 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.

//! Preimage pallet benchmarking.

use super::*;
use frame_benchmarking::{account, benchmarks, whitelist_account};
use frame_support::assert_ok;
use frame_system::RawOrigin;
use sp_runtime::traits::Bounded;
use sp_std::{prelude::*, vec};

use crate::Pallet as Preimage;

const SEED: u32 = 0;

fn funded_account<T: Config>(name: &'static str, index: u32) -> T::AccountId {
let caller: T::AccountId = account(name, index, SEED);
T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());
caller
}

fn preimage_and_hash<T: Config>() -> (Vec<u8>, T::Hash) {
sized_preimage_and_hash::<T>(T::MaxSize::get())
}

fn sized_preimage_and_hash<T: Config>(size: u32) -> (Vec<u8>, T::Hash) {
let mut preimage = vec![];
preimage.resize(size as usize, 0);
let hash = <T as frame_system::Config>::Hashing::hash(&preimage[..]);
(preimage, hash)
}

benchmarks! {
// Expensive note - will reserve.
note_preimage {
let s in 0 .. T::MaxSize::get();
let caller = funded_account::<T>("caller", 0);
whitelist_account!(caller);
let (preimage, hash) = sized_preimage_and_hash::<T>(s);
}: _(RawOrigin::Signed(caller), preimage)
verify {
assert!(Preimage::<T>::have_preimage(&hash));
}
// Cheap note - will not reserve since it was requested.
note_requested_preimage {
let s in 0 .. T::MaxSize::get();
let caller = funded_account::<T>("caller", 0);
whitelist_account!(caller);
let (preimage, hash) = sized_preimage_and_hash::<T>(s);
assert_ok!(Preimage::<T>::request_preimage(T::ManagerOrigin::successful_origin(), hash.clone()));
}: note_preimage(RawOrigin::Signed(caller), preimage)
verify {
assert!(Preimage::<T>::have_preimage(&hash));
}
// Cheap note - will not reserve since it's the manager.
note_no_deposit_preimage {
let s in 0 .. T::MaxSize::get();
let (preimage, hash) = sized_preimage_and_hash::<T>(s);
assert_ok!(Preimage::<T>::request_preimage(T::ManagerOrigin::successful_origin(), hash.clone()));
}: note_preimage<T::Origin>(T::ManagerOrigin::successful_origin(), preimage)
verify {
assert!(Preimage::<T>::have_preimage(&hash));
}

// Expensive unnote - will unreserve.
unnote_preimage {
let caller = funded_account::<T>("caller", 0);
whitelist_account!(caller);
let (preimage, hash) = preimage_and_hash::<T>();
assert_ok!(Preimage::<T>::note_preimage(RawOrigin::Signed(caller.clone()).into(), preimage));
}: _(RawOrigin::Signed(caller), hash.clone())
verify {
assert!(!Preimage::<T>::have_preimage(&hash));
}
// Cheap unnote - will not unreserve since there's no deposit held.
unnote_no_deposit_preimage {
let (preimage, hash) = preimage_and_hash::<T>();
assert_ok!(Preimage::<T>::note_preimage(T::ManagerOrigin::successful_origin(), preimage));
}: unnote_preimage<T::Origin>(T::ManagerOrigin::successful_origin(), hash.clone())
verify {
assert!(!Preimage::<T>::have_preimage(&hash));
}

// Expensive request - will unreserve the noter's deposit.
request_preimage {
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));
}: _<T::Origin>(T::ManagerOrigin::successful_origin(), hash)
verify {
assert_eq!(StatusFor::<T>::get(&hash), Some(RequestStatus::Requested(1)));
}
// Cheap request - would unreserve the deposit but none was held.
request_no_deposit_preimage {
let (preimage, hash) = preimage_and_hash::<T>();
assert_ok!(Preimage::<T>::note_preimage(T::ManagerOrigin::successful_origin(), preimage));
}: request_preimage<T::Origin>(T::ManagerOrigin::successful_origin(), hash)
verify {
assert_eq!(StatusFor::<T>::get(&hash), Some(RequestStatus::Requested(1)));
}
// Cheap request - the preimage is not yet noted, so deposit to unreserve.
request_unnoted_preimage {
let (_, hash) = preimage_and_hash::<T>();
}: request_preimage<T::Origin>(T::ManagerOrigin::successful_origin(), hash)
verify {
assert_eq!(StatusFor::<T>::get(&hash), Some(RequestStatus::Requested(1)));
}
// Cheap request - the preimage is already requested, so just a counter bump.
request_requested_preimage {
let (_, hash) = preimage_and_hash::<T>();
assert_ok!(Preimage::<T>::request_preimage(T::ManagerOrigin::successful_origin(), hash.clone()));
}: request_preimage<T::Origin>(T::ManagerOrigin::successful_origin(), hash)
verify {
assert_eq!(StatusFor::<T>::get(&hash), Some(RequestStatus::Requested(2)));
}

// Expensive unrequest - last reference and it's noted, so will destroy the preimage.
unrequest_preimage {
let (preimage, hash) = preimage_and_hash::<T>();
assert_ok!(Preimage::<T>::request_preimage(T::ManagerOrigin::successful_origin(), hash.clone()));
assert_ok!(Preimage::<T>::note_preimage(T::ManagerOrigin::successful_origin(), preimage));
}: _<T::Origin>(T::ManagerOrigin::successful_origin(), hash.clone())
verify {
assert_eq!(StatusFor::<T>::get(&hash), None);
}
// Cheap unrequest - last reference, but it's not noted.
unrequest_unnoted_preimage {
let (_, hash) = preimage_and_hash::<T>();
assert_ok!(Preimage::<T>::request_preimage(T::ManagerOrigin::successful_origin(), hash.clone()));
}: unrequest_preimage<T::Origin>(T::ManagerOrigin::successful_origin(), hash.clone())
verify {
assert_eq!(StatusFor::<T>::get(&hash), None);
}
// Cheap unrequest - not the last reference.
unrequest_multi_referenced_preimage {
let (_, hash) = preimage_and_hash::<T>();
assert_ok!(Preimage::<T>::request_preimage(T::ManagerOrigin::successful_origin(), hash.clone()));
assert_ok!(Preimage::<T>::request_preimage(T::ManagerOrigin::successful_origin(), hash.clone()));
}: unrequest_preimage<T::Origin>(T::ManagerOrigin::successful_origin(), hash.clone())
verify {
assert_eq!(StatusFor::<T>::get(&hash), Some(RequestStatus::Requested(1)));
}

impl_benchmark_test_suite!(Preimage, crate::mock::new_test_ext(), crate::mock::Test);
}
Loading

0 comments on commit 54e714b

Please sign in to comment.