Polkadot Release Analysis v0.9.34

:warning: The following report is not an exhaustive list of changes included in the release, but a set of changes that we felt deserved to be highlighted due to their impact on the Polkadot ecosystem builders.

Please do not stop reading the release notes v0.9.34. This report is complementary to the changelogs, not a replacement.

Highlights are categorized into High Impact, Medium Impact, and Low Impact for ease of navigation.

Help us improve the release analysis by filling out this 6 question survey.

Summary

One PR in this release has been flagged by the Release Analysis team as high impact for Polkadot Builders.

This release contains several updates to the newly rolled out OpenGov governance system among various other medium and low impact PR’s.

This is a runtime-only release. No node client is released.


Runtimes built on release v0.9.34

  • Westend v9340
  • Kusama v9340
  • Polkadot v9340

As stated in the release notes:

This polkadot runtime replaces runtime 9320 and 9330.
This kusama runtime replaces runtime 9330.



:exclamation:High Impact

ed25519_verify: Support using dalek for historical blocks

PR: https://github.com/paritytech/substrate/pull/12661

Switching to ed25519-zebra was a breaking change. ed25519-zebra is more permissive when it comes to the verification of signatures. This means that some chains may fail to sync from genesis when using ed25519-zebra.

How this impacts Polkadot builders?

If you are aware that the chain that you are syncing from may be affected by this change, this PR includes an extension that can be registered to the runtime execution environment to signal that ed25519-dalek should be used for verification. In this way the blocks that should be verified by dalek will be verified using the correct library.

The extension can be registered in the following way directly after the client is created:

use sc_client_api::ExecutorProvider;
client.execution_extensions().set_extensions_factory(
    // Let the `UseDalekExt` extension being registered for each runtime invocation
    // until the execution happens in the context of block `1000`.
    sc_client_api::execution_extensions::ExtensionBeforeBlock::<Block, UseDalekExt>::new(1000)
);

Note that in the above example we know that prior to block 1000, all blocks should be verified by ed25519-dalek instead of ed25519-zebra. From 1000 on, they will be then verified using ed25519-zebra.


:warning: Medium Impact

Asset Pallet: Support repeated destroys to safely destroy large assets

PR: https://github.com/paritytech/substrate/pull/12310

Cumulus Companion PR: PR #1742

This PR is the part of #Issue 12275.

Why is this change interesting for builders?

Assets pallet has a destroy function to destroy an entire asset class. This function has some issues, particularly when we destroy an asset with a large number of accounts, it leads to a weight which exceeds the maximum block limit.

This PR is an attempt to fix this issue.

How this impacts Polkadot builders?

As part of this PR, destroy function has been broken into four new extrinsics. This is well described in PR description. Due to these changes, this PR also adds migration for the same.

A new constant type RemoveItemsLimit has also been introduced in Assets pallet’s Config trait.

If you are using Asset pallet in your runtime, you have to add this new config type, otherwise runtime compilation will fail because of missing type error.

impl pallet_assets::Config for Runtime {
	// Other Config types
	type RemoveItemsLimit = ConstU32<1000>;
	
}

Remove the wasmtime feature flag

PR: https://github.com/paritytech/substrate/pull/12684

Polkadot companion PR: https://github.com/paritytech/polkadot/pull/6268
Cumulus companion PR: https://github.com/paritytech/cumulus/pull/1861

PR #12486 enabled wasmtime by default. However, the flag for it was still there. This PR removes the flag. Now wasmtime will be unconditionally compiled in.

Any downstream project that depends on Substrate and which is used to specify the wasmtime feature flag in its dependencies will now need to remove it.

Add with_weight extrinsic

PR: Add `with_weight` extrinsic by shawntabrizi · Pull Request #12848 · paritytech/substrate · GitHub

Adds to pallet utility the possibility of dispatching any extrinsic with custom weight. This PR introduces to said pallet a new extrinsic, with_weight. The dispatch origin for this call must be Root. It won’t check the weight of the call, and instead allows the Root origin to specify the weight of the call.

Having the possibility for such an option has raised importance lately, after some changes to pallet scheduler, it was found that in scenarios like executing a runtime upgrade, the capacity for overriding the call’s weight could avoid problems like the runtime upgrade not being executed due to being considered over-weight.

API for registering inactive funds

PR: https://github.com/paritytech/substrate/pull/12813

