# Polkadot Release Analysis v0.9.43
: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.43](https://github.com/paritytech/polkadot/releases/tag/v0.9.43). 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/mdneyTfvYDtXftaX9)
# Summary
In this release we are covering Polkadot release `v0.9.43`. Notable changes include:
- breaking changes made to the `try-runtime` feature
- the removal of CLI options and old macros
- changes related to asset accounts
- first steps towards deprecating controller accounts
- new pallets as well as several other features
</br>
## Runtimes built on release v0.9.43
- **Rococo v9430**
- **Westend v9430**
- **Kusama v9430**
- **Polkadot v9430**
<br/>
# :hammer_and_wrench: Tooling Section
- TxWrapperCore - [6.0.1](https://github.com/paritytech/txwrapper-core/releases/tag/v6.0.1)
- SubstrateApiSidecar - [17.1.0](https://github.com/paritytech/substrate-api-sidecar/releases/tag/v17.1.0)
- PolkadotJsApi - [10.9.1](https://github.com/polkadot-js/api/releases/tag/v10.9.1)
First beta release of [Asset Transfer API](https://github.com/paritytech/asset-transfer-api/releases/tag/v0.1.0-beta.0) is out. Aiming to provide tools for easily transferring assets across common good parachains.
---
<br/>
# ❗️ High Impact
### BREAKING - Try-runtime: Use proper error types
PR: https://github.com/paritytech/substrate/pull/13993
**Why is this change interesting for builders?**
At the moment, all runtime upgrade hooks, which are enabled with `try-runtime` feature uses `&'static str` as error type. These hooks are helpful to inspect and compare the runtime state before and after a runtime upgrade for testing purposes but the current error type is not very helpful to handle the errors.
As a part of this PR, a new error type `TryRuntimeError` has been introduced, which is an alias for `DispatchError`.
**How does this impact the Polkadot builders?**
After this PR, `&'static str` will not be supported as error return type for these hooks. If you are using runtime upgrade hooks, you MUST update the return type, otherwise, this would cause a compilation failure.
**How to use?**
1) Please refer below example to update error types
```diff
- fn pre_upgrade() -> Result<Vec<u8>, &'static str> {
+ fn pre_upgrade() -> Result<Vec<u8>, sp_runtime::TryRuntimeError> {
- fn post_upgrade(_state: Vec<u8>) -> Result<(), &'static str> {
+ fn post_upgrade(_state: Vec<u8>) -> Result<(), sp_runtime::TryRuntimeError> {
```
2) Also from now onwards, you should not use `assert!`, `assert_eq!` or similar because code in these macros may panic. instead in case of an error we should return the `TryRuntimeError` type.
This [Cumulus companion PR](https://github.com/paritytech/cumulus/pull/2615/files#diff-66b2e0c4220d9c11c14f91de7153b86c0fe8796e50792173b646dd5b55d85f1e) is a perfect example of how to incorporate this new change.
Polkadot companion PR: [#7146](https://github.com/paritytech/polkadot/pull/7146)
Cumulus companion PR: [#2615](https://github.com/paritytech/cumulus/pull/2615)
Related Issue: [#13736](https://github.com/paritytech/substrate/issues/13736)
---
# ⚠️ Medium Impact
### Staking::{bond, set_controller} to set controllers to stash only.
PR: https://github.com/paritytech/substrate/pull/14039
**Why is this important?**
Controller accounts are in the process of being deprecated in favor of proxy accounts.
This PR makes it so it is no longer possible to set a unique address for a stash's controller. `set_controller` call logic has been changed to (re)-set the controller of a stash to the stash itself. This call previously accepted a `controller` argument to set the controller to an account other than the stash itself. This functionality has now been removed, now only setting the controller to the stash, if it is not already.
The `bond` call no longer takes a controller account as an argument and uses the stash account in its place.
**How does this impacts the Polkadot builders?**
If you are building any staking UIs, it is important for your team to update your UIs accordingly.
**Why is this change interesting for builders?**
This change turns off the ability to create new unique stash & controller pairs, aiding in the controller account deprecation and migration to proxy accounts.
**How to use?**
* **`set_controller(controller)`** has become **`set_controller()`**. This call simply sets the controller account to the caller’s stash account, if it is not already.
* **`bond(controller, value, payee)`** has become **`bond(value, payee)`**. This call now sets the caller as the controller account (same as the stash).
### Allow Creation of Asset Accounts That Don't Exist Yet and Add Blocked Status
PR: https://github.com/paritytech/substrate/pull/13843
**Why is this important?**
This PR does the following:
- adds dispatchables [`touch_other`](https://github.com/paritytech/substrate/blob/075ba84345c58611beaf8b3effcd321db5a92f6b/frame/assets/src/lib.rs#L1557-L1569) and [`refund_other`](https://github.com/paritytech/substrate/blob/075ba84345c58611beaf8b3effcd321db5a92f6b/frame/assets/src/lib.rs#L1580-L1592) to the assets pallet which allows the asset class's `Freezer` or `Admin` to create an account with zero balance in the asset class by placing a deposit; and to remove/refund.
- adds a new [`AccountTouch`](https://github.com/paritytech/substrate/blob/075ba84345c58611beaf8b3effcd321db5a92f6b/frame/support/src/traits/misc.rs#L1157-L1168) trait that allows other pallets to touch an account into existence for an asset class
- adds a new account status of `Blocked` (invoked by the asset class's `Freezer` via the new dispatchable [`block`](https://github.com/paritytech/substrate/blob/075ba84345c58611beaf8b3effcd321db5a92f6b/frame/assets/src/lib.rs#L1603-L1614)). Unlike `Frozen`, which prevents withdrawals from an account, `Blocked` prevents both withdrawals from and deposits into the blocked account.
**How to use?**
The new [`AccountTouch`](https://paritytech.github.io/substrate/master/frame_support/traits/trait.AccountTouch.html) trait that is available to pallets:
```rust
/// Trait for creating an asset account with a deposit taken from a designated depositor specified
/// by the client.
pub trait AccountTouch<AssetId, AccountId> {
/// The type for currency units of the deposit.
type Balance;
/// The deposit amount of a native currency required for creating an asset account.
fn deposit_required() -> Self::Balance;
/// Create an account for `who` of the `asset` with a deposit taken from the `depositor`.
fn touch(asset: AssetId, who: AccountId, depositor: AccountId) -> DispatchResult;
}
```
An example of the `AccountTouch` trait implementation can be found in [pallet assets](https://github.com/paritytech/substrate/blob/075ba84345c58611beaf8b3effcd321db5a92f6b/frame/assets/src/lib.rs#L1641-L1654):
```rust
/// Implements [AccountTouch] trait.
/// Note that a depositor can be any account, without any specific privilege.
/// This implementation is supposed to be used only for creation of system accounts.
impl<T: Config<I>, I: 'static> AccountTouch<T::AssetId, T::AccountId> for Pallet<T, I> {
type Balance = DepositBalanceOf<T, I>;
fn deposit_required() -> Self::Balance {
T::AssetAccountDeposit::get()
}
fn touch(asset: T::AssetId, who: T::AccountId, depositor: T::AccountId) -> DispatchResult {
Self::do_touch(asset, who, depositor, false)
}
}
```
And an example usage of it can be found in [pallet asset-conversion](https://github.com/paritytech/substrate/blob/fe65adb22c29692b58f9add1d8d876e7429d499b/frame/asset-conversion/src/lib.rs#LL156C1-L160C51):
```rust
/// Registry for the assets.
type Assets: Inspect<Self::AccountId, AssetId = Self::AssetId, Balance = Self::AssetBalance>
+ Mutate<Self::AccountId>
+ AccountTouch<Self::AssetId, Self::AccountId>
+ ContainsPair<Self::AssetId, Self::AccountId>;
```
Create an asset account for `who`.
```rust
pub fn touch_other(origin: OriginFor<T>, id: T::AssetIdParameter, who: AccountIdLookupOf<T>,)
```
Cumulus Companion PR: [#2437](https://github.com/paritytech/cumulus/pull/2437)
---
### rpc server: break legacy CLI options and remove "backward compatible HTTP server"
PR: https://github.com/paritytech/substrate/pull/13384
**Why is this important?**
After [#12663](https://github.com/paritytech/substrate/pull/12663) was merged the RPC server supports WS/HTTP on the same socket and the HTTP server was kept for backwards compatibility.
This PR removes the HTTP server on port `9933`, makes the default RPC port `9944` and removes / renames all websocket / HTTP specific options, as follows:
- `--rpc-max-payload` replaced by `--rpc-max-request-size` and `--rpc-max-response-size`
- `--ws-external` replaced by `--rpc-external`
- `--unsafe-ws-extneral` replaced by `--unsafe-rpc-external`
- `--ws-port` replaced by `--rpc-port`
- `--ws-max-connections` replaced by `--rpc-max-connections`
- `--rpc-http` replaced by `--rpc-addr`
- `--rpc-ws` replaced by `--rpc-addr`
- removed `--ws-max-out-buffer-capacity`
- removed `--ipc-path`
---
### XCM remote lock consumers
PR: https://github.com/paritytech/polkadot/pull/6947
**Why is this important?**
This PR introduces into `pallet-xcm` `Config` trait the following types
```rust
/// The maximum number of consumers a single remote lock may have.
type MaxRemoteLockConsumers: Get<u32>;
/// The ID type for local consumers of remote locks.
type RemoteLockConsumerIdentifier: Parameter + Member + MaxEncodedLen + Ord + Copy;
```
This allows for partial locking and unlocking of the remote lock as well as extending the lock for a specific user.
`RemoteLockedFungibleRecord` has been redefined:
```diff
- pub struct RemoteLockedFungibleRecord {}
+ pub struct RemoteLockedFungibleRecord<ConsumerIdentifier, MaxConsumers: Get<u32>> {}
```
The field `pub users` whitin the previos struct is also substituted:
```diff
- pub users: u32,
+ /// Local consumers of the remote lock with a consumer identifier and the amount
+ /// of fungible asset every consumer holds.
+ /// Every consumer can hold up to total amount of the remote lock.
+ pub consumers: BoundedVec<(ConsumerIdentifier, u128), MaxConsumers>,
```
**How does this impacts the Polkadot builders?**
The changes concerning `RemoteLockedFungibleRecord` require that all users of remote locks write migrations of their data to this new storage version.
Cumulus companion PR: [#2463](https://github.com/paritytech/cumulus/pull/2463)
---
# ℹ️ Low Impact
### NFTs fractionalization
PR: https://github.com/paritytech/substrate/pull/12565
**Why is this change interesting for builders?**
As a part of this PR, a new pallet, **NFT Fractionalization Pallet** has been introduced. Using this pallet, one can leverage partial ownership, transfers, and sales, of illiquid assets. This pallet:
- Takes the ownership of an NFT from the [pallet-nfts](https://paritytech.github.io/substrate/master/pallet_nfts/).
- It allows uers to lock the NFT, they own and create and mint a new fungible asset in the [pallet-assets](https://paritytech.github.io/substrate/master/pallet_assets/index.html)
- It allows user to burn the total issuance of the fungible asset and to unlock the NFT into their account.
Cumulus companion PR: [#2600](https://github.com/paritytech/cumulus/pull/2600)
### Assets: impl ContainsPair for asset and account IDs
PR: https://github.com/paritytech/substrate/pull/14119
**Why is this change interesting for builders?**
This PR introduced the implementation of [ContainsPair](https://paritytech.github.io/substrate/master/frame_support/traits/trait.ContainsPair.html) trait in [Assets Pallet](https://paritytech.github.io/substrate/master/pallet_assets/index.html). This will check whether a specific account exists for a given asset ID and account address.
**How to use?**
If you are using Assets pallet in your pallet you can have something like below:
```rust
type Assets: Inspect<Self::AccountId, AssetId = Self::AssetId, Balance = Self::AssetBalance>
+ Mutate<Self::AccountId>
+ ContainsPair<Self::AssetId, Self::AccountId>;
// You can call its contains method
if T::Assets::contains(&asset_id, &account_address) {
// Write your code
}
```
For more detailed example, you can also refer to [Asset-conversion pallet](https://github.com/paritytech/substrate/blob/31b57a1884b00ed979ba85343e308ed73756cb41/frame/asset-conversion/src/lib.rs#L390).
### add swapped event to registrar
PR: https://github.com/paritytech/polkadot/pull/5990
**Why is this important?**
Before this PR there were no events emitted when a parachain swapped with another parachain.
This PR introduces a Swapped event:
```rust
Swapped { para_id: ParaId, other_id: ParaId },
```
**How does this impacts the Polkadot builders?**
Builders can now have confirmation through events that a parachain has swapped with another parachain.
### Improve handling of unset StorageVersion
PR: https://github.com/paritytech/substrate/pull/13417
**Why is this change interesting for builders?**
If the `StorageVersion` is not set properly, it may lead to potential issues with migrations because currently we assume that `on_chain_storage_version() == current_storage_version()` for all pallets.
This PR makes the compilation fail if we forget to set the storage version in a pallet and do `on_chain_storage_version() == current_storage_version()`. This PR also checks in `post_upgrade` that the storage version on chain matches with the current storage version. This will make sure that no migration has been missed.
**How does this impact the Polkadot builders?**
If your pallet doesn't have the proper `StorageVersion` set on chain, try-runtime tests may start failing. To fix this:
```rust
fn on_runtime_upgrade() {
StorageVersion::new(EXPECTED_VERSION).put::<Pallet_That_Is_failing>();
}
```
Related Issue: [#13062](https://github.com/paritytech/substrate/issues/13062)
### AccountTouch trait: deposit_required accepts asset id
PR: https://github.com/paritytech/substrate/pull/14147
**Why is this important?**
This PR adds `AssetId` to `deposit_required` which allows to specify the asset id of the account to be created which can be used to determine the required deposit for account creation for that asset:
```rust
/// Trait for creating an asset account with a deposit taken from a designated depositor specified
/// by the client.
pub trait AccountTouch<AssetId, AccountId> {
/// The type for currency units of the deposit.
type Balance;
/// The deposit amount of a native currency required for creating an account of the `asset`.
fn deposit_required(asset: AssetId) -> Self::Balance;
/// Create an account for `who` of the `asset` with a deposit taken from the `depositor`.
fn touch(asset: AssetId, who: AccountId, depositor: AccountId) -> DispatchResult;
}
```
### Deprecate Pallet decl_* Macros
PR: https://github.com/paritytech/substrate/pull/13705
**Why is this change interesting for builders?**
As a part of this PR, all `decl_*` macros(`decl_module`, `decl_storage`, `decl_error` and `decl_event`) have been deprecated and will be removed soon. If you are using these deprecated macros in your application, you should start using `#[frame_support::pallet]` attribute.
Related Issue: [#12248](https://github.com/paritytech/substrate/issues/12248)
Depends on: [#12445](https://github.com/paritytech/substrate/pull/12445), [#12401](https://github.com/paritytech/substrate/pull/12401)
---
### Prepare `sc-network` for `ProtocolController`/`NotificationService`
PR: https://github.com/paritytech/substrate/pull/14080
**Why is this important?**
In preparation for an upcoming refactor of the notification protocol subsystem, the initialization process of network protocols have been modified. A new network configuration object has been introduced which allows storing consumable, networking-related configuration before `build_network()` is called, providing a more flexible way of initializing protocols.
**How does this impacts the Polkadot builders?**
Moreover, these changes include `FullNetworkConfiguration` as the store for protocol-related configuration which is consumable by `sc-network`, allowing protocols to be fully initialized before the network is started. The `net_config` of your chain might need a few modifications in your `node/service.rs` file. For examples, please refer to the companion PRs.
Polkadot commpanion PR: [#7184](https://github.com/paritytech/polkadot/pull/7184)
Cumulus companion PR: [#2526](https://github.com/paritytech/cumulus/pull/2526)
---
### Adds ability to use default hasher in dev_mode for explicit key binding
PR: https://github.com/paritytech/substrate/pull/14164
**Why is this important?**
This PR adds a default hasher (`Blake2_128Concat`) to[`dev_mode`](https://paritytech.github.io/substrate/master/pallet_dev_mode).
**Why is this change interesting for builders?**
One more feature added to [`dev_mode`](https://forum.polkadot.network/t/polkadot-release-analysis-v0-9-33/1287#add-dev-mode-palletdev_mode-12). Using [`dev_mode`](https://paritytech.github.io/substrate/master/pallet_dev_mode) helps focus on core pallet logic, quickly create prototypes, and overall speed up development.
**How to use?**
When in [`dev_mode`](https://paritytech.github.io/substrate/master/pallet_dev_mode) the syntax is as follows:
```
#[pallet::storage]
pub type Baz<T: Config> = StorageMap<Key = T::AccountId, Value = T::Balance>;
```
When not in [`dev_mode`](https://paritytech.github.io/substrate/master/pallet_dev_mode) the above will throw an error.
Keep in mind [`dev_mode`](https://paritytech.github.io/substrate/master/pallet_dev_mode) is for development puposes and not meant to be used in production.
Related Issue: [#14118](https://github.com/paritytech/substrate/issues/14118)
### Actually respect locks of zero
PR: https://github.com/paritytech/substrate/pull/14144
**Why is this important?**
Previously, if [`set_lock`](https://paritytech.github.io/substrate/master/frame_support/traits/trait.LockableCurrency.html#tymethod.set_lock) was called with an amount of zero, it would result in a no-op. With this PR, if the balance is zero then `Self::remove_lock(id, who);` is called:
```diff
- // Is a no-op if lock amount is zero or `reasons` `is_none()`.
// Set or alter a lock on the balance of `who`
fn set_lock(...) {
- if amount.is_zero() || reasons.is_empty() {
+ if reasons.is_empty() || amount.is_zero() {
+ Self::remove_lock(id, who);
return
}
```
**How to use?**
```rust
#[test]
fn set_lock_with_amount_zero_removes_lock() {
ExtBuilder::default()
.existential_deposit(1)
.monied(true)
.build_and_execute_with(|| {
Balances::set_lock(ID_1, &1, u64::MAX, WithdrawReasons::all());
Balances::set_lock(ID_1, &1, 0, WithdrawReasons::all());
assert_ok!(<Balances as Currency<_>>::transfer(&1, &2, 1, AllowDeath));
});
}
```
- https://github.com/paritytech/substrate/blob/0e9c1cef3cd16730846a7ca99a26cb26bfd1d95f/frame/balances/src/tests/currency_tests.rs#L36-L46
### [Feature] XCM-Emulator
PR: https://github.com/paritytech/cumulus/pull/2447
**Why is this important?**
[XCM-Emulator](https://github.com/paritytech/cumulus/pull/2447) is a tool to emulate XCM program execution using pre-configured runtimes, including those used to run on live networks, such as Kusama, Polkadot, Statemine, etc.
This allows for testing cross-chain message passing, verifying outcomes, weights and side-effects.
This tool allows for multi-network declaration via `decl_test_relay_chain`, `decl_test_parachain` and `decl_test_network`.
Handy helper functions `within_threshold` & `weight_within_threshold` for events assessment and `assert_expected_events` macro that helps to check received events with pattern matching and conditional assertion of theirs inner fields. [Example](https://github.com/paritytech/cumulus/blob/342babdf31733202d8c57abc91cd19b69c008e5f/parachains/integration-tests/emulated/assets/statemint/src/tests/reserve_transfer.rs#L34-L38).
---
### Add Foreign Assets to Statemint
PR: https://github.com/paritytech/cumulus/pull/2540/
**Why is this important?**
Following the steps taken in [#2133](https://github.com/paritytech/cumulus/pull/2133) and with its audit finished, foreign assets are now available in Polkadot's Asset Hub (Statemint).
**Why is this change interesting for builders?**
This allows for bridges to represent assets from other networks as well as other parachains to represent their assets.
### [xcm] Foreign global consensus parachain LocationToAccountId converter
PR: https://github.com/paritytech/polkadot/pull/7016
**Why is this change interesting for builders?**
As a part of this PR, a converter has been introduced in XCM, which converts a location which is a top-level parachain into a 32-byte `AccountId`. This `AccountId` will always be the same for the same parachain index under the same Relay-chain, regardless of the relative security of this Relay-chain compared to the local chain.
This will be used for sovereign accounts of parachain represented on different global consensus. You can find more details in this [polkadot forum discussion](https://forum.polkadot.network/t/bridge-hub-questions/2693/5).
### contracts: Make Origin information available
PR: https://github.com/paritytech/substrate/pull/13708
**Why is this important?**
This PR implements a new `Origin` enum for `pallet-contracts` with, at the moment, two accepted origins: `Signed(T::AccountId)` and `Root`.
`ensure_origin` has been implemented in `Invokables` trait, which can be used to to check whether the origin is allow to invoke.
`ensure_signed` has been removed from the dispatchables `call`, `instantiate` and `instantiate_with_code`, and replaced with `Invokables::ensure_origin`. Per the PR description, as a result `PostDispatchInfo.actual_weight` is now `Some(x)` instead of `None`, that was before.
**How does this impacts the Polkadot builders?**
As for now, when the origin is `Root` there is not any charge or refund of storage deposit.