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 runtime_upgrades() runtime API for DomainRuntimeUpgrades #3337

Merged
merged 6 commits into from
Jan 8, 2025

Conversation

teor2345
Copy link
Member

@teor2345 teor2345 commented Jan 7, 2025

This PR adds a new runtime_upgrades() domains runtime API, which returns the contents of DomainRuntimeUpgrades.

It simplifies the fraud proof and inherents code that searches through the block header for upgrades, to use the new API instead. (No inherents are added or removed, we just change how we process them to avoid duplicating the same work inside and outside the runtime.)

I also made some changes to:

  • clarify the names of the domain runtime code proofs
  • clarify the domains API doc comments

Part of #3281.

This PR doesn't need spec changes, because the changes are too low-level. The changes in my spec PR describe the implementation before and after the changes in this PR.
subspace/protocol-specs#51

Code contributor checklist:

@teor2345 teor2345 added the breaking-runtime This PR introduces breaking changes to the runtime label Jan 7, 2025
@teor2345 teor2345 self-assigned this Jan 7, 2025
NingLin-P
NingLin-P previously approved these changes Jan 7, 2025
Copy link
Member

@NingLin-P NingLin-P left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

Comment on lines +80 to +103
// The runtime_upgrades() API is only present in API versions 2 and later. On earlier versions,
// we need to call legacy code.
// TODO: remove version check before next network
let domains_api_version = runtime_api
.api_version::<dyn DomainsApi<CBlock, CBlock::Header>>(consensus_block_hash)?
// It is safe to return a default version of 1, since there will always be version 1.
.unwrap_or(1);

let is_upgraded = if domains_api_version >= 2 {
let runtime_upgrades = runtime_api.runtime_upgrades(consensus_block_hash)?;
runtime_upgrades.contains(&runtime_id)
} else {
let header = consensus_client.header(consensus_block_hash)?.ok_or(
sp_blockchain::Error::MissingHeader(format!(
"No header found for {consensus_block_hash:?}"
)),
)?;
header
.digest()
.logs
.iter()
.filter_map(|log| log.as_domain_runtime_upgrade())
.any(|upgraded_runtime_id| upgraded_runtime_id == runtime_id)
};
Copy link
Member Author

@teor2345 teor2345 Jan 8, 2025

Choose a reason for hiding this comment

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

I think we'll need this compatibility code for inherents, so that runtime upgrades on Taurus will work. I avoided repeating the compatibility code by calling this method instead.

I think we'll be able to remove this code (edit: the compatibility code) after the runtime on Taurus is upgraded, and most nodes on Taurus and Mainnet are upgraded?

Copy link
Member

Choose a reason for hiding this comment

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

I didn't read into this PR to understand the context, but as a general rule inherents can't be removed without making it impossible to import older blocks. They are kind of like host functions for runtime environment that once added can't be removed.

Copy link
Member Author

@teor2345 teor2345 Jan 8, 2025

Choose a reason for hiding this comment

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

I didn't read into this PR to understand the context, but as a general rule inherents can't be removed without making it impossible to import older blocks. They are kind of like host functions for runtime environment that once added can't be removed.

No inherents are added or removed in this PR, it just changes how we process them to avoid some duplicate work.

This PR changes the runtime code the domain client calls when it processes a domain runtime upgrade inherent. Previously, we searched through the block header to determine if the runtime was upgraded. Now we ask the runtime for a list of upgraded runtime IDs (which the domains pallet has already determined by doing a similar search.)

Copy link
Member

Choose a reason for hiding this comment

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

I think we'll be able to remove this code (edit: the compatibility code) after the runtime on Taurus is upgraded, and most nodes on Taurus and Mainnet are upgraded.

Nazar is correct, we can't remove the compatibility code even after runtime/node upgraded. Because the runtime code is on-chain state, it applies to block that after the upgrade and before the next upgrade, older block will still use the old runtime (which doesn't have the new runtime API). Image a node (running on the latest release that doesn't contain the compatibility code) just joined the network and sync from genesis, it will fail to call the new API until the block that upgrade the runtime.

@teor2345 teor2345 requested a review from NingLin-P January 8, 2025 01:40
@teor2345 teor2345 added this pull request to the merge queue Jan 8, 2025
Merged via the queue into main with commit bfa1eef Jan 8, 2025
8 checks passed
@teor2345 teor2345 deleted the runtime-upgrades-api branch January 8, 2025 11:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking-runtime This PR introduces breaking changes to the runtime
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants