Support v16 metadata and use it by default if it's available (#1999)

* Support v16 metadata and use it by default if it's available

* lockfile

* fix blocks test; new transaction extension in kitchensink runtime

* Bump scale-typegen to 0.11.1 to cater for Duration prelude type

* fmt

* Fix no-std test building

* Cargo update and bump substrate deps

* Update test and no-std deps

* fmt

* fix test
This commit is contained in:
James Wilson
2025-05-08 14:44:44 +01:00
committed by GitHub
parent 4524590821
commit 9ba89e3ed7
16 changed files with 1674 additions and 1223 deletions
+28 -30
View File
@@ -90,23 +90,23 @@ async fn fetch_metadata_http(url: Url, version: MetadataVersion) -> Result<Vec<u
async fn fetch_metadata(client: impl ClientT, version: MetadataVersion) -> Result<Vec<u8>, Error> {
const UNSTABLE_METADATA_VERSION: u32 = u32::MAX;
// Fetch available metadata versions. If error, revert to legacy metadata code.
async fn fetch_available_versions(
client: &impl ClientT,
) -> Result<Vec<u32>, Error> {
let res: String = client
.request("state_call", rpc_params!["Metadata_metadata_versions", "0x"])
.await?;
let raw_bytes = hex::decode(res.trim_start_matches("0x"))?;
Decode::decode(&mut &raw_bytes[..]).map_err(Into::into)
}
// Fetch metadata using the "new" state_call interface
async fn fetch_inner(
client: &impl ClientT,
version: MetadataVersion,
supported_versions: Vec<u32>,
) -> Result<Vec<u8>, Error> {
// Look up supported versions:
let supported_versions: Vec<u32> = {
let res: String = client
.request(
"state_call",
rpc_params!["Metadata_metadata_versions", "0x"],
)
.await?;
let raw_bytes = hex::decode(res.trim_start_matches("0x"))?;
Decode::decode(&mut &raw_bytes[..])?
};
// Return the version the user wants if it's supported:
let version = match version {
MetadataVersion::Latest => *supported_versions
@@ -128,7 +128,7 @@ async fn fetch_metadata(client: impl ClientT, version: MetadataVersion) -> Resul
version
} else {
return Err(Error::Other(format!(
"The node does not have version {version} available"
"The node does not have metadata version {version} available"
)));
}
}
@@ -150,7 +150,7 @@ async fn fetch_metadata(client: impl ClientT, version: MetadataVersion) -> Resul
Decode::decode(&mut &metadata_bytes[..])?;
let Some(metadata) = metadata else {
return Err(Error::Other(format!(
"The node does not have version {version} available"
"The node does not have metadata version {version} available"
)));
};
Ok(metadata.0)
@@ -159,19 +159,7 @@ async fn fetch_metadata(client: impl ClientT, version: MetadataVersion) -> Resul
// Fetch metadata using the "old" state_call interface
async fn fetch_inner_legacy(
client: &impl ClientT,
version: MetadataVersion,
) -> Result<Vec<u8>, Error> {
// If the user specifically asks for anything other than version 14 or "latest", error.
if !matches!(
version,
MetadataVersion::Latest | MetadataVersion::Version(14)
) {
return Err(Error::Other(
"The node can only return version 14 metadata using the legacy API but you've asked for something else"
.to_string(),
));
}
// Fetch the metadata.
let metadata_string: String = client
.request("state_call", rpc_params!["Metadata_metadata", "0x"])
@@ -183,9 +171,19 @@ async fn fetch_metadata(client: impl ClientT, version: MetadataVersion) -> Resul
Ok(metadata.0)
}
// Fetch using the new interface, falling back to trying old one if there's an error.
match fetch_inner(&client, version).await {
Ok(s) => Ok(s),
Err(_) => fetch_inner_legacy(&client, version).await,
match fetch_available_versions(&client).await {
Ok(supported_versions) => {
fetch_inner(&client, version, supported_versions).await
},
Err(e) => {
// The "new" interface failed. if the user is asking for V14 or the "latest"
// metadata then try the legacy interface instead. Else, just return the
// reason for failure.
if matches!(version, MetadataVersion::Version(14) | MetadataVersion::Latest) {
fetch_inner_legacy(&client).await
} else {
Err(e)
}
}
}
}
+13 -12
View File
@@ -100,7 +100,7 @@ impl StripMetadata for v16::RuntimeMetadataV16 {
error: None,
view_functions: vec![],
docs: vec![],
deprecation_info: v16::DeprecationStatus::NotDeprecated,
deprecation_info: v16::ItemDeprecationInfo::NotDeprecated,
};
}
}
@@ -780,26 +780,26 @@ mod test {
ty: frame_metadata::v16::StorageEntryType::Plain(meta_type::<A>()),
default: vec![],
docs: vec![],
deprecation_info: v16::DeprecationStatus::NotDeprecated,
deprecation_info: v16::ItemDeprecationInfo::NotDeprecated,
}],
}),
event: Some(v16::PalletEventMetadata {
ty: meta_type::<B>(),
deprecation_info: v16::DeprecationInfo::NotDeprecated,
deprecation_info: v16::EnumDeprecationInfo::nothing_deprecated(),
}),
constants: vec![],
associated_types: vec![],
view_functions: vec![],
error: None,
docs: vec![],
deprecation_info: v16::DeprecationStatus::NotDeprecated,
deprecation_info: v16::ItemDeprecationInfo::NotDeprecated,
},
v16::PalletMetadata {
name: "Second",
index: 1,
calls: Some(v16::PalletCallMetadata {
ty: meta_type::<C>(),
deprecation_info: v16::DeprecationInfo::NotDeprecated,
deprecation_info: v16::EnumDeprecationInfo::nothing_deprecated(),
}),
storage: None,
event: None,
@@ -808,7 +808,7 @@ mod test {
ty: meta_type::<D>(),
value: vec![],
docs: vec![],
deprecation_info: v16::DeprecationStatus::NotDeprecated,
deprecation_info: v16::ItemDeprecationInfo::NotDeprecated,
}],
associated_types: vec![v16::PalletAssociatedTypeMetadata {
name: "Hasher",
@@ -824,15 +824,16 @@ mod test {
}],
output: meta_type::<G>(),
docs: vec![],
deprecation_info: v16::DeprecationStatus::NotDeprecated,
deprecation_info: v16::ItemDeprecationInfo::NotDeprecated,
}],
error: None,
docs: vec![],
deprecation_info: v16::DeprecationStatus::NotDeprecated,
deprecation_info: v16::ItemDeprecationInfo::NotDeprecated,
},
];
let extrinsic = v16::ExtrinsicMetadata {
call_ty: meta_type::<N>(), // same as outer_enums.call_enum_ty
versions: vec![0],
transaction_extensions_by_version: BTreeMap::new(),
transaction_extensions: vec![],
@@ -845,7 +846,7 @@ mod test {
name: "SomeApi",
version: Compact(2),
docs: vec![],
deprecation_info: v16::DeprecationStatus::NotDeprecated,
deprecation_info: v16::ItemDeprecationInfo::NotDeprecated,
methods: vec![v16::RuntimeApiMethodMetadata {
name: "some_method",
inputs: vec![v16::FunctionParamMetadata {
@@ -854,14 +855,14 @@ mod test {
}],
output: meta_type::<K>(),
docs: vec![],
deprecation_info: v16::DeprecationStatus::NotDeprecated,
deprecation_info: v16::ItemDeprecationInfo::NotDeprecated,
}],
},
v16::RuntimeApiMetadata {
name: "AnotherApi",
version: Compact(1),
docs: vec![],
deprecation_info: v16::DeprecationStatus::NotDeprecated,
deprecation_info: v16::ItemDeprecationInfo::NotDeprecated,
methods: vec![v16::RuntimeApiMethodMetadata {
name: "another_method",
inputs: vec![v16::FunctionParamMetadata {
@@ -870,7 +871,7 @@ mod test {
}],
output: meta_type::<M>(),
docs: vec![],
deprecation_info: v16::DeprecationStatus::NotDeprecated,
deprecation_info: v16::ItemDeprecationInfo::NotDeprecated,
}],
},
];