# Polkadot Release Analysis v0.9.33

**URL:** <https://forum.polkadot.network/t/polkadot-release-analysis-v0-9-33/1287>\
**Category:** Ecosystem\
**Tags:** release-analysis\
**Created:** [November 30, 2022, 11:05am UTC](https://forum.polkadot.network/t/polkadot-release-analysis-v0-9-33/1287 "2022-11-30T11:05:02Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![alejandro](https://dub1.discourse-cdn.com/flex005/user_avatar/forum.polkadot.network/alejandro/32/55_2.png) [@alejandro](https://forum.polkadot.network/u/alejandro)\
**Post date:** [November 30, 2022, 11:05am UTC](https://forum.polkadot.network/t/polkadot-release-analysis-v0-9-33/1287/1 "2022-11-30T11:05:02Z")

</div>

⚠ _ **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.33](https://github.com/paritytech/polkadot/releases/tag/v0.9.33). 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.** _

# Summary

This release is mostly adding some fixes and enhancements around some FRAME pallets and improving the developer user experience. Some low impact yet note-worthy PRs include:

- [Updating the Polkadot inflation model](https://hackmd.io/d6x3106ITi2KNT1TG7JUsg?both#Update-Polkadot-inflation-to-take-into-account-auctions)
- [Increasing the number of nominators that can be rewarded per validator](https://hackmd.io/d6x3106ITi2KNT1TG7JUsg?both#Increase-max-rewardable-nominators)
- [Dev Mode!](https://hackmd.io/d6x3106ITi2KNT1TG7JUsg?both#Add-Dev-Mode-palletdev_mode)

The Polkadot Release Analysis team has found no PR’s in this release that are considered high impact towards builders on Polkadot.

  

## Runtimes built on release v0.9.33

- **Rococo v9330**
- **Westend v9330**
- **Kusama v9330**
- **Polkadot v9330**

  

* * *

# ⚠ Medium Impact

### Remove sp\_tasks::spawn API and related code + host functions

PR [Remove `sp_tasks::spawn` API and related code + host functions by koute · Pull Request #12639 · paritytech/substrate · GitHub](https://github.com/paritytech/substrate/pull/12639)

This PR is the part of [#Issue 11227](https://github.com/paritytech/substrate/issues/11227).

**Why is this important?**

At the moment, `sp_tasks::spawn` runtime API has many issues and is not safe to use. Neither Polkadot nor Cumulus nor any [Polkadot host](https://wiki.polkadot.network/docs/learn-polkadot-host) implementation is using it.

This PR removes `sp_tasks` library and all its related code completely. The PR has a more detailed explanation.

**How this impacts the Polkadot builders?**

You only need to update `Cargo.lock`, which should happen automatically, once you compile the code.

### Make Multisig Pallet Bounded

PR [Make Multisig Pallet Bounded by shawntabrizi · Pull Request #12457 · paritytech/substrate · GitHub](https://github.com/paritytech/substrate/pull/12457)

_Polkadot Companion PR: [PR #6172](https://github.com/paritytech/polkadot/pull/6172)_  
_Cumulus Companion PR: [PR #1793](https://github.com/paritytech/cumulus/pull/1793)_

This PR is the part of [#Issue 8629](https://github.com/paritytech/substrate/issues/8629).

**Why is this important?**

As a part of this PR, the following changes have been made in `MultiSig` pallet

- `Vec` is turned into a `BoundedVec`
- `without_storage_info` has been removed from `MultiSig` pallet
- Type of `MaxSignatories` config parameter has been changed from `u16` to `u32`

**How this impacts the Polkadot builders?**

If you are using `MultiSig` pallet in your runtime, it is recommended to update the type of `MaxSignatories` from `u16` to `u32`, although nothing will be broken if you don’t.

An example of the `pallet_multisig` pallet runtime configuration:

```rust
impl pallet_multisig::Config for Runtime {
	type RuntimeEvent = RuntimeEvent;
	type RuntimeCall = RuntimeCall;
	type Currency = Balances;
	type DepositBase = DepositBase;
	type DepositFactor = DepositFactor;
	type MaxSignatories = ConstU32<100>; // Update this from u16 to u32
	type WeightInfo = pallet_multisig::weights::SubstrateWeight<Runtime>;
}

```

* * *

### Add `CreateOrigin` to Assets Pallet

PR [https://github.com/paritytech/substrate/pull/12586](https://github.com/paritytech/substrate/pull/12586)

_Cumulus Companion PR: [PR #1808](https://github.com/paritytech/cumulus/pull/1808)_

This PR is the part of [#Issue 6126](https://github.com/paritytech/polkadot/issues/6126).

**Why is this important?**

A new origin `CreateOrigin` has been introduced in `Assets` pallet’s `Config` trait. Only this origin will be allowed to create a new class of fungible assets.

`fn create` has also been altered accordingly to use this origin.

**How this impacts the Polkadot builders?**

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.

**How to use**

```rust
impl pallet_assets::Config for Runtime {
	// Other Config types
	type CreateOrigin = AsEnsureOriginWithArg<EnsureSigned<AccountId>>;
	
}

```

* * *

### Fix fungible unbalanced trait

PR [Fix fungible unbalanced trait by zjb0807 · Pull Request #12569 · paritytech/substrate · GitHub](https://github.com/paritytech/substrate/pull/12569)

As the PR description is very clear and concise, we will share it as it is:

> _The `fungibles::Inspect::balance()` include free and reserved, but `fungibles::Unbalanced::setbalance` didn’t check reserved in `fungibles::Unbalanced::decreasebalance()`, `fungibles::Unbalanced::decreasebalanceatmost()`, `fungibles::Unbalanced::increasebalanceatmost()`, `fungibles::Unbalanced::increasebalance()`._
> 
> _e.g. Alice’s balance is 100(free: 50, reserved: 50), decreasebalance(20), the final balance is 120(free: 80, reserved: 50), but the expected balance should be 80(free: 30, reserved: 50)_

This is solved by substracting the reserved amount of the new amount set in the `fn set_balance` (free = new\_balance - reserved).

* * *

### Fix a few migration issues with 2D weights

PR [Fix a few migration issues with 2D weights by KiChjang · Pull Request #1755 · paritytech/cumulus · GitHub](https://github.com/paritytech/cumulus/pull/1755/files)

This PR introduces 2D Weights as the default weight struct used in both, `dmp-queue` and `xcmp-queue` pallets. The fields using the new weights are:

- `xcmp_max_individual_weight` for `QueueConfigData` struct at `xcmp-queue` module.
- `max_individual` for `ConfigData` struct at `dmp-queue` module.

These two values above define the maximum amount of weight any individual message may consume. Messages above this weight go into the overweight queue and may only be serviced explicitly.

It also introduces a migration that translates `ReservedXcmpWeightOverride` and `ReservedDmpWeightOverride` values into the new Weight multidimensional struct. These two define the weight we reserve at the beginning of the block for processing, respectively, XCMP and DMP messages. This overrides the amount set in the Config trait.

### Make `ValidateUnsigned` available on all chains for `paras` module.

PR [Make ValidateUnsigned available on all chains for paras. by eskimor · Pull Request #6214 · paritytech/polkadot · GitHub](https://github.com/paritytech/polkadot/pull/6214)

**Why is this important?**

There is [paras](https://paritytech.github.io/polkadot/book/runtime/paras.html) module, which tracks the current status of all parachain and parathreads. Every parachain/parathread has to be registered in this module in order to be considered as live.

This pallet has a dispatchable function `include_pvf_check_statement`, which includes a statement for a PVF pre-checking vote. More info on PVF pre-checking can be found [here](https://github.com/paritytech/polkadot/blob/c289aced8c7f124acd60d0764de35cec1047549f/runtime/parachains/src/paras/mod.rs#L74-L106).

Before this change, [`ValidateUnsigned`](https://paritytech.github.io/substrate/master/sp_runtime/traits/trait.ValidateUnsigned.html) trait was not enabled on all chains to validate these unsigned transactions.

**How this impacts the Polkadot builders?**

As a part of this PR, [`ValidateUnsigned`](https://paritytech.github.io/substrate/master/sp_runtime/traits/trait.ValidateUnsigned.html) trait has been enabled for [paras module](https://paritytech.github.io/polkadot/book/runtime/paras.html) on all chains (Polkadot, Kusama, Rococo, and Westend) to make PVF pre-checking work.

If you are not familiar with what the Parachain Validation Function (PVF) is, there was a nice post about it recently. You can find it [here](https://substrate.stackexchange.com/questions/5940/what-is-the-parachain-validation-function-pvf).

### fix: `construct_runtime` multiple features

PR [fix: construct\_runtime multiple features by mrshiposha · Pull Request #12594 · paritytech/substrate · GitHub](https://github.com/paritytech/substrate/pull/12594)

[PR #11818](https://github.com/paritytech/substrate/pull/11818) introduced support for `#[cfg(feature = <...>)]` attribute into the `construct_runtime!` macro. This enabled the ability to feature-gate in the runtime.

However, compilation issues arose when trying to add more than one feature into the `construct_runtime!` macro. Users were prompted with _multiple definition_ errors when compiling. This PR fixes this and allows users to bring more than one feature into this macro without any problems.

**How to use**

```toml
# definition of features in Cargo file
[features]

# -- snip --
frame-feature-testing = []
frame-feature-testing-2 = []

```

```rust
// definition of feature-gated pallets in runtime file

#[cfg(feature = "frame-feature-testing")]
impl pallet1::Config for Runtime {
	type RuntimeOrigin = RuntimeOrigin;
}

#[cfg(feature = "frame-feature-testing-2")]
impl pallet2::Config for Runtime {
	type RuntimeOrigin = RuntimeOrigin;
}

// -- snip --
frame_support::construct_runtime!(
	pub enum Runtime where
		Block = Block,
		NodeBlock = Block,
		UncheckedExtrinsic = UncheckedExtrinsic
	{
        // -- snip --
            #[cfg(feature = "frame-feature-testing")]
            Example1: pallet1,
            #[cfg(feature = "frame-feature-testing-2")]
            Example2: pallet2,
        // -- snip --
        }

```

To enable the example features defined above, compile with the `--features` flag:

```rust
--features=frame-feature-testing,frame-feature-testing-2

```

and both pallets will be present in the resulting runtime!

# ℹ Low Impact

### Add Dev Mode (#[pallet(dev\_mode)])

PR [https://github.com/paritytech/substrate/pull/12536](https://github.com/paritytech/substrate/pull/12536)

**Why is this important?**

This PR allows developers to implement pallets in [Dev Mode](https://paritytech.github.io/substrate/master/frame_support/attr.pallet.html#dev-mode-palletdev_mode) without worrying about a number of constraints (e.g. weights) and it provides defaults for a number of things, and disables accidental production compilation of the pallet.

**How this impacts the Polkadot builders?**

If a pallet is marked with `#[pallet(dev_mode)]`, it will set up default weight as `0` if not specified, and will automatically mark all storage items with `#[pallet::unbounded]`, meaning you do not need to implement `MaxEncodedLen`.

**How to use**

Developers can enable `dev_mode` by marking the pallet with:

```rust
#[frame_support::pallet(dev_mode)]
pub mod pallet {

// ---- Your pallet codebase ----

}

```

For more details, please see [issue #8965](https://github.com/paritytech/substrate/issues/8965)

### pallet-sudo: add `CheckOnlySudoAccount` signed extension

PR [https://github.com/paritytech/substrate/pull/12496](https://github.com/paritytech/substrate/pull/12496)

This PR adds a signed extension: `CheckOnlySudoAccount` which prevents any transaction from entering the pool, unless they are signed by the sudo account.

**How to use**

You can add this in the runtime:

```rust
/// The SignedExtension to the basic transaction logic.
pub type SignedExtra = (
    // --- Other Checks ----
    pallet_sudo::CheckOnlySudoAccount<Runtime>
);

```

### Treat near-zero intercept values as zero when calculating weights

PR [Treat near-zero intercept values as zero when calculating weights by koute · Pull Request #12573 · paritytech/substrate · GitHub](https://github.com/paritytech/substrate/pull/12573)

**How this impacts the Polkadot builders?**

Currently when we execute benchmarking to calculate weights, there could be a possiblity of generating a slightly negative, near-zero intercept value when running the linear regression. As part of this PR, these values will be treated as zero.

An example of this scenario could be found in this PR.

```rust
#[test]
	fn intercept_of_a_little_under_zero_is_rounded_up_to_zero() {
		// Analytically this should result in an intercept of 0, but
		// due to numerical imprecision this will generate an intercept
		// equal to roughly -0.0000000000000004440892098500626
		let data = vec![
			benchmark_result(vec![(BenchmarkParameter::n, 1)], 2, 0, 0, 0),
			benchmark_result(vec![(BenchmarkParameter::n, 2)], 4, 0, 0, 0),
			benchmark_result(vec![(BenchmarkParameter::n, 3)], 6, 0, 0, 0),
		];

		let extrinsic_time =
			Analysis::min_squares_iqr(&data, BenchmarkSelector::ExtrinsicTime).unwrap();
		assert_eq!(extrinsic_time.base, 0);
		assert_eq!(extrinsic_time.slopes, vec![2000]);
	}

```

Related discussion can be found here [#12482 (comment)](https://github.com/paritytech/substrate/pull/12482#discussion_r1002097077).

### Defensively calculates the minimum and maximum of two values

PR [https://github.com/paritytech/substrate/pull/12554](https://github.com/paritytech/substrate/pull/12554)

**Why is this important?**

The default Rust `min/max` function compares and returns minimum and maximum of two numbers whether it is `self` or `others`.

For example:

```rust
assert_eq!(10, 10_u32.max(9_u32)); // This and..
assert_eq!(10, 9_u32.max(10_u32)); // ..this are the same

// Similarly

assert_eq!(9, 9_u32.min(10_u32)); // This and..
assert_eq!(9, 10_u32.min(9_u32)); // ..this are the same

```

In some cases, we want these operations to perform defensively. As a part of this PR, two traits `DefensiveMin` and `DefensiveMax` (with functions `defensive_min`, `defensive_strict_min`, `defensive_max`, `defensive_strict_max`) are introduced to execute min/max operations defensively.

**How this impacts the Polkadot builders?**

After using `DefensiveMin` and `DefensiveMax`, we can check whether `self` is smaller/larger (strictly) than `others`.

**How to use**

```rust
assert_eq!(10, 10_u32.defensive_max(9_u32)); // This will work
assert_eq!(10, 9_u32.defensive_max(10_u32)); // This will panic

assert_eq!(9, 9_u32.defensive_min(10_u32)); // This will work
assert_eq!(9, 10_u32.defensive_min(9_u32)); // This will panic

```

For more details, please click here [Issue #12550](https://github.com/paritytech/substrate/issues/12550)

### Defensively truncate an input if the `TryFrom` conversion fails.

PR [Add `DefensiveTruncateFrom` by ggwpez · Pull Request #12515 · paritytech/substrate · GitHub](https://github.com/paritytech/substrate/pull/12515)

**Why is this important?**

As part of this PR, a trait `DefensiveTruncateFrom` with function `defensive_truncate_from` has been introduced, which first tries non-truncating conversion using `TryFrom` and falls back to truncating if that fails.

**How to use**

```rust
let unbound = vec![1u32, 2, 3, 4];
let bound = BoundedVec::<u32, ConstU32<4>>::defensive_truncate_from(unbound.clone());
assert_eq!(bound, unbound);

```

### Check if approval voting db is empty on startup

PR [Check if approval voting db is empty on startup by sandreim · Pull Request #6219 · paritytech/polkadot · GitHub](https://github.com/paritytech/polkadot/pull/6219)

**Why is this important?**

Currently, it is very challenging to debug parachain consensus related finality issues at startup.

A parachains DB sanity check has been added at node startup. This will help to debug whether the parachains DB is empty at startup or not. If yes, this check will emit a proper `info!` log.

For more details, please click here [Issue #6177](https://github.com/paritytech/polkadot/issues/6177)

### use associated iterator types for `InspectEnumerable`

PR [https://github.com/paritytech/substrate/pull/12389](https://github.com/paritytech/substrate/pull/12389)

**Why is this important?**

There is an interface `InspectEnumerable` for enumerating items over a collection or many collections of NFTs. At the moment, it is forcing to use `Box<dyn Iterator>` for the method return types.  
This PR changes the return types of the `InspectEnumerable` trait’s methods to an associated iterator type. While implementing this trait, if the user doesn’t want to name the type, he/she can always define boxed iterators.

For more details, please click here [Issue #12231](https://github.com/paritytech/substrate/issues/12231)

### New Weights for All Pallets

PR [https://github.com/paritytech/substrate/pull/12325](https://github.com/paritytech/substrate/pull/12325)

Based on the fix added in the previous release: [Improve base weights consistency and make sure they’re never zero](https://github.com/paritytech/substrate/pull/11806), all the weights were recalculated for all the FRAME pallets.

It is recommended that after this fix arrives on the chain, all weights are recalculated.

### Add `map` and `try_map` methods to `BoundedBTreeMap`

PR [Add map and try\_map methods to BoundedBTreeMap by benluelo · Pull Request #12581 · paritytech/substrate · GitHub](https://github.com/paritytech/substrate/pull/12581)

This PR implements `map` and `try_map` for `BoundedBTreeMap` struct. These two new functions allow applying a certain function _f_ to each value of the map. The difference between these two is that `try_map` allows short circuiting in case an error is found.  
None of these two new operations affect the lenght of the map.

```rust
let b1: BoundedBTreeMap<u8, u8, ConstU32<7>> = [1, 2, 3, 4].into_iter().map(|k| (k, k)).try_collect().unwrap();
let b2: BoundedBTreeMap<u8, u16, ConstU32<7>> = [1, 2, 3, 4].into_iter().map(|k| (k, (k as u16) * 100)).try_collect().unwrap();

assert_eq!(Ok(b2), b1.try_map(|(_, v)| (v as u16).checked_mul(100_u16).ok_or("overflow")));

```

### Update Polkadot inflation to take into account auctions

PR: [https://github.com/paritytech/polkadot/pull/5872](https://github.com/paritytech/polkadot/pull/5872)

Moving away from a more static definition of inflation for Polkadot by taking into account the number of slots that have been auctioned and that have active parachains:

```rust
let auctioned_slots = Paras::parachains()
			.into_iter()
			// all active para-ids that do not belong to a system or common good chain is the number
			// of parachains that we should take into account for inflation.
			.filter(|i| *i >= LOWEST_PUBLIC_ID)
			.count() as u64;
// --snip

// 30% reserved for up to 60 slots.
let auction_proportion = Perquintill::from_rational(auctioned_slots.min(60), 200u64);

```

And it does affect the `ideal_stake` in the following way:

```rust
// Therefore the ideal amount at stake (as a percentage of total issuance) is 75% less the
// amount that we expect to be taken up with auctions.
let ideal_stake = Perquintill::from_percent(75).saturating_sub(auction_proportion);

```

### Increase max rewardable nominators

PR: [Increase max rewardable nominators by kianenigma · Pull Request #6230 · paritytech/polkadot · GitHub](https://github.com/paritytech/polkadot/pull/6230)

Following the rest of improvements staking is receiving across the board, this PR doubles the number of nominators rewarded per validator:

```diff
- pub const MaxNominatorRewardedPerValidator: u32 = 256;
+ pub const MaxNominatorRewardedPerValidator: u32 = 512;

```

This number should help to reduce the number of oversubscribed validators.

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

[ Help us improve the release analysis by filling out this 6 question survey.  
 ](https://forms.gle/uPR7BvwPDoH89G3h8)

---

<div class="post-metadata">

**Author:** ![hectorb](https://dub1.discourse-cdn.com/flex005/user_avatar/forum.polkadot.network/hectorb/32/729_2.png) [@hectorb](https://forum.polkadot.network/u/hectorb)\
**Post date:** [December 12, 2022, 9:59am UTC](https://forum.polkadot.network/t/polkadot-release-analysis-v0-9-33/1287/2 "2022-12-12T09:59:41Z")

</div>

**⚠ Important update about Polkadot and Kusama Runtime upgrades:**

As it is mentioned on the release notes for [v0.9.34 Release](https://github.com/paritytech/polkadot/releases/tag/v0.9.34):

Polkadot runtimes v9320 and v9330 are replaced by v9340.  
Kusama runtime v9330 is replaced by v9340.

---

<div class="post-metadata">

**Author:** ![hectorb](https://dub1.discourse-cdn.com/flex005/user_avatar/forum.polkadot.network/hectorb/32/729_2.png) [@hectorb](https://forum.polkadot.network/u/hectorb)\
**Post date:** [December 15, 2022, 5:35pm UTC](https://forum.polkadot.network/t/polkadot-release-analysis-v0-9-33/1287/3 "2022-12-15T17:35:23Z")

</div>

In case you missed it, this is the report for the previous release (0.9.31 + 0.9.32):

> [@Polkadot Release Analysis](https://forum.polkadot.network/t/polkadot-release-analysis/1026):
>
> Over the past few weeks, we have been analyzing and summarizing the last few Polkadot releases. The goal for this exercise is to gain a better understanding of new things coming in the release(s) and their impact on chain builders. The outcome is an analysis report for each Polkadot release. Each analysis report consists of high, medium, and low impact changes from a builders’ perspective. It also contains relevant code snippets and the motivation around these new changes/updates. We are now re…
