Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[stable2412] Backport #6923 #6934

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
6 changes: 6 additions & 0 deletions Cargo.lock

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

110 changes: 110 additions & 0 deletions cumulus/polkadot-omni-node/lib/src/common/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,117 @@ pub trait RuntimeResolver {
pub struct DefaultRuntimeResolver;

impl RuntimeResolver for DefaultRuntimeResolver {
<<<<<<< HEAD
fn runtime(&self, _chain_spec: &dyn ChainSpec) -> sc_cli::Result<Runtime> {
Ok(Runtime::Omni(BlockNumber::U32, Consensus::Aura(AuraConsensusId::Sr25519)))
=======
fn runtime(&self, chain_spec: &dyn ChainSpec) -> sc_cli::Result<Runtime> {
let Ok(metadata_inspector) = MetadataInspector::new(chain_spec) else {
log::info!("Unable to check metadata. Skipping metadata checks. Metadata checks are supported for metadata versions v14 and higher.");
return Ok(Runtime::Omni(BlockNumber::U32, Consensus::Aura(AuraConsensusId::Sr25519)))
};

let block_number = match metadata_inspector.block_number() {
Some(inner) => inner,
None => {
log::warn!(
r#"⚠️ There isn't a runtime type named `System`, corresponding to the `frame-system`
pallet (https://docs.rs/frame-system/latest/frame_system/). Please check Omni Node docs for runtime conventions:
https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/omni_node/index.html#runtime-conventions.
Note: We'll assume a block number size of `u32`."#
);
BlockNumber::U32
},
};

if !metadata_inspector.pallet_exists(DEFAULT_PARACHAIN_SYSTEM_PALLET_NAME) {
log::warn!(
r#"⚠️ The parachain system pallet (https://docs.rs/crate/cumulus-pallet-parachain-system/latest) is
missing from the runtime’s metadata. Please check Omni Node docs for runtime conventions:
https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/omni_node/index.html#runtime-conventions."#
);
}

Ok(Runtime::Omni(block_number, Consensus::Aura(AuraConsensusId::Sr25519)))
}
}

struct MetadataInspector(Metadata);

impl MetadataInspector {
fn new(chain_spec: &dyn ChainSpec) -> Result<MetadataInspector, sc_cli::Error> {
MetadataInspector::fetch_metadata(chain_spec).map(MetadataInspector)
}

fn pallet_exists(&self, name: &str) -> bool {
self.0.pallet_by_name(name).is_some()
}

fn block_number(&self) -> Option<BlockNumber> {
let pallet_metadata = self.0.pallet_by_name(DEFAULT_FRAME_SYSTEM_PALLET_NAME);
pallet_metadata
.and_then(|inner| inner.storage())
.and_then(|inner| inner.entry_by_name("Number"))
.and_then(|number_ty| match number_ty.entry_type() {
StorageEntryType::Plain(ty_id) => Some(ty_id),
_ => None,
})
.and_then(|ty_id| self.0.types().resolve(*ty_id))
.and_then(|portable_type| BlockNumber::from_type_def(&portable_type.type_def))
}

fn fetch_metadata(chain_spec: &dyn ChainSpec) -> Result<Metadata, sc_cli::Error> {
let mut storage = chain_spec.build_storage()?;
let code_bytes = storage
.top
.remove(sp_storage::well_known_keys::CODE)
.ok_or("chain spec genesis does not contain code")?;
let opaque_metadata = fetch_latest_metadata_from_code_blob(
&WasmExecutor::<ParachainHostFunctions>::builder()
.with_allow_missing_host_functions(true)
.build(),
sp_runtime::Cow::Borrowed(code_bytes.as_slice()),
)
.map_err(|err| err.to_string())?;

Metadata::decode(&mut (*opaque_metadata).as_slice()).map_err(Into::into)
}
}

#[cfg(test)]
mod tests {
use crate::runtime::{
BlockNumber, MetadataInspector, DEFAULT_FRAME_SYSTEM_PALLET_NAME,
DEFAULT_PARACHAIN_SYSTEM_PALLET_NAME,
};
use codec::Decode;
use cumulus_client_service::ParachainHostFunctions;
use sc_executor::WasmExecutor;
use sc_runtime_utilities::fetch_latest_metadata_from_code_blob;

fn cumulus_test_runtime_metadata() -> subxt_metadata::Metadata {
let opaque_metadata = fetch_latest_metadata_from_code_blob(
&WasmExecutor::<ParachainHostFunctions>::builder()
.with_allow_missing_host_functions(true)
.build(),
sp_runtime::Cow::Borrowed(cumulus_test_runtime::WASM_BINARY.unwrap()),
)
.unwrap();

subxt_metadata::Metadata::decode(&mut (*opaque_metadata).as_slice()).unwrap()
}

#[test]
fn test_pallet_exists() {
let metadata_inspector = MetadataInspector(cumulus_test_runtime_metadata());
assert!(metadata_inspector.pallet_exists(DEFAULT_PARACHAIN_SYSTEM_PALLET_NAME));
assert!(metadata_inspector.pallet_exists(DEFAULT_FRAME_SYSTEM_PALLET_NAME));
}

#[test]
fn test_runtime_block_number() {
let metadata_inspector = MetadataInspector(cumulus_test_runtime_metadata());
assert_eq!(metadata_inspector.block_number().unwrap(), BlockNumber::U32);
>>>>>>> e6ddd392 (omni-node: Tolerate failing metadata check (#6923))
}
}
12 changes: 12 additions & 0 deletions prdoc/pr_6923.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
title: 'omni-node: Tolerate failing metadata check'
doc:
- audience: Node Operator
description: |-
#6450 introduced metadata checks. Supported are metadata v14 and higher.

However, of course old chain-specs have a genesis code blob that might be on older version. This needs to be tolerated. We should just skip the checks in that case.

Fixes #6921
crates:
- name: polkadot-omni-node-lib
bump: patch
Loading