This PR introduces the concept of active and inactive funds within the total of the issuance, dividing it into two concepts, InactiveIssuance and ActiveIssuance.

On one side, we can find InactiveIssuance as a storage item on pallet-balances

/// The total units of outstanding deactivated balance in the system.
#[pallet::storage]
#[pallet::getter(fn inactive_issuance)]
#[pallet::whitelist_storage]
pub type InactiveIssuance<T: Config<I>, I: 'static = ()> =
    StorageValue<_, T::Balance, ValueQuery>;

This should generally be used rather than TotalIssuance.

Not only that but it also introduces ActiveIssuanceOf

// A non-const `Get` implementation parameterised by a `Currency` impl which provides the result
/// of `active_issuance`.
pub struct ActiveIssuanceOf<C: Currency<A>, A>(sp_std::marker::PhantomData<(C, A)>);
impl<C: Currency<A>, A> Get<C::Balance> for ActiveIssuanceOf<C, A> {
   fn get() -> C::Balance {
   	C::active_issuance()
   }
}

What is an example of funds that could be considered as inactive? Well, some funds from Treasury could fit into this definition. Take a look at the following storage item inside the treasury-pallet:

/// The amount which has been reported as inactive to Currency.
#[pallet::storage]
pub type Inactive<T: Config<I>, I: 'static = ()> = StorageValue<_, BalanceOf<T, I>, ValueQuery>;

Relevant migrations are in place along with this change.

Allow Sufficient Assets for XCM Fee Payment on Statemint

PR: https://github.com/paritytech/cumulus/pull/1910

This PR adds a new configuration to Trader in xcm_executor for Statemint runtime.
Appending the Trader configuration with TakeFirstAssetTrader allows execution to be paid with sufficient assets existing in pallet-assets.

This change was applied previously to Statemine (on Kusama), and now this will also be available in Statemint (on Polkadot).


:information_source: Low Impact

Add Offchain Worker to Parachain Config by Default

PR: https://github.com/paritytech/cumulus/pull/1860

To make off-chain data integration secure and more efficient, Substrate provides off-chain workers. Off-chain workers allow your Substrate node to offload tasks that take too long or too much CPU / memory resources to compute, or have a non-deterministic result.

This PR enables Offchain workers in the Cumulus parachain template by default.

pallet-balances: Fix inactive funds migration

PR: https://github.com/paritytech/substrate/pull/12840

After the inclusion of PR #12813 that introduced ActiveIssuanceOf, this PR includes a migration for pallet-balances where it sets storage_version attribute for the Pallet. At the same time, the migration will take the addition of balances from a list of provided accounts as a parameter and mark the resulting balance as inactive using deactivate.

OpenGov: Abstentions

PR: OpenGov: Abstentions by gavofyork · Pull Request #12842 · paritytech/substrate · GitHub

How this impacts Polkadot builders?

This PR should not affect any builder that is not working on a governance system based on OpenGov as it only includes new tweaks on how this system works. As of writing, OpenGov is present on Kusama.

Why is this change interesting for builders?

Note this change is interesting for the whole of the ecosystem.
SplitAbstain variant has been added into AccountVote enum so users can still show paritcipation without affecting the result of the voting.
This is important as in a case where one is neither for or against a proposal, it is possible to abstain, making a vote count as support for it, and so helping it to close faster, but not adding to the count of aye or nay votes.

OpenGov improvements for Kusama

PR: https://github.com/paritytech/polkadot/pull/6372

Why is this change interesting for builders?

Now that OpenGov is live on the Kusama network, this PR includes some improvements to the OpenGov governance system.

Some of the changes come from the suggestions/improvements that were requested on the Polkadot Forum. You can find the discussion here.

This PR also introduces migrations for Crowdloan and XCM checking account for all chains (Polkadot, Kusama, Rococo, and Westend).

Update DefaultNoBound derive macro

PR: https://github.com/paritytech/substrate/pull/12723

Among different fixes and improvements, this PR updates DefaultNoBound derive macro to follow rust RFC 3107, changing the behaviour of the macro from choosing always the first variant as default, to using the variant annotated with #[default].
#[default] attribute is now required.

How to use

The following is an example of how an enum which uses DefaultNoBound derive macro looks like:

