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

add the ability to declare multiple impl blocks #6795

Open
wants to merge 15 commits into
base: master
Choose a base branch
from

Conversation

pkhry
Copy link
Contributor

@pkhry pkhry commented Dec 9, 2024

Description

Adds the ability to split single impl_runtime_apis into multiple modules through sp_api::impl_runtime_apis_ext.

Example block would look like:

impl_runtime_apis! {
    impl trait Example<Block> for Runtime {
             fn example() {}
    }
    // `use` makes metadata from and runtime_versions visible to the main impl block.
    use other::*;
}

#[sp_api::impl_runtime_apis_ext]
mod other {
        use super::*; 
     	impl super::Example2<Block> for Runtime {
		fn same_name() -> String {
			"example".to_string()
		}
	}
}

also see: #3067

Review Notes

The main difference between impl_runtime_apis and impl_runtime_apis_ext is the fact that the latter doesn't generate base runtime structures and doesn't track the imports to aggregate them inside the metadata and runtime_api_versions.

Everything needs to be defined in the same crate due to dependency on RuntimeApi struct that will need to be imported into the impl_runtime_apis_ext manually for now.

TODOs:

  • RUNTIME_API_VERSION
    was a const before, i've moved it to a standalone function inside the main impl block.
    The question is should it be tied to the runtime via trait e.g RuntimeApiVersion and if yes where should it go?(sp_api or sp_version)
    I've tried to figure out a way to use a const but given that all of the const declarations contain data inside a std::borrow::Cow and and there's no way to get value out in const expression and i've failed to do so, if someone has any idea how to get around this i would really appreciate some input.
    		pub fn runtime_api_versions() -> #c::ApisVec {
    		let api = #c::vec::Vec::from([RUNTIME_API_VERSIONS.into_owned(), #(#modules::RUNTIME_API_VERSIONS.into_owned()),*]).concat();
    		api.into()
    	}

@pkhry
Copy link
Contributor Author

pkhry commented Dec 11, 2024

/cmd fmt

@pkhry pkhry added I5-enhancement An additional feature request. T1-FRAME This PR/Issue is related to core FRAME, the framework. D1-medium Can be fixed by a coder with good Rust knowledge but little knowledge of the codebase. labels Dec 11, 2024
Copy link

Command "fmt" has started 🚀 See logs here

Copy link

Command "fmt" has finished ✅ See logs here

@pkhry pkhry marked this pull request as ready for review December 16, 2024 15:04
@pkhry pkhry requested a review from a team as a code owner December 16, 2024 15:04
Copy link
Contributor

@gui1117 gui1117 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, but I didn't look carefully.

