mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 04:41:03 +00:00
Relay-parent digest logs for parachains (#2552)
* add digest item for relay-parent to primitives * add a relay-parent-storage-root digest as a workaround * more docs * deposit log in pallet-parachain-system * even more docs * fix duplicate imports after botched mertge * fix hyperlinks in docs * clean up match Co-authored-by: Bastian Köcher <git@kchr.de> * improve docs * fix typo * add number to the digest item --------- Co-authored-by: Bastian Köcher <git@kchr.de>
This commit is contained in:
@@ -385,6 +385,16 @@ pub mod pallet {
|
|||||||
)
|
)
|
||||||
.expect("Invalid relay chain state proof");
|
.expect("Invalid relay chain state proof");
|
||||||
|
|
||||||
|
// Deposit a log indicating the relay-parent storage root.
|
||||||
|
// TODO: remove this in favor of the relay-parent's hash after
|
||||||
|
// https://github.com/paritytech/cumulus/issues/303
|
||||||
|
frame_system::Pallet::<T>::deposit_log(
|
||||||
|
cumulus_primitives_core::rpsr_digest::relay_parent_storage_root_item(
|
||||||
|
vfp.relay_parent_storage_root,
|
||||||
|
vfp.relay_parent_number,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
// initialization logic: we know that this runs exactly once every block,
|
// initialization logic: we know that this runs exactly once every block,
|
||||||
// which means we can put the initialization logic here to remove the
|
// which means we can put the initialization logic here to remove the
|
||||||
// sequencing problem.
|
// sequencing problem.
|
||||||
|
|||||||
@@ -1006,3 +1006,18 @@ fn upgrade_version_checks_should_work() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn deposits_relay_parent_storage_root() {
|
||||||
|
BlockTests::new().add_with_post_test(
|
||||||
|
123,
|
||||||
|
|| {},
|
||||||
|
|| {
|
||||||
|
let digest = System::digest();
|
||||||
|
assert!(cumulus_primitives_core::rpsr_digest::extract_relay_parent_storage_root(
|
||||||
|
&digest
|
||||||
|
)
|
||||||
|
.is_some());
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
use polkadot_parachain::primitives::HeadData;
|
use polkadot_parachain::primitives::HeadData;
|
||||||
use scale_info::TypeInfo;
|
use scale_info::TypeInfo;
|
||||||
use sp_runtime::{traits::Block as BlockT, RuntimeDebug};
|
use sp_runtime::RuntimeDebug;
|
||||||
use sp_std::prelude::*;
|
use sp_std::prelude::*;
|
||||||
|
|
||||||
pub use polkadot_core_primitives::InboundDownwardMessage;
|
pub use polkadot_core_primitives::InboundDownwardMessage;
|
||||||
@@ -33,6 +33,12 @@ pub use polkadot_primitives::{
|
|||||||
AbridgedHostConfiguration, AbridgedHrmpChannel, PersistedValidationData,
|
AbridgedHostConfiguration, AbridgedHrmpChannel, PersistedValidationData,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub use sp_runtime::{
|
||||||
|
generic::{Digest, DigestItem},
|
||||||
|
traits::Block as BlockT,
|
||||||
|
ConsensusEngineId,
|
||||||
|
};
|
||||||
|
|
||||||
pub use xcm::latest::prelude::*;
|
pub use xcm::latest::prelude::*;
|
||||||
|
|
||||||
/// A module that re-exports relevant relay chain definitions.
|
/// A module that re-exports relevant relay chain definitions.
|
||||||
@@ -198,6 +204,88 @@ impl<B: BlockT> ParachainBlockData<B> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A consensus engine ID indicating that this is a Cumulus Parachain.
|
||||||
|
pub const CUMULUS_CONSENSUS_ID: ConsensusEngineId = *b"CMLS";
|
||||||
|
|
||||||
|
/// Consensus header digests for Cumulus parachains.
|
||||||
|
#[derive(Clone, RuntimeDebug, Decode, Encode, PartialEq)]
|
||||||
|
pub enum CumulusDigestItem {
|
||||||
|
/// A digest item indicating the relay-parent a parachain block was built against.
|
||||||
|
#[codec(index = 0)]
|
||||||
|
RelayParent(relay_chain::Hash),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CumulusDigestItem {
|
||||||
|
/// Encode this as a Substrate [`DigestItem`].
|
||||||
|
pub fn to_digest_item(&self) -> DigestItem {
|
||||||
|
DigestItem::Consensus(CUMULUS_CONSENSUS_ID, self.encode())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extract the relay-parent from the provided header digest. Returns `None` if none were found.
|
||||||
|
///
|
||||||
|
/// If there are multiple valid digests, this returns the value of the first one, although
|
||||||
|
/// well-behaving runtimes should not produce headers with more than one.
|
||||||
|
pub fn extract_relay_parent(digest: &Digest) -> Option<relay_chain::Hash> {
|
||||||
|
digest.convert_first(|d| match d {
|
||||||
|
DigestItem::Consensus(id, val) if id == &CUMULUS_CONSENSUS_ID =>
|
||||||
|
match CumulusDigestItem::decode(&mut &val[..]) {
|
||||||
|
Ok(CumulusDigestItem::RelayParent(hash)) => Some(hash),
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Utilities for handling the relay-parent storage root as a digest item.
|
||||||
|
///
|
||||||
|
/// This is not intended to be part of the public API, as it is a workaround for
|
||||||
|
/// <https://github.com/paritytech/cumulus/issues/303> via
|
||||||
|
/// <https://github.com/paritytech/polkadot/issues/7191>.
|
||||||
|
///
|
||||||
|
/// Runtimes using the parachain-system pallet are expected to produce this digest item,
|
||||||
|
/// but will stop as soon as they are able to provide the relay-parent hash directly.
|
||||||
|
///
|
||||||
|
/// The relay-chain storage root is, in practice, a unique identifier of a block
|
||||||
|
/// in the absence of equivocations (which are slashable). This assumes that the relay chain
|
||||||
|
/// uses BABE or SASSAFRAS, because the slot and the author's VRF randomness are both included
|
||||||
|
/// in the relay-chain storage root in both cases.
|
||||||
|
///
|
||||||
|
/// Therefore, the relay-parent storage root is a suitable identifier of unique relay chain
|
||||||
|
/// blocks in low-value scenarios such as performance optimizations.
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub mod rpsr_digest {
|
||||||
|
use super::{relay_chain, ConsensusEngineId, Decode, Digest, DigestItem, Encode};
|
||||||
|
use codec::Compact;
|
||||||
|
|
||||||
|
/// A consensus engine ID for relay-parent storage root digests.
|
||||||
|
pub const RPSR_CONSENSUS_ID: ConsensusEngineId = *b"RPSR";
|
||||||
|
|
||||||
|
/// Construct a digest item for relay-parent storage roots.
|
||||||
|
pub fn relay_parent_storage_root_item(
|
||||||
|
storage_root: relay_chain::Hash,
|
||||||
|
number: impl Into<Compact<relay_chain::BlockNumber>>,
|
||||||
|
) -> DigestItem {
|
||||||
|
DigestItem::Consensus(RPSR_CONSENSUS_ID, (storage_root, number.into()).encode())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extract the relay-parent storage root and number from the provided header digest. Returns `None`
|
||||||
|
/// if none were found.
|
||||||
|
pub fn extract_relay_parent_storage_root(
|
||||||
|
digest: &Digest,
|
||||||
|
) -> Option<(relay_chain::Hash, relay_chain::BlockNumber)> {
|
||||||
|
digest.convert_first(|d| match d {
|
||||||
|
DigestItem::Consensus(id, val) if id == &RPSR_CONSENSUS_ID => {
|
||||||
|
let (h, n): (relay_chain::Hash, Compact<relay_chain::BlockNumber>) =
|
||||||
|
Decode::decode(&mut &val[..]).ok()?;
|
||||||
|
|
||||||
|
Some((h, n.0))
|
||||||
|
},
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Information about a collation.
|
/// Information about a collation.
|
||||||
///
|
///
|
||||||
/// This was used in version 1 of the [`CollectCollationInfo`] runtime api.
|
/// This was used in version 1 of the [`CollectCollationInfo`] runtime api.
|
||||||
|
|||||||
Reference in New Issue
Block a user