// source: https://github.com/paritytech/substrate/blob/2e21c35f879e904101d8305eef7a203d95dd6cd6/frame/transaction-payment/asset-tx-payment/src/lib.rs
#[derive(Encode, Decode, DefaultNoBound, TypeInfo)]
pub enum InitialPayment<T: Config> {
	/// No initial fee was payed.
	#[default]
	Nothing,
	/// The initial fee was payed in the native currency.
	Native(LiquidityInfoOf<T>),
	/// The initial fee was payed in an asset.
	Asset(CreditOf<T::AccountId, T::Fungibles>),
}

InitialPayment::Nothing will be the default variant for this enum.

Support OpenGov Calls in Proxy Definitions

PR: Support OpenGov Calls in Proxy Definitions by joepetrowski · Pull Request #6366 · paritytech/polkadot · GitHub

This PR is the part of #Issue 6333.

Why is this change interesting for builders?

Proxy pallet filters the calls a proxy account can dispatch based on the proxy type. In the runtime, you can restrict transactions for a proxy account using the following proxy types:

  • Any
  • NonTransfer
  • Governance
  • Staking
  • IdentityJudgement
  • CancelProxy
  • Auction

At the moment, only Gov v1 pallets are included in Kusama runtime proxy definition. This PR adds OpenGov pallets into the proxy definitions.

Fix the light client protocol protobuf schema

PR: Fix the light client protocol protobuf schema by tomaka · Pull Request #12732 · paritytech/substrate · GitHub

Before this PR, if a node received a “light client request” which could not be served the message would send back an empty proof. This has been amended to the correct intended behaviour which is to send a response without a proof and the response should indicate the type of response it is.

Additionally, this PR also switches the schema to protobuf 2. Reason being that each field is either explicitly required or optional, so the exact information that is being sent is clearer.

Make public is_passing and ReferendumStatus

PR: Make public is_passing and ReferendumStatus by 4meta5 · Pull Request #12667 · paritytech/substrate · GitHub

Pallet referenda now exposes read access to fn is_passing() ( a private function ) as pub fn is_referendum_passing(ReferendumIndex) which will return whether the referendum is passing. This rederendum must be ongoing and its track must exist.
This PR also changes to public the visibility of the fields from the following structs:

  • DecidingStatus
  • Deposit
  • ReferendumStatus

find the definition of these structs in frame/referenda/src/types.rs

with the intention that this information can be accessed from, for instance, precompiles and allows different collectives to participate in different referenda as they fit their liking, independently of how these collectives are technically implemented.

Make Gov2 Curve::threshold fn public

PR: Make Gov2 Curve::threshold fn public by 4meta5 · Pull Request #12814 · paritytech/substrate · GitHub

In the very same lines as PR #12667, this PR changes the visibility of fn threshold to public, so other modules can access this information. The relevant information here is the value of a certain threshold curve for a given x. This function can be found in frame/referenda/src/types.rs

New root_testing pallet

PR: New `root_testing` pallet by Szegoo · Pull Request #12451 · paritytech/substrate · GitHub

To keep the codebase tidy and coherent, this pallet moves the function fill_block from root_offences_pallet to a new pallet, root_testing which at the moment only hosts this function as an extrinsic, and enables the user to fill a block up to a given ratio.

This pallet should only be used for testing purposes.

Allow other pallets to check asset ids.

PR: https://github.com/paritytech/substrate/pull/12666

This PR implements InspectEnumerable for assets pallet. Which allows other pallets to know what assets are in existence.

The InspectEnumerable trait:

/// Interface for enumerating assets in existence or owned by a given account.
pub trait InspectEnumerable<AccountId>: Inspect<AccountId> {
	type AssetsIterator;

	/// Returns an iterator of the collections in existence.
	fn asset_ids() -> Self::AssetsIterator;
}

We can see that, fn asset_ids() will return an AssetsIterator. Note that iterating this list invokes a storage read per item.

Move WeightCounter to sp-weights

PR: Move `WeightCounter` to `sp-weights` by ggwpez · Pull Request #12603 · paritytech/substrate · GitHub

WeightCounter has been renamed to WeightMeter and moved into sp-weights.
Can be used to check if enough weight for an operation is available before committing to it.

use sp_weights::{Weight, WeightMeter};

// The weight is limited to (10, 0).
let mut meter = WeightMeter::from_limit(Weight::from_parts(10, 0));
// There is enough weight remaining for an operation with (5, 0) weight.
assert!(meter.check_accrue(Weight::from_parts(5, 0)));
// There is not enough weight remaining for an operation with (6, 0) weight.
assert!(!meter.check_accrue(Weight::from_parts(6, 0)));

