Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Benchmark Slots and Auction #2181

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 7 additions & 22 deletions runtime/common/src/crowdloan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -690,26 +690,18 @@ mod tests {
RefCell<HashMap<u32, (ValidationCode, HeadData)>> = 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 {
const MAX_CODE_SIZE: u32 = 100;
const MAX_HEAD_DATA_SIZE: u32 = 10;

fn new_id() -> ParaId {
PARACHAIN_COUNT.with(|p| {
*p.borrow_mut() += 1;
(*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,
_parachain: bool,
Expand Down Expand Up @@ -1444,7 +1436,7 @@ mod tests {
#[cfg(feature = "runtime-benchmarks")]
mod benchmarking {
use super::{*, Module as Crowdloan};
use crate::slots::Module as Slots;
use crate::slots::{Module as Slots, Registrar};
use frame_system::RawOrigin;
use frame_support::{
assert_ok,
Expand All @@ -1455,10 +1447,6 @@ mod benchmarking {

use frame_benchmarking::{benchmarks, whitelisted_caller, account, whitelist_account};

// TODO: replace with T::Parachains::MAX_CODE_SIZE
const MAX_CODE_SIZE: u32 = 10;
const MAX_HEAD_DATA_SIZE: u32 = 10;

fn assert_last_event<T: Config>(generic_event: <T as Config>::Event) {
let events = frame_system::Module::<T>::events();
let system_event: <T as frame_system::Config>::Event = generic_event.into();
Expand Down Expand Up @@ -1487,8 +1475,7 @@ mod benchmarking {
}

fn worst_validation_code<T: Config>() -> Vec<u8> {
// TODO: replace with T::Parachains::MAX_CODE_SIZE
let mut validation_code = vec![0u8; MAX_CODE_SIZE as usize];
let mut validation_code = vec![0u8; T::Parachains::MAX_CODE_SIZE as usize];
// Replace first bytes of code with "WASM_MAGIC" to pass validation test.
let _ = validation_code.splice(
..crate::WASM_MAGIC.len(),
Expand All @@ -1500,13 +1487,11 @@ mod benchmarking {
fn worst_deploy_data<T: Config>() -> DeployData<T::Hash> {
let validation_code = worst_validation_code::<T>();
let code = primitives::v1::ValidationCode(validation_code);
// TODO: replace with T::Parachains::MAX_HEAD_DATA_SIZE
let head_data = HeadData(vec![0u8; MAX_HEAD_DATA_SIZE as usize]);
let head_data = HeadData(vec![0u8; T::Parachains::MAX_HEAD_DATA_SIZE as usize]);

DeployData {
code_hash: T::Hashing::hash(&code.0),
// TODO: replace with T::Parachains::MAX_CODE_SIZE
code_size: MAX_CODE_SIZE,
code_size: T::Parachains::MAX_CODE_SIZE,
initial_head_data: head_data,
}
}
Expand Down
174 changes: 146 additions & 28 deletions runtime/common/src/slots.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,14 @@ pub trait Config: frame_system::Config {

/// Parachain registration API.
pub trait Registrar<AccountId> {
/// Create a new unique parachain identity for later registration.
fn new_id() -> ParaId;
/// Maximum code size allowed.
const MAX_CODE_SIZE: u32;

/// Checks whether the given initial head data size falls within the limit.
fn head_data_size_allowed(head_data_size: u32) -> bool;
/// Maximum head data size allowed.
const MAX_HEAD_DATA_SIZE: u32;

/// Checks whether the given validation code falls within the limit.
fn code_size_allowed(code_size: u32) -> bool;
/// Create a new unique parachain identity for later registration.
fn new_id() -> ParaId;

/// Register a parachain with given `code` and `initial_head_data`. `id` must not yet be registered or it will
/// result in a error.
Expand Down Expand Up @@ -288,6 +288,8 @@ decl_event!(
Reserved(AccountId, Balance, Balance),
/// Funds were unreserved since bidder is no longer active. [bidder, amount]
Unreserved(AccountId, Balance),
/// Result of the Para Registration
RegisterParaResult(DispatchResult),
}
);

Expand Down Expand Up @@ -486,11 +488,11 @@ decl_module! {
}

ensure!(
T::Parachains::head_data_size_allowed(initial_head_data.0.len() as _),
T::Parachains::MAX_HEAD_DATA_SIZE >= initial_head_data.0.len() as _,
Error::<T>::HeadDataTooLarge,
);
ensure!(
T::Parachains::code_size_allowed(code_size),
T::Parachains::MAX_CODE_SIZE >= code_size,
Error::<T>::CodeTooLarge,
);

Expand Down Expand Up @@ -530,8 +532,10 @@ decl_module! {
// Should have already begun. Remove the on-boarding entry and register the
// parachain for its immediate start.
<Onboarding<T>>::remove(&para_id);
let _ = T::Parachains::
// TODO: Probably best to make sure this doesn't fail or handle fail conditions.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stray TODO

let result = T::Parachains::
register_para(para_id, true, code, initial_head_data);
Self::deposit_event(RawEvent::RegisterParaResult(result));
}

Ok(())
Expand Down Expand Up @@ -1007,26 +1011,18 @@ mod tests {
RefCell<HashMap<u32, (ValidationCode, HeadData)>> = 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 {
const MAX_CODE_SIZE: u32 = 100;
const MAX_HEAD_DATA_SIZE: u32 = 10;

fn new_id() -> ParaId {
PARACHAIN_COUNT.with(|p| {
*p.borrow_mut() += 1;
(*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,
_parachain: bool,
Expand Down Expand Up @@ -1081,7 +1077,7 @@ mod tests {

// This function basically just builds a genesis storage key/value store according to
// our desired mock up.
fn new_test_ext() -> sp_io::TestExternalities {
pub fn new_test_ext() -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
pallet_balances::GenesisConfig::<Test>{
balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)],
Expand Down Expand Up @@ -1674,7 +1670,7 @@ mod tests {

run_to_block(10);

let code = vec![0u8; (MAX_CODE_SIZE + 1) as _];
let code = vec![0u8; (<Test as Config>::Parachains::MAX_CODE_SIZE + 1) as _];
let h = BlakeTwo256::hash(&code[..]);
assert_eq!(
Slots::fix_deploy_data(
Expand All @@ -1697,8 +1693,8 @@ mod tests {

run_to_block(10);

let code = vec![0u8; MAX_CODE_SIZE as _];
let head_data = vec![1u8; MAX_HEAD_DATA_SIZE as _].into();
let code = vec![0u8; <Test as Config>::Parachains::MAX_CODE_SIZE as _];
let head_data = vec![1u8; <Test as Config>::Parachains::MAX_HEAD_DATA_SIZE as _].into();
let h = BlakeTwo256::hash(&code[..]);
assert_ok!(Slots::fix_deploy_data(
Origin::signed(1), 0, 0.into(), h, code.len() as _, head_data,
Expand All @@ -1718,8 +1714,8 @@ mod tests {

run_to_block(10);

let code = vec![0u8; MAX_CODE_SIZE as _];
let head_data = vec![1u8; (MAX_HEAD_DATA_SIZE + 1) as _].into();
let code = vec![0u8; <Test as Config>::Parachains::MAX_CODE_SIZE as _];
let head_data = vec![1u8; (<Test as Config>::Parachains::MAX_HEAD_DATA_SIZE + 1) as _].into();
let h = BlakeTwo256::hash(&code[..]);
assert_eq!(
Slots::fix_deploy_data(
Expand All @@ -1742,8 +1738,8 @@ mod tests {

run_to_block(10);

let code = vec![0u8; MAX_CODE_SIZE as _];
let head_data = vec![1u8; MAX_HEAD_DATA_SIZE as _].into();
let code = vec![0u8; <Test as Config>::Parachains::MAX_CODE_SIZE as _];
let head_data = vec![1u8; <Test as Config>::Parachains::MAX_HEAD_DATA_SIZE as _].into();
let h = BlakeTwo256::hash(&code[..]);
assert_ok!(Slots::fix_deploy_data(
Origin::signed(1), 0, 0.into(), h, (code.len() - 1) as _, head_data,
Expand All @@ -1752,3 +1748,125 @@ mod tests {
});
}
}

#[cfg(feature = "runtime-benchmarks")]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this don't deserve a new file? this file is already > 1500 lines...

mod benchmarking {
use super::*;
use crate::slots::Module as Slots;
use frame_system::RawOrigin;
use frame_benchmarking::{benchmarks, account};

fn assert_last_event<T: Config>(generic_event: <T as Config>::Event) {
let events = frame_system::Module::<T>::events();
let system_event: <T as frame_system::Config>::Event = generic_event.into();
// compare to the last event record
let frame_system::EventRecord { event, .. } = &events[events.len() - 1];
assert_eq!(event, &system_event);
}

benchmarks! {
new_auction {
let lease_period_index = Slots::<T>::lease_period_index();
let duration = 100u32.into();
}: _(RawOrigin::Root, duration, lease_period_index)
verify {
let auction_counter = AuctionCounter::get();
let ending = <frame_system::Module<T>>::block_number() + duration;
assert_last_event::<T>(RawEvent::AuctionStarted(auction_counter, lease_period_index, ending).into());
}

// Worst case scenario:
// * Parachain already has many bids in the queue, and presents a new one
// which intersects all the old ones. (Passes intersection test)
// * There is already a winner of the range being bid on, so we must return
// funds to that user.
// * We must bond new funds to make the bid.
// *
// bid


// bid_renew

set_offboarding {
let sender = ParaId::default().into_account();
let dest: T::AccountId = account("dest", 0, 0);
let dest_lookup = T::Lookup::unlookup(dest.clone());
}: _(RawOrigin::Signed(sender), dest_lookup)
verify {
assert_eq!(Offboarding::<T>::get(ParaId::default()), dest);
}

fix_deploy_data {
let para_id = ParaId::default();
let bidder: T::AccountId = account("bidder", 0, 0);
let onboarding_data = (
LeasePeriodOf::<T>::default(),
IncomingParachain::Unset(
NewBidder {
who: bidder.clone(),
sub: Default::default(),
}
),
);
let head_data = HeadData(vec![0u8; T::Parachains::MAX_HEAD_DATA_SIZE as usize]);
Onboarding::<T>::insert(&para_id, onboarding_data.clone());
}: _(
RawOrigin::Signed(bidder),
Default::default(),
para_id.clone(),
Default::default(),
T::Parachains::MAX_CODE_SIZE,
head_data
)
verify {
// Onboarding data updated.
assert!(Onboarding::<T>::get(&para_id) != Some(onboarding_data));
}

elaborate_deploy_data {
let para_id = ParaId::default();

let mut validation_code = vec![0u8; T::Parachains::MAX_CODE_SIZE as usize];
// Replace first bytes of code with "WASM_MAGIC" to pass validation test.
let _ = validation_code.splice(
..crate::WASM_MAGIC.len(),
crate::WASM_MAGIC.iter().cloned(),
).collect::<Vec<_>>();
let code = ValidationCode(validation_code);
let head_data = HeadData(vec![0u8; T::Parachains::MAX_HEAD_DATA_SIZE as usize]);

let onboarding_data = (
LeasePeriodOf::<T>::default(),
IncomingParachain::Fixed {
code_hash: T::Hashing::hash(&code.0),
code_size: T::Parachains::MAX_CODE_SIZE,
initial_head_data: head_data,
},
);
Onboarding::<T>::insert(&para_id, onboarding_data);
}: _(RawOrigin::Root, para_id, code)
verify {
// Onboarding is removed if the call is successful.
assert!(!Onboarding::<T>::contains_key(&para_id));
assert_last_event::<T>(RawEvent::RegisterParaResult(Ok(())).into());
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::slots::tests::{new_test_ext, Test};
use frame_support::assert_ok;

#[test]
fn test_benchmarks() {
new_test_ext().execute_with(|| {
assert_ok!(test_benchmark_new_auction::<Test>());
assert_ok!(test_benchmark_set_offboarding::<Test>());
assert_ok!(test_benchmark_fix_deploy_data::<Test>());
assert_ok!(test_benchmark_elaborate_deploy_data::<Test>());
});
}
}

}