github paritytech/polkadot-sdk polkadot-stable2506
Polkadot stable2506

latest releases: polkadot-stable2506-2-rc1, polkadot-stable2503-9, polkadot-stable2503-9-rc1...
one month ago

This release contains the changes from polkadot-stable2503 to polkadot-stable2506.

ℹ️ Please note:

The tag corresponding to the current stable release polkadot-stable2506 and matching the old pattern will be available under polkadot-v1.19.0.

Changelog

Changelog for Node Dev

ℹ️ These changes are relevant to: Those who build around the client side code. Alternative client builders, SMOLDOT, those who consume RPCs. These are people who are oblivious to the runtime changes. They only care about the meta-protocol, not the protocol itself.

[#8533]: fatxpool: add fallback for ready at light

Add fallback for ready_at_light for the case of not finding a best view that can be used to return a set of ready transactions. Optimised as well how the best view is searched.

[#8948]: make sure dispute_coordinator/approval-voting parallel can receive priority messages

#8834, changed relay_chain_selection to send priority messages, but did not configured the subsystems to tell they can receive priority messages, with can_receive_priority_messages flag.

If can_receive_priority_messages is not specified orchestra falls back when sending a priority message to the normal queue,
so this resulted in the messages not being processed ahead of the others in the queue.

Fix this configuration mistake and add a test to make sure priority messages are consumed ahead of normal ones by the subsystems.

[#7867]: benchmark/storage Make read/write benchmarks more accurate

Improve the benchmark accuracy of read/write costs by making sure for both reads and write we compute the amortized cost of a single key operation, by adding a batch functionality to make sure the cost of common operations like root computation is spread across multiple keys. Additionally, also add a pov-recorder flag, so that we are able to replicate the same environment as parachains do.

[#8973]: Add polkadot_parachain_peer_connectivity metric

Adds polkadot_parachain_peer_connectivity histogram metric to better understand connectivity patterns.

[#8443]: Stabilize V16 metadata

Metadata V16 is stabilized. V16 metadata exposes information about Pallet View Functions and V5 transactions,
and can be obtained, where applicable, by using the Runtime APIs Metadata_metadata_at_version(16).

[#8923]: fatxpool: fix: remove invalid txs from the dropped stream controller

While testing mortal transaction I encountered exactly the same problem as in #8490.
This PR should fix the problem.

fixes: #8490

[#8072]: RFC-0008: Store parachain bootnodes in the relay chain DHT

Implement RFC-0008 "DHT bootnodes".

With this mechanism, every parachain node is eligible to act as a bootnode. If its peer ID is close to the parachain key for the current relay chain epoch, it becomes discoverable by other parachain nodes via the relay chain DHT. This removes the need to specify bootnodes in the parachain chainspec, eliminating a single point of failure and simplifying things for parachain operators.

The mechanism is enabled by default. The embedded DHT bootnode can be disabled using the --no-dht-bootnode flag, and discovery of such nodes can be disabled with the --no-dht-bootnode-discovery flag.

[#8606]: Use hashbrown hashmap/hashset in validation context

Discovered while profiling #6131 (comment) with the benchmark #8069 that when running in validation a big chunk of the time is spent inserting and retrieving data from the BTreeMap/BTreeSet.

By switching to hashbrown HashMap/HashSet in validation TrieCache and TrieRecorder and the memory-db paritytech/trie#221 read costs improve with around ~40% and write with about ~20%

[#9050]: dispute-coordinator: handle race with offchain disabling

Fixes a potential race with off-chain disabling when we learned about disablement after importing a dispute from that validator.

[#8594]: omni-node: fix benchmark pallet to work with --runtime

polkadot-omni-node benchmark pallet can use one of --runtime or --chain now, like frame-omni-bencher does.

[#7955]: Add ApprovedPeer UMP signal

Add a new ApprovedPeer UMP signal variant for specifying a peerid that should be credited for authoring and supplying the candidate.
Will be used by the new collator protocol implementation for promoting the reputation of collators. Candidates should still not emit any UMP signals until the CandidateReceiptV2 node feature is enabled.

[#8370]: fix unneeded collator connection issue

This PR fixes an issue where collators continued attempting to connect to validators even after their core assignment was removed, leading to unnecessary connections and log spam An unneeded collator connected.
The fix ensures collators only connect to validators if there are cores assigned to the parachain.

[#8314]: Add RPCs in the statement store to get the statements and not just the statement data.

In statement-store, statements can contain a proof with the signature of the statement, this proof is useful to assert that the statement comes from the expected account. This proof also signs for all the statements fields, those can also be useful information for the receiver.

This PR adds broadcasts_stmt, posted_stmt, and posted_clear_stmt RPCs to get the full statements from the statement store.

[#8688]: bound trusted local cache to shared limits sizes

Since there is no point in letting local cache grow past the shared cache limits, bound it to those limits.

[#7556]: Add trie cache warmup

Warm up the Trie cache based on a CLI flag to enhance the performance of smart contracts on AssetHub by reducing storage access time.

[#8837]: Cache locally controlled validator indices in dispute-coordinator

dispute-coordinator uses keystore.key_pair() to obtain the set of locally controlled validator IDs. This operation happens on each import and is expensive because it involves key generation from a seed phrase. This patch lazily determines the set of locally controlled validator IDs and caches the result for each session.

[#8833]: Check artifact integrity before execution

In case of a corrupted artifact, we can find it out before execution and re-prepare the artifact.

[#9102]: polkadot-omni-node: pass timestamp inherent data for block import

This should allow aura runtimes to check timestamp inherent data when syncing/importing blocks
that include timestamp inherent data.

Runtime developers can check timestamp inherent data while using polkadot-omni-node-lib/polkadot-omni-node/polkadot-parachain binaries.
This change is backwards compatible and doesn't require runtimes to check the timestamp inherent, but they are able to do it now if needed.

[#8134]: separate validation and collation protocols

This PR completes the removal of validation protocol versions 1 and 2 by separating validation from collation. Previously, a shared Versioned enum prevented full removal.
With this change, outdated validation messages are now eliminated.

[#8831]: dispute-coordinator: increase lru_observed_blocks_capacity

Under increase load with finality lagging behind there is a risk for blocks to arrive late or out of sequence in that case we will end up scrapping from the received block un till last finalized block and then process all the dispute in-between.

This couple with other inefficiencies like #8823 will increase unnecessarily the load on dispute-coordinator.

Decided to make this super large to err on the cautious side, the Hash size is only 32 bytes, so this will make the LRU grow up to 65k, which I don't think is a significant increase.

[#9094]: bitfield_distribution: fix subsystem clogged at begining of a session

handle_peer_view_change gets called on NewGossipTopology with the existing view of the peer to cover for the case when the topology might arrive late, but in that case in the view will contain old blocks from previous session, so since the X/Y neighbour change because of the topology change you end up sending a lot of messages for blocks before the session changed.

Fix it by checking the send message only for relay chains that are in the same session as the current topology.

[#8332]: parachain informant

Adds a new cumulus-relay-chain-streams crate to make it easier to reuse relay chain streams.

[#8839]: net/discovery: File persistence for AddrCache

Persisting the AddrCache periodically (every 10 minutes) and on worker shutdown. Read AddrCache from file upon launch of worker.

AddrCache is saved as authority_discovery_addr_cache.json in the
folder configured by net_config_path of NetworkConfiguration.

This reduces the time it takes for a node to reconnect to peers after restart.

[#9264]: gossip-support: make low connectivity message an error

All is not well when a validator is not properly connected, e.g: of things that might happen:

The problem is seen in polkadot_parachain_peer_count metrics, but it seems people are not monitoring that well enough, so let's make it more visible nodes with low connectivity are not working in good conditions.

I also reduced the threshold to 85%, so that we don't trigger this error to eagerly.

[#8230]: add parachain block validation latency metrics and logs

This change introduces a few metrics (and corresponding logs) to track the state of collations:

  • time till collation fetched
  • backing latency (counting from RP)
  • backing latency (counting from collation fetch)
  • inclusion latency
  • expired collations (not backed, not advertised, not fetched)

These metrics are useful to determine the reliability of parachain block production and validation.

[#9059]: Fetch parent block api_version

This is required to ensure that we use the api_version of the runtime that will be used on the relay chain to validate the block. Otherwise the node may thinks the runtime was already upgraded and sends data to the relay chain that can not be decoded by the runtime and thus, the validation fails.

[#8832]: increase session index cache

A 10 session index cache is not enough when you run under intense pressure and finality is lagg since you will end requesting the session index for blocks older than that. So let's make this cache larger to achieve its purpose even under intense load when it actually matters more to be faster.

The session_index_cache keeps a Hash and a u32, so that's about 36 bytes per entry, with this increase it can grow up to 65k which is not that big in my book.

[#7666]: Migrate 0009-approval-voting-coalescing.zndsl to zombienet-sdk

Migrate test from the legacy zombienet to the newer version.

[#8001]: Structured Logging for transaction pool

Replacement of log crate with tracing crate for structured logging in transaction pool.

[#7682]: Make SharedTrieCache/LocalTrieCache work with entire state in memory

Extended LocalTrieCache with a trusted configuration that expands to hold everything in memory and then propagates all the data back to the SharedTrieCache. This new configuration is used on authoring
and import paths.

[#9127]: add block hashes to the randomness used by hashmaps and friends in validation context

#8606 paritytech/trie#221 replaced the usage of BTreeMap with HashMaps in validation context. The keys are already derived with a cryptographic hash function from user data, so users should not be able to manipulate it.

To be on safe side this PR also modifies the TrieCache, TrieRecorder and MemoryDB to use a hasher that on top of the default generated randomness also adds randomness generated from the hash of the relaychain and that of the parachain blocks, which is not something users can control or guess ahead of time.

[#8323]: Allow genesis-presets to be patched and remove native runtime calls from the staging-node-cli

This allows that we can update the hardcoded genesis-presets with some json-values, closes #7748.

Ideally, we should be able to remove calls into the native runtime with this (i.e., don't link the runtime in the node's code).

[#8102]: Make min_peers_to_start_warp_sync configurable

Make min_peers_to_start_warp_sync configurable. Parachains for example only need 1 peer, because the target block is downloaded from the relay chain.

Parachains automatically will get this change via cumulus_service::prepare_node_config.

[#8596]: fatxpool: limits handling optimizations and fixes

This PR adds some optimization and fixes in handling limits in fork-aware transaction pool.

[#8445]: Fix the clearing of gap sync on known imported blocks

This PR ensures that warp sync gaps are properly cleared when known blocks are imported. Previously, gaps were only removed in response to ImportedUnknown events.
This limitation caused issues for asset-hub and bridge-hub collators, which remained stuck in the "Block history" state without progressing.
The root cause lies in the client.info() reporting a gap during node startup or restart (ie block verification fails). In some cases, a peer may respond with the missing blocks after we’ve already imported them locally, leaving the gap open.

[#8500]: txpool: fix tx removal from unlocks set

Now removing a tx subtree will correctly remove it from the transactions that would unlock it.

[#8153]: Introduce SelectCore digest in Cumulus

Right now the select core information are only send as an UMPSignal to the relay chain. For a node to calculate the core of a block, it is first required execute the block to call selected_core runtime api.

This pull requests solves this by putting the selected core into a digest. Thus, the node can directly fetch it from the header.

[#6137]: cumulus: ParachainBlockData support multiple blocks

This pull request adds support to ParachainBlockData to support multiple blocks at once. This basically means that cumulus based Parachains could start packaging multiple blocks into one PoV.
From the relay chain PoV nothing changes and these PoVs appear like any other PoV. Internally this PoV then executes the blocks sequentially. However, all these blocks together can use the same amount of resources like a single PoV.
This pull request is basically a preparation to support running parachains with a faster block time than the relay chain.

This changes the encoding of ParachainBlockData. However, encoding and decoding is made in a backwards and forwards compatible way. This means that there is no dependency between the collator and runtime upgrade.

[#8069]: Benchmark storage access on block validation

Adds checking storage weights on block validation for both read and write benchmarks.

[#8130]: rpc v2: move archive MethodResult to the archive mod

MethodResult, MethodResultOk and MethodResultErr are archive specific types and are therefore moved the the archive mod.

[#7375]: Refactor the host <-> runtime interface machinery (the #[runtime_interface] macro) and the way host functions are defined

This PR refactors the way the host functions are defined.

Previously the way a given type was marshalled through the host <-> runtime boundary was
hardcoded for every type by the virtue of it implementing the relevant conversion traits.

This had two major consequences:

  • It was not obvious how a given type is going to be passed just by looking at its type alone, masking potentially expensive marshalling strategies. (For example, returning Option<u32> was done through the SCALE codec and involved extra memory allocations!)
  • It was not possible to use multiple marshalling strategies for a single type, making some of the future improvements we'd like to do (e.g. move the runtime memory allocator into the runtime) very hard to do.

So this PR disentangles this mess and makes the marshalling strategies explicit. This makes it much more clear how a given type in a given host function is marshalled, and also makes it possible to use different marshalling strategies for the same type in different host functions.

Before this PR you'd define a host function like this:

    #[runtime_interface]
    trait MyInterface {
        fn say_hello_world(name: &str) {
            println!("Hello {name}!");
        }
    }

and after this PR you'll define it like this:

    #[runtime_interface]
    trait MyInterface {
        fn say_hello_world(name: PassFatPointerAndRead<&str>) {
            println!("Hello {name}!", name);
        }
    }

In this case the strategy for passing the &str is now explicitly specified (PassFatPointerAndRead).
Note that the actual API generated by this macro and the way arguments are accessed is completely unchanged!
The #[runtime_interface] machinery automatically "strips" away the marshalling strategy wrappers, so neither the body of the say_hello_world function here nor its callers need to be changed.

Please pay attention that enums with explicit discriminant numbers (if different from implicit, that is, not starting from zero or not sequential) using the old PassByEnum strategy, should be carefully migrated to preserve compatibility, as PassByEnum was always using implicitly generated discriminants starting from zero, and the PassAs strategy introduced by this PR passes actual values.

Furthermore, to explicitly distinguish between the runtime compilation mode and native mode, #[cfg(substrate_runtime)] is now used instead of #[cfg(not(feature = "std"))]. That allows for fine-tuning the compilation behavior without relying solely on the std feature.

[#7980]: fatxpool: optimize txs prunning based on inactive views provides tags

Optimization of transaction pruning. More datils can be found in the PR description.

[#8834]: extend overseer to send priority messages

Extend overseer to send priority messages, the new functionality is used for sending messages on the grandpa call path when we call dispute-coordinator and approval-voting in finality_target_with_longest_chain to make sure we don't block unnecessarily.

Changelog for Runtime Dev

ℹ️ These changes are relevant to: All of those who rely on the runtime. A parachain team that is using a pallet. A DApp that is using a pallet. These are people who care about the protocol (WASM, not the meta-protocol (client).)

[#8932]: pallet-balances: Do not create account in benchmarking

This particular benchmark is about benchmarking the account creation, so we should not create it before :)

Closes: #8927

[#8311]: [pallet-revive] update tracing rpc methods parameters

Update debug_trace* methods to support extra parameters supported by geth.
The method now can specify a timeout and whether or not we should only return a trace for the top call.

[#6324]: Introduce #[pallet::authorize(...)] macro attribute and AuthorizeCall system transaction extension Extrinsics with calls such as claim or apply_authorized_upgrade wants to be valid depending on the parameters of the call or/and the state of the chain.

Valid in the sense of transaction validity, if the extrinsic is not valid it can't be included in a (valid) block.
For instance claim is valid if the signature given as a parameter of the call is valid and if the state of the chain contains some pending claim.
Or the apply_authorized_upgrade is valid if the code given as a paramter of the call match the authorized hashed code on chain.
Those operation don't require a signed origin and are currently achieved using ValidateUnsigned.
This PR introduce a new pallet attribute #[pallet::authorize(...)] and a new system transaction extension AuthorizeCall to ease such operations.
This change is part of the broader plan for extrinsics: #2415.

The usage of pallet::authorize can be found in the rust documentation. It takes a function to define the validation logic. Another attribute pallet::weight_of_authorize is introduced, it takes a function to define the weight of the validation logic.

The runtime must now use the new system transaction extension AuthorizeCall in their transaction extension pipeline. It is suggested to put it first.

pub type TxExtension = (
    frame_system::AuthorizeCall<Runtime>
    frame_system::CheckNonZeroSender<Runtime>,
    frame_system::CheckSpecVersion<Runtime>,
    ...
);

[#8376]: Remove TakeFirstAssetTrader from AH Westend and Rococo

Removed TakeFirstAssetTrader from Asset Hub Westend and Rococo. Improved macros, fixed tests.
This implies asset sufficiency no longer guarantees that weight can also be bought with it.
SwapFirstAssetTrader is used instead which will attempt to swap some of the given asset for the required amount of native asset to buy weight. This may or may not succeed depending on whether there is a local pool present with enough liquidity to serve the swap.

[#7995]: Add PureKilled event to pallet-proxy

The extrinsic pallet_proxy::kill_pure now emits an event.

[#9137]: Pallet XCM - transfer_assets pre-ahm patch

Pallet XCM's transfer_assets extrinsic now returns an error when it determines that a reserve transfer of DOT|KSM|WND|PAS has to be done.
This is a safeguard in preparation for the Asset Hub Migration (AHM), where the reserve of DOT|KSM|WND|PAS will change from the Relay Chain to Asset Hub.
After the migration, another patch will remove this error case and use the correct reserve.
The pallet uses the UniversalLocation configuration to figure out the correct asset being transferred. It's very important to have that configuration correct.

[#7867]: benchmark/storage Make read/write benchmarks more accurate

Improve the benchmark accuracy of read/write costs by making sure for both reads and write we compute the amortized cost of a single key operation, by adding a batch functionality to make sure the cost of common operations like root computation is spread across multiple keys. Additionally, also add a pov-recorder flag, so that we are able to replicate the same environment as parachains do.

[#8422]: [AHM] Staking async fixes for XCM and election planning

This PR brings a few small fixes related to the XCM messages of stkaing-async, among other small fixes:

  • Allows xcm::validate to check the message size, and we actually now act upon it in the staking-async-rc/parachain-runtimes. The code is a bit duplicate now, and there is a TOOD about how to better refactor it later.
  • Part of this work is backported separately as #8409
  • It brings a default EraElectionPlannerOf which should be the right tool to use to ensure elections always happen in time, with an educated guess based on ElectionProvider::duration rather than a random number.
  • It adds a few unit tests about the above
  • It silences some logs that were needlessly INFO, and makes the printing of some types a bit more CLI friendly.
  • Renames type SessionDuration in staking-async to type RelaySessionDuration for better clarity.

[#8679]: Shared Add ethereum-standards crate

Shared PR that adds ethereum-standards crate used by upcoming #7762 and #8365

[#8281]: workaround: XcmPaymentApi::query_weight_to_asset_fee simple common impl

This PR adds a common implementation for XcmPaymentApi::query_weight_to_asset_fee to pallet-xcm.

This PR is a simple alternative to #8202 (which could still be useful for other reasons).
It uses a workaround instead of a big refactoring.

The workaround is described in the doc comment query_weight_to_asset_fee in pallet-xcm

[#8535]: Make WeightBounds return XcmError to surface failures

Improved XCM weight calculation error handling and traceability. The WeightBounds trait now returns detailed XcmError types instead of opaque results, allowing downstream consumers to access specific error context for failures like instruction decoding issues, weight overflows, and instruction limit violations. Added structured debug logging with contextual information to aid in diagnosing weight estimation failures during message preparation and execution.

[#8122]: Accommodate small changes to unstable V16 metadata format

The frame-metadata version is bumped, which leads to a few minor changes to our sp-metadata-ir crate to accommodate small changes in the unstable V16 metadata format.

[#8652]: [pallet-revive] impl_revive_api macro

Move pallet-revive runtime api implementation in a macro, so that we don't repeat the code for every runtime.

[#8662]: [pallet-revive] update dry-run logic

  • Revert #8504
  • Add a prepare_dry_run that run before dry_run

[#8718]: Record ed as part of the storage deposit

Fixes paritytech/contract-issues#38

[#7833]: add poke_deposit extrinsic to pallet-society

This PR adds a new extrinsic poke_deposit to pallet-society. This extrinsic will be used to re-adjust the deposits made in the pallet to create a bid.

[#8787]: Westend governance authorize_upgrade integration tests

Integration tests covering authorize_upgrade with whitelisting via Collectives for Westend network

[#8262]: pallet_revive: Replace adhoc pre-compiles with pre-compile framework

This PRs adds the ability to define custom pre-compiles from outside the pallet. Before, all pre-compiles were hard coded as part of the pallet.

Design

  1. Adding a pre-compile is as easy as implementing the new Precompile trait on any type. It can be added to the pallet by passing it into Config::Precompiles. This config know excepts a tuple of multiple types that each implement Precompile.
  2. Each pre-compile has to implement Solidity ABI. Meaning its inputs and outputs are encoded according to Eth ABI. This makes writing a pre-compile much simpler since it doesn't have to implement its own decoding logic. More importantly: It makes it trivial to consume the API from a Solidity contract.
  3. We constrain the address space of pre-compiles to a safe range so that they cannot accidentally match a wide range creating a collision with real contracts.
  4. We check that pre-compile address ranges do not overlap at compile time.
  5. Pre-compiles behave exactly as a normal contract. They exist as frames on the call stack and the environment they observe is their own (not the one of the calling contract). They can also be delegate called which changes the semantics in the same way as for normal contracts: They observe the environment of the calling contract.
  6. They can also be called by the origin without any other contract in-between.

Check the rustdocs of the precompile module on how to write a pre-compile.

Changes

  1. A new module precompiles is added that contains the framework to write pre-compiles. It also contains the sub module builtin that contains hard coded pre-compiles which exist Ethereum.
  2. The pure_precompiles module was deleted since all its pre-compiles were ported over to the new framework and are now housed in builtin.
  3. The CallSetup type is moved outside of the benchmarking module because it is also needed for testing code now. It is intended to be used for implementors outside of the crate to test the pre-compiles (in addition to benchmarking them).

Follow Ups

  • Enrich the CallSetup API with more functions in order to allow testing more complex scenarios. Should probably be done in tandem with writing the ERC20 pre-compile.
  • The collision checks for pre-compile addresses are done at compile time. They need some try_build tests to make sure it works as intended.

[#8369]: Enhancements to macros for trusted teleporter scenarios

Improvements have been made to the macros used for testing trusted teleporter functionality between relay chains and parachains. Changes include:

  • Integration of dry-run support to accurately estimate and verify the fees expected during testing
  • Parameterization of the macro, allowing users to specify which transfer-related extrinsic to test. This replaces the previous hardcoded use of limited_teleport_assets with the option to test alternatives such as transfer_assets

[#8234]: Set a memory limit when decoding an UncheckedExtrinsic

This PR sets a 16 MiB heap memory limit when decoding an UncheckedExtrinsic.
The ExtrinsicCall trait has been moved from frame-support to sp-runtime.
The EnsureInherentsAreFirst trait has been removed and the checking logic has been moved to frame-executive.

[#7730]: Nest errors in pallet-xcm

To address the issue of vague LocalExecutionIncomplete errors in pallet-xcm, the PR introduces LocalExecutionIncompleteWithError(ExecutionError), which nests a compact ExecutionError enum—aligned with XcmError and excluding strings like in FailedToTransactAsset: to provide detailed error information within FRAME's 4-byte limit. This enhances error reporting by specifying causes like insufficient balance or asset transaction failures, with strings logged for debugging.

[#7955]: Add ApprovedPeer UMP signal

Add a new ApprovedPeer UMP signal variant for specifying a peerid that should be credited for authoring and supplying the candidate.
Will be used by the new collator protocol implementation for promoting the reputation of collators. Candidates should still not emit any UMP signals
until the CandidateReceiptV2 node feature is enabled.

[#8118]: Safer conversions in polkadot-runtime-parachains

Use TryFrom impls instead of as operator for conversions.

[#6312]: DeprecationInfo propagate or automatically add allow(deprecated) attributes in the generated code.

Propagates or automatically adds allow(deprecated) attributes on Constants, RuntimeApis, Runtime Calls and enum variants
to reduce noise produced by warnings inside generated code.

[#8477]: FeeTracker deduplications

This PR refactors the FeeTracker trait in order to make it more reusable.

[#7220]: Yet Another Parachain Runtime

Yet Another Parachain is introduced, with the main purpose to be a target for the Spammening events, but also to be used like one more general-purpose testing parachain runtime.

[#8148]: [revive] eth-rpc refactoring

Refactor eth-rpc

  • Get rid of the in memory-cache, we can just store receipts / logs into sqlite
  • Track both best and finalized blocks so that we can properly index transactions in case of a relay chain re-org
  • Keep reference to the latest finalized block so that we can use that for queries that use the finalized block tag
  • use --index-last-n-blocks cli parameter to re-index the last n block when the server start
  • Fix issue with gas_price calculation for EIP1559

tested changes with paritytech/evm-test-suite#87

fix paritytech/contract-issues#35 paritytech/contract-issues#33

[#8314]: Add RPCs in the statement store to get the statements and not just the statement data.

In statement-store, statements can contain a proof with the signature of the statement, this proof is useful to assert that the statement comes from the expected account. This proof also signs for all the statements fields, those can also be useful information for the receiver.

This PR adds broadcasts_stmt, posted_stmt, and posted_clear_stmt RPCs to get the full statements from the statement store.

[#5884]: Set PoV size limit to 10 Mb

Bumps the default PoV size limit to 10 Mb on both relay chain and parachains.

[#3811]: Implicit chill when full unbounding in [pallet_staking]

Modifies the unbond extrinsic to forcefully chill stash when unbonding if the value to be unbonded is the total of what is bonded

[#9139]: Expose more constants for pallet-xcm

Exposes more constants (UniversalLocation, MaxLockers, MaxRemoteLockConsumers), similar as AdvertisedXcmVersion.

[#8197]: [pallet-revive] add fee_history

Add eth_feeHistory method to the eth-rpc fix paritytech/contract-issues#39

[#8212]: [pallet-revive] fix bn128 benchmark

Update bn128 benchmarks

[#8724]: Implement detailed logging for XCM failures

This PR improves diagnostics in XCM-related code by adding detailed error logging, especially within map_err paths. It includes clearer messages, standardized log targets, and richer context to aid runtime developers and node operators in debugging and monitoring.

[#8633]: Staking (EPMB): update the semantics of elect() and Phase::Extract(N)

  • Make elect() in EPMB solely responsible for Phase::Export transitions:
    • before this change, the handling was split between EPMB's on_initialize()/next() and elect() (triggered by staking-async's on_initialize()).
  • Update the semantics of elect(N) and of the inner value of Export(N):
    • calling elect(N) means now that we are expecting to serve result for page N and to transition to Phase::Export(N-1) if N > 0 or to Phase::Off if N == 0.

For a 4-page election, the flow is the following:

  • elect(3): If in Done, serve result for page 3, transition to Export(2).
  • elect(2): If in Export(2), serve result for page 2, transition to Export(1).
  • elect(1): If in Export(1), serve result for page 1, transition to Export(0).
  • elect(0): If in Export(0), serve result for page 0, transition to Off.

This change fixes the issue for which we were handling multiple transactions in the same block in case staking-async pallet was initialized before epmb:

In block X:

  • when in Phase::Done, calling elect(N) as coming for staking-async's on_initialize(), forced the transition Done -> Export(N)
  • the following next() triggered by EPMB's on_initialize() forced the transition still within block X from Export(N) to Export(N-1)

[#7960]: Stabilize pallet view functions

Pallet view functions are no longer marked as experimental, and their use is suggested starting from this PR.

[#9102]: polkadot-omni-node: pass timestamp inherent data for block import

This should allow aura runtimes to check timestamp inherent data when syncing/importing blocks that include timestamp inherent data.

Runtime developers can check timestamp inherent data while using polkadot-omni-node-lib/polkadot-omni-node/polkadot-parachain binaries.
This change is backwards compatible and doesn't require runtimes to check the timestamp inherent, but they are able to do it now if needed.

[#6827]: Introduction of Approval Slashes

Introduces a more aggressive slashing scheme.
Lazy or spammy validators will from now on be slashable in disputes.
Even if your validator is not a backer but it approves an invalid block it will be slashed 2%.
If your validator raises or supports fake alarms (disputes against valid blocks) you will be slashed (0%) and disabled for the remainder of the era, which will potentially reduce era point gains.

[#8745]: Use correct relay parent offset in YAP parachain

The relay parent offset in the yap parachain is now properly set to RELAY_PARENT_OFFSET.

[#7720]: Clamp Core Fellowship Benchmarks to Runtime MaxRank Configuration

This change modifies the MaxRank type in the Core Fellowship pallet configuration from
u32 to u16. Runtime developers updating to this version must:

  • Change any ConstU32<N> usages for MaxRank to ConstU16<N>

Enabling reliable benchmarking for constrained configurations like MaxRank=1 while
maintaining compatibility with larger rank ranges.

[#7882]: add poke_deposit extrinsic to pallet-recovery

This PR adds a new extrinsic poke_deposit to pallet-recovery. This extrinsic will be used to re-adjust the deposits made in the pallet.

[#8687]: Staking (EPMB): Add defensive error handling to voter snapshot creation and solution verification

  • Refactor snapshot creation to emit events and triggers defensive panic on failure
  • Replace unwrap() with defensive_unwrap_or(u32::MAX) to ensure solution fails verification gracefully when desired_targets is unavailable rather than panicking.
  • Add error events for failed target and voter snapshots

[#8545]: [pallet-revive] eth-rpc improved healthcheck

  • Check that the cached latest block is properly synced in the healthcheck
  • Add additional traces to debug broken block subscription

[#8339]: [AHM] add election-provider-multi-block::minimum-score to genesis config

Adds the ability to set the genesis miniumScore in election-provider-multi-block.

[#8528]: FeeTracker: remove get_min_fee_factor()

Related to #8462

Follow-up for #8477

The minimal fee factor should always be 1

[#8694]: Fix pallet_migrations benchmark when FailedMigrationHandler emits events

When FailedMigrationHandler emits events, the UpgradeFailed event is not the last one, so assert_last_event fails. Fixed by checking that the UpgradeFailed event is emitted, even if it is not the last one.

[#8164]: [PoP] Add personhood tracking pallets

This PR adds the building blocks of a Proof of Personhood system.

pallet-people

The People pallet stores and manages identifiers of individuals who have proven their personhood. It tracks their personal IDs, organizes their cryptographic keys into rings, and allows them to use contextual aliases through authentication in extensions. When transactions include cryptographic proofs of belonging to the people set, the pallet's transaction extension verifies these proofs before allowing the transaction to proceed. This enables other pallets to check if actions come from unique persons while preserving privacy through the ring-based structure.

The pallet implements the PeopleTrait interface and accepts new persons after they prove their uniqueness elsewhere, stores their information, and will support removing persons in the future. While other systems (e.g., wallets) generate the proofs, this pallet handles the storage of all necessary data and verifies the proofs when used.

People are identified through a new cryptographic primitive, as defined in the GenerateVerifiable interface in the verifiable crate. People get the privilege of running free transactions for supported calls through a combination of a new AsPerson transaction extension and new origin types PersonalIdentity and PersonalAlias.

pallet-origin-restriction

This pallet tracks certain origin and limits how much total "fee usage" they can accumulate. Usage gradually recovers as blocks pass. This pallet and its associated transaction extension are used to limit the amount of on-chain compute people get when they run free transactions, since the fee model does not apply to them.

pallet-dummy-dim

Allows control of a PeopleTrait interface through a privileged origin by simulating a DIM. It is meant only to help in testing scenarios and acts as a control panel for PeopleTrait implementers. It is not an official DIM and should not be used in production, but, like pallet-sudo, should prove useful on testnets.

[#8387]: Update tests-evm.yml

Update the sha for the evm-test suite

[#8903]: ParachainSystem: Do not emit the SelectCore digest

This will be moved into an inherent digest.

[#8587]: [pallet-revive] make subscription task panic on error

  • subscription task are "essential tasks" and the service should go down when they fail.
  • Upgrade subxt to 0.41
  • Update zombienet-sdk to use the subxt re-export of subxt so it does not conflict with the workspace version

[#8664]: [pallet-revive] Fix rpc-types

Update rpc-types

  • Remove unnecessary derive traits
  • Fix json decoding for BlockNumberOrTagOrHash

[#7597]: Introduce CreateBare, deprecated CreateInherent

Rename CreateInherent to CreateBare, add method create_bare and deprecate create_inherent.

Both unsigned transaction and inherent use the extrinsic type Bare.
Before this PR CreateInherent trait was use to generate unsigned transaction, now unsigned transaction can be generated using a proper trait CreateBare.

How to upgrade:

  • Change usage of CreateInherent to CreateBare and create_inherent to create_bare.
  • Implement CreateBare for the runtime, the method create_bare is usually implemented using Extrinsic::new_bare.

[#8599]: Snowbridge: Unpaid execution when bridging to Ethereum

In Snowbridge V2, the execution fee on Ethereum is estimated dynamically and injected into the XCM, eliminating the need to preconfigure the bridge fee.
Additionally, we also aim to avoid maintaining the Asset Hub’s sovereign account on the Bridge Hub.

[#7592]: Add Paras authorize_code_hash + apply_authorized_code feature

This feature is useful when triggering a Paras pallet call from a different chain than the one where the Paras pallet is deployed. For example, we may want to send Paras::force_set_current_code(para, code) from the Collectives and/or AssetHub to the relay chain (because the relaychain governance will be migrated to the AssetHub as a part of AHM).
The primary reason for this approach is to avoid transferring the entire new_code Wasm blob between chains. Instead, we authorize the code_hash using root via fn authorize_force_set_current_code_hash(new_authorization, expire_at). This authorization can later be applied by anyone using Paras::apply_authorized_force_set_current_code(para, new_code). If expire_at is reached without the authorization being used, it is automatically removed.

[#8179]: Do not make pallet-identity benchmarks signature-dependent

  • Includes a BenchmarkHelper configuration item in pallet-identity to handle signing operations.
  • Abstracts away the explicit link with Sr25519 schema in the benchmarks, allowing chains with a different one to be able to run them and calculate the weights.
  • Adds a default implementation for the empty tuple that leaves the code equivalent.

Adding the following to your implementation of the frame_identity::Config should be enough:

#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper = ();

[#8310]: staking-async: add missing new_session_genesis

Fix issue #8302 as introduced by #8127 where the staking-async module could fail during genesis.
The issue was related to the staking-async module in the Polkadot SDK, specifically with the implementation of the historical::SessionManager
trait in the ah-client pallet with missing implementations of the new_session_genesis method in two different places:

  • In the pallet_session::SessionManager<T::AccountId> implementation
  • In the historical::SessionManager<T::AccountId, sp_staking::Exposure<T::AccountId, BalanceOf>>
    implementation

Note: the SessionManager trait requires the implementation of new_session_genesis for proper functioning, especially during chain initialization.
The pallet-staking-async/ah-client has different operating modes:

  • Passive: Delegates operations to a fallback implementation
  • Buffered: Buffers operations for later processing
  • Active: Performs operations directly

[#8734]: [pallet-revive] contract's nonce starts at 1

nonce starting value should be 1 see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-161.md

[#8274]: [pallet-revive] add get_storage_var_key for variable-sized keys

This adds a new runtime ReviveApi call get_storage_var_key, which does the same as get_storage, but for variable-sized keys.

[#8750]: Move Transaction depth limit checks

This moves the check of the transaction depth limit to frame-executive
instead of having it hidden in the sp-api macros.

If you have used MAX_EXTRINSIC_DEPTH from the sp-api crate, the constant was moved to frame-support:

-sp_api::MAX_EXTRINSIC_DEPTH
+frame_support::MAX_EXTRINSIC_DEPTH

[#8382]: add poke_deposit extrinsic to pallet-bounties

This PR adds a new extrinsic poke_deposit to pallet-bounties. This extrinsic will be used to re-adjust the deposits made in the pallet to create a new bounty.

[#8316]: Remove slashing spans from pallet-staking-async

This change removes SlashingSpans, SpanSlash, and related metadata and logic from pallet-staking-async, simplifying the slashing system.

  • Removes storage items: SlashingSpans, SpanSlash.
  • Removes error: IncorrectSlashingSpans.
  • Deprecates num_slashing_spans parameter in withdraw_unbonded, force_unstake, and reap_stash extrinsics (kept for backward compatibility).

Functional change to slashing rewards:

  • Old behavior: reward = 50% of SlashRewardFraction, halved again for each successive slash in the same era.
  • New behavior: no successive reward halving; only highest offence per validator/nominator per era is considered.

[#8584]: Remove all XCM dependencies from pallet-revive

This PR removes all XCM dependencies from pallet-revive, including the mock-network crate which was primarily used to test the unstable xcm_execute and xcm_send APIs. These APIs (along their respective tests) will be moved to the XCM precompile in pallet-xcm to avoid cyclic dependencies.

[#7944]: Allow to set a worst case buy execution fee asset and weight

Allows to set a worst case for the BuyExecution XCM instruction benchmark. Currently the benchmark assumes best case scenario (i.e.) the case where does not even need to go into the Trader. This PR allows developers to set the worst-case scenario as they wish.

Breaking changes:

  • Change fee_asset in the benchmarking helper to worst_case_for_trader which
    now should return both the fee_asset and the weight to use

[#8861]: paras_inherent: fix overweight warn

This fixes an incorrect warning in the relay chain runtime

[#8299]: Collator: Support building on older relay parents

Introduce mechanisms to build on relay parents that are not at the tip of the relay chain. This is useful in combination with the slot-based collator (--authoring slot-based) and elastic-scaling. Relay chain forks are short. By choosing a relay parent with an offset, forks have already settled and therefore parachain forks become less likely too.

Migration: Teams that want to keep behaviour as-is can just add type RelayParentOffset = ConstU32<0>; to the
cumulus_pallet_parachain_system::Config in their runtime. Teams that wish to leverage the new functionality can find more documentation here

[#8470]: Stabilize the FRAME umbrella crate

Stabilizing the FRAME umbrella crate, which is no longer marked as experimental.
Improving the related documentation, including README and maintenance notes.

After integrating the FRAME umbrella crate in 17 pallets as May 9 2025 and modifying it in the process (see #6504),
it is now stable and it can be used for pallet development.

Key improvements:

  • Enhanced documentation with clear usage guidelines
  • Added comprehensive maintenance notes for future contributors
  • Established clear design principles for prelude usage and module organization
  • Updated documentation links to point to the official hosted docs

[#8708]: feat: add collator peer ID to ParachainInherentData

Adds an optional collator_peer_id field to the new version of ParachainInherentData introduced in PR #8299. The field is currently unused and defaults to None, but is included proactively to avoid creating another inherent data version in the future.
This sets the stage for sending collator peer IDs via UMP signals in upcoming work.

[#8409]: check XCM size in VMP routing

This PR adds the ability for a UMP (para -> relay), when using UpwardMessageSender to also check the size of the message within validate. This is exposed into the existing validate of ParentAsUmp.

[#8891]: RuntimeAllocator: Align returned pointers

Rust recently switched the default alignment of u128 to 16bytes: https://blog.rust-lang.org/2024/03/30/i128-layout-update/ This broke the assumption of our host allocator that the biggest alignment is 8 bytes.

To fix the alignment issue, the runtime allocator now takes care of aligned the returned pointer. We are abusing the fact that we know how the host allocator is working and storing some extra data in its header. This is not a perfect solution as we don't align the host side pointers, but the host side is mainly allocating u8 arrays that should be fine with the 8byte alignment. Any node side change would be a consensus breaking change.

[#8163]: chore: idiomatic rust cleanup

Description

This PR performs a series of non-functional refactors across multiple files to improve code readability and consistency.

Key changes include:
• Replacing verbose pattern matches with shorter .ok(), .err(), or .ok_or()? alternatives.
• Using div_ceil() instead of manual (x + 1) / 2 calculations for better clarity.
• Removing redundant .clone().take() patterns to simplify logic.
• Applying consistent and idiomatic Rust expressions throughout the codebase.

These changes do not affect runtime functionality, but improve maintainability and align the code with modern Rust practices.

Integration

No integration steps are required. These are non-functional refactors that do not alter the runtime behavior or public APIs. Downstream projects should experience no impact.

Review Notes

All changes are cosmetic or idiomatic improvements:
• Each change was tested to ensure it preserves the original behavior.
• Focus was on readability, simplicity, and reducing redundancy.
• No logic paths were altered; only how those paths are expressed.

[#8725]: Snowbridge: register polkadot native asset with fee

To enforce a fee for PNA registration.

[#8715]: [AHM] Prepare For Westend Cleanup

Pulling out the simple pieces of #7997 for easier review:

  • Fix hypothetically macro to use proper Result type
  • Add DefensiveTruncateInto as counter part to DefensiveTruncateFrom
  • Add DecodeWithMemTracking to many structs
  • Make storage items public

[#8704]: [AHM] Repot the weights of epmb pallet to expose kusama and polkadot weights

Adds updated weights for the pallet-election-provider-multi-block pallet to reflect the anticipated configuration in Polkadot and Kusama-like networks.

[#8327]: Update to the latest unstable V16 metadata.

The frame-metadata version is bumped to v22 to bring in the latest unstable V16 metadata format. Notably, deprecation information has changed slightly, and deprecation notices on the outer Event/Error enums are no longer supported (but each variant can still be marked as deprecated).

[#8103]: [pallet-revive] Add genesis config

  • Add genesis config
  • Mapped dev accounts in kitchensink genesis

One can test a local westend with endowed and mapped accounts with the following approach

cargo build -p asset-hub-westend-runtime
chain-spec-builder -c /tmp/ah-westend-spec.json \
  create \
  --para-id 1000 \
  --relay-chain dontcare \
  --runtime ./target/debug/wbuild/asset-hub-westend-runtime/asset_hub_westend_runtime.wasm \
  named-preset development

# Endowed
# Alith:
# H160: 0xf24FF3a9CF04c71Dbc94D0b566f7A27B94566cac
# SS58: 5CfCLa2N85aH2tUKT48LmRSGNx27DnJUayMXyiwqvvcU97VN2sk
# Private key (ecdsa): 0x5fb92d6e98884f76de468fa3f6278f8807c48bebc13595d45af5bdc4da702133

# Alice:  (subkey inspect //Alice)
# SS58: 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
# Private key (sr2259): 0xe5be9a5092b81bca64be81d212e7f2f9eba183bb7a90954f7b76361f6edb5c0a

jq '.genesis.runtimeGenesis.patch.balances.balances = [
    ["5CfCLa2N85aH2tUKT48LmRSGNx27DnJUayMXqvvcU97VN2sk", 1000000001000000000],
    ["5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY", 1000000001000000000]
  ]
| .genesis.runtimeGenesis.patch.revive.mappedAccounts = [
    "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY"
]
' /tmp/ah-westend-spec.json >~/ah-westend-spec.json

[#7719]: Add export-chain-spec substrate CLI command

This release adds a new export-chain-spec command to export raw chain specs directly from the node.
The build-spec command is now on a deprecation path across all nodes and will display a warning, encouraging the use of export-chain-spec for chain spec exports.

[#6010]: Proof Of Possession for public keys

Introduced ProofOfPossessionGenerator and ProofOfPossessionVerifier traits.
Provided blanket implementations for all crypto Pair types implementing the NonAggregatable trait. Currently, this includes all cryptographic types except the experimental BLS, which have dedicated implementations.
Implemented ProofOfPossessionVerifier for all application-level crypto wrappers from the sp-application-cryptocrate.
Enabled PoP generation for all RuntimePublic crypto types, allowing PoP generation within the runtime context (with support of sp-io host function).
BLS PoP generation within the context of runtime requires a new dedicated host function in sp-io and a new dedicated Keystore method.

[#7936]: Replace Validator FullIdentification from Exposure to Existence

This introduces a new type in pallet-staking, ExistenceOf, which replaces ExposureOf.
With this change, runtimes can be configured to identify a validator solely by their presence, rather than using full exposure data.

This is particularly useful when configuring historical sessions, for example:

impl pallet_session::historical::Config for Runtime {
  type FullIdentification = pallet_staking::Existence;
  type FullIdentificationOf = pallet_staking::ExistenceOf<Runtime>;
}

However, for existing runtimes that depend on the Exposure type for pallet-offences - often configured like this:

impl pallet_offences::Config for Runtime {
  ...
  type IdentificationTuple = pallet_session::historical::IdentificationTuple<Self>;
}

Where IdentificationTuple is defined as:

pub type IdentificationTuple<T> = (<T as pallet_session::Config>::ValidatorId, <T as Config>::FullIdentification);

You should use ExistenceOrLegacyExposureOf instead. This type includes a custom encoder/decoder that supports both
the legacy Exposure type and the new Existence type.

This compatibility layer is necessary because pallet-offences stores the FullIdentification type in its storage.
If you replace FullIdentification with Existence directly, any previously stored items using Exposure will fail to decode. ExistenceOrLegacyExposureOf ensures backward compatibility after this change.

[#8248]: Frame: Authorize pallet::error int discriminant

Authorize int discriminants for pallet::error

Why?
The raw hex value shows up in tools like polkadotjs, being able to quiclkly scan the enum of the code base to find out what error was triggered can be very useful, especially when the enum is large like in pallet-revive

e.g:

#[pallet::error]
#[repr(u8)]
pub enum Error<T> {
    /// Invalid schedule supplied, e.g. with zero weight of a basic operation.
    InvalidSchedule = 0x00,
    /// Invalid combination of flags supplied to `seal_call` or `seal_delegate_call`.
    InvalidCallFlags = 0x01,
    /// The executed contract exhausted its gas limit.
    OutOfGas = 0x02,
    /// ...
}

[#8038]: Fix penpal runtime

Allow using Penpal native asset (PEN) for paying local fees and allow teleporting it from/to AH.
Also allow unpaid execution from relay chain for sudo calls.

[#8238]: Add checked_sqrt to the FixedPointNumber trait

Adds the function checked_sqrt to the FixedPointNumber trait, and deprecates const fn try_sqrt inside of the implement_fixed macro in favor of a const fn checked_sqrt which does the same thing. This affects [FixedI64, FixedU64, FixedI128, FixedU128].

[#8344]: XCMP weight metering: account for the MQ page position

This PR introduces some XCMP weight metering improvements.

[#8021]: XCMP: use batching when enqueuing inbound messages

This PR implements batching for the XCMP inbound enqueueing logic, which leads to an about ~75x performance
improvement for that specific code.

The PR also moves the footprint() method from the EnqueuMessage trait to a new QueueuFootprintQuery trait.

[#8531]: Added OnNewHead to pallet-bridge-parachains

This PR introduces a new OnNewHead hook for pallet-bridge-parachains, which is triggered when a new parachain head is relayed.

It will be used in conjunction with the syncing mechanism, which sends relayed AssetHubRococo headers with state_roots to AssetHubWestend for message proof verification.

[#8700]: transfer_assets benchmarking and weights for people chains

Introduces implementation of set_up_complex_asset_transfer() to correctly benchmark weights for transfer_assets extrinsics on Rococo People and Westend People

[#8504]: Fix generated address returned by Substrate RPC runtime call

Description

When dry-running a contract deployment through the runtime API, the returned address does not match the actual address that will be used when the transaction is submitted. This inconsistency occurs because the address derivation logic doesn't properly account for the difference between transaction execution and dry-run execution contexts.

The issue stems from the create1 address derivation logic in exec.rs:

address::create1(
    &deployer,
    // the Nonce from the origin has been incremented pre-dispatch, so we
    // need to subtract 1 to get the nonce at the time of the call.
    if origin_is_caller {
        account_nonce.saturating_sub(1u32.into()).saturated_into()
    } else {
        account_nonce.saturated_into()
    },
)

The code correctly subtracts 1 from the account nonce during a transaction execution (because the nonce is incremented pre-dispatch), but doesn't account for execution context - whether it's a real transaction or a dry run through the RPC.

Review Notes

This PR adds a new condition to check for the ExecContext when calculating the nonce for address derivation:

address::create1(
    &deployer,
    // the Nonce from the origin has been incremented pre-dispatch, so we
    // need to subtract 1 to get the nonce at the time of the call.
    if origin_is_caller && matches!(exec_context, ExecContext::Transaction) {
        account_nonce.saturating_sub(1u32.into()).saturated_into()
    } else {
        account_nonce.saturated_into()
    },
)

A new test nonce_not_incremented_in_dry_run() has been added to verify the behavior.

Before Fix

  • Dry-run contract deployment returns address derived with nonce N
  • Actual transaction deployment creates contract at address derived with nonce N-1
  • Result: Inconsistent addresses between simulation and actual execution

After Fix

  • Dry-run and actual transaction deployments both create contracts at the same address
  • Result: Consistent contract addresses regardless of execution context
  • Added test case to verify nonce handling in different execution contexts

This fix ensures that users can rely on the address returned by a dry run to match the actual address that will be used when the transaction is submitted.

Fixes paritytech/contract-issues#37

[#8273]: pallet-revive: Add net-listening rpc

Add net_listening rpc method
Does not seem to be required but is used by some wallet like subwallet

[#8667]: revive: Simplify the storage meter

Historically, the collection of storage deposits was running in an infallible context. Meaning we needed to make sure that the caller was able to pay the deposits when the last contract execution returns. To achieve that, we capped the storage deposit limit to the maximum balance of the origin. This made the code more complex: It conflated the deposit limit with the amount of balance the origin has.

In the meantime, we changed code around to make the deposit collection fallible. But never changed this aspect.

This PR rectifies that by doing:

  • The root storage meter and all its nested meter's limits are completely independent of the origin's balance. This makes it way easier to argue about the limit that a nested meter has at any point.
  • Consistently use StorageDepositNotEnoughFunds (limit not reached) and StorageDepositLimitExhausted (limit reached).
  • Origin not being able to pay the ed for a new account is now StorageDepositNotEnoughFunds and traps the caller rather then being a TransferFailed return code. Important since we are hiding the ed from contracts. So it should also not be an error code that must be handled.

Im preparation for: paritytech/contract-issues#38

[#8289]: Extract create_pool_with_native_on macro to common crate

Extract the macro in the bridge-hub-westend-integration-tests crate to the emulated-integration-tests-common
crate, so that it can be used in the runtimes repository as well.

[#8069]: Benchmark storage access on block validation

Adds checking storage weights on block validation for both read and write benchmarks.

[#9077]: [stable2506] Bump spec_version to 1_019_001 and reorder prdocs

Bump spec_version to 1_019_001 and reorder prdocs

[#7857]: Add new host APIs set_storage_or_clear and get_storage_or_zero

Description

This PR introduces two new storage API functions—set_storage_or_clear and get_storage_or_zero—which provide fixed‑size (32‑byte) storage operations. These APIs are an attempt to match Ethereum’s SSTORE semantics. These APIs provide additional functionality for setting and retrieving storage values and clearing storage when a zero value is provided and returning zero bytes when a key does not exist.

Fixes #6944
Review Notes

  • Changes in runtime.rs
    Added the set_storage_or_clear function to set storage at a fixed 256-bit key with a fixed 256-bit value. If the provided value is all zeros, the key is cleared.
    Added the get_storage_or_zero function to read storage at a fixed 256-bit key and write back a fixed 256-bit value. If the key does not exist, 32 bytes of zero are written back.
  • Changes in storage.rs
    Added test cases to cover the new set_storage_or_clear and get_storage_or_zero APIs.
    .
// Example usage of the new set_storage_or_clear function
let existing = api::set_storage_or_clear(StorageFlags::empty(), &KEY, &VALUE_A);
assert_eq!(existing, None);

// Example usage of the new get_storage_or_zero function
let mut stored: [u8; 32] = [0u8; 32];
let _ = api::get_storage_or_zero(StorageFlags::empty(), &KEY, &mut stored);
assert_eq!(stored, VALUE_A);

[#8702]: [AHM] Relax the requirement for RC-Client to receive +1 session reports

Something that we learned in westend: if ah-client decides to go to Buffered mode ever again, it might skip some sessions. Atm, we were enforcing sessions to be strictly incremented by one once received by RC client. This could cause us to drop some validator reward points.

As a simple fix, this PR relaxes this check such that if the last repot was x:

  1. x+1 is our expected behavior
  2. x+2 and more is still accepted, but we emit warning events
  3. x and below is still dropped. This can only happen due to: unforeseen bug in RC, or XCM failing to send messages in order.

[#8554]: pallet-assets ERC20 precompile

Add ERC20 precompile for pallet-asset.

Since there can be multiple instances of pallet-assets, the Precompile is implemented for an AssetPrecompileConfig that defines both the address range to match and how to extract the asset_id from the address.

For now I have only created one AssetIdExtractor that pulls an u32 asset id encoded in the address.

Follow up PR will define stateful extractor to extract the id from storage for foreign assets.

Other solidity traits will be added in follow up PRs

[#8337]: add staking/election related view functions

Adds two self-explanatory view functions to staking/election related pallets.
To be used by wallets wishing to perform rebag operation, and use by staking miner(s) to know how much deposit they need in advance.

[#7229]: FRAME: Deprecate RuntimeEvent associated type from Config trait

This PR removes the need for defining RuntimeEvent in the Config trait of a pallet. It uses associated type bound feature under the hood to make sure that Event of the pallet is convertible to the frame_system::RuntimeEvent type.

With this change, we can do this:

#[pallet::config]
pub trait Config: frame_system::Config {
}

instead of this:

#[pallet::config]
pub trait Config: frame_system::Config {
        /// Overarching event type.
      #[allow(deprecated)]
      type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
}

The latter compiles but is redundant since the associated type bound is automatically appended
if pallet defines Event type, i.e it looks like this after macro expansion:

#[pallet::config]
pub trait Config: frame_system::Config + frame_system::Config<RuntimeEvent: From<Event<Self>>> {
}

[#8127]: [AHM] Async Staking module across AH and RC

This PR is the final outcome of a multi-month development period, with a lot of background work since 2022. Its main aim is to make pallet-staking, alongside its type ElectionProvider compatible to be used in a parachain, and report back the validator set to a relay-chain.

This setup is intended to be used for Polkadot, Kusama and Westend relay-chains, with the corresponding AssetHubs hosting the staking system.

While this PR is quite big, a lot of the diffs are due to adding a relay and parachain runtime for testing. The following is a guide to help reviewers/auditors distinguish what has actually changed in this PR.

Added

This PR adds the following new pallets, all of which are not used anywhere yet, with the exception of one (see westend-runtime changes below).

pallet-election-provider-multi-block

This is a set of 4 pallets, capable of implementing an async, multi-page ElectionProvider.
This pallet is not used in any real runtime yet, and is intended to be used in AssetHub, next to pallet-staking-async.

pallet-staking-async

A fork of the old pallet-staking, with a number of key differences, making it suitable to be used in a parachain:

  1. It no longer has access to a secure timestamp, previously used to calculate the duration of an era. 2. It no longer has access to a pallet-session.
  2. It no longer has access to a pallet-authorship.
  3. It is capable of working with a multi-page ElectionProvider, aka. pallet-election-provider-multi-block.

To compensate for the above, this pallet relies on XCM messages coming from the relay-chain,
informing the pallet of:

  • When a new era should be activated, and how long its duration was
  • When an offence has happened on the relay relay-chain
  • When a session ends on the relay-chain, and how many reward points were accumulated for each
    validators during that period.

pallet-staking-async-ah-client and pallet-staking-async-rc-client

Are the two new pallets that facilitate the above communication.

pallet-ahm-test

A test-only crate that contains e2e rust-based unit test for all of the above.

pallet-staking-async-rc-runtime and pallet-staking-async-parachain-runtime

Forks of westend and westend-asset-hub, customized to be used for testing all of the above with Zombienet. It contains a lot of unrelated code as well.

Changed

Identification

This mechanism, which lives on the relay-chain, is expressed by type FullIdentification and type FullIdentificationOf in runtimes. It is a way to identify the full data needed to slash a validator. Historically, it was pointing to a validator, and their struct Exposure. With the move to Asset-Hub, this is no longer possible for two reasons:

  1. Relay chain no longer knows the full exposures
  2. Even if, the full exposures are getting bigger and bigger and relying the entirety of it is not scalable.

Instead, runtimes now move to a new type FullIdentificationOf = DefaultExposureOf, which will identify a validator with a Exposure::default(). This is suboptimal, as it forces us to still store a number of bytes. Yet, it allows any old FullIdentification, pertaining to an old slash, to be decoded. This compromise is only needed to cater for slashes that happen around the time of AHM.

westend-runtime

This runtime already has the pallet-staking-async-ah-client, integrated into all the places such that:

  1. It handles the validator reward points
  2. It handles offences
  3. It is the SessionManager

Yet, it is delegating all of the above to its type Fallback, which is the old pallet-staking. This is a preparatory step for AHM, and should not be any logical change.

pallet-election-provider-multi-phase

This is the old single-page ElectionProvider. It has been updated to work with multi-page traits, yet it only supports page-size = 1 for now. It should not have seen any logical changes.

pallet-bags-list

Now has two new features. 1. It can be Locked, in which case all updates to it fail with an Err(_), even deletion of a node. This is needed because we cannot alter any nodes in this pallet during a multi-page iteration, aka. multi-page snapshot. 2. To combat this, the same rebag transaction can be also be used to remove a node from the list, or add a node to the list. This is done through the score_of api.

See the file changes and tests under ./substrate/frame/bags-list for more info.

RuntimeDebug -> Debug

To facilitate debugging, a number of types' RuntimeDebug impl has been changed to Debug. See #3107

[#8980]: Fix revive-fixtures build script

Fix compilation issue with pallet-revive-fixtures build.rs script.

[#5620]: New NFT traits: granular and abstract interface

This PR introduces a new set of traits that represent different asset operations in a granular and abstract way.
The new abstractions provide an interface for collections and tokens for use in general and XCM contexts.

[#8271]: Snowbridge - Message reward topups

This PR enables the ability to add a tip to an Inbound or Outbound message, in case the relayer reward is too low and not profitable to process. The tip is added to the relayer reward when processing a message.

[#8171]: Add vested transfer event emission

Add event VestingCreated and emit on vested transfer.

[#7762]: ERC20 Asset Transactor

This PR introduces an Asset Transactor for dealing with ERC20 tokens and adds it to Asset Hub Westend.
This means asset ids of the form { parents: 0, interior: X1(AccountKey20 { key, network }) } will be matched by this transactor and the corresponding transfer function will be called in the smart contract whose address is key.
If your chain uses pallet-revive, you can support ERC20s as well by adding the transactor, which lives in assets-common.

[#8559]: [pallet-revive] rename DepositLimit::Unchecked & minor code cleanup

minor cleanups for pallet-revive eth-rpc rename DepositLimit::Unchecked to DepositLimit::UnsafeOnlyForDryRun

Changelog for Node Operator

ℹ️ These changes are relevant to: Those who don't write any code and only run code.

[#8370]: fix unneeded collator connection issue

This PR fixes an issue where collators continued attempting to connect to validators even after their core assignment was removed, leading to unnecessary connections and log spam An unneeded collator connected.
The fix ensures collators only connect to validators if there are cores assigned to the parachain.

[#8345]: tx/metrics: Add metrics for the RPC v2 transactionWatch_v1_submitAndWatch

This PR adds metrics for the following RPC subscription: transactionWatch_v1_submitAndWatch

Metrics are exposed in two ways:

  • simple counters of how many events we've seen globally
  • a histogram vector of execution times, which is labeled by initial event -> final event
  • This helps us identify how long it takes the transaction pool to advance the state of the events, and further debug issues

Part of: #8336

(outdated) PoC Dashboards

Screenshot 2025-04-28 at 17 50 48

Next steps

  • initial dashboards with a live node
  • adjust testing

[#8860]: [stable2506] Backport #8860 relay chain logic (runtime + client)

This PR relaxes the advancement rule for HRMP messages, making it possible to keep the old watermark.

[#9047]: Add extra information to the harmless error logs during validate_transaction

Adds additional information to the harmless error logs "Bad input data provided" during validate_transaction.

[#6827]: Introduction of Approval Slashes

Introduces a more aggressive slashing scheme.
Lazy or spammy validators will from now on be slashable in disputes.
Even if your validator is not a backer but it approves an invalid block it will be slashed 2%.
If your validator raises or supports fake alarms (disputes against valid blocks) you will be slashed (0%) and disabled for the remainder of the era, which will potentially reduce era point gains.

[#8441]: Update prdoc in 8327 to fix release issue

Update the prdoc in 8327 to fix a release issue.

[#8332]: parachain informant

Closes #8216. Adds parachain_block_authorship_duration and parachain_unincluded_segment_size parachain metrics.

[#8076]: Enable statement store with new CLI arg in polkadot-omni-node and polkadot-parachain

In polkadot-omni-node-lib, a new cli arg --enable-statement-store is introduced, if set to true then the statement store is enabled in the node.

The statement store is an off-chain data-store for signed statements accessible via RPC and offchain worker.
It uses the runtime api to get the allowance associated to an account.

This takes effect in polkadot-omni-node and polkadot-parachain and any node depending on polkadot-omni-node-lib.

In cumulus-client-service the BuildNetworkParams now takes the metrics configuration explicitly, you can use the same configuration as before using the network backend used when calling build_network:

let metrics = NetworkBackend::register_notification_metrics(
    parachain_config.prometheus_config.as_ref().map(|config| &config.registry),
);

[#8208]: Omni Node: Enable OCW http

This enables the HTTP support for the OCW.

Closes: #8203

[#8445]: Fix the clearing of gap sync on known imported blocks

This PR ensures that warp sync gaps are properly cleared when known blocks are imported. Previously, gaps were only removed in response to ImportedUnknown events.
This limitation caused issues for asset-hub and bridge-hub collators, which remained stuck in the "Block history" state without progressing.
The root cause lies in the client.info() reporting a gap during node startup or restart (ie block verification fails). In some cases, a peer may respond with the missing blocks after we’ve already imported them locally, leaving the gap open.

[#7980]: fatxpool: optimize txs prunning based on inactive views provides tags

Optimization of transaction pruning. More datils can be found in the PR description.

Changelog for Runtime User

ℹ️ These changes are relevant to: Anyone using the runtime. This can be a token holder or a dev writing a front end for a chain.

[#8376]: Remove TakeFirstAssetTrader from AH Westend and Rococo

Removed TakeFirstAssetTrader from Asset Hub Westend and Rococo. Improved macros, fixed tests.
This implies asset sufficiency no longer guarantees that weight can also be bought with it.
SwapFirstAssetTrader is used instead which will attempt to swap some of the given asset for the required amount of native asset to buy weight. This may or may not succeed depending on whether there is a local pool present with enough liquidity to serve the swap.

[#9137]: Pallet XCM - transfer_assets pre-ahm patch

Pallet XCM's transfer_assets extrinsic now returns an error when it determines that a reserve transfer of DOT|KSM|WND|PAS has to be done.
This is a safeguard in preparation for the Asset Hub Migration (AHM), where the reserve of DOT|KSM|WND|PAS will change from the Relay Chain to Asset Hub.
After the migration, another patch will remove this error case and use the correct reserve.
limited_reserve_transfer_assets, transfer_assets_using_type_and_then or execute should be used instead, since they provide the ability to specify the reserve you want to use.

[#6312]: DeprecationInfo propagate or automatically add allow(deprecated) attributes in the generated code.

Propagates or automatically adds allow(deprecated) attributes on Constants, RuntimeApis, Runtime Calls and enum variants
to reduce noise produced by warnings inside generated code.

[#9139]: Expose more constants for pallet-xcm

Exposes more constants (UniversalLocation, MaxLockers, MaxRemoteLockConsumers), similar as AdvertisedXcmVersion.

[#9202]: apply_authorized_force_set_current_code does not need to consume the whole block

There is no need that this dispatchable consumes the full block as this is just writing the given value to storage. On a chain this is done, because the runtime changes and thus, a lot of stuff potentially changes. In the case of upgrading the parachain code on the relay chain, the relay chain runtime itself does not change.

[#8254]: Introduce remove_upgrade_cooldown

This dispatchable enables anyone to pay for removing an active upgrade cooldown from a parachain instead of waiting for the cooldown to be finished. It is useful for times when a parachain needs to apply an upgrade faster than the upgrade cooldown, but it will need to pay in this case. The dispatchable enables anyone to remove an upgrade cooldown of any parachain. The caller needs to pay for the removal and the tokens are burned on a successful removal.

[#8470]: Stabilize the FRAME umbrella crate

Stabilizing the FRAME umbrella crate, which is no longer marked as experimental.
Improving the related documentation, including README and maintenance notes.

After integrating the FRAME umbrella crate in 17 pallets as May 9 2025 and modifying it in the process (see #6504),
it is now stable and it can be used for pallet development.

Key improvements:

  • Enhanced documentation with clear usage guidelines
  • Added comprehensive maintenance notes for future contributors
  • Established clear design principles for prelude usage and module organization
  • Updated documentation links to point to the official hosted docs

[#9077]: [stable2506] Bump spec_version to 1_019_001 and reorder prdocs

Bump spec_version to 1_019_001 and reorder prdocs

[#8171]: Add vested transfer event emission

Add event VestingCreated and emit on vested transfer.

[#8925]: Multisig::as_multi_threshold_1: Send MultisigExecuted event

So the behavior is the same as as_multi when it comes to sending an event.

Closes: #8924

[#7762]: ERC20 Asset Transactor

This PR allows ERC20 tokens on Asset Hub to be referenced in XCM via their smart contract address.
This is the first step towards cross-chain transferring ERC20s created on the Hub.

Rust compiler versions

This release was built and tested against the following versions of rustc.
Other versions may work.

  • Rust Stable: 1.84.1

Runtimes

The information about the runtimes included in this release can be found below.
The runtimes have been built using srtool v0.18.2 and rustc 1.84.1 (e71f9a9a9 2025-01-27).

Westend

🏋️ Runtime Size:          2.35 MB (2462014 bytes)
🔥 Core Version:          westend-1019002 (parity-westend-0.tx27.au2)
🗜 Compressed:            Yes: 74.3%
🎁 Metadata version:      V14
🗳️ system.setCode hash:   0x2d95a3b5f3ad0455cd95b8c14ef33d4aa0ea790bec20f9278f53f0551235a4d9
🗳️ authorizeUpgrade hash: 0x6650080f8d2f9d70d3eeac6839d92db54a215dc468d045a81eea26cff227282b
🗳️ Blake2-256 hash:       0xc992635c1f3e58266ce7266543f4ef040f9102a827b0a3985ec120dc50595dd4
📦 IPFS:                  QmPgQV5iEFw19PHMX7sYafaxnJDABEP7HNeSftGBp12XxK

Westend Assethub

🏋️ Runtime Size:          2.11 MB (2213746 bytes)
🔥 Core Version:          westmint-1019002 (westmint-0.tx16.au1)
🗜 Compressed:            Yes: 77%
🎁 Metadata version:      V14
🗳️ system.setCode hash:   0x28b54aa5693915bde75c463bbd2ae1274be8f33f394787a55c990ff5606bb840
🗳️ authorizeUpgrade hash: 0xd15e03b05e61c9651238ee807694e5f74a376fcf966277e3bbdf49ba85b02682
🗳️ Blake2-256 hash:       0xcd06061f471978e0c22bec2e6b345a6110024684dabf2e5b128ba2a6cd74495b
📦 IPFS:                  QmUTv4zjghxrWGPu9tea4cRGtwhff43D9UTY63e3s5mDTe

Westend Bridgehub

🏋️ Runtime Size:          1.77 MB (1860532 bytes)
🔥 Core Version:          bridge-hub-westend-1019002 (bridge-hub-westend-0.tx6.au1)
🗜 Compressed:            Yes: 74.15%
🎁 Metadata version:      V14
🗳️ system.setCode hash:   0x712c56b81268d32cc12eecafb19d616fab6a34e0266cd0eeef681893afd24a7b
🗳️ authorizeUpgrade hash: 0xed1635ce657e5cc0d90adb2bab21a7eab4cd56995d4898d5ecb0ab234d2ead96
🗳️ Blake2-256 hash:       0x04eef7b7f64da2b231f7a5d2ce28759ab132b3df93f0cd22c3e7222e65578861
📦 IPFS:                  QmYWavwYVe2jZkFBfzdftVJh3rTJWGBcV1MQyoXcEkGqtA

Westend Collectives

🏋️ Runtime Size:          1.55 MB (1623364 bytes)
🔥 Core Version:          collectives-westend-1019002 (collectives-westend-0.tx6.au1)
🗜 Compressed:            Yes: 75.62%
🎁 Metadata version:      V14
🗳️ system.setCode hash:   0x0664d0179fd7723cc6f0b572dad7af159bef40df1341baaee39842276a12078c
🗳️ authorizeUpgrade hash: 0x87bfd1bd85ed141536f8685b1bff524921320571b29f536288ea8711dd2e573e
🗳️ Blake2-256 hash:       0x52448c9368a65a356c476e0121a1ddd20c79c12b35ab7ddf4600045712e4af2e
📦 IPFS:                  QmYBAqudzp6BHUkUUgXYRu1PDuJ66UGFWDS7XXteB9EeCv

Westend Coretime

🏋️ Runtime Size:          1.37 MB (1434459 bytes)
🔥 Core Version:          coretime-westend-1019002 (coretime-westend-0.tx2.au1)
🗜 Compressed:            Yes: 74.91%
🎁 Metadata version:      V14
🗳️ system.setCode hash:   0x144c2b5697a6a95512b8ead596f4f7d910a1d8e7d4a5a628ce3531ef128dbe96
🗳️ authorizeUpgrade hash: 0xf0c0bbd6c3a2ff8ba12086ad8e2b64faf3b837d1b362eeb381a8390de0c8e44b
🗳️ Blake2-256 hash:       0x116bce45b7ad50675252202a86f032f5faba25d8711da26bfb95bca93dfa6ca8
📦 IPFS:                  QmSiSKuZEd4q68buE619DnZohmoj8BuAc5AvX7jjfvaGAo

Westend Glutton

🏋️ Runtime Size:          659.79 kB (675624 bytes)
🔥 Core Version:          glutton-westend-1019002 (glutton-westend-0.tx1.au1)
🗜 Compressed:            Yes: 72.92%
🎁 Metadata version:      V14
🗳️ system.setCode hash:   0x533cdf707b3b2ae3bbc8c5ba28f0bb3b9c93fe269a6c42e24c54521a8d849917
🗳️ authorizeUpgrade hash: 0x525235041556df4518220122ab9635b01fc5cdaaad8b5594377a26740da50f6a
🗳️ Blake2-256 hash:       0xc9dc6eaeec8bb618b90d53a247a8faa129015087a164c0e5a8beca2f9a361ad7
📦 IPFS:                  QmTSrUeeB2Agc7ZkhBgk1zmjYUBFDQPyLY39k9NCAGkMk4

Westend People

🏋️ Runtime Size:          1.36 MB (1430507 bytes)
🔥 Core Version:          people-westend-1019002 (people-westend-0.tx2.au1)
🗜 Compressed:            Yes: 74.82%
🎁 Metadata version:      V14
🗳️ system.setCode hash:   0x04133cc0606fe393ea24cfe845d1cea2a53904c6dfa856a0381fa51206c72cc8
🗳️ authorizeUpgrade hash: 0x7a317936c1debf48d2518cca2b2bc712f66f95f50bd1a9b9b1bafac7d450b223
🗳️ Blake2-256 hash:       0x720f15c41d8b478b5857c89e04330fd00d977d9f37622b0f898de39be27202cc
📦 IPFS:                  QmaEAbuzVBV2FtNY39U5qfZSCdiK9XVthPvBoMUuw3Uv6H

Docker images

The docker images for the polkadot node binary and the polkadot-parachain binary can be found at Docker hub (will be available a few minutes after the release has been published):

You may also pull it with:

docker pull parity/polkadot:stable2506

or

docker pull parity/polkadot-parachain:stable2506

Don't miss a new polkadot-sdk release

NewReleases is sending notifications on new releases.