Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into tomasz-zombie-manua…
Browse files Browse the repository at this point in the history
…l-ci
  • Loading branch information
tmpolaczyk committed Jul 30, 2024
2 parents bc2002b + 3d6ee41 commit b2866de
Show file tree
Hide file tree
Showing 15 changed files with 561 additions and 63 deletions.
9 changes: 8 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions pallets/author-noting/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ sp-trie = { workspace = true }

cumulus-pallet-parachain-system = { workspace = true }
cumulus-primitives-core = { workspace = true }
dp-chain-state-snapshot = { workspace = true }
dp-core = { workspace = true }
nimbus-primitives = { workspace = true }
tp-author-noting-inherent = { workspace = true }
Expand All @@ -55,7 +54,6 @@ std = [
"cumulus-pallet-parachain-system/std",
"cumulus-primitives-core/std",
"cumulus-primitives-core/std",
"dp-chain-state-snapshot/std",
"dp-core/std",
"frame-benchmarking/std",
"frame-support/std",
Expand Down
58 changes: 36 additions & 22 deletions pallets/author-noting/src/benchmarks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@

//! Benchmarking
use {
crate::{Call, Config, Pallet},
cumulus_pallet_parachain_system::RelaychainStateProvider,
crate::{Call, Config, Pallet, RelayOrPara},
core::any::{Any, TypeId},
frame_benchmarking::{account, benchmarks},
frame_support::assert_ok,
frame_system::RawOrigin,
Expand Down Expand Up @@ -57,31 +57,45 @@ benchmarks! {
// Depend on the number of parachains registered
let x in 0..100;

let mut sproof_builder = test_sproof::ParaHeaderSproofBuilder::default();
let mut container_chains = vec![];

for para_id in 0..x {
let para_id = para_id.into();
container_chains.push(para_id);
// Mock assigned authors for this para id
let author: T::AccountId = account("account id", 0u32, 0u32);
// Use the max allowed value for num_each_container_chain
let num_each_container_chain = 2;
T::ContainerChainAuthor::set_authors_for_para_id(para_id, vec![author; num_each_container_chain]);
sproof_builder.num_items += 1;
}

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

let data = tp_author_noting_inherent::OwnParachainInherentData {
relay_storage_proof: proof,
let data = if TypeId::of::<<<T as Config>::RelayOrPara as RelayOrPara>::InherentArg>() == TypeId::of::<tp_author_noting_inherent::OwnParachainInherentData>() {
let mut sproof_builder = test_sproof::ParaHeaderSproofBuilder::default();

for para_id in 0..x {
let para_id = para_id.into();
container_chains.push(para_id);
// Mock assigned authors for this para id
let author: T::AccountId = account("account id", 0u32, 0u32);
// Use the max allowed value for num_each_container_chain
let num_each_container_chain = 2;
T::ContainerChainAuthor::set_authors_for_para_id(para_id, vec![author; num_each_container_chain]);
sproof_builder.num_items += 1;
}

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

T::RelayOrPara::set_current_relay_chain_state(cumulus_pallet_parachain_system::RelayChainState {
state_root: root,
number: 0,
});

let arg = tp_author_noting_inherent::OwnParachainInherentData {
relay_storage_proof: proof,
};

*(Box::new(arg) as Box<dyn Any>).downcast().unwrap()
} else if TypeId::of::<<<T as Config>::RelayOrPara as RelayOrPara>::InherentArg>() == TypeId::of::<()>() {
// TODO: we need to write to storage the elements from the proof
unimplemented!("Benchmark will fail because headers have not been written to storage");
//let arg = ();
//*(Box::new(arg) as Box<dyn Any>).downcast().unwrap()
} else {
unreachable!("Unknown InherentArg")
};

T::ContainerChains::set_current_container_chains(&container_chains);
T::RelayChainStateProvider::set_current_relay_chain_state(cumulus_pallet_parachain_system::RelayChainState {
state_root: root,
number: 0,
});

}: _(RawOrigin::None, data)

set_author {
Expand Down
107 changes: 82 additions & 25 deletions pallets/author-noting/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
#![cfg_attr(not(feature = "std"), no_std)]

pub use dp_chain_state_snapshot::*;
use {
cumulus_pallet_parachain_system::RelaychainStateProvider,
cumulus_primitives_core::{
Expand All @@ -47,8 +46,9 @@ use {
sp_runtime::{traits::Header, DigestItem, DispatchResult, RuntimeString},
tp_author_noting_inherent::INHERENT_IDENTIFIER,
tp_traits::{
AuthorNotingHook, ContainerChainBlockInfo, GetContainerChainAuthor,
GetCurrentContainerChains,
AuthorNotingHook, ContainerChainBlockInfo, GenericStateProof, GenericStorageReader,
GetContainerChainAuthor, GetCurrentContainerChains, LatestAuthorInfoFetcher,
NativeStorageReader, ReadEntryErr,
},
};

Expand All @@ -66,7 +66,6 @@ mod benchmarks;
mod mock_proof;

pub use pallet::*;
use tp_traits::LatestAuthorInfoFetcher;

#[frame_support::pallet]
pub mod pallet {
Expand All @@ -79,18 +78,17 @@ pub mod pallet {

type ContainerChains: GetCurrentContainerChains;

type SelfParaId: Get<ParaId>;
type SlotBeacon: SlotBeacon;

type ContainerChainAuthor: GetContainerChainAuthor<Self::AccountId>;

type RelayChainStateProvider: cumulus_pallet_parachain_system::RelaychainStateProvider;

/// An entry-point for higher-level logic to react to containers chains authoring.
///
/// Typically, this can be a hook to reward block authors.
type AuthorNotingHook: AuthorNotingHook<Self::AccountId>;

type RelayOrPara: RelayOrPara;

/// Weight information for extrinsics in this pallet.
type WeightInfo: WeightInfo;
}
Expand Down Expand Up @@ -140,7 +138,7 @@ pub mod pallet {
#[pallet::weight((T::WeightInfo::set_latest_author_data(<T::ContainerChains as GetCurrentContainerChains>::MaxContainerChains::get()), DispatchClass::Mandatory))]
pub fn set_latest_author_data(
origin: OriginFor<T>,
data: tp_author_noting_inherent::OwnParachainInherentData,
data: InherentDataOf<T>,
) -> DispatchResultWithPostInfo {
ensure_none(origin)?;

Expand All @@ -157,22 +155,15 @@ pub mod pallet {
// when we have no containers registered
// Essentially one can pass an empty proof if no container-chains are registered
if !registered_para_ids.is_empty() {
let tp_author_noting_inherent::OwnParachainInherentData {
relay_storage_proof,
} = data;

let relay_chain_state = T::RelayChainStateProvider::current_relay_chain_state();
let relay_storage_root = relay_chain_state.state_root;
let relay_storage_rooted_proof =
GenericStateProof::new(relay_storage_root, relay_storage_proof)
.expect("Invalid relay chain state proof");
let storage_reader = T::RelayOrPara::create_storage_reader(data);

let parent_tanssi_slot = u64::from(T::SlotBeacon::slot()).into();

// TODO: we should probably fetch all authors-containers first
// then pass the vector to the hook, this would allow for a better estimation
for para_id in registered_para_ids {
match Self::fetch_block_info_from_proof(
&relay_storage_rooted_proof,
&storage_reader,
para_id,
parent_tanssi_slot,
) {
Expand Down Expand Up @@ -304,11 +295,7 @@ pub mod pallet {
}

fn create_inherent(data: &InherentData) -> Option<Self::Call> {
let data: tp_author_noting_inherent::OwnParachainInherentData = data
.get_data(&INHERENT_IDENTIFIER)
.ok()
.flatten()
.expect("there is not data to be posted; qed");
let data = T::RelayOrPara::create_inherent_arg(data);

Some(Call::set_latest_author_data { data })
}
Expand All @@ -321,8 +308,8 @@ pub mod pallet {

impl<T: Config> Pallet<T> {
/// Fetch author and block number from a proof of header
fn fetch_block_info_from_proof(
relay_state_proof: &GenericStateProof<cumulus_primitives_core::relay_chain::Block>,
fn fetch_block_info_from_proof<S: GenericStorageReader>(
relay_state_proof: &S,
para_id: ParaId,
tanssi_slot: Slot,
) -> Result<ContainerChainBlockInfo<T::AccountId>, Error<T>> {
Expand Down Expand Up @@ -437,3 +424,73 @@ impl<T: Config> LatestAuthorInfoFetcher<T::AccountId> for Pallet<T> {
LatestAuthor::<T>::get(para_id)
}
}

/// This pallet has slightly different behavior when used in a parachain vs when used in a relay chain
/// (solochain). The main difference is:
/// * In relay mode, we don't need a storage proof, so the inherent doesn't need any input argument,
/// and instead of reading from a storage proof we read from storage directly.
pub trait RelayOrPara {
type InherentArg: TypeInfo + Clone + PartialEq + Encode + Decode + core::fmt::Debug;
type GenericStorageReader: GenericStorageReader;

fn create_inherent_arg(data: &InherentData) -> Self::InherentArg;
fn create_storage_reader(data: Self::InherentArg) -> Self::GenericStorageReader;

#[cfg(feature = "runtime-benchmarks")]
fn set_current_relay_chain_state(state: cumulus_pallet_parachain_system::RelayChainState);
}

pub type InherentDataOf<T> = <<T as Config>::RelayOrPara as RelayOrPara>::InherentArg;

pub struct RelayMode;
pub struct ParaMode<RCSP: RelaychainStateProvider>(PhantomData<RCSP>);

impl RelayOrPara for RelayMode {
type InherentArg = ();
type GenericStorageReader = NativeStorageReader;

fn create_inherent_arg(_data: &InherentData) -> Self::InherentArg {
// This ignores the inherent data entirely, so it is compatible with clients that don't add our inherent
}

fn create_storage_reader(_data: Self::InherentArg) -> Self::GenericStorageReader {
NativeStorageReader
}

#[cfg(feature = "runtime-benchmarks")]
fn set_current_relay_chain_state(_state: cumulus_pallet_parachain_system::RelayChainState) {}
}

impl<RCSP: RelaychainStateProvider> RelayOrPara for ParaMode<RCSP> {
type InherentArg = tp_author_noting_inherent::OwnParachainInherentData;
type GenericStorageReader = GenericStateProof<cumulus_primitives_core::relay_chain::Block>;

fn create_inherent_arg(data: &InherentData) -> Self::InherentArg {
let data/*: tp_author_noting_inherent::OwnParachainInherentData*/ = data
.get_data(&INHERENT_IDENTIFIER)
.ok()
.flatten()
.expect("there is not data to be posted; qed");

data
}

fn create_storage_reader(data: Self::InherentArg) -> Self::GenericStorageReader {
let tp_author_noting_inherent::OwnParachainInherentData {
relay_storage_proof,
} = data;

let relay_chain_state = RCSP::current_relay_chain_state();
let relay_storage_root = relay_chain_state.state_root;
let relay_storage_rooted_proof =
GenericStateProof::new(relay_storage_root, relay_storage_proof)
.expect("Invalid relay chain state proof");

relay_storage_rooted_proof
}

#[cfg(feature = "runtime-benchmarks")]
fn set_current_relay_chain_state(state: cumulus_pallet_parachain_system::RelayChainState) {
RCSP::set_current_relay_chain_state(state)
}
}
6 changes: 3 additions & 3 deletions pallets/author-noting/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// along with Tanssi. If not, see <http://www.gnu.org/licenses/>

use {
crate::{self as author_noting_pallet, Config},
crate::{self as author_noting_pallet, Config, ParaMode},
bounded_collections::bounded_vec,
cumulus_pallet_parachain_system::{RelayChainState, RelaychainStateProvider},
cumulus_primitives_core::ParaId,
Expand Down Expand Up @@ -208,11 +208,11 @@ impl Config for Test {
type WeightInfo = ();
type RuntimeEvent = RuntimeEvent;
type ContainerChainAuthor = MockAuthorFetcher;
type SelfParaId = ParachainId;
type SlotBeacon = DummyBeacon;
type ContainerChains = MockContainerChainGetter;
type AuthorNotingHook = ();
type RelayChainStateProvider = MockRelayStateProvider;
// Unit tests only check ParaMode, for RelayMode see integration tests
type RelayOrPara = ParaMode<MockRelayStateProvider>;
}

struct BlockTest {
Expand Down
2 changes: 2 additions & 0 deletions primitives/traits/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ version = "0.1.0"
workspace = true

[dependencies]
dp-chain-state-snapshot = { workspace = true }
frame-support = { workspace = true }
impl-trait-for-tuples = { workspace = true }
macro_rules_attribute = { workspace = true }
Expand All @@ -27,6 +28,7 @@ cumulus-primitives-core = { workspace = true }
default = [ "std" ]
std = [
"cumulus-primitives-core/std",
"dp-chain-state-snapshot/std",
"frame-support/std",
"parity-scale-codec/std",
"scale-info/std",
Expand Down
Loading

0 comments on commit b2866de

Please sign in to comment.