Add starts_with to v0 and v1 MultiLocation

PR: Add `starts_with` to v0 and v1 MultiLocation by joepetrowski · Pull Request #6311 · paritytech/polkadot · GitHub

Now starts_with is available to be used with MultiLocation type for v0 and v1. This function will return whether self begins with or is equal to a given prefix.

Signature of the function:

pub fn starts_with(&self, prefix: &Junctions) -> bool

This allows users to write checks like the following:

let full: MultiLocation = (Parent, Parachain(1000), AccountId32 { network: Any, id: [0; 32] }).into();
let identity: MultiLocation = full.clone();
let prefix: MultiLocation = (Parent, Parachain(1000)).into();
let wrong_parachain: MultiLocation = (Parent, Parachain(1001)).into();
let wrong_account: MultiLocation = (Parent, Parachain(1000), AccountId32 { network: Any, id: [1; 32] }).into();
let no_parents: MultiLocation = (Parachain(1000)).into();
let too_many_parents: MultiLocation = (Parent, Parent, Parachain(1000)).into();

assert!(full.starts_with(&identity));
assert!(full.starts_with(&prefix));
assert!(!full.starts_with(&wrong_parachain));
assert!(!full.starts_with(&wrong_account));
assert!(!full.starts_with(&no_parents));
assert!(!full.starts_with(&too_many_parents));

Add Weightless benchmark bailing

PR: https://github.com/paritytech/substrate/pull/12829

Polkadot Companion PR: PR #6328

Cumulus Companion PR: PR #1940

Why is this change interesting for builders?

At the momemt, it’s hard to write benchmarking if you have configured custom origin as NeverEnsureOrigin and you expect it be as dispatch origin.

You may need to add multiple if’s to handle such scenarios like #11562.

As a part of this PR, a new benchmarking error Weightless has been introduced, which indicates that no weight can be determined.

How to use

let custom_origin = T::CustomOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;

Bounties use SpendOrigin

PR: https://github.com/paritytech/substrate/pull/12808

Why is this change interesting for builders?

Bounties pallet uses ApproveOrigin for some dispatchable functions like approve_bounty and propose_curator. ApproveOrigin is the origin from where only approval comes. It does not have the information about how much the maximum amount that this origin is allowed to spend at a time.

After this PR, Bounties pallet will use SpendOrigin which solves this purpose. This will also be beneficial for OpenGov.

contracts: Replace cargo feature unstable-interface with config

PR: contracts: Replace cargo feature `unstable-interface` with config by athei · Pull Request #12787 · paritytech/substrate · GitHub

Polkadot Companion PR: PR #1916

Why is this change interesting for builders?

At the moment, if we want to access Contracts pallet callable functions, which are marked with #[unstable], we have to compile this with a substrate runtime feature contracts-unstable-interface using below command.

cargo run --release --features contracts-unstable-interface -- --dev

As part of this PR, this feature has been removed and a new config UnsafeUnstableInterface has been added in Contracts pallet.

How this impacts Polkadot builders?

If you are using Contracts pallet in your runtime, you have to add this new config type, otherwise runtime compilation will fail because of a missing type error.

How to use

impl pallet_contracts::Config for Runtime {
	// Other Config types
	type UnsafeUnstableInterface = ConstBool<false>;
}

MMR: move RPC code from frame/ to client/

PR: MMR: move RPC code from frame/ to client/ by acatangiu · Pull Request #12805 · paritytech/substrate · GitHub

Polkadot Companion PR: PR #6369

Cumulus Companion PR: PR #1923

Why is this change interesting for builders?

Merkle Mountain Ranges(MMR) are an alternative to Merkle trees. Before this PR, MMR RPC crate existed in Frame. As a part of this PR, this has been moved to the right place, which is in client/.

How this impacts Polkadot builders?

If you are using this crate, you may need to rename this crate in your codebase. Please see companion PRs for reference.

Remove Default, HasCompact, and TypeInfo trait bounds on AssetId

PR: https://github.com/paritytech/substrate/pull/12740

Cumulus Companion PR: PR #1898

This PR is the part of #Issue 12738.

Why is this change interesting for builders?

If you are using Assets pallet for dealing with fungible assets and you want to use it’s associated type AssetId to support those assets, your asset should meet the trait bound of AssetId.

As a part of this PR, the trait bound on AssetId has been relaxed.

How this impacts Polkadot builders?

In this PR, some trait bounds Default, HasCompact, and TypeInfo has been removed. This would cause the breaking changes at the existing places, where we are using #[pallet::compact] id: T::AssetId (compact asset id).

To prevent this breaking change, a new config type AssetIdParameter has also been introduced as a part of this PR.

A benchmarking helper trait BenchmarkHelper is also introduced to support the benchmarking of this new type.

How to use

If you are using Asset pallet in your runtime, you have to add these new config types, otherwise runtime compilation will fail because of missing type error.

impl pallet_assets::Config for Runtime {
    // Other Config types
    type AssetIdParameter = codec::Compact<u32>;
    #[cfg(feature = "runtime-benchmarks")]
    type BenchmarkHelper = ();
}

add EnsureWithSuccess

PR: add EnsureWithSuccess by xlc · Pull Request #12775 · paritytech/substrate · GitHub

Why is this change interesting for builders?

A new origin validator EnsureWithSuccess has been introduced as a part of this PR, which not only verifies the origin but also provides a success value.

Suppose we have a scenario, where we want to use some funds from an ensured origin. We can use EnsureWithSuccess in such scenarios. We can provide origins with some spend limit.

Non-Interactive Staking

PR: Non-Interactive Staking by gavofyork · Pull Request #12610 · paritytech/substrate · GitHub

Polkadot Companion PR: PR #6352

Why is this important?

Gilt pallet is being renamed to Non-Interactive Staking (NIS) pallet with several updates to the pallet itself. NIS pallet (formerly known as Gilt pallet) allows for accounts to auction for being frozen and receive open-ended inflation-protection in return. Learn about the pallet here.

Refer to the PR for a list of all the changes.

How this impacts Polkadot builders?

If you are using Gilt pallet in your runtime, you will have to modify your codebase to match the new name and modified associated types. If these changes are not made, runtime compilation will fail.

How to use

It is recommended to check the PR to see all the differences.
Let’s take an example of updating a runtime:

In Cargo.toml, you have to replace pallet-gilt with pallet-nis.

Additionally, in lib.rs you will have to do similar,

- impl pallet_gilt::Config for Runtime {
+ impl pallet_nis::Config for Runtime {

// Modify the associated types

}

construct_runtime!(
    ....
-        Gilt: pallet_gilt,
+        Nis: pallet_nis,
    ....
    }
);

Your friendly neighbourhood Polkadot Release Analysis team,
@hectorb @alejandro @bruno @ayush.mishra

8 Likes

In case you missed the report from the previous release (v0.9.33):

2 Likes

Thank you for the Analysis.

In addition, to support the ed25519_verify historical import of block, you need to ensure you are using the correct version of ed25519 crate.
We were using 1.5.2 and had to revert to 1.0.3 (like substrate is using) to get it to work properly.

1 Like

Neither there is version 1.0.3 nor there is 1.5.2 of ed25519-dalek. So, not sure what you are talking about?

I could be wrong as I didn’t do the fix myself, but our client was broken until we did:

1 Like

Thank you very much Alan for your comment. We very much appreciate any builder team member adding any additional information/correction to the report.

PR #6372 in this release modifies the following values

pub const QUID: Balance = UNITS / 30;
pub const CENTS: Balance = QUID / 100;

This introduces a change of factor 10x in the derivative values. Even though this is a change in Kusama constants, common good chains as Statemine pull these values.

This might require chains to adjust the construction of XCM messages being sent to networks pulling the changes accordingly.

:warning: Polkadot v9340 Runtime Upgrade :warning:

Assuming Referendum 96 passes (currently 99% in favor), Polkadot will upgrade to runtime v9340 on Saturday 14 Jan. This will have several effects: please read below! Polkassembly

:warning: First, any outstanding multisig calls (ones where one signatory has signed, but not the threshold) will not be able to execute. Please either finish your multisig calls before this upgrade, or wait until after it is completed. Remove multisig's Calls by gavofyork · Pull Request #12072 · paritytech/substrate · GitHub

:warning: All preimages and the dispatch queue will be cleared. Any Referenda already passed but not enacted will thus not execute. If the Referendum is ongoing, the preimage can be re-uploaded after the upgrade. Bound uses of `Call` by gavofyork · Pull Request #11649 · paritytech/substrate · GitHub