mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 04:41:03 +00:00
Introduce a maximum code size and head data size (#835)
* add a maximum code size and head data size * get existing tests passing * add tests for slots logic * test registrar behavior * introduce maximums and bump versions * address review grumbles * work around publicizing derive * remove unneeded and wrong doc
This commit is contained in:
committed by
GitHub
parent
9b23f3f1f0
commit
295151338d
@@ -108,8 +108,12 @@ impl<AccountId: Clone + Default + Codec> Bidder<AccountId> {
|
||||
pub enum IncomingParachain<AccountId, Hash> {
|
||||
/// Deploy information not yet set; just the bidder identity.
|
||||
Unset(NewBidder<AccountId>),
|
||||
/// Deploy information set only by code hash; so we store the code hash and head data.
|
||||
Fixed { code_hash: Hash, initial_head_data: Vec<u8> },
|
||||
/// Deploy information set only by code hash; so we store the code hash, code size, and head data.
|
||||
///
|
||||
/// The code size must be included so that checks against a maximum code size
|
||||
/// can be done. If the size of the preimage of the code hash does not match
|
||||
/// the given code size, it will not be possible to register the parachain.
|
||||
Fixed { code_hash: Hash, code_size: u32, initial_head_data: Vec<u8> },
|
||||
/// Deploy information fully set; so we store the code and head data.
|
||||
Deploy { code: Vec<u8>, initial_head_data: Vec<u8> },
|
||||
}
|
||||
@@ -250,6 +254,10 @@ decl_error! {
|
||||
NotCurrentAuction,
|
||||
/// Not an auction.
|
||||
NotAuction,
|
||||
/// Given code size is too large.
|
||||
CodeTooLarge,
|
||||
/// Given initial head data is too large.
|
||||
HeadDataTooLarge,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -402,6 +410,7 @@ decl_module! {
|
||||
#[compact] sub: SubId,
|
||||
#[compact] para_id: ParaId,
|
||||
code_hash: T::Hash,
|
||||
code_size: u32,
|
||||
initial_head_data: Vec<u8>
|
||||
) {
|
||||
let who = ensure_signed(origin)?;
|
||||
@@ -412,7 +421,17 @@ decl_module! {
|
||||
} else {
|
||||
Err(Error::<T>::AlreadyRegistered)?
|
||||
}
|
||||
let item = (starts, IncomingParachain::Fixed{code_hash, initial_head_data});
|
||||
|
||||
ensure!(
|
||||
T::Parachains::head_data_size_allowed(initial_head_data.len() as _),
|
||||
Error::<T>::HeadDataTooLarge,
|
||||
);
|
||||
ensure!(
|
||||
T::Parachains::code_size_allowed(code_size),
|
||||
Error::<T>::CodeTooLarge,
|
||||
);
|
||||
|
||||
let item = (starts, IncomingParachain::Fixed{code_hash, code_size, initial_head_data});
|
||||
<Onboarding<T>>::insert(¶_id, item);
|
||||
}
|
||||
|
||||
@@ -432,8 +451,10 @@ decl_module! {
|
||||
pub fn elaborate_deploy_data(_origin, #[compact] para_id: ParaId, code: Vec<u8>) -> DispatchResult {
|
||||
let (starts, details) = <Onboarding<T>>::get(¶_id)
|
||||
.ok_or(Error::<T>::ParaNotOnboarding)?;
|
||||
if let IncomingParachain::Fixed{code_hash, initial_head_data} = details {
|
||||
if let IncomingParachain::Fixed{code_hash, code_size, initial_head_data} = details {
|
||||
ensure!(code.len() as u32 == code_size, Error::<T>::InvalidCode);
|
||||
ensure!(<T as system::Trait>::Hashing::hash(&code) == code_hash, Error::<T>::InvalidCode);
|
||||
|
||||
if starts > Self::lease_period_index() {
|
||||
// Hasn't yet begun. Replace the on-boarding entry with the new information.
|
||||
let item = (starts, IncomingParachain::Deploy{code, initial_head_data});
|
||||
@@ -918,6 +939,9 @@ mod tests {
|
||||
RefCell<HashMap<u32, (Vec<u8>, Vec<u8>)>> = RefCell::new(HashMap::new());
|
||||
}
|
||||
|
||||
const MAX_CODE_SIZE: u32 = 100;
|
||||
const MAX_HEAD_DATA_SIZE: u32 = 10;
|
||||
|
||||
pub struct TestParachains;
|
||||
impl Registrar<u64> for TestParachains {
|
||||
fn new_id() -> ParaId {
|
||||
@@ -926,6 +950,15 @@ mod tests {
|
||||
(*p.borrow() - 1).into()
|
||||
})
|
||||
}
|
||||
|
||||
fn head_data_size_allowed(head_data_size: u32) -> bool {
|
||||
head_data_size <= MAX_HEAD_DATA_SIZE
|
||||
}
|
||||
|
||||
fn code_size_allowed(code_size: u32) -> bool {
|
||||
code_size <= MAX_CODE_SIZE
|
||||
}
|
||||
|
||||
fn register_para(
|
||||
id: ParaId,
|
||||
_info: ParaInfo,
|
||||
@@ -1144,7 +1177,7 @@ mod tests {
|
||||
|
||||
run_to_block(9);
|
||||
let h = BlakeTwo256::hash(&[42u8][..]);
|
||||
assert_ok!(Slots::fix_deploy_data(Origin::signed(1), 0, 0.into(), h, vec![69]));
|
||||
assert_ok!(Slots::fix_deploy_data(Origin::signed(1), 0, 0.into(), h, 1, vec![69]));
|
||||
assert_ok!(Slots::elaborate_deploy_data(Origin::signed(0), 0.into(), vec![42]));
|
||||
|
||||
run_to_block(10);
|
||||
@@ -1169,7 +1202,7 @@ mod tests {
|
||||
|
||||
run_to_block(11);
|
||||
let h = BlakeTwo256::hash(&[42u8][..]);
|
||||
assert_ok!(Slots::fix_deploy_data(Origin::signed(1), 0, 0.into(), h, vec![69]));
|
||||
assert_ok!(Slots::fix_deploy_data(Origin::signed(1), 0, 0.into(), h, 1, vec![69]));
|
||||
assert_ok!(Slots::elaborate_deploy_data(Origin::signed(0), 0.into(), vec![42]));
|
||||
with_parachains(|p| {
|
||||
assert_eq!(p.len(), 1);
|
||||
@@ -1279,7 +1312,7 @@ mod tests {
|
||||
|
||||
for &(para, sub, acc) in &[(0, 0, 1), (1, 0, 2), (2, 0, 3), (3, 1, 4), (4, 1, 5)] {
|
||||
let h = BlakeTwo256::hash(&[acc][..]);
|
||||
assert_ok!(Slots::fix_deploy_data(Origin::signed(acc as _), sub, para.into(), h, vec![acc]));
|
||||
assert_ok!(Slots::fix_deploy_data(Origin::signed(acc as _), sub, para.into(), h, 1, vec![acc]));
|
||||
assert_ok!(Slots::elaborate_deploy_data(Origin::signed(0), para.into(), vec![acc]));
|
||||
}
|
||||
|
||||
@@ -1326,7 +1359,7 @@ mod tests {
|
||||
|
||||
run_to_block(10);
|
||||
let h = BlakeTwo256::hash(&[1u8][..]);
|
||||
assert_ok!(Slots::fix_deploy_data(Origin::signed(1), 0, 0.into(), h, vec![1]));
|
||||
assert_ok!(Slots::fix_deploy_data(Origin::signed(1), 0, 0.into(), h, 1, vec![1]));
|
||||
assert_ok!(Slots::elaborate_deploy_data(Origin::signed(0), 0.into(), vec![1]));
|
||||
|
||||
assert_ok!(Slots::new_auction(Origin::ROOT, 5, 2));
|
||||
@@ -1371,7 +1404,7 @@ mod tests {
|
||||
|
||||
run_to_block(10);
|
||||
let h = BlakeTwo256::hash(&[1u8][..]);
|
||||
assert_ok!(Slots::fix_deploy_data(Origin::signed(1), 0, 0.into(), h, vec![1]));
|
||||
assert_ok!(Slots::fix_deploy_data(Origin::signed(1), 0, 0.into(), h, 1, vec![1]));
|
||||
assert_ok!(Slots::elaborate_deploy_data(Origin::signed(0), 0.into(), vec![1]));
|
||||
|
||||
assert_ok!(Slots::new_auction(Origin::ROOT, 5, 2));
|
||||
@@ -1560,4 +1593,94 @@ mod tests {
|
||||
];
|
||||
assert_eq!(Slots::calculate_winners(winning.clone(), TestParachains::new_id), winners);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deploy_code_too_large() {
|
||||
new_test_ext().execute_with(|| {
|
||||
run_to_block(1);
|
||||
assert_ok!(Slots::new_auction(Origin::ROOT, 5, 1));
|
||||
assert_ok!(Slots::bid(Origin::signed(1), 0, 1, 1, 1, 5));
|
||||
|
||||
run_to_block(9);
|
||||
assert_eq!(Slots::onboard_queue(1), vec![0.into()]);
|
||||
|
||||
run_to_block(10);
|
||||
|
||||
let code = vec![0u8; (MAX_CODE_SIZE + 1) as _];
|
||||
let h = BlakeTwo256::hash(&code[..]);
|
||||
assert_eq!(
|
||||
Slots::fix_deploy_data(
|
||||
Origin::signed(1), 0, 0.into(), h, code.len() as _, vec![1],
|
||||
),
|
||||
Err(Error::<Test>::CodeTooLarge.into()),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deploy_maximum_ok() {
|
||||
new_test_ext().execute_with(|| {
|
||||
run_to_block(1);
|
||||
assert_ok!(Slots::new_auction(Origin::ROOT, 5, 1));
|
||||
assert_ok!(Slots::bid(Origin::signed(1), 0, 1, 1, 1, 5));
|
||||
|
||||
run_to_block(9);
|
||||
assert_eq!(Slots::onboard_queue(1), vec![0.into()]);
|
||||
|
||||
run_to_block(10);
|
||||
|
||||
let code = vec![0u8; MAX_CODE_SIZE as _];
|
||||
let head_data = vec![1u8; MAX_HEAD_DATA_SIZE as _];
|
||||
let h = BlakeTwo256::hash(&code[..]);
|
||||
assert_ok!(Slots::fix_deploy_data(
|
||||
Origin::signed(1), 0, 0.into(), h, code.len() as _, head_data,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deploy_head_data_too_large() {
|
||||
new_test_ext().execute_with(|| {
|
||||
run_to_block(1);
|
||||
assert_ok!(Slots::new_auction(Origin::ROOT, 5, 1));
|
||||
assert_ok!(Slots::bid(Origin::signed(1), 0, 1, 1, 1, 5));
|
||||
|
||||
run_to_block(9);
|
||||
assert_eq!(Slots::onboard_queue(1), vec![0.into()]);
|
||||
|
||||
run_to_block(10);
|
||||
|
||||
let code = vec![0u8; MAX_CODE_SIZE as _];
|
||||
let head_data = vec![1u8; (MAX_HEAD_DATA_SIZE + 1) as _];
|
||||
let h = BlakeTwo256::hash(&code[..]);
|
||||
assert_eq!(
|
||||
Slots::fix_deploy_data(
|
||||
Origin::signed(1), 0, 0.into(), h, code.len() as _, head_data,
|
||||
),
|
||||
Err(Error::<Test>::HeadDataTooLarge.into()),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn code_size_must_be_correct() {
|
||||
new_test_ext().execute_with(|| {
|
||||
run_to_block(1);
|
||||
assert_ok!(Slots::new_auction(Origin::ROOT, 5, 1));
|
||||
assert_ok!(Slots::bid(Origin::signed(1), 0, 1, 1, 1, 5));
|
||||
|
||||
run_to_block(9);
|
||||
assert_eq!(Slots::onboard_queue(1), vec![0.into()]);
|
||||
|
||||
run_to_block(10);
|
||||
|
||||
let code = vec![0u8; MAX_CODE_SIZE as _];
|
||||
let head_data = vec![1u8; MAX_HEAD_DATA_SIZE as _];
|
||||
let h = BlakeTwo256::hash(&code[..]);
|
||||
assert_ok!(Slots::fix_deploy_data(
|
||||
Origin::signed(1), 0, 0.into(), h, (code.len() - 1) as _, head_data,
|
||||
));
|
||||
assert!(Slots::elaborate_deploy_data(Origin::signed(0), 0.into(), code).is_err());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user