diff --git a/primitives/parachain-inherent/src/mock.rs b/primitives/parachain-inherent/src/mock.rs index e69b0a80911..e4ca16414c1 100644 --- a/primitives/parachain-inherent/src/mock.rs +++ b/primitives/parachain-inherent/src/mock.rs @@ -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 { /// 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 @@ -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 + 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. @@ -59,6 +64,20 @@ pub struct MockValidationDataInherentDataProvider { pub raw_horizontal_messages: Vec<(ParaId, Vec)>, } +pub trait GenerateRandomness { + fn generate_randomness(&self, input: I) -> relay_chain::Hash; +} + +impl GenerateRandomness 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 @@ -130,7 +149,9 @@ impl MockXcmConfig { } #[async_trait::async_trait] -impl InherentDataProvider for MockValidationDataInherentDataProvider { +impl> InherentDataProvider + for MockValidationDataInherentDataProvider +{ fn provide_inherent_data( &self, inherent_data: &mut InherentData, @@ -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( diff --git a/test/relay-sproof-builder/src/lib.rs b/test/relay-sproof-builder/src/lib.rs index 1faa37a1478..5c2a1a1063f 100644 --- a/test/relay-sproof-builder/src/lib.rs +++ b/test/relay-sproof-builder/src/lib.rs @@ -44,6 +44,7 @@ pub struct RelayStateSproofBuilder { pub hrmp_channels: BTreeMap, pub current_slot: relay_chain::v2::Slot, pub current_epoch: u64, + pub randomness: relay_chain::Hash, } impl Default for RelayStateSproofBuilder { @@ -69,6 +70,7 @@ impl Default for RelayStateSproofBuilder { hrmp_channels: BTreeMap::new(), current_slot: 0.into(), current_epoch: 0u64, + randomness: relay_chain::Hash::default(), } } } @@ -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()); }