Skip to content

Commit 4d24ae0

Browse files
gavofyorkshawntabrizikianenigmagui1117Parity Bot
authored
Preimage registrar and Scheduler integration (paritytech#10356)
* 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>
1 parent a991b0a commit 4d24ae0

File tree

24 files changed

+3593
-1288
lines changed

24 files changed

+3593
-1288
lines changed

Cargo.lock

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ members = [
102102
"frame/nicks",
103103
"frame/node-authorization",
104104
"frame/offences",
105+
"frame/preimage",
105106
"frame/proxy",
106107
"frame/randomness-collective-flip",
107108
"frame/recovery",

bin/node/runtime/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ pallet-mmr = { version = "4.0.0-dev", default-features = false, path = "../../..
7878
pallet-multisig = { version = "4.0.0-dev", default-features = false, path = "../../../frame/multisig" }
7979
pallet-offences = { version = "4.0.0-dev", default-features = false, path = "../../../frame/offences" }
8080
pallet-offences-benchmarking = { version = "4.0.0-dev", path = "../../../frame/offences/benchmarking", default-features = false, optional = true }
81+
pallet-preimage = { version = "4.0.0-dev", default-features = false, path = "../../../frame/preimage" }
8182
pallet-proxy = { version = "4.0.0-dev", default-features = false, path = "../../../frame/proxy" }
8283
pallet-randomness-collective-flip = { version = "4.0.0-dev", default-features = false, path = "../../../frame/randomness-collective-flip" }
8384
pallet-recovery = { version = "4.0.0-dev", default-features = false, path = "../../../frame/recovery" }
@@ -141,6 +142,7 @@ std = [
141142
"node-primitives/std",
142143
"sp-offchain/std",
143144
"pallet-offences/std",
145+
"pallet-preimage/std",
144146
"pallet-proxy/std",
145147
"sp-core/std",
146148
"pallet-randomness-collective-flip/std",
@@ -202,6 +204,7 @@ runtime-benchmarks = [
202204
"pallet-membership/runtime-benchmarks",
203205
"pallet-mmr/runtime-benchmarks",
204206
"pallet-multisig/runtime-benchmarks",
207+
"pallet-preimage/runtime-benchmarks",
205208
"pallet-proxy/runtime-benchmarks",
206209
"pallet-scheduler/runtime-benchmarks",
207210
"pallet-society/runtime-benchmarks",
@@ -243,6 +246,7 @@ try-runtime = [
243246
"pallet-identity/try-runtime",
244247
"pallet-scheduler/try-runtime",
245248
"pallet-offences/try-runtime",
249+
"pallet-preimage/try-runtime",
246250
"pallet-proxy/try-runtime",
247251
"pallet-randomness-collective-flip/try-runtime",
248252
"pallet-session/try-runtime",

bin/node/runtime/src/lib.rs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,8 @@ parameter_types! {
337337
pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) *
338338
RuntimeBlockWeights::get().max_block;
339339
pub const MaxScheduledPerBlock: u32 = 50;
340+
// Retry a scheduled item every 10 blocks (1 minute) until the preimage exists.
341+
pub const NoPreimagePostponement: Option<u32> = Some(10);
340342
}
341343

342344
impl pallet_scheduler::Config for Runtime {
@@ -349,6 +351,25 @@ impl pallet_scheduler::Config for Runtime {
349351
type MaxScheduledPerBlock = MaxScheduledPerBlock;
350352
type WeightInfo = pallet_scheduler::weights::SubstrateWeight<Runtime>;
351353
type OriginPrivilegeCmp = EqualPrivilegeOnly;
354+
type PreimageProvider = Preimage;
355+
type NoPreimagePostponement = NoPreimagePostponement;
356+
}
357+
358+
parameter_types! {
359+
pub const PreimageMaxSize: u32 = 4096 * 1024;
360+
pub const PreimageBaseDeposit: Balance = 1 * DOLLARS;
361+
// One cent: $10,000 / MB
362+
pub const PreimageByteDeposit: Balance = 1 * CENTS;
363+
}
364+
365+
impl pallet_preimage::Config for Runtime {
366+
type WeightInfo = pallet_preimage::weights::SubstrateWeight<Runtime>;
367+
type Event = Event;
368+
type Currency = Balances;
369+
type ManagerOrigin = EnsureRoot<AccountId>;
370+
type MaxSize = PreimageMaxSize;
371+
type BaseDeposit = PreimageBaseDeposit;
372+
type ByteDeposit = PreimageByteDeposit;
352373
}
353374

354375
parameter_types! {
@@ -688,8 +709,6 @@ parameter_types! {
688709
pub const MinimumDeposit: Balance = 100 * DOLLARS;
689710
pub const EnactmentPeriod: BlockNumber = 30 * 24 * 60 * MINUTES;
690711
pub const CooloffPeriod: BlockNumber = 28 * 24 * 60 * MINUTES;
691-
// One cent: $10,000 / MB
692-
pub const PreimageByteDeposit: Balance = 1 * CENTS;
693712
pub const MaxVotes: u32 = 100;
694713
pub const MaxProposals: u32 = 100;
695714
}
@@ -1307,6 +1326,7 @@ construct_runtime!(
13071326
Recovery: pallet_recovery,
13081327
Vesting: pallet_vesting,
13091328
Scheduler: pallet_scheduler,
1329+
Preimage: pallet_preimage,
13101330
Proxy: pallet_proxy,
13111331
Multisig: pallet_multisig,
13121332
Bounties: pallet_bounties,
@@ -1686,6 +1706,7 @@ impl_runtime_apis! {
16861706
list_benchmark!(list, extra, pallet_mmr, Mmr);
16871707
list_benchmark!(list, extra, pallet_multisig, Multisig);
16881708
list_benchmark!(list, extra, pallet_offences, OffencesBench::<Runtime>);
1709+
list_benchmark!(list, extra, pallet_preimage, Preimage);
16891710
list_benchmark!(list, extra, pallet_proxy, Proxy);
16901711
list_benchmark!(list, extra, pallet_scheduler, Scheduler);
16911712
list_benchmark!(list, extra, pallet_session, SessionBench::<Runtime>);
@@ -1764,6 +1785,7 @@ impl_runtime_apis! {
17641785
add_benchmark!(params, batches, pallet_mmr, Mmr);
17651786
add_benchmark!(params, batches, pallet_multisig, Multisig);
17661787
add_benchmark!(params, batches, pallet_offences, OffencesBench::<Runtime>);
1788+
add_benchmark!(params, batches, pallet_preimage, Preimage);
17671789
add_benchmark!(params, batches, pallet_proxy, Proxy);
17681790
add_benchmark!(params, batches, pallet_scheduler, Scheduler);
17691791
add_benchmark!(params, batches, pallet_session, SessionBench::<Runtime>);
@@ -1811,11 +1833,13 @@ mod tests {
18111833

18121834
#[test]
18131835
fn call_size() {
1836+
let size = core::mem::size_of::<Call>();
18141837
assert!(
1815-
core::mem::size_of::<Call>() <= 200,
1816-
"size of Call is more than 200 bytes: some calls have too big arguments, use Box to reduce the
1838+
size <= 200,
1839+
"size of Call {} is more than 200 bytes: some calls have too big arguments, use Box to reduce the
18171840
size of Call.
18181841
If the limit is too strong, maybe consider increase the limit to 300.",
1842+
size,
18191843
);
18201844
}
18211845
}

frame/democracy/src/tests.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ impl pallet_scheduler::Config for Test {
120120
type MaxScheduledPerBlock = ();
121121
type WeightInfo = ();
122122
type OriginPrivilegeCmp = EqualPrivilegeOnly;
123+
type PreimageProvider = ();
124+
type NoPreimagePostponement = ();
123125
}
124126
parameter_types! {
125127
pub const ExistentialDeposit: u64 = 1;

frame/preimage/Cargo.toml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
[package]
2+
name = "pallet-preimage"
3+
version = "4.0.0-dev"
4+
authors = ["Parity Technologies <admin@parity.io>"]
5+
edition = "2021"
6+
license = "Apache-2.0"
7+
homepage = "https://substrate.io"
8+
repository = "https://github.com/paritytech/substrate/"
9+
description = "FRAME pallet for storing preimages of hashes"
10+
readme = "README.md"
11+
12+
[dependencies]
13+
codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive"] }
14+
scale-info = { version = "1.0", default-features = false, features = ["derive"] }
15+
16+
sp-std = { version = "4.0.0", default-features = false, path = "../../primitives/std" }
17+
sp-io = { version = "4.0.0-dev", default-features = false, path = "../../primitives/io" }
18+
sp-core = { version = "4.1.0-dev", default-features = false, optional = true, path = "../../primitives/core" }
19+
sp-runtime = { version = "4.0.0-dev", default-features = false, path = "../../primitives/runtime" }
20+
frame-system = { version = "4.0.0-dev", default-features = false, path = "../system" }
21+
frame-support = { version = "4.0.0-dev", default-features = false, path = "../support" }
22+
frame-benchmarking = { version = "4.0.0-dev", default-features = false, path = "../benchmarking", optional = true }
23+
24+
[dev-dependencies]
25+
sp-core = { version = "4.1.0-dev", path = "../../primitives/core", default-features = false }
26+
pallet-balances = { version = "4.0.0-dev", path = "../balances" }
27+
28+
[features]
29+
default = ["std"]
30+
runtime-benchmarks = [
31+
"frame-benchmarking",
32+
"frame-support/runtime-benchmarks",
33+
"frame-system/runtime-benchmarks",
34+
]
35+
std = [
36+
"codec/std",
37+
"scale-info/std",
38+
"sp-std/std",
39+
"sp-io/std",
40+
"sp-core/std",
41+
"sp-runtime/std",
42+
"frame-system/std",
43+
"frame-support/std",
44+
"frame-benchmarking/std",
45+
]
46+
try-runtime = ["frame-support/try-runtime"]

frame/preimage/src/benchmarking.rs

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
// This file is part of Substrate.
2+
3+
// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd.
4+
// SPDX-License-Identifier: Apache-2.0
5+
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
18+
//! Preimage pallet benchmarking.
19+
20+
use super::*;
21+
use frame_benchmarking::{account, benchmarks, whitelist_account};
22+
use frame_support::assert_ok;
23+
use frame_system::RawOrigin;
24+
use sp_runtime::traits::Bounded;
25+
use sp_std::{prelude::*, vec};
26+
27+
use crate::Pallet as Preimage;
28+
29+
const SEED: u32 = 0;
30+
31+
fn funded_account<T: Config>(name: &'static str, index: u32) -> T::AccountId {
32+
let caller: T::AccountId = account(name, index, SEED);
33+
T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());
34+
caller
35+
}
36+
37+
fn preimage_and_hash<T: Config>() -> (Vec<u8>, T::Hash) {
38+
sized_preimage_and_hash::<T>(T::MaxSize::get())
39+
}
40+
41+
fn sized_preimage_and_hash<T: Config>(size: u32) -> (Vec<u8>, T::Hash) {
42+
let mut preimage = vec![];
43+
preimage.resize(size as usize, 0);
44+
let hash = <T as frame_system::Config>::Hashing::hash(&preimage[..]);
45+
(preimage, hash)
46+
}
47+
48+
benchmarks! {
49+
// Expensive note - will reserve.
50+
note_preimage {
51+
let s in 0 .. T::MaxSize::get();
52+
let caller = funded_account::<T>("caller", 0);
53+
whitelist_account!(caller);
54+
let (preimage, hash) = sized_preimage_and_hash::<T>(s);
55+
}: _(RawOrigin::Signed(caller), preimage)
56+
verify {
57+
assert!(Preimage::<T>::have_preimage(&hash));
58+
}
59+
// Cheap note - will not reserve since it was requested.
60+
note_requested_preimage {
61+
let s in 0 .. T::MaxSize::get();
62+
let caller = funded_account::<T>("caller", 0);
63+
whitelist_account!(caller);
64+
let (preimage, hash) = sized_preimage_and_hash::<T>(s);
65+
assert_ok!(Preimage::<T>::request_preimage(T::ManagerOrigin::successful_origin(), hash.clone()));
66+
}: note_preimage(RawOrigin::Signed(caller), preimage)
67+
verify {
68+
assert!(Preimage::<T>::have_preimage(&hash));
69+
}
70+
// Cheap note - will not reserve since it's the manager.
71+
note_no_deposit_preimage {
72+
let s in 0 .. T::MaxSize::get();
73+
let (preimage, hash) = sized_preimage_and_hash::<T>(s);
74+
assert_ok!(Preimage::<T>::request_preimage(T::ManagerOrigin::successful_origin(), hash.clone()));
75+
}: note_preimage<T::Origin>(T::ManagerOrigin::successful_origin(), preimage)
76+
verify {
77+
assert!(Preimage::<T>::have_preimage(&hash));
78+
}
79+
80+
// Expensive unnote - will unreserve.
81+
unnote_preimage {
82+
let caller = funded_account::<T>("caller", 0);
83+
whitelist_account!(caller);
84+
let (preimage, hash) = preimage_and_hash::<T>();
85+
assert_ok!(Preimage::<T>::note_preimage(RawOrigin::Signed(caller.clone()).into(), preimage));
86+
}: _(RawOrigin::Signed(caller), hash.clone())
87+
verify {
88+
assert!(!Preimage::<T>::have_preimage(&hash));
89+
}
90+
// Cheap unnote - will not unreserve since there's no deposit held.
91+
unnote_no_deposit_preimage {
92+
let (preimage, hash) = preimage_and_hash::<T>();
93+
assert_ok!(Preimage::<T>::note_preimage(T::ManagerOrigin::successful_origin(), preimage));
94+
}: unnote_preimage<T::Origin>(T::ManagerOrigin::successful_origin(), hash.clone())
95+
verify {
96+
assert!(!Preimage::<T>::have_preimage(&hash));
97+
}
98+
99+
// Expensive request - will unreserve the noter's deposit.
100+
request_preimage {
101+
let (preimage, hash) = preimage_and_hash::<T>();
102+
let noter = funded_account::<T>("noter", 0);
103+
whitelist_account!(noter);
104+
assert_ok!(Preimage::<T>::note_preimage(RawOrigin::Signed(noter).into(), preimage));
105+
}: _<T::Origin>(T::ManagerOrigin::successful_origin(), hash)
106+
verify {
107+
assert_eq!(StatusFor::<T>::get(&hash), Some(RequestStatus::Requested(1)));
108+
}
109+
// Cheap request - would unreserve the deposit but none was held.
110+
request_no_deposit_preimage {
111+
let (preimage, hash) = preimage_and_hash::<T>();
112+
assert_ok!(Preimage::<T>::note_preimage(T::ManagerOrigin::successful_origin(), preimage));
113+
}: request_preimage<T::Origin>(T::ManagerOrigin::successful_origin(), hash)
114+
verify {
115+
assert_eq!(StatusFor::<T>::get(&hash), Some(RequestStatus::Requested(1)));
116+
}
117+
// Cheap request - the preimage is not yet noted, so deposit to unreserve.
118+
request_unnoted_preimage {
119+
let (_, hash) = preimage_and_hash::<T>();
120+
}: request_preimage<T::Origin>(T::ManagerOrigin::successful_origin(), hash)
121+
verify {
122+
assert_eq!(StatusFor::<T>::get(&hash), Some(RequestStatus::Requested(1)));
123+
}
124+
// Cheap request - the preimage is already requested, so just a counter bump.
125+
request_requested_preimage {
126+
let (_, hash) = preimage_and_hash::<T>();
127+
assert_ok!(Preimage::<T>::request_preimage(T::ManagerOrigin::successful_origin(), hash.clone()));
128+
}: request_preimage<T::Origin>(T::ManagerOrigin::successful_origin(), hash)
129+
verify {
130+
assert_eq!(StatusFor::<T>::get(&hash), Some(RequestStatus::Requested(2)));
131+
}
132+
133+
// Expensive unrequest - last reference and it's noted, so will destroy the preimage.
134+
unrequest_preimage {
135+
let (preimage, hash) = preimage_and_hash::<T>();
136+
assert_ok!(Preimage::<T>::request_preimage(T::ManagerOrigin::successful_origin(), hash.clone()));
137+
assert_ok!(Preimage::<T>::note_preimage(T::ManagerOrigin::successful_origin(), preimage));
138+
}: _<T::Origin>(T::ManagerOrigin::successful_origin(), hash.clone())
139+
verify {
140+
assert_eq!(StatusFor::<T>::get(&hash), None);
141+
}
142+
// Cheap unrequest - last reference, but it's not noted.
143+
unrequest_unnoted_preimage {
144+
let (_, hash) = preimage_and_hash::<T>();
145+
assert_ok!(Preimage::<T>::request_preimage(T::ManagerOrigin::successful_origin(), hash.clone()));
146+
}: unrequest_preimage<T::Origin>(T::ManagerOrigin::successful_origin(), hash.clone())
147+
verify {
148+
assert_eq!(StatusFor::<T>::get(&hash), None);
149+
}
150+
// Cheap unrequest - not the last reference.
151+
unrequest_multi_referenced_preimage {
152+
let (_, hash) = preimage_and_hash::<T>();
153+
assert_ok!(Preimage::<T>::request_preimage(T::ManagerOrigin::successful_origin(), hash.clone()));
154+
assert_ok!(Preimage::<T>::request_preimage(T::ManagerOrigin::successful_origin(), hash.clone()));
155+
}: unrequest_preimage<T::Origin>(T::ManagerOrigin::successful_origin(), hash.clone())
156+
verify {
157+
assert_eq!(StatusFor::<T>::get(&hash), Some(RequestStatus::Requested(1)));
158+
}
159+
160+
impl_benchmark_test_suite!(Preimage, crate::mock::new_test_ext(), crate::mock::Test);
161+
}

0 commit comments

Comments
 (0)