Skip to content

Commit 5bbcfa2

Browse files
bkonturgithub-actions[bot]bkchrkianenigmaacatangiu
authored andcommitted
Add Paras authorize_code_hash + apply_authorized_code feature (#7592)
Closes: #7574 Relates to: #7591 ## Motivation This feature is useful when triggering a `Paras` pallet call from a different chain than the one where the `Paras` pallet is deployed. For example, we may want to send `Paras::force_set_current_code(para, code)` from the Collectives and/or AssetHub to the relay chain (because the relaychain governance will be migrated to the AssetHub as a part of AHM). The primary reason for this approach is to avoid transferring the entire `new_code` Wasm blob between chains. Instead, we authorize the `code_hash` using `root` via `fn authorize_force_set_current_code_hash(new_authorization, expire_at)`. This authorization can later be applied by anyone using `Paras::apply_authorized_force_set_current_code(para, new_code)`. If `expire_at` is reached without the authorization being used, it is automatically removed. ## Usage This feature is intended for use in two scenarios: - The D-Day scenario, where we can restart AssetHub from Collectives — see the PoC: #8141 - Using `force_set_current_code` for any parachain from migrated governance to AssetHub (AHM) ## TODO - [x] ~cover also `add_trusted_validation_code` or `force_schedule_code_upgrade` - see comment bellow: #7592 (comment) no see other [comment](#7592 (comment)) ## Open questions - [ ] ~Do we need something like `poke_authorized_code_hash`? E.g. in case that we authorize code hash, but nobody would apply it and the parachain starts working with old/other_new code? Is this possible?~ - [ ] Do we need something similar for `frame_system` pallet and `set_code` / `set_code_without_checks`? - [ ] Can we achieve the same with `pallet-whitelist`? - [ ] Do we have other extrinsics over chains which has `code` attribute? - [x] Do we need to add `validate_unsigned` for `apply_authorized_code`? --------- Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Bastian Köcher <git@kchr.de> Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: Adrian Catangiu <adrian@parity.io>
1 parent d13e2c2 commit 5bbcfa2

16 files changed

Lines changed: 688 additions & 124 deletions

File tree

polkadot/runtime/common/src/assigned_slots/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,7 @@ mod tests {
734734
type AssignCoretime = ();
735735
type Fungible = Balances;
736736
type CooldownRemovalMultiplier = ConstUint<1>;
737+
type AuthorizeCurrentCodeOrigin = EnsureRoot<Self::AccountId>;
737738
}
738739

739740
impl parachains_shared::Config for Test {

polkadot/runtime/common/src/integration_tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ impl paras::Config for Test {
216216
type AssignCoretime = ();
217217
type Fungible = Balances;
218218
type CooldownRemovalMultiplier = ConstUint<1>;
219+
type AuthorizeCurrentCodeOrigin = EnsureRoot<Self::AccountId>;
219220
}
220221

221222
parameter_types! {

polkadot/runtime/common/src/paras_registrar/mock.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ impl paras::Config for Test {
131131
type AssignCoretime = ();
132132
type Fungible = Balances;
133133
type CooldownRemovalMultiplier = ConstUint<1>;
134+
type AuthorizeCurrentCodeOrigin = frame_system::EnsureRoot<u64>;
134135
}
135136

136137
impl configuration::Config for Test {

polkadot/runtime/parachains/src/mock.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ use frame_support::{
4040
PalletId,
4141
};
4242
use frame_support_test::TestRandomness;
43-
use frame_system::limits;
43+
use frame_system::{limits, EnsureRoot};
4444
use polkadot_primitives::{
4545
AuthorityDiscoveryId, Balance, BlockNumber, CandidateHash, Moment, SessionIndex, UpwardMessage,
4646
ValidationCode, ValidatorIndex,
@@ -249,6 +249,7 @@ impl crate::paras::Config for Test {
249249
type AssignCoretime = ();
250250
type Fungible = Balances;
251251
type CooldownRemovalMultiplier = ConstUint<1>;
252+
type AuthorizeCurrentCodeOrigin = EnsureRoot<AccountId>;
252253
}
253254

254255
impl crate::dmp::Config for Test {}

polkadot/runtime/parachains/src/paras/benchmarking.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,44 @@ mod benchmarks {
282282
Ok(())
283283
}
284284

285+
#[benchmark]
286+
fn authorize_force_set_current_code_hash() {
287+
let para_id = ParaId::from(1000);
288+
let code = ValidationCode(vec![0; 32]);
289+
let new_code_hash = code.hash();
290+
let valid_period = BlockNumberFor::<T>::from(1_000_000_u32);
291+
292+
#[extrinsic_call]
293+
_(RawOrigin::Root, para_id, new_code_hash, valid_period);
294+
295+
assert_last_event::<T>(
296+
Event::CodeAuthorized {
297+
para_id,
298+
code_hash: new_code_hash,
299+
expire_at: frame_system::Pallet::<T>::block_number().saturating_add(valid_period),
300+
}
301+
.into(),
302+
);
303+
}
304+
305+
#[benchmark]
306+
fn apply_authorized_force_set_current_code(c: Linear<MIN_CODE_SIZE, MAX_CODE_SIZE>) {
307+
let code = ValidationCode(vec![0; c as usize]);
308+
let para_id = ParaId::from(1000);
309+
let expire_at =
310+
frame_system::Pallet::<T>::block_number().saturating_add(BlockNumberFor::<T>::from(c));
311+
AuthorizedCodeHash::<T>::insert(
312+
&para_id,
313+
AuthorizedCodeHashAndExpiry::from((code.hash(), expire_at)),
314+
);
315+
generate_disordered_pruning::<T>();
316+
317+
#[extrinsic_call]
318+
_(RawOrigin::Root, para_id, code);
319+
320+
assert_last_event::<T>(Event::CurrentCodeUpdated(para_id).into());
321+
}
322+
285323
impl_benchmark_test_suite!(
286324
Pallet,
287325
crate::mock::new_test_ext(Default::default()),

0 commit comments

Comments
 (0)