@@ -374,7 +404,7 @@ fn generate_runtime_api_base_structures() -> Result<TokenStream> {
{
type RuntimeApi = RuntimeApiImpl<Block, C>;

fn construct_runtime_api<'a>(
fn construct_runtime_api<'a>(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
fn construct_runtime_api<'a>(
fn construct_runtime_api<'a>(

Comment on lines 925 to 928
pub fn runtime_api_versions() -> #c::ApisVec {
let api = #c::vec::Vec::from([RUNTIME_API_VERSIONS.into_owned(), #(#modules::RUNTIME_API_VERSIONS.into_owned()),*]).concat();
api.into()
}
Copy link
Contributor

@gui1117 gui1117 Dec 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really like that RUNTIME_API_VERSIONS change its definition from: "all runtime api versions" to "runtime api versions only defined in the main macro". And that people should now use runtime_api_versions.

I would prefer to deprecate or remove, rather than changing the definition like this.

Why not handling this on the macro side: impl_ext can generate a PARTIAL_API_VERSIONS constant and the main macro would then concatenate all the versions in the final constant.

You can concatenate in const like this:

const A: &[(u32, u32)] = &[(0, 1)];
const B: &[(u32, u32)] = &[(0, 1)];
const C: alloc::borrow::Cow<'static, [(u32, u32)]> = Cow::Borrowed({
	const LEN: usize = A.len() + B.len();
	const ARR: [(u32, u32); LEN] = {
		let mut arr = [(0, 0); LEN];
		let mut cursor = 0;
		let mut i = 0;
		while i < A.len() {
			arr[i] = A[i];
			i += 1;
		}
		let mut i = 0;
		while i < B.len() {
			arr[cursor] = B[i];
			cursor += 1;
			i += 1;
		}
		arr
	};
	&ARR
});

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines 873 to 893
let mut path: Vec<Ident> = vec![];
fn call(path: &mut Vec<Ident>, item: &UseTree) -> Result<()> {
match &item {
syn::UseTree::Path(use_path) => {
path.push(use_path.ident.clone());
call(path, use_path.tree.as_ref())
},
syn::UseTree::Glob(_) => Ok(()),
syn::UseTree::Name(_) | syn::UseTree::Rename(_) | syn::UseTree::Group(_) => {
let error = Error::new(
item.span(),
"Unsupported syntax used to import api implementaions from an extension module. \
Try using `pub use <path>::*` or `use <path>::*`",
);
return Err(error)
},
}
}
call(&mut path, &item.tree)?;
let tok = quote::quote! {#(#path)::*};
Ok(syn::parse::<TypePath>(tok.into())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe move this to its own function for readability.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed alltogether

Kind::Ext => quote! {
#[doc(hidden)]
#[inline(always)]
pub fn runtime_metadata() -> #crate_::vec::Vec<#crate_::metadata_ir::RuntimeApiMetadataIR> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would name it partial_runtime_metadata to avoid confusion and suggestions from rustc

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

fn same_name() -> String {
"example".to_string()
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having 2 external implementation would be even better for testing. like ext1 and ext2.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added another one

@@ -102,17 +102,24 @@ mod apis {

fn wild_card(_: u32) {}
}
pub use ext::*;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually I don't very like to use rust-syntax to derive a different meaning. But here it can be ok as we still reexport ext in the scope, and only impl and use item are allowed.

I also feel a syntax like:

external_impl!{ext, ext2}

can be more readable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added custom syntax for those blocks following the suggestion as external_impls!{ <listed impls> }

@paritytech-review-bot paritytech-review-bot bot requested a review from a team January 8, 2025 16:03
@pkhry
Copy link
Contributor Author

pkhry commented Jan 8, 2025

/cmd fmt

Copy link

github-actions bot commented Jan 8, 2025

Command "fmt" has started 🚀 See logs here

Copy link

github-actions bot commented Jan 8, 2025

Command "fmt" has finished ✅ See logs here

@pkhry
Copy link
Contributor Author

pkhry commented Jan 8, 2025

bot update-ui

@command-bot
Copy link

command-bot bot commented Jan 8, 2025

@pkhry https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/jobs/7988624 was started for your command "$PIPELINE_SCRIPTS_DIR/commands/update-ui/update-ui.sh". Check out https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/pipelines?page=1&scope=all&username=group_605_bot to know what else is being executed currently.

Comment bot cancel 1-c947521c-6067-4a42-85e2-8a2553241df3 to cancel this command or bot cancel to cancel all commands in this pull request.

@command-bot
Copy link

command-bot bot commented Jan 8, 2025

@pkhry Command "$PIPELINE_SCRIPTS_DIR/commands/update-ui/update-ui.sh" has finished. Result: https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/jobs/7988624 has finished. If any artifacts were generated, you can download them from https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/jobs/7988624/artifacts/download.

@pkhry
Copy link
Contributor Author

pkhry commented Jan 8, 2025

/cmd update-ui

Copy link

github-actions bot commented Jan 8, 2025

Command "update-ui" has started 🚀 See logs here

@paritytech-workflow-stopper
Copy link

All GitHub workflows were cancelled due to failure one of the required jobs.
Failed workflow url: https://github.com/paritytech/polkadot-sdk/actions/runs/12675007314
Failed job name: test-linux-stable

1 similar comment
@paritytech-workflow-stopper
Copy link

All GitHub workflows were cancelled due to failure one of the required jobs.
Failed workflow url: https://github.com/paritytech/polkadot-sdk/actions/runs/12675007314
Failed job name: test-linux-stable

Copy link

github-actions bot commented Jan 8, 2025

Command "update-ui" has failed ❌! See logs here

@pkhry
Copy link
Contributor Author

pkhry commented Jan 10, 2025

/cmd update-ui

Copy link

Command "update-ui" has started 🚀 See logs here

Copy link

Command "update-ui" has finished ✅ See logs here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
D1-medium Can be fixed by a coder with good Rust knowledge but little knowledge of the codebase. I5-enhancement An additional feature request. T1-FRAME This PR/Issue is related to core FRAME, the framework.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants