Skip to content
Merged
Show file tree
Hide file tree
Changes from 61 commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
0f707a3
fix misleading comment
ordian Oct 7, 2024
2872818
wip, it compiles
ordian Oct 9, 2024
c403cb7
fix cumulus code fetching
ordian Oct 11, 2024
2b29d09
Merge branch 'master' into ao-fix-issue-64
ordian Oct 11, 2024
ec8953a
Merge branch 'master' into ao-fix-issue-64
ordian Oct 14, 2024
1f270c5
remove unused import
ordian Oct 14, 2024
2df352d
fmt with specific nightly version
ordian Oct 14, 2024
b805d5d
emit events on first setting pending code, fix benches
ordian Oct 14, 2024
f032277
some fixes
ordian Oct 16, 2024
cc678c6
avoid double negatives
ordian Oct 16, 2024
42ef263
make it actually work
ordian Oct 17, 2024
3e2b570
rm some todos
ordian Oct 18, 2024
c1a4613
use state_version to enact new upgrade mechanism
ordian Nov 4, 2024
9ea2099
Merge branch 'master' into ao-fix-issue-64
ordian Nov 5, 2024
6cb2d1a
Merge branch 'master' into ao-fix-issue-64
ordian Nov 28, 2024
b4fea58
Merge branch 'master' into ao-fix-issue-64
ordian Jan 6, 2025
c7aab54
fix cumulus runtime_upgrade_events test
ordian Jan 7, 2025
f2f031c
Merge branch 'master' into ao-fix-issue-64
ordian Jan 7, 2025
f559a11
not sure about this test fix..
ordian Jan 7, 2025
86c5223
Merge remote-tracking branch 'origin/ao-fix-issue-64' into ao-fix-iss…
ordian Jan 7, 2025
8eafd23
fmt
ordian Jan 7, 2025
025cedb
Merge branch 'master' into ao-fix-issue-64
ordian Jan 8, 2025
8f752db
Merge branch 'master' into ao-fix-issue-64
ordian Mar 11, 2025
1a38893
Merge remote-tracking branch 'origin' into ao-fix-issue-64
ordian Mar 17, 2025
2e296bd
remove TODO
ordian Mar 17, 2025
2f1b0a6
use exists and kill instead of optional
ordian Mar 17, 2025
c946aea
Merge branch 'ao-fix-issue-64' of github.com:paritytech/polkadot-sdk …
ordian Mar 17, 2025
199418b
Merge branch 'master' into ao-fix-issue-64
ordian Mar 25, 2025
c9a6397
make version_increment test runtime use system_version 3
ordian Apr 14, 2025
7b92cb5
actually use system_version 3 always for test runtime
ordian Apr 14, 2025
66c2373
simple unit test
ordian Apr 28, 2025
e1da881
Merge branch 'master' into ao-fix-issue-64
ordian Apr 28, 2025
8868f36
add missing file
ordian Apr 28, 2025
67a1bfe
Merge branch 'master' into ao-fix-issue-64
ordian May 27, 2025
8f15c8b
Merge branch 'master' into ao-fix-issue-64
ordian Jun 12, 2025
5cd6006
Merge branch 'master' into ao-fix-issue-64
ordian Jul 3, 2025
8166525
Merge branch 'master' into ao-fix-issue-64
ordian Jul 24, 2025
0e55b43
Merge branch 'master' into ao-fix-issue-64
ordian Jul 24, 2025
16b433a
Merge remote-tracking branch 'origin/master' into ao-fix-issue-64
s0me0ne-unkn0wn Nov 25, 2025
f9c0146
Merge branch 'master' into ao-fix-issue-64
s0me0ne-unkn0wn Dec 12, 2025
6f21c26
Apply suggestions from code review
s0me0ne-unkn0wn Dec 15, 2025
e640d86
Remove redundant mock
s0me0ne-unkn0wn Dec 15, 2025
748d479
Optimize storage operations; simplify logic
s0me0ne-unkn0wn Dec 17, 2025
77f02b0
Fix upgrade logic
s0me0ne-unkn0wn Dec 17, 2025
a57fe0d
Minor `fmt`
s0me0ne-unkn0wn Dec 17, 2025
d6a4b9f
Merge branch 'master' into ao-fix-issue-64
s0me0ne-unkn0wn Jan 8, 2026
c0ae2f8
Fix code fetching in basic collator
s0me0ne-unkn0wn Jan 13, 2026
9f36857
Merge branch 'master' into ao-fix-issue-64
s0me0ne-unkn0wn Jan 13, 2026
e68398e
Merge remote-tracking branch 'origin/master' into ao-fix-issue-64
s0me0ne-unkn0wn Feb 17, 2026
e207f35
`fmt`
s0me0ne-unkn0wn Feb 17, 2026
763a1cc
Fix logic and events to be RFC complaint
s0me0ne-unkn0wn Feb 17, 2026
1ad0dd3
Deposit log earlier
s0me0ne-unkn0wn Feb 18, 2026
39bf5e3
Merge remote-tracking branch 'origin/master' into ao-fix-issue-64
s0me0ne-unkn0wn Feb 23, 2026
af36a92
Make `runtime_version` call context-aware
s0me0ne-unkn0wn Feb 23, 2026
c323341
Address discussions
s0me0ne-unkn0wn Feb 26, 2026
b3b3b15
Merge remote-tracking branch 'origin/master' into ao-fix-issue-64
s0me0ne-unkn0wn Feb 26, 2026
6c36abe
Update from github-actions[bot] running command 'prdoc --bump major -…
github-actions[bot] Feb 26, 2026
2524869
`zepter`
s0me0ne-unkn0wn Feb 26, 2026
d99035d
Update pr_6029.prdoc
s0me0ne-unkn0wn Feb 26, 2026
cbc3529
Fix block validation
s0me0ne-unkn0wn Feb 27, 2026
36df204
Update tests
s0me0ne-unkn0wn Feb 27, 2026
e0fb90b
Fix `frame_system` tests
s0me0ne-unkn0wn Mar 2, 2026
109919a
Merge remote-tracking branch 'origin/master' into ao-fix-issue-64
s0me0ne-unkn0wn Mar 2, 2026
e4f18e8
Update from github-actions[bot] running command 'update-ui'
github-actions[bot] Mar 3, 2026
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
1 change: 1 addition & 0 deletions Cargo.lock

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

18 changes: 12 additions & 6 deletions cumulus/client/consensus/aura/src/collators/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,12 +175,18 @@ where
continue;
}

let Ok(Some(code)) =
params.para_client.state_at(parent_hash).map_err(drop).and_then(|s| {
s.storage(&sp_core::storage::well_known_keys::CODE).map_err(drop)
})
else {
continue;
let code = {
let Ok(state) = params.para_client.state_at(parent_hash) else { continue };
let Ok(pending) = state.storage(&sp_core::storage::well_known_keys::PENDING_CODE)
else {
continue;
};
let Some(code) = pending.or_else(|| {
state.storage(&sp_core::storage::well_known_keys::CODE).ok().flatten()
}) else {
continue;
};
code
};

super::check_validation_code_or_log(
Expand Down
2 changes: 1 addition & 1 deletion cumulus/client/relay-chain-inprocess-interface/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ impl RelayChainInProcessInterface {
#[async_trait]
impl RelayChainInterface for RelayChainInProcessInterface {
async fn version(&self, relay_parent: PHash) -> RelayChainResult<RuntimeVersion> {
Ok(self.full_client.runtime_version_at(relay_parent)?)
Ok(self.full_client.runtime_version_at(relay_parent, CallContext::Offchain)?)
}

async fn retrieve_dmq_contents(
Expand Down
4 changes: 2 additions & 2 deletions cumulus/pallets/parachain-system/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -801,8 +801,8 @@ pub mod pallet {
/// applied.
///
/// As soon as the relay chain gives us the go-ahead signal, we will overwrite the
/// [`:code`][sp_core::storage::well_known_keys::CODE] which will result the next block process
/// with the new validation code. This concludes the upgrade process.
/// [`:pending_code`][sp_core::storage::well_known_keys::PENDING_CODE] which will result the
/// next block to be processed with the new validation code. This concludes the upgrade process.
#[pallet::storage]
pub type PendingValidationCode<T: Config> = StorageValue<_, Vec<u8>, ValueQuery>;

Expand Down
1 change: 1 addition & 0 deletions cumulus/pallets/parachain-system/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ impl BlockTests {
}

// clean up
System::maybe_apply_pending_code_upgrade();
let header = System::finalize();
let head_data = relay_chain::HeadData(header.encode());
parent_head_data = head_data.clone();
Expand Down
5 changes: 3 additions & 2 deletions cumulus/pallets/parachain-system/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -872,7 +872,7 @@ fn hrmp_outbound_respects_used_bandwidth() {
fn runtime_upgrade_events() {
BlockTests::new()
.with_relay_sproof_builder(|_, block_number, builder| {
if block_number > 1 {
if block_number == 2 {
builder.upgrade_go_ahead = Some(relay_chain::UpgradeGoAhead::GoAhead);
}
})
Expand All @@ -895,8 +895,9 @@ fn runtime_upgrade_events() {
|| {
let events = System::events();

// system_version 1: update_code_in_storage writes :code directly,
// emitting both the digest and CodeUpdated event in the same block.
assert_eq!(events[0].event, RuntimeEvent::System(frame_system::Event::CodeUpdated));

assert_eq!(
events[1].event,
RuntimeEvent::ParachainSystem(crate::Event::ValidationFunctionApplied {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,13 @@ where
},
);

if overlay.storage(well_known_keys::CODE).is_some() && num_blocks > 1 {
let code_upgrade_detected =
if <PSC as frame_system::Config>::Version::get().system_version >= 3 {
overlay.storage(well_known_keys::PENDING_CODE).is_some()
} else {
overlay.storage(well_known_keys::CODE).is_some()
};
if code_upgrade_detected && num_blocks > 1 {
panic!("When applying a runtime upgrade, only one block per PoV is allowed. Received {num_blocks}.")
}
run_with_externalities_and_recorder::<B, _, _>(
Expand Down
4 changes: 2 additions & 2 deletions cumulus/test/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
impl_version: 1,
apis: RUNTIME_API_VERSIONS,
transaction_version: 1,
system_version: 1,
system_version: 3,
};

#[cfg(any(feature = "increment-spec-version", feature = "elastic-scaling"))]
Expand All @@ -217,7 +217,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
impl_version: 1,
apis: RUNTIME_API_VERSIONS,
transaction_version: 1,
system_version: 1,
system_version: 3,
};

pub const EPOCH_DURATION_IN_BLOCKS: u32 = 10 * MINUTES;
Expand Down
45 changes: 45 additions & 0 deletions prdoc/pr_6029.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
title: Implementation of RFC-123
doc:
- audience: Node Dev
description: |-
Store a runtime upgrade in `:pending_code` before moving it to `:code` in the next block. It's gated by `system_version` of the runtime
and is activated for runtimes with `system_version` >= 3.
crates:
- name: sc-service
bump: major
- name: cumulus-client-collator
bump: patch
- name: cumulus-client-consensus-aura
bump: patch
- name: cumulus-pallet-parachain-system
bump: patch
- name: frame-executive
bump: minor
- name: frame-support
bump: patch
- name: frame-system
bump: minor
- name: sp-core
bump: patch
- name: sp-state-machine
bump: major
- name: sp-storage
bump: minor
- name: frame-benchmarking-cli
bump: patch
- name: frame-system-benchmarking
bump: patch
- name: cumulus-relay-chain-inprocess-interface
bump: patch
- name: sc-client-api
bump: major
- name: sc-rpc-spec-v2
bump: patch
- name: sc-rpc
bump: patch
- name: sp-api-proc-macro
bump: major
- name: sp-api
bump: major
- name: sp-version
bump: major
3 changes: 2 additions & 1 deletion substrate/bin/node/bench/src/construct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ use sc_transaction_pool_api::{
TransactionStatusStreamFor, TxHash, TxInvalidityReportMap,
};
use sp_consensus::{Environment, ProposeArgs, Proposer};
use sp_core::traits::CallContext;
use sp_inherents::InherentDataProvider;
use sp_runtime::OpaqueExtrinsic;

Expand Down Expand Up @@ -112,7 +113,7 @@ impl core::Benchmark for ConstructionBenchmark {

let _ = context
.client
.runtime_version_at(context.client.chain_info().genesis_hash)
.runtime_version_at(context.client.chain_info().genesis_hash, CallContext::Offchain)
.expect("Failed to get runtime version")
.spec_version;

Expand Down
3 changes: 2 additions & 1 deletion substrate/bin/node/bench/src/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use std::borrow::Cow;
use node_primitives::Block;
use node_testing::bench::{BenchDb, BlockType, DatabaseType, KeyTypes};
use sc_client_api::backend::Backend;
use sp_core::traits::CallContext;

use crate::{
common::SizeType,
Expand Down Expand Up @@ -99,7 +100,7 @@ impl core::Benchmark for ImportBenchmark {

let _ = context
.client
.runtime_version_at(context.client.chain_info().genesis_hash)
.runtime_version_at(context.client.chain_info().genesis_hash, CallContext::Offchain)
.expect("Failed to get runtime version")
.spec_version;

Expand Down
3 changes: 2 additions & 1 deletion substrate/bin/node/bench/src/txpool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use node_testing::bench::{BenchDb, BlockType, DatabaseType, KeyTypes};

use sc_transaction_pool::BasicPool;
use sc_transaction_pool_api::{TransactionPool, TransactionSource};
use sp_core::traits::CallContext;

use crate::core::{self, Mode, Path};

Expand Down Expand Up @@ -61,7 +62,7 @@ impl core::Benchmark for PoolBenchmark {

let _ = context
.client
.runtime_version_at(genesis_hash)
.runtime_version_at(genesis_hash, CallContext::Offchain)
.expect("Failed to get runtime version")
.spec_version;

Expand Down
7 changes: 5 additions & 2 deletions substrate/bin/node/cli/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -900,7 +900,7 @@ mod tests {
use sc_service_test::TestNetNode;
use sc_transaction_pool_api::ChainEvent;
use sp_consensus::{BlockOrigin, Environment, Proposer};
use sp_core::crypto::Pair;
use sp_core::{crypto::Pair, traits::CallContext};
use sp_inherents::InherentDataProvider;
use sp_keyring::Sr25519Keyring;
use sp_keystore::KeystorePtr;
Expand Down Expand Up @@ -1081,7 +1081,10 @@ mod tests {
let genesis_hash = service.client().block_hash(0).unwrap().unwrap();
let best_hash = service.client().chain_info().best_hash;
let (spec_version, transaction_version) = {
let version = service.client().runtime_version_at(best_hash).unwrap();
let version = service
.client()
.runtime_version_at(best_hash, CallContext::Offchain)
.unwrap();
(version.spec_version, version.transaction_version)
};
let signer = charlie.clone();
Expand Down
2 changes: 1 addition & 1 deletion substrate/bin/node/testing/src/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ impl<'a> BlockContentIterator<'a> {
fn new(content: BlockContent, keyring: &'a BenchKeyring, client: &Client) -> Self {
let genesis_hash = client.chain_info().genesis_hash;
let runtime_version = client
.runtime_version_at(genesis_hash)
.runtime_version_at(genesis_hash, sp_api::CallContext::Offchain)
.expect("There should be runtime version at 0");

BlockContentIterator { iteration: 0, content, keyring, runtime_version, genesis_hash }
Expand Down
6 changes: 5 additions & 1 deletion substrate/client/api/src/call_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,11 @@ pub trait CallExecutor<B: BlockT>: RuntimeVersionOf {
/// Extract RuntimeVersion of given block
///
/// No changes are made.
fn runtime_version(&self, at_hash: B::Hash) -> Result<RuntimeVersion, sp_blockchain::Error>;
fn runtime_version(
&self,
at_hash: B::Hash,
call_context: CallContext,
) -> Result<RuntimeVersion, sp_blockchain::Error>;

/// Prove the execution of the given `method`.
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ where
return None;
}

let block_rt = match self.client.runtime_version_at(block) {
let block_rt = match self.client.runtime_version_at(block, sp_api::CallContext::Offchain) {
Ok(rt) => rt,
Err(err) => return Some(err.into()),
};
Expand All @@ -262,7 +262,8 @@ where
},
};

let parent_rt = match self.client.runtime_version_at(parent) {
let parent_rt = match self.client.runtime_version_at(parent, sp_api::CallContext::Offchain)
{
Ok(rt) => rt,
Err(err) => return Some(err.into()),
};
Expand Down
10 changes: 7 additions & 3 deletions substrate/client/rpc-spec-v2/src/chain_head/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use sc_client_api::{
StaleBlock, StorageData, StorageEventStream, StorageKey, StorageProvider,
};
use sc_utils::mpsc::{tracing_unbounded, TracingUnboundedSender};
use sp_api::{CallApiAt, CallApiAtParams};
use sp_api::{CallApiAt, CallApiAtParams, CallContext};
use sp_blockchain::{BlockStatus, CachedHeaderMetadata, HeaderBackend, HeaderMetadata, Info};
use sp_consensus::BlockOrigin;
use sp_runtime::{
Expand Down Expand Up @@ -241,8 +241,12 @@ impl<Block: BlockT, Client: CallApiAt<Block>> CallApiAt<Block> for ChainHeadMock
self.client.call_api_at(params)
}

fn runtime_version_at(&self, hash: Block::Hash) -> Result<RuntimeVersion, sp_api::ApiError> {
self.client.runtime_version_at(hash)
fn runtime_version_at(
&self,
hash: Block::Hash,
call_context: CallContext,
) -> Result<RuntimeVersion, sp_api::ApiError> {
self.client.runtime_version_at(hash, call_context)
}

fn state_at(&self, at: Block::Hash) -> Result<Self::StateBackend, sp_api::ApiError> {
Expand Down
13 changes: 9 additions & 4 deletions substrate/client/rpc/src/state/state_full.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,9 @@ where
block: Option<Block::Hash>,
) -> std::result::Result<RuntimeVersion, Error> {
self.block_or_best(block).map_err(client_err).and_then(|block| {
self.client.runtime_version_at(block).map_err(|e| Error::Client(Box::new(e)))
self.client
.runtime_version_at(block, CallContext::Offchain)
.map_err(|e| Error::Client(Box::new(e)))
})
}

Expand Down Expand Up @@ -380,7 +382,9 @@ where
fn subscribe_runtime_version(&self, pending: PendingSubscriptionSink) {
let initial = match self
.block_or_best(None)
.and_then(|block| self.client.runtime_version_at(block).map_err(Into::into))
.and_then(|block| {
self.client.runtime_version_at(block, CallContext::Offchain).map_err(Into::into)
})
.map_err(|e| Error::Client(Box::new(e)))
{
Ok(initial) => initial,
Expand All @@ -398,8 +402,9 @@ where
.import_notification_stream()
.filter(|n| future::ready(n.is_new_best))
.filter_map(move |n| {
let version =
client.runtime_version_at(n.hash).map_err(|e| Error::Client(Box::new(e)));
let version = client
.runtime_version_at(n.hash, CallContext::Offchain)
.map_err(|e| Error::Client(Box::new(e)));

match version {
Ok(version) if version != previous_version => {
Expand Down
Loading
Loading