# Polkadot Release Analysis v0.9.40
: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.40](https://github.com/paritytech/polkadot/releases/tag/v0.9.40). 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.***
***Also there is a section related to all note worthy changes related to tooling integration.***
[Help us improve the release analysis by filling out this 6 question survey.](https://forms.gle/gKtXbmZ97a8myQGp7)
# Summary
In this release we can find a variety of very interesting changes, barriers within XCM configuration will now leverage a new Matcher API, pallet-nfts is receiving a new permission model along with new features for assets and nomination pools among other changes.
## Runtimes built on release v0.9.40
- **Rococo v9400**
- **Westend v9400**
- **Kusama v9400**
- **Polkadot v9400**
# :hammer_and_wrench: Tooling Section
---
- [TxWrapper Core](https://github.com/paritytech/txwrapper-core) - [v5.0.1](https://github.com/paritytech/txwrapper-core/releases/tag/v5.0.1)
- [Substrate Sidecar API](https://github.com/paritytech/substrate-api-sidecar) - [v14.5.1](https://github.com/paritytech/substrate-api-sidecar/releases/tag/v14.5.1)
- [Polkadot JS API](https://github.com/polkadot-js/api) - [v10.1.4](https://github.com/polkadot-js/api/releases/tag/v10.1.4)
---
# ❗️ High Impact
### Introduce XCM matcher for writing barriers
PR: https://github.com/paritytech/polkadot/pull/6756
Related PR: https://github.com/paritytech/cumulus/pull/2290
Related Issues:
https://github.com/paritytech/polkadot/issues/4276
**Why is this change interesting for builders?**
With XCM, Polkadot enables secure cross-chain exchange of any type of data. However a cross-chain message needs to be whitelisted in the receiver end to be accepted. The whitelisting happens in a place called the Barrier. Barriers are a set of filters to statically accept or reject XCM messages.
This PR introduces a new API `fn matchers()` for `&mut [Instructions<Call>]` that is similar to iterators: it can advance the current instruction to the next while ensuring the current instruction matches/fulfills a certain condition; it can assert the remaining number of instructions left to process; and it can also skip instructions while a condition is being evaluated as true.
The main purpose of creating a Matcher API instead of using iterators is that of purpose and clarity -- it is much easier to maintain, audit and write matchers over iterators, as they are intended to be declarative in nature.
Here is an example for how the matcher can be implemented on Statemint/e where it should filter reserve transfer from the relay chain:
```rust
// See issue <https://github.com/paritytech/polkadot/issues/5233>
pub struct DenyReserveTransferToRelayChain;
impl ShouldExecute for DenyReserveTransferToRelayChain {
fn should_execute<RuntimeCall>(
origin: &MultiLocation,
message: &mut [Instruction<RuntimeCall>],
_max_weight: Weight,
_weight_credit: &mut Weight,
) -> Result<(), ()> {
message.matcher().match_next_inst_while(
|_| true,
|inst| match inst {
InitiateReserveWithdraw {
reserve: MultiLocation { parents: 1, interior: Here },
..
} |
DepositReserveAsset {
dest: MultiLocation { parents: 1, interior: Here }, ..
} |
TransferReserveAsset {
dest: MultiLocation { parents: 1, interior: Here }, ..
} => {
Err(()) // Deny
},
// An unexpected reserve transfer has arrived from the Relay Chain. Generally,
// `IsReserve` should not allow this, but we just log it here.
ReserveAssetDeposited { .. }
if matches!(origin, MultiLocation { parents: 1, interior: Here }) =>
{
log::warn!(
target: "xcm::barrier",
"Unexpected ReserveAssetDeposited from the Relay Chain",
);
Ok(ControlFlow::Continue(()))
},
_ => Ok(ControlFlow::Continue(())),
},
)?;
// Permit everything else
Ok(())
}
}
```
---
# ⚠️ Medium Impact
### [NFTs] Rework permissions model
PR: https://github.com/paritytech/substrate/pull/13482
**Why is this important?**
This PR introduces changes to the permissions model in the pallet-nfts, a collection of non-fungible tokens. The Admin account will no longer be able to transfer or burn items it doesn't own, and to destroy the collection, there should be zero items left. Some actions were moved from one role to another to simplify accounts management, particularly for complex collections where each role represents a separate service with its own responsibilities.
The Owner can destroy the collection, redeposit, set the team, set the collection max supply, and lock the collection. Admin can set attributes and metadata, lock item properties, and perform actions that were moved from the Owner role. Freezer can lock and unlock item transfer. Issuer can mint tokens, force mint with custom item configuration, update mint settings, and perform actions that were moved from the Owner role.
**Why is this change interesting for builders?**
The changes introduced in this PR are interesting for builders because they make it easier to create complex non-fungible token collections with multiple roles and responsibilities. The improved security and account management features provide builders with more flexibility and control over their collections.responsibilities.
---
### Yieldable queues for pallet `MessageQueue`
PR: https://github.com/paritytech/substrate/pull/13424
**Why is this important?**
Introduces a new variant to [`ProcessMessageError` enum](https://github.com/paritytech/substrate/blob/76fed9b9082daade5392663f25ed8968f8e8c11c/frame/support/src/traits/messages.rs#L27-L48), with it a queue hints the message processor to cease servicing this queue and proceed to the next one.
A new implementation for `ServiceQueues`, `NoopServiceQueues` that will service queues by doing nothing. We can see the reason for this in the PR description itself.
> ServiceQueues cannot be implemented for () due to its associated type.
Lastly, [`fn process_message`](https://github.com/paritytech/substrate/blob/76fed9b9082daade5392663f25ed8968f8e8c11c/frame/support/src/traits/messages.rs#L50-L63) in `pub trait ProcessMessage` sees its signature changed, using now a `&mut WeightMeter instead` of `Weight`, and only returning whether the message was processed.
```diff
fn process_message(
message: &[u8],
origin: Self::Origin,
- weight_limit: Weight,
+ meter: &mut WeightMeter,
- ) -> Result<(bool, Weight), ProcessMessageError>;
+ ) -> Result<bool, ProcessMessageError>;
```
**Why is this change interesting for builders?**
⚠️ The changes made to `ProcessMessageError` and `ProcessMessage` are breaking changes, we have not being able to identify any usage of this pallet downstream and that is why these changes come with no migrations, but if you do, please migrate consequently.
---
# ℹ️ Low Impact
### Assets pallet: Giving the asset owner the ability to set minimum balance
PR: https://github.com/paritytech/substrate/pull/13486
**Why is this change interesting for builders?**
At the moment, there is no way to set minimum balance of an asset by asset owner. However there is a workaround by setting through `force_asset_status` extrinsic but this requires `ForceOrigin`.
As a part of this PR, [Asset pallet](https://paritytech.github.io/substrate/master/pallet_assets/index.html) has introduced a new extrinsic `set_min_balance` to set minimum balance by asset owner. This extrinsic still has some limitations. This extrinsic will only be allowed if:
- If there is no account holding the asset
- If new `min` balance is less than the old one
- If the asset is not marked as sufficient
**Does this change have a related companion PR?**
Cumulus companion PR: https://github.com/paritytech/cumulus/pull/2253
Related Issues:
https://github.com/paritytech/substrate/issues/13402
Related PR:
https://github.com/paritytech/substrate/pull/13510
---
### Pub enum runtime to pub struct runtime
PR: https://github.com/paritytech/substrate/pull/13250
**Why is this change interesting for builders?**
Even though `construct_runtime!` macro [accepts both `struct`s and `enum`s](https://github.com/paritytech/substrate/blob/f1be359b7c1099f3066552b03b02bcc1816008cd/frame/support/procedural/src/construct_runtime/parse.rs#L77-L82) at the moment, this PR substitutes all `pub enum Runtime` declarations with `pub struct Runtime` in the sake of having a clearer code base.
This is **not** a breaking change, but please understand this change and apply it as a good practice in your runtime.
---
### Nomination Pool Commission
PR: https://github.com/paritytech/substrate/pull/13128
**Why is this important?**
With these changes nomination pools receive new functionality, commissions.
A pool can optionally have a commission configuration, via the `root` role, set with `set_commission` and claimed with `claim_commission`. A payee account must be supplied with the desired commission percentage. Beyond the commission itself, a pool can have a maximum commission and a change rate.
Importantly, both max commission `set_commission_max` and change rate
`set_commission_change_rate` can not be removed once set, and can only be set to more restrictive values (i.e. a lower max commission or a slower change rate) in subsequent updates.
This is how the new elements look like:
```rust
pub struct Commission<T: Config> {
/// Optional commission rate of the pool along with the account commission is paid to.
pub current: Option<(Perbill, T::AccountId)>,
/// Optional maximum commission that can be set by the pool `root`. Once set, this value can
/// only be updated to a decreased value.
pub max: Option<Perbill>,
/// Optional configuration around how often commission can be updated, and when the last
/// commission update took place.
pub change_rate: Option<CommissionChangeRate<T::BlockNumber>>,
/// The block from where throttling should be checked from. This value will be updated on all
/// commission updates and when setting an initial `change_rate`.
pub throttle_from: Option<T::BlockNumber>,
}
pub struct CommissionChangeRate<BlockNumber> {
/// The maximum amount the commission can be updated by per `min_delay` period.
pub max_increase: Perbill,
/// How often an update can take place.
pub min_delay: BlockNumber,
}
/// The maximum commission that can be charged by a pool. Used on commission payouts to bound
/// pool commissions that are > `GlobalMaxCommission`, necessary if a future
/// `GlobalMaxCommission` is lower than some current pool commissions.
#[pallet::storage]
pub type GlobalMaxCommission<T: Config> = StorageValue<_, Perbill, OptionQuery>;
```
The following extrinsics are available for the `root` role of a nomination pool to dispatch:
- [`set_commission`](https://github.com/paritytech/substrate/blob/76fed9b9082daade5392663f25ed8968f8e8c11c/frame/nomination-pools/src/lib.rs#L2537)
- [`set_commission_max`](https://github.com/paritytech/substrate/blob/76fed9b9082daade5392663f25ed8968f8e8c11c/frame/nomination-pools/src/lib.rs#L2573)
- [`set_commission_change_rate`](https://github.com/paritytech/substrate/blob/76fed9b9082daade5392663f25ed8968f8e8c11c/frame/nomination-pools/src/lib.rs#L2595)
- [`claim_commission`](https://github.com/paritytech/substrate/blob/76fed9b9082daade5392663f25ed8968f8e8c11c/frame/nomination-pools/src/lib.rs#L2621)
Participate in the discussion on which values should `GlobalMaxCommission` have in the [related Polkadot forum post](https://forum.polkadot.network/t/discussion-on-global-maximum-commission-for-nomination-pools-on-polkadot/2325/1).
---
### Salary pallet (#13378)
PR: https://github.com/paritytech/substrate/pull/13378
**Why is this change interesting for builders?**
A new pallet has been released that allows for periodic payments to members of a ranked collective according to rank.
There are some interesting features such as a "budget" (the total budget per cycle) and setting up a "paymaster" (means by which we can make payments to the account). You can see an example configuration [here](https://github.com/paritytech/substrate/blob/76fed9b9082daade5392663f25ed8968f8e8c11c/bin/node/runtime/src/lib.rs#L1555-L1558) where the budget and paymaster are configured as the following:
```rust
parameter_types! {
pub const Budget: Balance = 10_000 * DOLLARS;
pub TreasuryAccount: AccountId = Treasury::account_id();
}
impl pallet_salary::Config for Runtime {
type WeightInfo = ();
type RuntimeEvent = RuntimeEvent;
type Paymaster = pallet_salary::PayFromAccount<Balances, TreasuryAccount>;
type Members = RankedCollective;
type Salary = SalaryForRank;
type RegistrationPeriod = ConstU32<200>;
type PayoutPeriod = ConstU32<200>;
type Budget = Budget;
}
```
You can read the code for the salary pallet [here](https://github.com/paritytech/substrate/blob/polkadot-v0.9.40/frame/salary/src/lib.rs).
---
### Return account's asset balances
PR: https://github.com/paritytech/substrate/pull/13352
**Why is this change interesting for builders?**
As a part of this PR, [Asset pallet](https://paritytech.github.io/substrate/master/pallet_assets/index.html) has introduced a new RPC end point `account_balances` which will return all asset ids with their corresponding balance for an associated account.
**Does this change have a related companion PR?**
Cumulus companion PR: https://github.com/paritytech/cumulus/pull/2180
---
### Metadata V15: Expose pallet documentation
PR: https://github.com/paritytech/substrate/pull/13452
**Why is this important?**
This patch adds the functionality to include pallet documentation in the runtime metadata. Pallet documentation can be defined in different ways such as a doc string, including an external file or including the documentation using the pallet_doc attribute. This new feature allows developers to provide a more detailed description of the pallets, making it easier for other developers to understand and use the pallets. The documentation is included in the runtime metadata and is expanded on the pallet module. Unlike the doc attribute, which is inserted at the beginning of the module, the documentation provided to the pallet_doc attribute is not. This new functionality has been added to the final metadata V15 PR and has been tested in unit tests, UI tests, and subxt. This is important for Polkadot builders because it will make it easier for them to understand the functionality of different pallets, reducing development time and increasing the interoperability of different components.
**Code Snippets**
```rust
#[pallet::pallet]
/// Documentation for pallet 1
#[doc = "Documentation for pallet 2"]
#[doc = include_str!("../README.md")]
#[pallet_doc("../doc1.md")]
#[pallet_doc("../doc2.md")]
pub struct Pallet<T>(_);
```