alejandro
Mon, 31 Jul 2023 19:04:35 +0000
Ecosystem

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

Sidecar - v17.1.1

Txwrapper - v7.0.1

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 is PristineCode with the original uploaded (and validated) codes.

Renames OwnerInfo into CodeInfo, which incurs moving it to another StorageMap.
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: https://github.com/paritytech/substrate/pull/11324

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: 'static = ()> =
-    StorageValue<_, Vec<T::AccountId>, ValueQuery>;

+ pub type Members<T: Config, 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: Take into account proof size for transaction payment and priority by Ank4n · Pull Request #13958 · paritytech/substrate · GitHub

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: https://github.com/paritytech/substrate/pull/14045

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: pallet-aura: Allow multiple blocks per slot by rphmeier · Pull Request #14024 · paritytech/substrate · GitHub

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

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

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: Frame: Give Referendum `SubmitOrigin` argument by gavofyork · Pull Request #14326 · paritytech/substrate · GitHub

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: Asset Conversion pallet by gilescope · Pull Request #12984 · paritytech/substrate · GitHub

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

PR: Bump sp-crates from latest crates.io version and release by lexnv · Pull Request #14265 · paritytech/substrate · GitHub

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:

Economic Model for System Para Collators

Rename Statemint to Asset Hub

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

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: Soft deprecate GenesisConfig by juangirini · Pull Request #14210 · paritytech/substrate · GitHub

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:

frame/example/default-config

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: Adds ability to prepare/initialize before running `set_code` benchmark by bkontur · Pull Request #14435 · paritytech/substrate · GitHub

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

PR: [NFTs] Add mint price to the witness object on mint and confirm it by jsidorenko · Pull Request #14257 · paritytech/substrate · GitHub

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.

4 posts - 1 participant