Upgradeable validation functions (#918)

* upgrade primitives to allow changing validation function

* set up storage schema for old parachains code

* fix compilation errors

* fix test compilation

* add some tests for past code meta

* most of the runtime logic for code upgrades

* implement old-code pruning

* add a couple tests

* clean up remaining TODOs

* add a whole bunch of tests for runtime functionality

* remove unused function

* fix runtime compilation

* extract some primitives to parachain crate

* add validation-code upgrades to validation params and result

* extend validation params with code upgrade fields

* provide maximums to validation params

* port test-parachains

* add a code-upgrader test-parachain and tests

* fix collator tests

* move test-parachains to own folder to work around compilation errors

* fix test compilation

* update the Cargo.lock

* fix parachains tests

* remove dbg! invocation

* use new pool in code-upgrader

* bump lockfile

* link TODO to issue
This commit is contained in:
Robert Habermeier
2020-04-06 10:43:19 -04:00
committed by GitHub
parent b31b52dddf
commit 10cec3b591
43 changed files with 1830 additions and 444 deletions
+5 -1
View File
@@ -582,7 +582,7 @@ mod tests {
};
use frame_support::traits::Contains;
use sp_core::H256;
use primitives::parachain::{Info as ParaInfo, Id as ParaId};
use primitives::parachain::{Info as ParaInfo, Id as ParaId, Scheduling};
// The testing primitives are very useful for avoiding having to work with signatures
// or public keys. `u64` is used as the `AccountId` and no `Signature`s are requried.
use sp_runtime::{
@@ -698,6 +698,10 @@ mod tests {
code_size <= MAX_CODE_SIZE
}
fn para_info(_id: ParaId) -> Option<ParaInfo> {
Some(ParaInfo { scheduling: Scheduling::Always })
}
fn register_para(
id: ParaId,
_info: ParaInfo,
File diff suppressed because it is too large Load Diff
+25 -15
View File
@@ -52,6 +52,9 @@ pub trait Registrar<AccountId> {
/// Checks whether the given validation code falls within the limit.
fn code_size_allowed(code_size: u32) -> bool;
/// Fetches metadata for a para by ID, if any.
fn para_info(id: ParaId) -> Option<ParaInfo>;
/// Register a parachain with given `code` and `initial_head_data`. `id` must not yet be registered or it will
/// result in a error.
///
@@ -83,6 +86,10 @@ impl<T: Trait> Registrar<T::AccountId> for Module<T> {
code_size <= <T as parachains::Trait>::MaxCodeSize::get()
}
fn para_info(id: ParaId) -> Option<ParaInfo> {
Self::paras(&id)
}
fn register_para(
id: ParaId,
info: ParaInfo,
@@ -653,15 +660,15 @@ mod tests {
traits::{
BlakeTwo256, IdentityLookup, Dispatchable,
AccountIdConversion,
}, testing::{UintAuthorityId, Header, TestXt}, KeyTypeId, Perbill, curve::PiecewiseLinear,
}, testing::{UintAuthorityId, TestXt}, KeyTypeId, Perbill, curve::PiecewiseLinear,
};
use primitives::{
parachain::{
ValidatorId, Info as ParaInfo, Scheduling, LOWEST_USER_ID, AttestedCandidate,
CandidateReceipt, HeadData, ValidityAttestation, Statement, Chain,
CollatorPair, CandidateCommitments, GlobalValidationSchedule, LocalValidationData,
CollatorPair, CandidateCommitments,
},
Balance, BlockNumber,
Balance, BlockNumber, Header,
};
use frame_support::{
traits::{KeyOwnerProofSystem, OnInitialize, OnFinalize},
@@ -710,7 +717,7 @@ mod tests {
type Origin = Origin;
type Call = Call;
type Index = u64;
type BlockNumber = u64;
type BlockNumber = BlockNumber;
type Hash = H256;
type Hashing = BlakeTwo256;
type AccountId = u64;
@@ -741,8 +748,8 @@ mod tests {
}
parameter_types!{
pub const LeasePeriod: u64 = 10;
pub const EndingPeriod: u64 = 3;
pub const LeasePeriod: BlockNumber = 10;
pub const EndingPeriod: BlockNumber = 3;
}
impl slots::Trait for Test {
@@ -791,6 +798,10 @@ mod tests {
parameter_types! {
pub const MaxHeadDataSize: u32 = 100;
pub const MaxCodeSize: u32 = 100;
pub const ValidationUpgradeFrequency: BlockNumber = 10;
pub const ValidationUpgradeDelay: BlockNumber = 2;
pub const SlashPeriod: BlockNumber = 50;
pub const ElectionLookahead: BlockNumber = 0;
}
@@ -830,11 +841,15 @@ mod tests {
type Origin = Origin;
type Call = Call;
type ParachainCurrency = balances::Module<Test>;
type BlockNumberConversion = sp_runtime::traits::Identity;
type ActiveParachains = Registrar;
type Registrar = Registrar;
type Randomness = RandomnessCollectiveFlip;
type MaxCodeSize = MaxCodeSize;
type MaxHeadDataSize = MaxHeadDataSize;
type ValidationUpgradeFrequency = ValidationUpgradeFrequency;
type ValidationUpgradeDelay = ValidationUpgradeDelay;
type SlashPeriod = SlashPeriod;
type Proof = session::historical::Proof;
type KeyOwnerProofSystem = session::historical::Module<Test>;
type IdentificationTuple = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, Vec<u8>)>>::IdentificationTuple;
@@ -929,7 +944,7 @@ mod tests {
Slots::on_initialize(System::block_number());
}
fn run_to_block(n: u64) {
fn run_to_block(n: BlockNumber) {
println!("Running until block {}", n);
while System::block_number() < n {
if System::block_number() > 1 {
@@ -972,18 +987,13 @@ mod tests {
collator: collator.public(),
signature: pov_block_hash.using_encoded(|d| collator.sign(d)),
pov_block_hash,
global_validation: GlobalValidationSchedule {
max_code_size: <Test as parachains::Trait>::MaxCodeSize::get(),
max_head_data_size: <Test as parachains::Trait>::MaxHeadDataSize::get(),
},
local_validation: LocalValidationData {
balance: Balances::free_balance(&id.into_account()),
parent_head: HeadData(Parachains::parachain_head(&id).unwrap()),
},
global_validation: Parachains::global_validation_schedule(),
local_validation: Parachains::current_local_validation_data(&id).unwrap(),
commitments: CandidateCommitments {
fees: 0,
upward_messages: vec![],
erasure_root: [1; 32].into(),
new_validation_code: None,
},
};
let (candidate, _) = candidate.abridge();
+15 -10
View File
@@ -878,7 +878,7 @@ mod tests {
use sp_core::H256;
use sp_runtime::{
Perbill, testing::Header,
Perbill,
traits::{BlakeTwo256, Hash, IdentityLookup},
};
use frame_support::{
@@ -886,7 +886,8 @@ mod tests {
traits::{OnInitialize, OnFinalize}
};
use balances;
use primitives::parachain::{Id as ParaId, Info as ParaInfo};
use primitives::{BlockNumber, Header};
use primitives::parachain::{Id as ParaId, Info as ParaInfo, Scheduling};
impl_outer_origin! {
pub enum Origin for Test {}
@@ -907,7 +908,7 @@ mod tests {
type Origin = Origin;
type Call = ();
type Index = u64;
type BlockNumber = u64;
type BlockNumber = BlockNumber;
type Hash = H256;
type Hashing = BlakeTwo256;
type AccountId = u64;
@@ -963,6 +964,10 @@ mod tests {
code_size <= MAX_CODE_SIZE
}
fn para_info(_id: ParaId) -> Option<ParaInfo> {
Some(ParaInfo { scheduling: Scheduling::Always })
}
fn register_para(
id: ParaId,
_info: ParaInfo,
@@ -997,8 +1002,8 @@ mod tests {
}
parameter_types!{
pub const LeasePeriod: u64 = 10;
pub const EndingPeriod: u64 = 3;
pub const LeasePeriod: BlockNumber = 10;
pub const EndingPeriod: BlockNumber = 3;
}
impl Trait for Test {
@@ -1025,7 +1030,7 @@ mod tests {
t.into()
}
fn run_to_block(n: u64) {
fn run_to_block(n: BlockNumber) {
while System::block_number() < n {
Slots::on_finalize(System::block_number());
Balances::on_finalize(System::block_number());
@@ -1453,8 +1458,8 @@ mod tests {
assert_ok!(Slots::new_auction(Origin::ROOT, 5, 1));
for i in 1..6 {
run_to_block(i);
for i in 1..6u64 {
run_to_block(i as _);
assert_ok!(Slots::bid(Origin::signed(i), 0, 1, 1, 4, i));
for j in 1..6 {
assert_eq!(Balances::reserved_balance(j), if j == i { j } else { 0 });
@@ -1481,8 +1486,8 @@ mod tests {
assert_ok!(Slots::new_auction(Origin::ROOT, 5, 1));
for i in 1..6 {
run_to_block(i + 3);
for i in 1..6u64 {
run_to_block((i + 3) as _);
assert_ok!(Slots::bid(Origin::signed(i), 0, 1, 1, 4, i));
for j in 1..6 {
assert_eq!(Balances::reserved_balance(j), if j == i { j } else { 0 });