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

Mock epoch index and randomness in SproofBuilder (for testing) #1594

Merged
merged 18 commits into from
Sep 8, 2022
Merged
36 changes: 34 additions & 2 deletions primitives/parachain-inherent/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ use cumulus_test_relay_sproof_builder::RelayStateSproofBuilder;
/// in addition to the messages themselves, you must provide some information about
/// your parachain's configuration in order to mock the MQC heads properly.
/// See [`MockXcmConfig`] for more information
pub struct MockValidationDataInherentDataProvider {
pub struct MockValidationDataInherentDataProvider<R = ()> {
/// The current block number of the local block chain (the parachain)
pub current_para_block: u32,
/// The relay block in which this parachain appeared to start. This will be the relay block
Expand All @@ -51,6 +51,11 @@ pub struct MockValidationDataInherentDataProvider {
/// The number of relay blocks that elapses between each parablock. Probably set this to 1 or 2
/// to simulate optimistic or realistic relay chain behavior.
pub relay_blocks_per_para_block: u32,
/// Number of parachain blocks per relay chain epoch
/// Mock epoch is computed by dividing `current_para_block` by this value.
pub para_blocks_per_relay_epoch: u32,
/// Function to mock BABE one epoch ago randomness using input current epoch
4meta5 marked this conversation as resolved.
Show resolved Hide resolved
pub relay_randomness_config: R,
/// XCM messages and associated configuration information.
pub xcm_config: MockXcmConfig,
/// Inbound downward XCM messages to be injected into the block.
Expand All @@ -59,6 +64,20 @@ pub struct MockValidationDataInherentDataProvider {
pub raw_horizontal_messages: Vec<(ParaId, Vec<u8>)>,
}

pub trait GenerateRandomness<I> {
fn generate_randomness(&self, input: I) -> relay_chain::Hash;
}

impl GenerateRandomness<u64> for () {
/// Default implementation uses relay epoch as randomness value
/// A more seemingly random implementation may hash the relay epoch instead
fn generate_randomness(&self, input: u64) -> relay_chain::Hash {
let mut mock_randomness: [u8; 32] = [0u8; 32];
mock_randomness[..8].copy_from_slice(&input.to_be_bytes());
mock_randomness.into()
}
}

/// Parameters for how the Mock inherent data provider should inject XCM messages.
/// In addition to the messages themselves, some information about the parachain's
/// configuration is also required so that the MQC heads can be read out of the
Expand Down Expand Up @@ -130,7 +149,9 @@ impl MockXcmConfig {
}

#[async_trait::async_trait]
impl InherentDataProvider for MockValidationDataInherentDataProvider {
impl<R: Send + Sync + GenerateRandomness<u64>> InherentDataProvider
for MockValidationDataInherentDataProvider<R>
{
fn provide_inherent_data(
&self,
inherent_data: &mut InherentData,
Expand Down Expand Up @@ -178,6 +199,17 @@ impl InherentDataProvider for MockValidationDataInherentDataProvider {
sproof_builder.upsert_inbound_channel(*para_id).mqc_head = Some(channel_mqc.head());
}

// Epoch is set equal to current para block / blocks per epoch
sproof_builder.current_epoch = if self.para_blocks_per_relay_epoch == 0 {
// do not divide by 0 => set epoch to para block number
self.current_para_block.into()
} else {
(self.current_para_block / self.para_blocks_per_relay_epoch).into()
};
// Randomness is set by randomness generator
sproof_builder.randomness =
self.relay_randomness_config.generate_randomness(self.current_para_block.into());

let (relay_parent_storage_root, proof) = sproof_builder.into_state_root_and_proof();

inherent_data.put_data(
Expand Down
6 changes: 6 additions & 0 deletions test/relay-sproof-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub struct RelayStateSproofBuilder {
pub hrmp_channels: BTreeMap<relay_chain::v2::HrmpChannelId, AbridgedHrmpChannel>,
pub current_slot: relay_chain::v2::Slot,
pub current_epoch: u64,
pub randomness: relay_chain::Hash,
}

impl Default for RelayStateSproofBuilder {
Expand All @@ -69,6 +70,7 @@ impl Default for RelayStateSproofBuilder {
hrmp_channels: BTreeMap::new(),
current_slot: 0.into(),
current_epoch: 0u64,
randomness: relay_chain::Hash::default(),
}
}
}
Expand Down Expand Up @@ -156,6 +158,10 @@ impl RelayStateSproofBuilder {
insert(relay_chain::well_known_keys::hrmp_channels(channel), metadata.encode());
}
insert(relay_chain::well_known_keys::EPOCH_INDEX.to_vec(), self.current_epoch.encode());
insert(
relay_chain::well_known_keys::ONE_EPOCH_AGO_RANDOMNESS.to_vec(),
self.randomness.encode(),
);
insert(relay_chain::well_known_keys::CURRENT_SLOT.to_vec(), self.current_slot.encode());
}

Expand Down