Polkadot Release Analysis v1.0.0
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 v1.0.0. 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.
Summary
This analysis is for Polkadot 1.0.0 release .
Note that from this release onwards the runtime code will be living in the fellowship!
This Polkadot Release Analysis (PRA) features notable changes like a complete shift in gas metering for pallet-contracts
, a starting point for a multi-block migration framework, pallet-aura
allowing multiple blocks per slot, and many more!
Breaking changes are also covered
Runtimes built on release v1.0.0
- Kusama v10000
- Polkadot v10000
Tooling Section
High Impact
contracts: switch to wasmi gas metering
PR: https://github.com/paritytech/substrate/pull/14084
Why is this important?
As it is explained in the original issue fuel consumption was measured via gas
host function invocation. For this the executed Wasm blob needed to be instrumented first, i.e. the aforementioned host function calls needed to be injected into each metering block of the code. Now we use built-in wasmi fuel metering instead, which allows us get rid of the instrumentation, saving both storage (as we don’t need to store the instrumented code alongside original code) and performance (as calling host function in every block is costly operation).
This change also translates into cost savings for both, contract authors and users. Also, fuel metering on the engine side is faster.
Another positive side effect of this change we is that other Wasm features beyond MVP can be enabled, like the sign_extension has been alreedy enabled at PR#14565
Why is this change interesting for builders?
Having the metering alogrithm being part of the runtime instead of declared in the client also means that changes made to this piece of logic won’t introduce consensus problems between versions.
As from this change two separate fuel meters exists, each having its own units of measurement:
- Gas Meter built into the pallet, measures 2-dimension Weight burn during runtime host function execution.
- Fuel Meter built into the wasmi, measures 1-dimension Fuel burn in engine for Wasm instruction execution.
Units of fuel consumption in wasmi are normalized, so that basic operations like i64.const
cost 1 Fuel. For conversion between the two UoM, the ref_time
component of i64.const
instruction Weight is used.
How does this impact the Polkadot builders?
To accomodate for these changes users of pallet-contract
need to run a migration, provided in this PR, which does the following:
- Removes
CodeStorage
with all instrumented contract codes.
The only one needed isPristineCode
with the original uploaded (and validated) codes. - Renames
OwnerInfo
intoCodeInfo
, which incurs moving it to anotherStorageMap
.
Code related “meta” data is stored in a separate storage item, which now contains not only owner-related fields. Hence the rename. - As the migration frees up a decent amount of storage, deposits attached to it are refunded.
The amount due to refund is calculated pro rata to the currently held deposit.
Society v2
PR: Society v2 by gavofyork · Pull Request #11324 · paritytech/substrate · GitHub
Why is this important?
Significant changes have been made to pallet-society
such as modifying how the society itself works in regards to membership and the voting of members. Refer to the PR description for a clear understanding of how the society will behave from now on.
How does this impact the Polkadot builders?
The changes revamp the definition of different storage items and types accross the pallet, for instance:
The number of members are no longer limited technically (Members is no longer a
Vec
item).
- pub type Members<T: Config<I>, I: 'static = ()> =
- StorageValue<_, Vec<T::AccountId>, ValueQuery>;
+ pub type Members<T: Config<I>, I: 'static = ()> =
+ StorageMap<_, Twox64Concat, T::AccountId, MemberRecord, OptionQuery>;
Inclusion of member ranks or use of BoundedVec
are other examples from the list of changes that require migrating the data to comply with the new definitions. This migration is provided within this PR, take care of running it in case you are a user of this pallet.
Other notable mentions is the inclusion of new extriniscs:
waive_repay
call_index:7
punish_skeptic
call_index:12
claim_membership
call_index:13
bestow_membership
call_index:14
kick_candidate
call_index:15
resign_candidacy
call_index:16
drop_candidate
call_index:17
Watch out for modifications on call indices from the previous version of the pallet.
Medium Impact
Take into account proof size for transaction payment and priority
PR: https://github.com/paritytech/substrate/pull/13958
Why is this important?
This PR makes changes to the transaction payment pallet specifically so that PoV size is now taken into account when calculating the TargetedFeeAdjustment
and transaction priority.
How does this impact the Polkadot builders?
PoV size or proof_size
is not something that needs to be taken into account for transactions on the Relay, however for parachains the PoV is limited to 5 MB. An attacker could take advantage of this by filling a block with storage size and not paying a transaction fee that takes into account the proof_size
.
There is also a note on the PR regarding considerations when selecting a max PoV size for your chain. If you select a really high value, it would result in your blocks never being full and if you select too low of a value, it would mean that your blocks would be constantly full and transaction fees would keep increasing. The key is to find an optimal PoV size. More info on this is in the PR description.
A new term is introduced with this PR: limiting dimension
which refers to the dimension (ref_time
and proof_size
) that has the scarcer resource. The following doc comment encompasses the full definition:
/// Since block weight is multi-dimension, we use the scarcer resource, referred as limiting
/// dimension, for calculation of fees. We determine the limiting dimension by comparing the
/// dimensions using the ratio of `dimension_value / max_dimension_value` and selecting the largest
/// ratio. For instance, if a block is 30% full based on `ref_time` and 25% full based on
/// `proof_size`, we identify `ref_time` as the limiting dimension, indicating that the block is 30%
/// full.
Related Issue: #13898
contracts: Multi block migrations
PR: contracts: Multi block migrations by pgherveou · Pull Request #14045 · paritytech/substrate · GitHub
Why is this change interesting for builders?
If we are upgrading to a new version and using pallet-contracts, we need to perform large storage migrations and all migrations need to happen in a single block.
As a part of this PR, this problem is solved by introducing multi-block migrations in the contracts pallet.
How does this impact the Polkadot builders?
This PR adds a multi-block migration framework for pallet-contracts. Please refer to the PR description for testing multi block migration. At the moment, this feature is available only for the contracts pallet and will be generalized to the rest of FRAME in the future.
With this PR, when the migration starts, access to pallet-contracts
is blocked while the migration is in progress.
Related Issue: #13638
Move type Migrations to Config
PR: https://github.com/paritytech/substrate/pull/14309
Why is this change interesting for builders?
As described above, a multi-block migration framework has been introduced for pallet-contracts in release-v1.0.0
.
This PR is related to that change and adds a new config in pallet-contracts
:
type Migrations: MigrateSequence
How does this impact the Polkadot builders?
If we are using pallet-contracts
, we need to include this in our runtime configuration with our pending migrations (or ()
if none). otherwise this will result in compilation failure.
How to use?
To avoid compilation failure:
impl pallet_contracts::Config for Runtime {
// .. snip
type Migrations = ();
}
For more details, please check the PR description.
Cumulus Companion PR: #2701
Related Substrate PR: #14045
pallet-aura: Allow multiple blocks per slot
PR: https://github.com/paritytech/substrate/pull/14024
Why is this change interesting for builders?
As we know, pallet-aura has a key role in the block authoring process. Aura works by having a list of authorities, who are allowed to produce blocks. The authorities must be chosen before block production begins and all authorities must know the entire authority set. Time is divided up into slots
of a fixed length. During each slot one block is produced, and the authorities take turns producing blocks in order forever.
At the moment, only one block is produced in each slot.
This PR optionally allows sequential blocks to be authored within the same slot.
How does this impact the Polkadot builders?
A new config type AllowMultipleBlocksPerSlot: Get<bool>
has been added in pallet-aura. If you are using Aura consensus for block authorization, this would be a breaking change and fail the compilation.
We can set its value as false
to maintain current behavior. If you are looking for enabling asynchronous backing, you can set its value as true
but this may require other changes alongside.
How to use?
To avoid compilation failure:
impl pallet_aura::Config for Runtime {
// .. snip
type AllowMultipleBlocksPerSlot = ConstBool<false>;
}
For more details, please check the PR description and related issue.
Cumulus Companion PR: #2707
Related Issue: #2476
[NFTs] Add minting price to the pre-signed mint object
Why is this important?
This PR allows for the PreSignedMint
data to include an optional mint price.
How does this impact the Polkadot builders?
This is a breaking change for the NFTs pallet as we are adding a new field mint_price
to the PreSignedMint
struct:
pub struct PreSignedMint<CollectionId, ItemId, AccountId, Deadline, Balance> {
/// A collection of the item to be minted.
pub(super) collection: CollectionId,
/// Item's ID.
pub(super) item: ItemId,
/// Additional item's key-value attributes.
pub(super) attributes: Vec<(Vec<u8>, Vec<u8>)>,
/// Additional item's metadata.
pub(super) metadata: Vec<u8>,
/// Restrict the claim to a particular account.
pub(super) only_account: Option<AccountId>,
/// A deadline for the signature.
pub(super) deadline: Deadline,
+ /// An optional price the claimer would need to pay for the mint.
+ pub(super) mint_price: Option<Balance>,
}
Why is this change interesting for builders?
Offchain minting allows others to know the what they will be claiming because the metadata and attributes are part of the presigned mint data and therefore known. Adding an optional price to this mint data allows for more use cases, elevating the offchain minting experience.
How to use?
PreSignedMint {
collection: 0,
item: 0,
attributes: vec![(vec![0], vec![1]), (vec![2], vec![3])],
metadata: vec![0, 1],
only_account: None,
deadline: 10000000,
mint_price: Some(10),
};
You can refer to the full test here.
Frame: Give Referendum SubmitOrigin argument
PR: https://github.com/paritytech/substrate/pull/14326
Why is this important?
This PR allows for a more granular control over a submission origin depending on the track it is submitting for. The type SubmitOrigin
in pallet-referenda
is now defined as:
type SubmitOrigin: EnsureOriginWithArg<
Self::RuntimeOrigin,
PalletsOriginOf<Self>,
Success = Self::AccountId,
>;
How does this impact the Polkadot builders?
Users of pallet-referenda
might encounter build errors related with their custom origins and as per the author’s instructions these can be solved by wrapping the type with frame_support::AsEnsureOriginWithArg
, e.g:
impl pallet_referenda::Config for Runtime {
type SubmitOrigin = MyEnsureOriginImpl;
// snip
}
The above, would become:
impl pallet_referenda::Config for Runtime {
type SubmitOrigin = frame_support::AsEnsureOriginWithArg<MyEnsureOriginImpl>;
// snip
}
Low Impact
Asset Conversion pallet
PR: https://github.com/paritytech/substrate/pull/12984
Why is this change interesting for builders?
As a part of this PR, A new Asset Conversion pallet has been introduced, which is a simple audited AMM (automated market maker) pallet. This pallet is based on Uniswap V2 logic.
This pallet allows you to:
- create a liquidity pool for 2 assets
- provide the liquidity and receive back an LP token
- exchange the LP token back to assets
- swap a specific amount of assets for another if there is a pool created, or
- swap some assets for a specific amount of another
- query for an exchange price via a runtime call endpoint
- query the size of a liquidity pool via a runtime api endpoint.
Related Issue: #33
Bump sp-crates from latest crates.io version and release
Why is this change interesting for builders?
As a part of this PR, sp-crates
have been bumped to the latest version. This might be a breaking change if you don’t update Cargo.toml
or Cargo.lock
.
If you are using sp-crates
without mentioning version in Cargo.toml
, then you can simply run cargo update
and update your Cargo.lock
.
In case, if you are using version, you have to update Cargo.toml
. For example:
- sp-core = { version = "7.0.0" }
+ sp-core = { version = "21.0.0" }
Related PR: #14237
Polkadot Companion PR: #7307
Cumulus Companion PR: #2655
Add Ability to Add/Remove Invulnerable Collators
PR: https://github.com/paritytech/cumulus/pull/2596
Why is this change interesting for builders?
As a part of this PR, two new extrinsics add_invulnerable
and remove_invulnerable
have been introduced, which will allow to add or remove individual collators to/from the Invulnerables set. Now there won’t be any need for any kind of nomination or delegation scheme.
Related Discussion:
Rename Statemint to Asset Hub
PR: Rename Statemint to Asset Hub by joepetrowski · Pull Request #2633 · paritytech/cumulus · GitHub
Why is this change interesting for builders?
Statemint
is a system parachain on Polkadot, also referred as common-good
parachain, allows the deployment and transfer of assets (both fungible and non-fungible tokens) and serves as the fundamental infrastructure that enables the Polkadot ecosystem to communicate with the rest of the on-chain and off-chain environment.
The name Statemint
has introduced a lot of confusion across the ecosystem (especially with its counterpart, Statemine).
As a part of this PR, Statemint
has been renamed to Asset Hub
. You can find more details here.
How does this impacts the Polkadot builders?
There are no changes on the chainspec or the endpoints even though the name has officially changed.
Related Issue: #2591
Related Discussion: The Naming of Things (viz. Statemint)
Soft deprecate GenesisConfig
PR: https://github.com/paritytech/substrate/pull/14210
Why is this change interesting for builders?
As a part of this PR, GenesisConfig
has been renamed to RuntimeGenesisConfig
. Most of the composite enums are already renamed earlier with the same pattern i.e. RuntimeXXX
.
This PR softy deprecates GenesisConfig
and does not generate a deprecation warning. However, a related PR #14224 has also been merged in the same release to generate a warning when using the runtime level GenesisConfig
.
Related PR: #14224
Related Issue: #14065
[FRAME Core] Default Pallet Config Trait / derive_impl
PR: https://github.com/paritytech/substrate/pull/13454
Why is this important?
This PR add the ability for a pallet to have a default config. This has been idea that has been discussed and is now coming to fruition.
This PR brings in the basic working functionality for a default config for testing purposes. There are a few more action items pending for this to be fully production ready.
How does this impact the Polkadot builders?
Having this feature would simplify runtime development as developers will often opt in for default values.
There is a full example pallet using the default config feature in Substrate:
This gist is that you annotate you pallet config like so:
#[pallet::config(with_default)]
pub trait Config: frame_system::Config {
...
You can optionally mark a type with no default:
#[pallet::no_default]
type CannotHaveDefault: Get<Self::AccountId>;
Adds ability to prepare/initialize before running set_code benchmark
PR: https://github.com/paritytech/substrate/pull/14435
Why is this change interesting for builders?
After the inclusion of benchmarks for system::set_code cumulus codebases might run into issues if configured with:
type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
This PR adds a way to provide the required pre existing data in order to benchmark successfully the above mentioned extinsic.
Cumulus companion PR #2766
[NFTs] Add mint price to the witness object on mint and confirm it
Why is this important?
This PR adds mint_price
to the witness data object.
How does this impact the Polkadot builders?
When minting an NFT using the NFTs pallet, there are three types of mints that are possible:
pub enum MintType<CollectionId> {
/// Only an `Issuer` could mint items.
Issuer,
/// Anyone could mint items.
Public,
/// Only holders of items in specified collection could mint new items.
HolderOf(CollectionId),
}
When HolderOf(CollectionId)
is used, a witness data object that proves that they are a holder of an NFT item in that collection is required. This is done via the MintWitness
:
pub struct MintWitness<ItemId, Balance> {
/// Provide the id of the item in a required collection.
pub owned_item: ItemId,
+ /// The price specified in mint settings.
+ pub mint_price: Option<Balance>,
}
mint_price
is now part of that witness data.
If you’re curious how the mint witness works, you can see in action in the NFTs pallet’s mint
call, specifically here.