From b76e91acc953e682b3ddcfc45ecacaaf26c694a1 Mon Sep 17 00:00:00 2001
From: georgepisaltu <52418509+georgepisaltu@users.noreply.github.com>
Date: Fri, 18 Oct 2024 20:37:32 +0300
Subject: [PATCH] FRAME: Reintroduce `TransactionExtension` as a replacement
 for `SignedExtension` (#3685)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Original PR https://github.com/paritytech/polkadot-sdk/pull/2280
reverted in https://github.com/paritytech/polkadot-sdk/pull/3665

This PR reintroduces the reverted functionality with additional changes,
related effort
[here](https://github.com/paritytech/polkadot-sdk/pull/3623).
Description is copied over from the original PR

First part of [Extrinsic
Horizon](https://github.com/paritytech/polkadot-sdk/issues/2415)

Introduces a new trait `TransactionExtension` to replace
`SignedExtension`. Introduce the idea of transactions which obey the
runtime's extensions and have according Extension data (né Extra data)
yet do not have hard-coded signatures.

Deprecate the terminology of "Unsigned" when used for
transactions/extrinsics owing to there now being "proper" unsigned
transactions which obey the extension framework and "old-style" unsigned
which do not. Instead we have __*General*__ for the former and
__*Bare*__ for the latter. (Ultimately, the latter will be phased out as
a type of transaction, and Bare will only be used for Inherents.)

Types of extrinsic are now therefore:
- Bare (no hardcoded signature, no Extra data; used to be known as
"Unsigned")
- Bare transactions (deprecated): Gossiped, validated with
`ValidateUnsigned` (deprecated) and the `_bare_compat` bits of
`TransactionExtension` (deprecated).
  - Inherents: Not gossiped, validated with `ProvideInherent`.
- Extended (Extra data): Gossiped, validated via `TransactionExtension`.
  - Signed transactions (with a hardcoded signature) in extrinsic v4.
- General transactions (without a hardcoded signature) in extrinsic v5.

`TransactionExtension` differs from `SignedExtension` because:
- A signature on the underlying transaction may validly not be present.
- It may alter the origin during validation.
- `pre_dispatch` is renamed to `prepare` and need not contain the checks
present in `validate`.
- `validate` and `prepare` is passed an `Origin` rather than a
`AccountId`.
- `validate` may pass arbitrary information into `prepare` via a new
user-specifiable type `Val`.
- `AdditionalSigned`/`additional_signed` is renamed to
`Implicit`/`implicit`. It is encoded *for the entire transaction* and
passed in to each extension as a new argument to `validate`. This
facilitates the ability of extensions to acts as underlying crypto.

There is a new `DispatchTransaction` trait which contains only default
function impls and is impl'ed for any `TransactionExtension` impler. It
provides several utility functions which reduce some of the tedium from
using `TransactionExtension` (indeed, none of its regular functions
should now need to be called directly).

Three transaction version discriminator ("versions") are now permissible
(RFC [here](https://github.com/polkadot-fellows/RFCs/pull/84)) in
extrinsic version 5:
- 0b00000100 or 0b00000101: Bare (used to be called "Unsigned"):
contains Signature or Extra (extension data). After bare transactions
are no longer supported, this will strictly identify an Inherents only.
Available in both extrinsic versions 4 and 5.
- 0b10000100: Old-school "Signed" Transaction: contains Signature, Extra
(extension data) and an extension version byte, introduced as part of
[RFC99](https://github.com/polkadot-fellows/RFCs/blob/main/text/0099-transaction-extension-version.md).
Still available as part of extrinsic v4.
- 0b01000101: New-school "General" Transaction: contains Extra
(extension data) and an extension version byte, as per RFC99, but no
Signature. Only available in extrinsic v5.

For the New-school General Transaction, it becomes trivial for authors
to publish extensions to the mechanism for authorizing an Origin, e.g.
through new kinds of key-signing schemes, ZK proofs, pallet state,
mutations over pre-authenticated origins or any combination of the
above.

`UncheckedExtrinsic` still maintains encode/decode backwards
compatibility with extrinsic version 4, where the first byte was encoded
as:
- 0b00000100 - Unsigned transactions
- 0b10000100 - Old-school Signed transactions, without the extension
version byte

Now, `UncheckedExtrinsic` contains a `Preamble` and the actual call. The
`Preamble` describes the type of extrinsic as follows:
```rust
/// A "header" for extrinsics leading up to the call itself. Determines the type of extrinsic and
/// holds any necessary specialized data.
#[derive(Eq, PartialEq, Clone)]
pub enum Preamble<Address, Signature, Extension> {
	/// An extrinsic without a signature or any extension. This means it's either an inherent or
	/// an old-school "Unsigned" (we don't use that terminology any more since it's confusable with
	/// the general transaction which is without a signature but does have an extension).
	///
	/// NOTE: In the future, once we remove `ValidateUnsigned`, this will only serve Inherent
	/// extrinsics and thus can be renamed to `Inherent`.
	Bare(ExtrinsicVersion),
	/// An old-school transaction extrinsic which includes a signature of some hard-coded crypto.
	/// Available only on extrinsic version 4.
	Signed(Address, Signature, ExtensionVersion, Extension),
	/// A new-school transaction extrinsic which does not include a signature by default. The
	/// origin authorization, through signatures or other means, is performed by the transaction
	/// extension in this extrinsic. Available starting with extrinsic version 5.
	General(ExtensionVersion, Extension),
}
```

## Code Migration

### NOW: Getting it to build

Wrap your `SignedExtension`s in `AsTransactionExtension`. This should be
accompanied by renaming your aggregate type in line with the new
terminology. E.g. Before:

```rust
/// The SignedExtension to the basic transaction logic.
pub type SignedExtra = (
	/* snip */
	MySpecialSignedExtension,
);
/// Unchecked extrinsic type as expected by this runtime.
pub type UncheckedExtrinsic =
	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
```

After:

```rust
/// The extension to the basic transaction logic.
pub type TxExtension = (
	/* snip */
	AsTransactionExtension<MySpecialSignedExtension>,
);
/// Unchecked extrinsic type as expected by this runtime.
pub type UncheckedExtrinsic =
	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
```

You'll also need to alter any transaction building logic to add a
`.into()` to make the conversion happen. E.g. Before:

```rust
fn construct_extrinsic(
		/* snip */
) -> UncheckedExtrinsic {
	let extra: SignedExtra = (
		/* snip */
		MySpecialSignedExtension::new(/* snip */),
	);
	let payload = SignedPayload::new(call.clone(), extra.clone()).unwrap();
	let signature = payload.using_encoded(|e| sender.sign(e));
	UncheckedExtrinsic::new_signed(
		/* snip */
		Signature::Sr25519(signature),
		extra,
	)
}
```

After:

```rust
fn construct_extrinsic(
		/* snip */
) -> UncheckedExtrinsic {
	let tx_ext: TxExtension = (
		/* snip */
		MySpecialSignedExtension::new(/* snip */).into(),
	);
	let payload = SignedPayload::new(call.clone(), tx_ext.clone()).unwrap();
	let signature = payload.using_encoded(|e| sender.sign(e));
	UncheckedExtrinsic::new_signed(
		/* snip */
		Signature::Sr25519(signature),
		tx_ext,
	)
}
```

### SOON: Migrating to `TransactionExtension`

Most `SignedExtension`s can be trivially converted to become a
`TransactionExtension`. There are a few things to know.

- Instead of a single trait like `SignedExtension`, you should now
implement two traits individually: `TransactionExtensionBase` and
`TransactionExtension`.
- Weights are now a thing and must be provided via the new function `fn
weight`.

#### `TransactionExtensionBase`

This trait takes care of anything which is not dependent on types
specific to your runtime, most notably `Call`.

- `AdditionalSigned`/`additional_signed` is renamed to
`Implicit`/`implicit`.
- Weight must be returned by implementing the `weight` function. If your
extension is associated with a pallet, you'll probably want to do this
via the pallet's existing benchmarking infrastructure.

#### `TransactionExtension`

Generally:
- `pre_dispatch` is now `prepare` and you *should not reexecute the
`validate` functionality in there*!
- You don't get an account ID any more; you get an origin instead. If
you need to presume an account ID, then you can use the trait function
`AsSystemOriginSigner::as_system_origin_signer`.
- You get an additional ticket, similar to `Pre`, called `Val`. This
defines data which is passed from `validate` into `prepare`. This is
important since you should not be duplicating logic from `validate` to
`prepare`, you need a way of passing your working from the former into
the latter. This is it.
- This trait takes a `Call` type parameter. `Call` is the runtime call
type which used to be an associated type; you can just move it to become
a type parameter for your trait impl.
- There's no `AccountId` associated type any more. Just remove it.

Regarding `validate`:
- You get three new parameters in `validate`; all can be ignored when
migrating from `SignedExtension`.
- `validate` returns a tuple on success; the second item in the tuple is
the new ticket type `Self::Val` which gets passed in to `prepare`. If
you use any information extracted during `validate` (off-chain and
on-chain, non-mutating) in `prepare` (on-chain, mutating) then you can
pass it through with this. For the tuple's last item, just return the
`origin` argument.

Regarding `prepare`:
- This is renamed from `pre_dispatch`, but there is one change:
- FUNCTIONALITY TO VALIDATE THE TRANSACTION NEED NOT BE DUPLICATED FROM
`validate`!!
- (This is different to `SignedExtension` which was required to run the
same checks in `pre_dispatch` as in `validate`.)

Regarding `post_dispatch`:
- Since there are no unsigned transactions handled by
`TransactionExtension`, `Pre` is always defined, so the first parameter
is `Self::Pre` rather than `Option<Self::Pre>`.

If you make use of `SignedExtension::validate_unsigned` or
`SignedExtension::pre_dispatch_unsigned`, then:
- Just use the regular versions of these functions instead.
- Have your logic execute in the case that the `origin` is `None`.
- Ensure your transaction creation logic creates a General Transaction
rather than a Bare Transaction; this means having to include all
`TransactionExtension`s' data.
- `ValidateUnsigned` can still be used (for now) if you need to be able
to construct transactions which contain none of the extension data,
however these will be phased out in stage 2 of the Transactions Horizon,
so you should consider moving to an extension-centric design.

---------

Signed-off-by: georgepisaltu <george.pisaltu@parity.io>
Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com>
Co-authored-by: Branislav Kontur <bkontur@gmail.com>
---
 Cargo.lock                                    |  77 +-
 Cargo.toml                                    |   4 +
 bridges/bin/runtime-common/Cargo.toml         |   3 +
 bridges/bin/runtime-common/src/extensions.rs  | 168 ++--
 bridges/bin/runtime-common/src/mock.rs        |   1 -
 .../chain-bridge-hub-cumulus/src/lib.rs       |   4 +-
 .../chains/chain-bridge-hub-rococo/src/lib.rs |   4 +-
 .../chain-bridge-hub-westend/src/lib.rs       |   4 +-
 bridges/chains/chain-kusama/src/lib.rs        |   4 +-
 .../chains/chain-polkadot-bulletin/src/lib.rs |  47 +-
 bridges/chains/chain-polkadot/src/lib.rs      |   4 +-
 bridges/chains/chain-rococo/src/lib.rs        |   4 +-
 bridges/chains/chain-westend/src/lib.rs       |   4 +-
 bridges/modules/relayers/Cargo.toml           |   1 +
 bridges/modules/relayers/src/extension/mod.rs | 229 +++--
 .../relayers/src/extension/priority.rs        |  36 +-
 bridges/primitives/polkadot-core/src/lib.rs   |  37 +-
 bridges/primitives/relayers/src/extension.rs  |   2 +-
 bridges/primitives/runtime/src/extensions.rs  | 128 ++-
 .../lib-substrate-relay/src/messages/mod.rs   |   4 +-
 .../pallets/ethereum-client/Cargo.toml        |   8 +-
 .../ethereum-client/fixtures/Cargo.toml       |   4 +-
 .../pallets/inbound-queue/fixtures/Cargo.toml |   4 +-
 .../outbound-queue/merkle-tree/Cargo.toml     |   7 +-
 .../src/validate_block/implementation.rs      |  11 +-
 .../assets/asset-hub-rococo/Cargo.toml        |   2 +
 .../assets/asset-hub-rococo/src/lib.rs        |  81 +-
 .../src/weights/frame_system_extensions.rs    | 132 +++
 .../asset-hub-rococo/src/weights/mod.rs       |   3 +
 .../pallet_asset_conversion_tx_payment.rs     |  92 ++
 .../src/weights/pallet_transaction_payment.rs |  67 ++
 .../assets/asset-hub-westend/Cargo.toml       |   2 +
 .../assets/asset-hub-westend/src/lib.rs       |  86 +-
 .../src/weights/frame_system_extensions.rs    | 132 +++
 .../asset-hub-westend/src/weights/mod.rs      |   3 +
 .../pallet_asset_conversion_tx_payment.rs     |  92 ++
 .../src/weights/pallet_transaction_payment.rs |  67 ++
 .../bridge-hubs/bridge-hub-rococo/Cargo.toml  |   1 +
 .../src/bridge_to_bulletin_config.rs          |   8 +-
 .../src/bridge_to_westend_config.rs           |   7 +-
 .../bridge-hubs/bridge-hub-rococo/src/lib.rs  |  31 +-
 .../src/weights/frame_system_extensions.rs    | 132 +++
 .../bridge-hub-rococo/src/weights/mod.rs      |   2 +
 .../src/weights/pallet_transaction_payment.rs |  67 ++
 .../bridge-hub-rococo/tests/snowbridge.rs     |  10 +-
 .../bridge-hub-rococo/tests/tests.rs          |  34 +-
 .../bridge-hubs/bridge-hub-westend/Cargo.toml |   1 +
 .../src/bridge_to_rococo_config.rs            |   7 +-
 .../bridge-hubs/bridge-hub-westend/src/lib.rs |  31 +-
 .../src/weights/frame_system_extensions.rs    | 132 +++
 .../bridge-hub-westend/src/weights/mod.rs     |   2 +
 .../src/weights/pallet_transaction_payment.rs |  67 ++
 .../bridge-hub-westend/tests/snowbridge.rs    |   6 +-
 .../bridge-hub-westend/tests/tests.rs         |  13 +-
 .../test-utils/src/test_cases/mod.rs          |   8 +-
 .../collectives-westend/Cargo.toml            |   1 +
 .../collectives-westend/src/lib.rs            |  12 +-
 .../src/weights/frame_system_extensions.rs    | 132 +++
 .../collectives-westend/src/weights/mod.rs    |   2 +
 .../src/weights/pallet_transaction_payment.rs |  67 ++
 .../contracts/contracts-rococo/Cargo.toml     |   1 +
 .../contracts/contracts-rococo/src/lib.rs     |  10 +-
 .../coretime/coretime-rococo/Cargo.toml       |   1 +
 .../coretime/coretime-rococo/src/lib.rs       |   9 +-
 .../src/weights/frame_system_extensions.rs    | 132 +++
 .../coretime-rococo/src/weights/mod.rs        |   2 +
 .../src/weights/pallet_transaction_payment.rs |  67 ++
 .../coretime/coretime-westend/Cargo.toml      |   1 +
 .../coretime/coretime-westend/src/lib.rs      |   9 +-
 .../src/weights/frame_system_extensions.rs    | 132 +++
 .../coretime-westend/src/weights/mod.rs       |   2 +
 .../src/weights/pallet_transaction_payment.rs |  67 ++
 .../glutton/glutton-westend/src/lib.rs        |   9 +-
 .../src/weights/frame_system_extensions.rs    | 130 +++
 .../runtimes/people/people-rococo/Cargo.toml  |   1 +
 .../runtimes/people/people-rococo/src/lib.rs  |   9 +-
 .../src/weights/frame_system_extensions.rs    | 132 +++
 .../people/people-rococo/src/weights/mod.rs   |   2 +
 .../src/weights/pallet_transaction_payment.rs |  67 ++
 .../runtimes/people/people-westend/Cargo.toml |   1 +
 .../runtimes/people/people-westend/src/lib.rs |   8 +-
 .../src/weights/frame_system_extensions.rs    | 132 +++
 .../people/people-westend/src/weights/mod.rs  |   2 +
 .../src/weights/pallet_transaction_payment.rs |  67 ++
 .../parachains/runtimes/test-utils/src/lib.rs |   2 +-
 .../runtimes/testing/penpal/Cargo.toml        |   1 +
 .../runtimes/testing/penpal/src/lib.rs        |  26 +-
 .../testing/rococo-parachain/Cargo.toml       |   1 +
 .../testing/rococo-parachain/src/lib.rs       |   7 +-
 cumulus/polkadot-omni-node/lib/Cargo.toml     |   1 +
 .../storage-weight-reclaim/Cargo.toml         |   4 +-
 .../storage-weight-reclaim/src/lib.rs         | 726 +-------------
 .../storage-weight-reclaim/src/tests.rs       | 706 ++++++++++++++
 cumulus/test/client/Cargo.toml                |   1 +
 cumulus/test/client/src/lib.rs                |  13 +-
 cumulus/test/runtime/src/lib.rs               |   9 +-
 cumulus/test/service/Cargo.toml               |   1 +
 cumulus/test/service/src/bench_utils.rs       |  14 +-
 cumulus/test/service/src/lib.rs               |   9 +-
 docs/sdk/Cargo.toml                           |   1 +
 docs/sdk/src/guides/enable_pov_reclaim.rs     |   4 +-
 .../src/reference_docs/extrinsic_encoding.rs  | 192 ++--
 .../src/reference_docs/frame_runtime_types.rs |   2 +-
 docs/sdk/src/reference_docs/mod.rs            |   5 +-
 .../src/reference_docs/signed_extensions.rs   | 133 +--
 .../reference_docs/transaction_extensions.rs  | 103 ++
 polkadot/node/service/Cargo.toml              |   6 +-
 polkadot/node/service/src/benchmarking.rs     |  18 +-
 polkadot/node/test/service/Cargo.toml         |   1 +
 polkadot/node/test/service/src/lib.rs         |  11 +-
 polkadot/runtime/common/Cargo.toml            |   1 +
 .../runtime/common/src/assigned_slots/mod.rs  |  13 +-
 polkadot/runtime/common/src/claims.rs         | 166 ++--
 .../runtime/common/src/integration_tests.rs   |  13 +-
 .../runtime/common/src/paras_registrar/mod.rs |  13 +-
 .../parachains/src/disputes/slashing.rs       |   7 +-
 polkadot/runtime/parachains/src/mock.rs       |  13 +-
 polkadot/runtime/parachains/src/paras/mod.rs  |   7 +-
 polkadot/runtime/rococo/Cargo.toml            |   1 +
 .../constants/src/weights/block_weights.rs    |  29 +-
 .../src/weights/extrinsic_weights.rs          |  29 +-
 polkadot/runtime/rococo/src/lib.rs            |  79 +-
 .../weights/frame_benchmarking_baseline.rs    |  43 +-
 .../rococo/src/weights/frame_system.rs        | 103 +-
 .../src/weights/frame_system_extensions.rs    | 134 +++
 polkadot/runtime/rococo/src/weights/mod.rs    |   2 +
 .../rococo/src/weights/pallet_asset_rate.rs   |  63 +-
 .../src/weights/pallet_balances_balances.rs   |  12 +-
 ...allet_balances_nis_counterpart_balances.rs |  12 +-
 .../rococo/src/weights/pallet_bounties.rs     | 218 +++--
 .../src/weights/pallet_child_bounties.rs      | 181 +++-
 .../src/weights/pallet_conviction_voting.rs   | 196 ++--
 .../rococo/src/weights/pallet_identity.rs     | 409 ++++----
 .../rococo/src/weights/pallet_indices.rs      |  73 +-
 .../src/weights/pallet_message_queue.rs       | 168 ++--
 .../rococo/src/weights/pallet_multisig.rs     | 123 +--
 .../runtime/rococo/src/weights/pallet_nis.rs  | 243 +++--
 .../rococo/src/weights/pallet_preimage.rs     | 252 ++---
 .../rococo/src/weights/pallet_proxy.rs        | 195 ++--
 .../src/weights/pallet_ranked_collective.rs   |  66 +-
 .../rococo/src/weights/pallet_recovery.rs     | 186 ++++
 .../pallet_referenda_fellowship_referenda.rs  | 235 ++---
 .../src/weights/pallet_referenda_referenda.rs | 283 +++---
 .../rococo/src/weights/pallet_scheduler.rs    | 146 +--
 .../runtime/rococo/src/weights/pallet_sudo.rs |  45 +-
 .../rococo/src/weights/pallet_timestamp.rs    |  35 +-
 .../src/weights/pallet_transaction_payment.rs |  68 ++
 .../rococo/src/weights/pallet_treasury.rs     | 183 ++--
 .../rococo/src/weights/pallet_utility.rs      |  47 +-
 .../rococo/src/weights/pallet_vesting.rs      | 254 ++---
 .../rococo/src/weights/pallet_whitelist.rs    |  68 +-
 .../runtime/rococo/src/weights/pallet_xcm.rs  |  90 +-
 .../weights/pallet_xcm_benchmarks_fungible.rs | 191 ++++
 .../weights/pallet_xcm_benchmarks_generic.rs  | 347 +++++++
 .../polkadot_runtime_common_assigned_slots.rs |  68 +-
 .../polkadot_runtime_common_auctions.rs       | 129 +--
 .../weights/polkadot_runtime_common_claims.rs | 148 +--
 .../polkadot_runtime_common_crowdloan.rs      | 219 +++--
 ...lkadot_runtime_common_identity_migrator.rs |  83 +-
 ...polkadot_runtime_common_paras_registrar.rs | 269 +++---
 .../weights/polkadot_runtime_common_slots.rs  | 119 ++-
 ...lkadot_runtime_parachains_configuration.rs |  48 +-
 .../polkadot_runtime_parachains_disputes.rs   |  19 +-
 ...polkadot_runtime_parachains_initializer.rs |  23 +-
 .../polkadot_runtime_parachains_on_demand.rs  |   8 +-
 .../polkadot_runtime_parachains_paras.rs      | 344 +++----
 .../src/weights/runtime_common_coretime.rs    |  86 ++
 polkadot/runtime/test-runtime/Cargo.toml      |   1 +
 polkadot/runtime/test-runtime/src/lib.rs      |  58 +-
 polkadot/runtime/westend/Cargo.toml           |   1 +
 polkadot/runtime/westend/src/lib.rs           |  78 +-
 polkadot/runtime/westend/src/tests.rs         |   2 +-
 .../src/weights/frame_system_extensions.rs    | 131 +++
 polkadot/runtime/westend/src/weights/mod.rs   |   2 +
 .../westend/src/weights/pallet_sudo.rs        |  11 +
 .../src/weights/pallet_transaction_payment.rs |  68 ++
 .../src/generic/benchmarking.rs               |   2 +-
 polkadot/xcm/pallet-xcm-benchmarks/src/lib.rs |   2 +-
 polkadot/xcm/pallet-xcm/src/lib.rs            |   4 +-
 polkadot/xcm/xcm-builder/Cargo.toml           |   1 +
 polkadot/xcm/xcm-builder/src/tests/mock.rs    |   4 +-
 .../xcm/xcm-builder/src/tests/pay/mock.rs     |  12 +-
 .../xcm-executor/integration-tests/src/lib.rs |   2 +-
 polkadot/xcm/xcm-executor/src/lib.rs          |   2 +-
 polkadot/xcm/xcm-runtime-apis/tests/mock.rs   |  13 +-
 .../xcm/xcm-simulator/fuzzer/src/parachain.rs |   4 +-
 .../xcm-simulator/fuzzer/src/relay_chain.rs   |   4 +-
 prdoc/pr_3685.prdoc                           | 300 ++++++
 substrate/.maintain/frame-weight-template.hbs |   2 +-
 .../bin/node/cli/benches/block_production.rs  |   7 +-
 substrate/bin/node/cli/benches/executor.rs    |   6 +-
 substrate/bin/node/cli/src/service.rs         |  16 +-
 substrate/bin/node/cli/tests/basic.rs         | 141 +--
 substrate/bin/node/cli/tests/fees.rs          |  14 +-
 .../bin/node/cli/tests/submit_transaction.rs  |  13 +-
 substrate/bin/node/runtime/src/lib.rs         | 150 ++-
 substrate/bin/node/testing/src/bench.rs       |  29 +-
 substrate/bin/node/testing/src/keyring.rs     |  28 +-
 .../client/api/src/notifications/tests.rs     |   4 +-
 substrate/client/db/benches/state_access.rs   |   4 +-
 substrate/client/db/src/lib.rs                | 261 +++--
 substrate/client/db/src/utils.rs              |   8 +-
 .../network-gossip/src/state_machine.rs       |   4 +-
 substrate/client/network/sync/src/blocks.rs   |   4 +-
 .../fork_aware_txpool/fork_aware_txpool.rs    |   5 +-
 .../single_state_txpool.rs                    |   5 +-
 substrate/frame/Cargo.toml                    |   5 +-
 substrate/frame/alliance/src/tests.rs         |   6 +-
 .../frame/asset-conversion/src/weights.rs     |   1 +
 substrate/frame/assets/src/tests.rs           |   4 +-
 substrate/frame/babe/src/equivocation.rs      |   7 +-
 substrate/frame/babe/src/mock.rs              |  13 +-
 substrate/frame/babe/src/tests.rs             |   2 +-
 substrate/frame/balances/Cargo.toml           |   1 +
 .../balances/src/tests/currency_tests.rs      |  17 +-
 substrate/frame/balances/src/tests/mod.rs     |   9 +-
 substrate/frame/beefy/src/equivocation.rs     |   7 +-
 substrate/frame/beefy/src/mock.rs             |  13 +-
 substrate/frame/collective/src/lib.rs         |  12 +-
 substrate/frame/collective/src/tests.rs       |  28 +-
 substrate/frame/contracts/src/wasm/runtime.rs |   4 +-
 .../election-provider-multi-phase/src/lib.rs  |   4 +-
 .../election-provider-multi-phase/src/mock.rs |  13 +-
 .../src/unsigned.rs                           |  14 +-
 .../test-staking-e2e/src/mock.rs              |  17 +-
 substrate/frame/elections-phragmen/src/lib.rs |   2 +-
 substrate/frame/examples/Cargo.toml           |   3 +
 .../authorization-tx-extension/Cargo.toml     |  62 ++
 .../src/extensions.rs                         | 132 +++
 .../authorization-tx-extension/src/lib.rs     | 158 ++++
 .../authorization-tx-extension/src/mock.rs    | 142 +++
 .../authorization-tx-extension/src/tests.rs   | 269 ++++++
 substrate/frame/examples/basic/src/lib.rs     |  98 +-
 substrate/frame/examples/basic/src/tests.rs   |  15 +-
 .../frame/examples/offchain-worker/src/lib.rs |  11 +-
 .../examples/offchain-worker/src/tests.rs     |  50 +-
 substrate/frame/examples/src/lib.rs           |   8 +-
 substrate/frame/examples/tasks/src/lib.rs     |  15 +-
 substrate/frame/examples/tasks/src/mock.rs    |  13 +-
 substrate/frame/examples/tasks/src/tests.rs   |   3 +-
 substrate/frame/examples/tasks/src/weights.rs |  78 +-
 substrate/frame/executive/src/tests.rs        | 269 ++++--
 substrate/frame/grandpa/src/equivocation.rs   |   7 +-
 substrate/frame/grandpa/src/mock.rs           |  13 +-
 substrate/frame/grandpa/src/tests.rs          |   2 +-
 substrate/frame/im-online/src/lib.rs          |   7 +-
 substrate/frame/im-online/src/mock.rs         |  21 +-
 substrate/frame/im-online/src/tests.rs        |   4 +-
 substrate/frame/lottery/src/lib.rs            |   2 +-
 .../frame/metadata-hash-extension/src/lib.rs  |  41 +-
 .../metadata-hash-extension/src/tests.rs      |  14 +-
 substrate/frame/mixnet/src/lib.rs             |   7 +-
 substrate/frame/multisig/src/lib.rs           |   4 +-
 substrate/frame/multisig/src/tests.rs         |  16 +-
 .../frame/offences/benchmarking/src/mock.rs   |  17 +-
 substrate/frame/proxy/src/lib.rs              |   4 +-
 substrate/frame/recovery/src/lib.rs           |   2 +-
 substrate/frame/revive/src/wasm/runtime.rs    |   4 +-
 substrate/frame/sassafras/src/lib.rs          |   7 +-
 substrate/frame/sassafras/src/mock.rs         |  17 +-
 substrate/frame/scheduler/src/lib.rs          |   2 +-
 substrate/frame/src/lib.rs                    |   6 +-
 substrate/frame/sudo/src/benchmarking.rs      |  34 +-
 substrate/frame/sudo/src/extension.rs         |  69 +-
 substrate/frame/sudo/src/lib.rs               |   8 +-
 substrate/frame/sudo/src/tests.rs             |   2 +-
 substrate/frame/sudo/src/weights.rs           |  21 +
 substrate/frame/support/Cargo.toml            |   4 +-
 .../src/construct_runtime/expand/inherent.rs  |  20 +-
 .../src/construct_runtime/expand/metadata.rs  |  20 +-
 .../src/construct_runtime/expand/origin.rs    |  20 +
 .../procedural/src/pallet/expand/call.rs      |   3 +-
 substrate/frame/support/src/dispatch.rs       | 555 ++++++++++-
 substrate/frame/support/src/lib.rs            |   7 +-
 substrate/frame/support/src/traits.rs         |   8 +-
 .../frame/support/src/traits/dispatch.rs      |  21 +-
 substrate/frame/support/src/traits/misc.rs    |  70 +-
 substrate/frame/support/test/Cargo.toml       |   5 +-
 .../undefined_inherent_part.stderr            |   5 +-
 .../support/test/tests/enum_deprecation.rs    |   8 +-
 substrate/frame/support/test/tests/pallet.rs  | 200 ++--
 .../support/test/tests/pallet_instance.rs     |  10 +-
 substrate/frame/support/test/tests/runtime.rs |  22 +-
 .../test/tests/runtime_legacy_ordering.rs     |  22 +-
 .../system/benchmarking/src/extensions.rs     | 248 +++++
 .../frame/system/benchmarking/src/lib.rs      |   1 +
 .../frame/system/benchmarking/src/mock.rs     |  38 +-
 .../system/src/extensions/check_genesis.rs    |  31 +-
 .../system/src/extensions/check_mortality.rs  |  88 +-
 .../src/extensions/check_non_zero_sender.rs   |  89 +-
 .../system/src/extensions/check_nonce.rs      | 334 +++++--
 .../src/extensions/check_spec_version.rs      |  30 +-
 .../system/src/extensions/check_tx_version.rs |  29 +-
 .../system/src/extensions/check_weight.rs     | 356 ++++---
 substrate/frame/system/src/extensions/mod.rs  |   3 +
 .../frame/system/src/extensions/weights.rs    | 217 +++++
 substrate/frame/system/src/lib.rs             |  43 +-
 substrate/frame/system/src/offchain.rs        | 103 +-
 substrate/frame/system/src/tests.rs           |  55 +-
 .../frame/transaction-payment/Cargo.toml      |   9 +
 .../asset-conversion-tx-payment/Cargo.toml    |  12 +
 .../asset-conversion-tx-payment/README.md     |   2 +-
 .../src/benchmarking.rs                       | 127 +++
 .../asset-conversion-tx-payment/src/lib.rs    | 301 ++++--
 .../asset-conversion-tx-payment/src/mock.rs   |  96 +-
 .../src/payment.rs                            |  56 +-
 .../asset-conversion-tx-payment/src/tests.rs  | 308 +++---
 .../src/weights.rs                            | 150 +++
 .../asset-tx-payment/Cargo.toml               |   1 +
 .../asset-tx-payment/README.md                |   2 +-
 .../asset-tx-payment/src/benchmarking.rs      | 131 +++
 .../asset-tx-payment/src/lib.rs               | 293 ++++--
 .../asset-tx-payment/src/mock.rs              |  79 +-
 .../asset-tx-payment/src/payment.rs           |  38 +
 .../asset-tx-payment/src/tests.rs             | 268 +++---
 .../asset-tx-payment/src/weights.rs           | 146 +++
 .../skip-feeless-payment/src/lib.rs           | 103 +-
 .../skip-feeless-payment/src/mock.rs          |  44 +-
 .../skip-feeless-payment/src/tests.rs         |  44 +-
 .../transaction-payment/src/benchmarking.rs   |  86 ++
 .../frame/transaction-payment/src/lib.rs      | 218 +++--
 .../frame/transaction-payment/src/mock.rs     |  19 +
 .../frame/transaction-payment/src/payment.rs  |  85 +-
 .../frame/transaction-payment/src/tests.rs    | 581 ++++++------
 .../frame/transaction-payment/src/types.rs    |   2 +-
 .../frame/transaction-payment/src/weights.rs  |  92 ++
 substrate/frame/utility/src/lib.rs            |   6 +-
 substrate/frame/utility/src/tests.rs          |  44 +-
 substrate/frame/verify-signature/Cargo.toml   |  70 ++
 substrate/frame/verify-signature/README.md    |  19 +
 .../verify-signature/src/benchmarking.rs      |  65 ++
 .../frame/verify-signature/src/extension.rs   | 157 +++
 substrate/frame/verify-signature/src/lib.rs   |  68 ++
 substrate/frame/verify-signature/src/tests.rs | 132 +++
 .../frame/verify-signature/src/weights.rs     |  75 ++
 substrate/frame/whitelist/src/benchmarking.rs |   2 +-
 substrate/frame/whitelist/src/lib.rs          |   4 +-
 substrate/frame/whitelist/src/tests.rs        |   6 +-
 substrate/primitives/consensus/pow/Cargo.toml |   7 +-
 .../primitives/consensus/slots/Cargo.toml     |   7 +-
 substrate/primitives/inherents/src/lib.rs     |   4 +-
 substrate/primitives/metadata-ir/src/lib.rs   |   2 +-
 substrate/primitives/metadata-ir/src/types.rs |  23 +-
 substrate/primitives/metadata-ir/src/v14.rs   |  12 +-
 substrate/primitives/metadata-ir/src/v15.rs   |  10 +-
 substrate/primitives/runtime/Cargo.toml       |   2 +
 .../primitives/runtime/src/generic/block.rs   |   2 +-
 .../runtime/src/generic/checked_extrinsic.rs  | 116 ++-
 .../primitives/runtime/src/generic/mod.rs     |   7 +-
 .../src/generic/unchecked_extrinsic.rs        | 890 +++++++++++++-----
 substrate/primitives/runtime/src/lib.rs       |  11 +-
 substrate/primitives/runtime/src/testing.rs   | 233 +----
 .../runtime/src/{traits.rs => traits/mod.rs}  | 343 ++++---
 .../as_transaction_extension.rs               | 130 +++
 .../dispatch_transaction.rs                   | 154 +++
 .../src/traits/transaction_extension/mod.rs   | 635 +++++++++++++
 .../runtime/src/transaction_validity.rs       |  10 +-
 substrate/primitives/storage/Cargo.toml       |   7 +-
 .../primitives/test-primitives/src/lib.rs     |  15 +-
 substrate/primitives/weights/Cargo.toml       |   4 +-
 substrate/scripts/run_all_benchmarks.sh       |  13 +
 substrate/test-utils/runtime/src/extrinsic.rs |  22 +-
 substrate/test-utils/runtime/src/lib.rs       |  97 +-
 .../benchmarking-cli/src/pallet/template.hbs  |   4 +
 .../frame/remote-externalities/src/lib.rs     |   5 +-
 substrate/utils/frame/rpc/client/src/lib.rs   |   5 +-
 templates/minimal/runtime/src/lib.rs          |   6 +-
 .../parachain/runtime/src/configs/mod.rs      |   1 +
 templates/parachain/runtime/src/lib.rs        |   6 +-
 templates/solochain/node/Cargo.toml           |   1 +
 templates/solochain/node/src/benchmarking.rs  |   6 +-
 templates/solochain/runtime/Cargo.toml        |  14 +-
 templates/solochain/runtime/src/apis.rs       |   2 +
 templates/solochain/runtime/src/benchmarks.rs |   1 +
 .../solochain/runtime/src/configs/mod.rs      |   1 +
 templates/solochain/runtime/src/lib.rs        |   8 +-
 umbrella/Cargo.toml                           |  12 +-
 umbrella/src/lib.rs                           |   4 +
 378 files changed, 17762 insertions(+), 6841 deletions(-)
 create mode 100644 cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/frame_system_extensions.rs
 create mode 100644 cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_asset_conversion_tx_payment.rs
 create mode 100644 cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_transaction_payment.rs
 create mode 100644 cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/frame_system_extensions.rs
 create mode 100644 cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_asset_conversion_tx_payment.rs
 create mode 100644 cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_transaction_payment.rs
 create mode 100644 cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/frame_system_extensions.rs
 create mode 100644 cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_transaction_payment.rs
 create mode 100644 cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/frame_system_extensions.rs
 create mode 100644 cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_transaction_payment.rs
 create mode 100644 cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/frame_system_extensions.rs
 create mode 100644 cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_transaction_payment.rs
 create mode 100644 cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/frame_system_extensions.rs
 create mode 100644 cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_transaction_payment.rs
 create mode 100644 cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/frame_system_extensions.rs
 create mode 100644 cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_transaction_payment.rs
 create mode 100644 cumulus/parachains/runtimes/glutton/glutton-westend/src/weights/frame_system_extensions.rs
 create mode 100644 cumulus/parachains/runtimes/people/people-rococo/src/weights/frame_system_extensions.rs
 create mode 100644 cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_transaction_payment.rs
 create mode 100644 cumulus/parachains/runtimes/people/people-westend/src/weights/frame_system_extensions.rs
 create mode 100644 cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_transaction_payment.rs
 create mode 100644 cumulus/primitives/storage-weight-reclaim/src/tests.rs
 create mode 100644 docs/sdk/src/reference_docs/transaction_extensions.rs
 create mode 100644 polkadot/runtime/rococo/src/weights/frame_system_extensions.rs
 create mode 100644 polkadot/runtime/rococo/src/weights/pallet_recovery.rs
 create mode 100644 polkadot/runtime/rococo/src/weights/pallet_transaction_payment.rs
 create mode 100644 polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_fungible.rs
 create mode 100644 polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_generic.rs
 create mode 100644 polkadot/runtime/rococo/src/weights/runtime_common_coretime.rs
 create mode 100644 polkadot/runtime/westend/src/weights/frame_system_extensions.rs
 create mode 100644 polkadot/runtime/westend/src/weights/pallet_transaction_payment.rs
 create mode 100644 prdoc/pr_3685.prdoc
 create mode 100644 substrate/frame/examples/authorization-tx-extension/Cargo.toml
 create mode 100644 substrate/frame/examples/authorization-tx-extension/src/extensions.rs
 create mode 100644 substrate/frame/examples/authorization-tx-extension/src/lib.rs
 create mode 100644 substrate/frame/examples/authorization-tx-extension/src/mock.rs
 create mode 100644 substrate/frame/examples/authorization-tx-extension/src/tests.rs
 create mode 100644 substrate/frame/system/benchmarking/src/extensions.rs
 create mode 100644 substrate/frame/system/src/extensions/weights.rs
 create mode 100644 substrate/frame/transaction-payment/asset-conversion-tx-payment/src/benchmarking.rs
 create mode 100644 substrate/frame/transaction-payment/asset-conversion-tx-payment/src/weights.rs
 create mode 100644 substrate/frame/transaction-payment/asset-tx-payment/src/benchmarking.rs
 create mode 100644 substrate/frame/transaction-payment/asset-tx-payment/src/weights.rs
 create mode 100644 substrate/frame/transaction-payment/src/benchmarking.rs
 create mode 100644 substrate/frame/transaction-payment/src/weights.rs
 create mode 100644 substrate/frame/verify-signature/Cargo.toml
 create mode 100644 substrate/frame/verify-signature/README.md
 create mode 100644 substrate/frame/verify-signature/src/benchmarking.rs
 create mode 100644 substrate/frame/verify-signature/src/extension.rs
 create mode 100644 substrate/frame/verify-signature/src/lib.rs
 create mode 100644 substrate/frame/verify-signature/src/tests.rs
 create mode 100644 substrate/frame/verify-signature/src/weights.rs
 rename substrate/primitives/runtime/src/{traits.rs => traits/mod.rs} (91%)
 create mode 100644 substrate/primitives/runtime/src/traits/transaction_extension/as_transaction_extension.rs
 create mode 100644 substrate/primitives/runtime/src/traits/transaction_extension/dispatch_transaction.rs
 create mode 100644 substrate/primitives/runtime/src/traits/transaction_extension/mod.rs

diff --git a/Cargo.lock b/Cargo.lock
index 846237e0374..4bb17e66dca 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1234,7 +1234,7 @@ dependencies = [
  "futures-lite 2.3.0",
  "parking",
  "polling 3.4.0",
- "rustix 0.38.21",
+ "rustix 0.38.25",
  "slab",
  "tracing",
  "windows-sys 0.52.0",
@@ -1316,7 +1316,7 @@ dependencies = [
  "cfg-if",
  "event-listener 5.2.0",
  "futures-lite 2.3.0",
- "rustix 0.38.21",
+ "rustix 0.38.25",
  "tracing",
 ]
 
@@ -1332,7 +1332,7 @@ dependencies = [
  "cfg-if",
  "futures-core",
  "futures-io",
- "rustix 0.38.21",
+ "rustix 0.38.25",
  "signal-hook-registry",
  "slab",
  "windows-sys 0.52.0",
@@ -2559,6 +2559,7 @@ dependencies = [
  "sp-runtime 31.0.1",
  "sp-std 14.0.0",
  "sp-trie 29.0.0",
+ "sp-weights 27.0.0",
  "staging-xcm",
  "static_assertions",
  "tuplex",
@@ -4554,6 +4555,7 @@ dependencies = [
  "cumulus-primitives-proof-size-hostfunction",
  "cumulus-test-runtime",
  "docify",
+ "frame-benchmarking",
  "frame-support",
  "frame-system",
  "log",
@@ -6654,7 +6656,7 @@ version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "29f9df8a11882c4e3335eb2d18a0137c505d9ca927470b0cac9c6f0ae07d28f7"
 dependencies = [
- "rustix 0.38.21",
+ "rustix 0.38.25",
  "windows-sys 0.48.0",
 ]
 
@@ -7845,7 +7847,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
 dependencies = [
  "hermit-abi 0.3.9",
- "rustix 0.38.21",
+ "rustix 0.38.25",
  "windows-sys 0.48.0",
 ]
 
@@ -9203,9 +9205,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
 
 [[package]]
 name = "linux-raw-sys"
-version = "0.4.10"
+version = "0.4.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f"
+checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829"
 
 [[package]]
 name = "lioness"
@@ -10690,6 +10692,7 @@ dependencies = [
 name = "pallet-asset-conversion-tx-payment"
 version = "10.0.0"
 dependencies = [
+ "frame-benchmarking",
  "frame-support",
  "frame-system",
  "pallet-asset-conversion",
@@ -11511,6 +11514,24 @@ dependencies = [
  "substrate-test-utils",
 ]
 
+[[package]]
+name = "pallet-example-authorization-tx-extension"
+version = "1.0.0"
+dependencies = [
+ "docify",
+ "frame-benchmarking",
+ "frame-support",
+ "frame-system",
+ "log",
+ "pallet-verify-signature",
+ "parity-scale-codec",
+ "scale-info",
+ "sp-core 28.0.0",
+ "sp-io 30.0.0",
+ "sp-keyring",
+ "sp-runtime 31.0.1",
+]
+
 [[package]]
 name = "pallet-example-basic"
 version = "27.0.0"
@@ -11636,6 +11657,7 @@ version = "4.0.0-dev"
 dependencies = [
  "pallet-default-config-example",
  "pallet-dev-mode",
+ "pallet-example-authorization-tx-extension",
  "pallet-example-basic",
  "pallet-example-frame-crate",
  "pallet-example-kitchensink",
@@ -12787,6 +12809,7 @@ dependencies = [
 name = "pallet-transaction-payment"
 version = "28.0.0"
 dependencies = [
+ "frame-benchmarking",
  "frame-support",
  "frame-system",
  "pallet-balances",
@@ -12918,6 +12941,25 @@ dependencies = [
  "sp-runtime 31.0.1",
 ]
 
+[[package]]
+name = "pallet-verify-signature"
+version = "1.0.0"
+dependencies = [
+ "frame-benchmarking",
+ "frame-support",
+ "frame-system",
+ "pallet-balances",
+ "pallet-collective",
+ "pallet-root-testing",
+ "pallet-timestamp",
+ "parity-scale-codec",
+ "scale-info",
+ "sp-core 28.0.0",
+ "sp-io 30.0.0",
+ "sp-runtime 31.0.1",
+ "sp-weights 27.0.0",
+]
+
 [[package]]
 name = "pallet-vesting"
 version = "28.0.0"
@@ -15286,6 +15328,7 @@ dependencies = [
  "pallet-tx-pause",
  "pallet-uniques",
  "pallet-utility",
+ "pallet-verify-signature",
  "pallet-vesting",
  "pallet-whitelist",
  "pallet-xcm",
@@ -15521,6 +15564,7 @@ dependencies = [
  "pallet-contracts",
  "pallet-default-config-example",
  "pallet-democracy",
+ "pallet-example-authorization-tx-extension",
  "pallet-example-offchain-worker",
  "pallet-example-single-block-migrations",
  "pallet-examples",
@@ -16281,7 +16325,7 @@ dependencies = [
  "cfg-if",
  "concurrent-queue",
  "pin-project-lite",
- "rustix 0.38.21",
+ "rustix 0.38.25",
  "tracing",
  "windows-sys 0.52.0",
 ]
@@ -16577,7 +16621,7 @@ dependencies = [
  "hex",
  "lazy_static",
  "procfs-core",
- "rustix 0.38.21",
+ "rustix 0.38.25",
 ]
 
 [[package]]
@@ -17996,14 +18040,14 @@ dependencies = [
 
 [[package]]
 name = "rustix"
-version = "0.38.21"
+version = "0.38.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3"
+checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e"
 dependencies = [
  "bitflags 2.6.0",
  "errno",
  "libc",
- "linux-raw-sys 0.4.10",
+ "linux-raw-sys 0.4.11",
  "windows-sys 0.48.0",
 ]
 
@@ -21863,7 +21907,7 @@ dependencies = [
 [[package]]
 name = "sp-crypto-ec-utils"
 version = "0.4.1"
-source = "git+https://github.com/paritytech/polkadot-sdk#82912acb33a9030c0ef3bf590a34fca09b72dc5f"
+source = "git+https://github.com/paritytech/polkadot-sdk#838a534da874cf6071fba1df07643c6c5b033ae0"
 dependencies = [
  "ark-bls12-377",
  "ark-bls12-377-ext",
@@ -22374,6 +22418,7 @@ dependencies = [
  "sp-weights 27.0.0",
  "substrate-test-runtime-client",
  "tracing",
+ "tuplex",
  "zstd 0.12.4",
 ]
 
@@ -22538,7 +22583,7 @@ dependencies = [
 [[package]]
 name = "sp-runtime-interface-proc-macro"
 version = "11.0.0"
-source = "git+https://github.com/paritytech/polkadot-sdk#82912acb33a9030c0ef3bf590a34fca09b72dc5f"
+source = "git+https://github.com/paritytech/polkadot-sdk#838a534da874cf6071fba1df07643c6c5b033ae0"
 dependencies = [
  "Inflector",
  "proc-macro-crate 1.3.1",
@@ -24359,7 +24404,7 @@ dependencies = [
  "cfg-if",
  "fastrand 2.1.0",
  "redox_syscall 0.4.1",
- "rustix 0.38.21",
+ "rustix 0.38.25",
  "windows-sys 0.48.0",
 ]
 
@@ -24389,7 +24434,7 @@ version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7"
 dependencies = [
- "rustix 0.38.21",
+ "rustix 0.38.25",
  "windows-sys 0.48.0",
 ]
 
diff --git a/Cargo.toml b/Cargo.toml
index 40d3615fed1..b357b99be11 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -347,6 +347,7 @@ members = [
 	"substrate/frame/election-provider-support/solution-type/fuzzer",
 	"substrate/frame/elections-phragmen",
 	"substrate/frame/examples",
+	"substrate/frame/examples/authorization-tx-extension",
 	"substrate/frame/examples/basic",
 	"substrate/frame/examples/default-config",
 	"substrate/frame/examples/dev-mode",
@@ -442,6 +443,7 @@ members = [
 	"substrate/frame/tx-pause",
 	"substrate/frame/uniques",
 	"substrate/frame/utility",
+	"substrate/frame/verify-signature",
 	"substrate/frame/vesting",
 	"substrate/frame/whitelist",
 	"substrate/primitives/api",
@@ -915,6 +917,7 @@ pallet-dev-mode = { path = "substrate/frame/examples/dev-mode", default-features
 pallet-election-provider-multi-phase = { path = "substrate/frame/election-provider-multi-phase", default-features = false }
 pallet-election-provider-support-benchmarking = { path = "substrate/frame/election-provider-support/benchmarking", default-features = false }
 pallet-elections-phragmen = { path = "substrate/frame/elections-phragmen", default-features = false }
+pallet-example-authorization-tx-extension = { path = "substrate/frame/examples/authorization-tx-extension", default-features = false }
 pallet-example-basic = { path = "substrate/frame/examples/basic", default-features = false }
 pallet-example-frame-crate = { path = "substrate/frame/examples/frame-crate", default-features = false }
 pallet-example-kitchensink = { path = "substrate/frame/examples/kitchensink", default-features = false }
@@ -991,6 +994,7 @@ pallet-treasury = { path = "substrate/frame/treasury", default-features = false
 pallet-tx-pause = { default-features = false, path = "substrate/frame/tx-pause" }
 pallet-uniques = { path = "substrate/frame/uniques", default-features = false }
 pallet-utility = { path = "substrate/frame/utility", default-features = false }
+pallet-verify-signature = { path = "substrate/frame/verify-signature", default-features = false }
 pallet-vesting = { path = "substrate/frame/vesting", default-features = false }
 pallet-whitelist = { path = "substrate/frame/whitelist", default-features = false }
 pallet-xcm = { path = "polkadot/xcm/pallet-xcm", default-features = false }
diff --git a/bridges/bin/runtime-common/Cargo.toml b/bridges/bin/runtime-common/Cargo.toml
index b8835d55f0d..37b56140c28 100644
--- a/bridges/bin/runtime-common/Cargo.toml
+++ b/bridges/bin/runtime-common/Cargo.toml
@@ -39,6 +39,7 @@ sp-io = { workspace = true }
 sp-runtime = { workspace = true }
 sp-std = { workspace = true }
 sp-trie = { optional = true, workspace = true }
+sp-weights = { workspace = true }
 
 # Polkadot dependencies
 xcm = { workspace = true }
@@ -80,6 +81,7 @@ std = [
 	"sp-runtime/std",
 	"sp-std/std",
 	"sp-trie/std",
+	"sp-weights/std",
 	"tuplex/std",
 	"xcm/std",
 ]
@@ -93,6 +95,7 @@ runtime-benchmarks = [
 	"pallet-bridge-messages/test-helpers",
 	"pallet-bridge-parachains/runtime-benchmarks",
 	"pallet-bridge-relayers/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"pallet-utility/runtime-benchmarks",
 	"sp-runtime/runtime-benchmarks",
 	"sp-trie",
diff --git a/bridges/bin/runtime-common/src/extensions.rs b/bridges/bin/runtime-common/src/extensions.rs
index dced5023947..19d1554c668 100644
--- a/bridges/bin/runtime-common/src/extensions.rs
+++ b/bridges/bin/runtime-common/src/extensions.rs
@@ -47,8 +47,7 @@ pub trait BridgeRuntimeFilterCall<AccountId, Call> {
 	/// Data that may be passed from the validate to `post_dispatch`.
 	type ToPostDispatch;
 	/// Called during validation. Needs to checks whether a runtime call, submitted
-	/// by the `who` is valid. `who` may be `None` if transaction is not signed
-	/// by a regular account.
+	/// by the `who` is valid. Transactions not signed are not validated.
 	fn validate(who: &AccountId, call: &Call) -> (Self::ToPostDispatch, TransactionValidity);
 	/// Called after transaction is dispatched.
 	fn post_dispatch(_who: &AccountId, _has_failed: bool, _to_post_dispatch: Self::ToPostDispatch) {
@@ -274,12 +273,10 @@ macro_rules! generate_bridge_reject_obsolete_headers_and_messages {
 	($call:ty, $account_id:ty, $($filter_call:ty),*) => {
 		#[derive(Clone, codec::Decode, Default, codec::Encode, Eq, PartialEq, sp_runtime::RuntimeDebug, scale_info::TypeInfo)]
 		pub struct BridgeRejectObsoleteHeadersAndMessages;
-		impl sp_runtime::traits::SignedExtension for BridgeRejectObsoleteHeadersAndMessages {
+		impl sp_runtime::traits::TransactionExtension<$call> for BridgeRejectObsoleteHeadersAndMessages {
 			const IDENTIFIER: &'static str = "BridgeRejectObsoleteHeadersAndMessages";
-			type AccountId = $account_id;
-			type Call = $call;
-			type AdditionalSigned = ();
-			type Pre = (
+			type Implicit = ();
+			type Val = Option<(
 				$account_id,
 				( $(
 					<$filter_call as $crate::extensions::BridgeRuntimeFilterCall<
@@ -287,72 +284,75 @@ macro_rules! generate_bridge_reject_obsolete_headers_and_messages {
 						$call,
 					>>::ToPostDispatch,
 				)* ),
-			);
+			)>;
+			type Pre = Self::Val;
 
-			fn additional_signed(&self) -> sp_std::result::Result<
-				(),
-				sp_runtime::transaction_validity::TransactionValidityError,
-			> {
-				Ok(())
+			fn weight(&self, _: &$call) -> frame_support::pallet_prelude::Weight {
+				frame_support::pallet_prelude::Weight::zero()
 			}
 
-			#[allow(unused_variables)]
 			fn validate(
 				&self,
-				who: &Self::AccountId,
-				call: &Self::Call,
-				_info: &sp_runtime::traits::DispatchInfoOf<Self::Call>,
+				origin: <$call as sp_runtime::traits::Dispatchable>::RuntimeOrigin,
+				call: &$call,
+				_info: &sp_runtime::traits::DispatchInfoOf<$call>,
 				_len: usize,
-			) -> sp_runtime::transaction_validity::TransactionValidity {
+				_self_implicit: Self::Implicit,
+				_inherited_implication: &impl codec::Encode,
+			) -> Result<
+				(
+					sp_runtime::transaction_validity::ValidTransaction,
+					Self::Val,
+					<$call as sp_runtime::traits::Dispatchable>::RuntimeOrigin,
+				), sp_runtime::transaction_validity::TransactionValidityError
+			> {
+				use $crate::extensions::__private::tuplex::PushBack;
+				use sp_runtime::traits::AsSystemOriginSigner;
+
+				let Some(who) = origin.as_system_origin_signer() else {
+					return Ok((Default::default(), None, origin));
+				};
+
+				let to_post_dispatch = ();
 				let tx_validity = sp_runtime::transaction_validity::ValidTransaction::default();
-				let to_prepare = ();
 				$(
 					let (from_validate, call_filter_validity) = <
 						$filter_call as
 						$crate::extensions::BridgeRuntimeFilterCall<
-							Self::AccountId,
+							$account_id,
 							$call,
-						>>::validate(&who, call);
+						>>::validate(who, call);
+					let to_post_dispatch = to_post_dispatch.push_back(from_validate);
 					let tx_validity = tx_validity.combine_with(call_filter_validity?);
 				)*
-				Ok(tx_validity)
+				Ok((tx_validity, Some((who.clone(), to_post_dispatch)), origin))
 			}
 
-			#[allow(unused_variables)]
-			fn pre_dispatch(
+			fn prepare(
 				self,
-				relayer: &Self::AccountId,
-				call: &Self::Call,
-				info: &sp_runtime::traits::DispatchInfoOf<Self::Call>,
-				len: usize,
+				val: Self::Val,
+				_origin: &<$call as sp_runtime::traits::Dispatchable>::RuntimeOrigin,
+				_call: &$call,
+				_info: &sp_runtime::traits::DispatchInfoOf<$call>,
+				_len: usize,
 			) -> Result<Self::Pre, sp_runtime::transaction_validity::TransactionValidityError> {
-				use $crate::extensions::__private::tuplex::PushBack;
-
-				let to_post_dispatch = ();
-				$(
-					let (from_validate, call_filter_validity) = <
-						$filter_call as
-						$crate::extensions::BridgeRuntimeFilterCall<
-							$account_id,
-							$call,
-						>>::validate(&relayer, call);
-					let _ = call_filter_validity?;
-					let to_post_dispatch = to_post_dispatch.push_back(from_validate);
-				)*
-				Ok((relayer.clone(), to_post_dispatch))
+				Ok(val)
 			}
 
 			#[allow(unused_variables)]
-			fn post_dispatch(
-				to_post_dispatch: Option<Self::Pre>,
-				info: &sp_runtime::traits::DispatchInfoOf<Self::Call>,
-				post_info: &sp_runtime::traits::PostDispatchInfoOf<Self::Call>,
+			fn post_dispatch_details(
+				to_post_dispatch: Self::Pre,
+				info: &sp_runtime::traits::DispatchInfoOf<$call>,
+				post_info: &sp_runtime::traits::PostDispatchInfoOf<$call>,
 				len: usize,
 				result: &sp_runtime::DispatchResult,
-			) -> Result<(), sp_runtime::transaction_validity::TransactionValidityError> {
+			) -> Result<frame_support::pallet_prelude::Weight, sp_runtime::transaction_validity::TransactionValidityError> {
 				use $crate::extensions::__private::tuplex::PopFront;
 
-				let Some((relayer, to_post_dispatch)) = to_post_dispatch else { return Ok(()) };
+				let Some((relayer, to_post_dispatch)) = to_post_dispatch else {
+					return Ok(frame_support::pallet_prelude::Weight::zero())
+				};
+
 				let has_failed = result.is_err();
 				$(
 					let (item, to_post_dispatch) = to_post_dispatch.pop_front();
@@ -363,7 +363,7 @@ macro_rules! generate_bridge_reject_obsolete_headers_and_messages {
 							$call,
 						>>::post_dispatch(&relayer, has_failed, item);
 				)*
-				Ok(())
+				Ok(frame_support::pallet_prelude::Weight::zero())
 			}
 		}
 	};
@@ -380,11 +380,16 @@ mod tests {
 	use bp_relayers::{RewardsAccountOwner, RewardsAccountParams};
 	use bp_runtime::HeaderId;
 	use bp_test_utils::{make_default_justification, test_keyring, TEST_GRANDPA_SET_ID};
+	use codec::{Decode, Encode, MaxEncodedLen};
 	use frame_support::{assert_err, assert_ok, traits::fungible::Mutate};
 	use pallet_bridge_grandpa::{Call as GrandpaCall, StoredAuthoritySet};
 	use pallet_bridge_parachains::Call as ParachainsCall;
+	use scale_info::TypeInfo;
 	use sp_runtime::{
-		traits::{parameter_types, ConstU64, Header as _, SignedExtension},
+		traits::{
+			parameter_types, AsSystemOriginSigner, AsTransactionAuthorizedOrigin, ConstU64,
+			DispatchTransaction, Header as _, TransactionExtension,
+		},
 		transaction_validity::{InvalidTransaction, TransactionValidity, ValidTransaction},
 		DispatchError,
 	};
@@ -402,12 +407,34 @@ mod tests {
 		);
 	}
 
+	#[derive(Debug, Clone, PartialEq, Encode, Decode, TypeInfo, MaxEncodedLen)]
 	pub struct MockCall {
 		data: u32,
 	}
 
+	#[derive(Debug, Clone, PartialEq, Encode, Decode, TypeInfo, MaxEncodedLen)]
+	pub struct MockOrigin(pub u64);
+
+	impl AsSystemOriginSigner<u64> for MockOrigin {
+		fn as_system_origin_signer(&self) -> Option<&u64> {
+			Some(&self.0)
+		}
+	}
+
+	impl AsTransactionAuthorizedOrigin for MockOrigin {
+		fn is_transaction_authorized(&self) -> bool {
+			true
+		}
+	}
+
+	impl From<u64> for MockOrigin {
+		fn from(o: u64) -> Self {
+			Self(o)
+		}
+	}
+
 	impl sp_runtime::traits::Dispatchable for MockCall {
-		type RuntimeOrigin = u64;
+		type RuntimeOrigin = MockOrigin;
 		type Config = ();
 		type Info = ();
 		type PostInfo = ();
@@ -579,12 +606,17 @@ mod tests {
 
 		run_test(|| {
 			assert_err!(
-				BridgeRejectObsoleteHeadersAndMessages.validate(&42, &MockCall { data: 1 }, &(), 0),
+				BridgeRejectObsoleteHeadersAndMessages.validate_only(
+					42u64.into(),
+					&MockCall { data: 1 },
+					&(),
+					0
+				),
 				InvalidTransaction::Custom(1)
 			);
 			assert_err!(
-				BridgeRejectObsoleteHeadersAndMessages.pre_dispatch(
-					&42,
+				BridgeRejectObsoleteHeadersAndMessages.validate_and_prepare(
+					42u64.into(),
 					&MockCall { data: 1 },
 					&(),
 					0
@@ -593,12 +625,17 @@ mod tests {
 			);
 
 			assert_err!(
-				BridgeRejectObsoleteHeadersAndMessages.validate(&42, &MockCall { data: 2 }, &(), 0),
+				BridgeRejectObsoleteHeadersAndMessages.validate_only(
+					42u64.into(),
+					&MockCall { data: 2 },
+					&(),
+					0
+				),
 				InvalidTransaction::Custom(2)
 			);
 			assert_err!(
-				BridgeRejectObsoleteHeadersAndMessages.pre_dispatch(
-					&42,
+				BridgeRejectObsoleteHeadersAndMessages.validate_and_prepare(
+					42u64.into(),
 					&MockCall { data: 2 },
 					&(),
 					0
@@ -608,37 +645,40 @@ mod tests {
 
 			assert_eq!(
 				BridgeRejectObsoleteHeadersAndMessages
-					.validate(&42, &MockCall { data: 3 }, &(), 0)
-					.unwrap(),
+					.validate_only(42u64.into(), &MockCall { data: 3 }, &(), 0)
+					.unwrap()
+					.0,
 				ValidTransaction { priority: 3, ..Default::default() },
 			);
 			assert_eq!(
 				BridgeRejectObsoleteHeadersAndMessages
-					.pre_dispatch(&42, &MockCall { data: 3 }, &(), 0)
+					.validate_and_prepare(42u64.into(), &MockCall { data: 3 }, &(), 0)
+					.unwrap()
+					.0
 					.unwrap(),
 				(42, (1, 2)),
 			);
 
 			// when post_dispatch is called with `Ok(())`, it is propagated to all "nested"
 			// extensions
-			assert_ok!(BridgeRejectObsoleteHeadersAndMessages::post_dispatch(
+			assert_ok!(BridgeRejectObsoleteHeadersAndMessages::post_dispatch_details(
 				Some((0, (1, 2))),
 				&(),
 				&(),
 				0,
-				&Ok(())
+				&Ok(()),
 			));
 			FirstFilterCall::verify_post_dispatch_called_with(true);
 			SecondFilterCall::verify_post_dispatch_called_with(true);
 
 			// when post_dispatch is called with `Err(())`, it is propagated to all "nested"
 			// extensions
-			assert_ok!(BridgeRejectObsoleteHeadersAndMessages::post_dispatch(
+			assert_ok!(BridgeRejectObsoleteHeadersAndMessages::post_dispatch_details(
 				Some((0, (1, 2))),
 				&(),
 				&(),
 				0,
-				&Err(DispatchError::BadOrigin)
+				&Err(DispatchError::BadOrigin),
 			));
 			FirstFilterCall::verify_post_dispatch_called_with(false);
 			SecondFilterCall::verify_post_dispatch_called_with(false);
diff --git a/bridges/bin/runtime-common/src/mock.rs b/bridges/bin/runtime-common/src/mock.rs
index 1d4043fc4b6..6cf04b452da 100644
--- a/bridges/bin/runtime-common/src/mock.rs
+++ b/bridges/bin/runtime-common/src/mock.rs
@@ -162,7 +162,6 @@ impl pallet_transaction_payment::Config for TestRuntime {
 		MinimumMultiplier,
 		MaximumMultiplier,
 	>;
-	type RuntimeEvent = RuntimeEvent;
 }
 
 impl pallet_bridge_grandpa::Config for TestRuntime {
diff --git a/bridges/chains/chain-bridge-hub-cumulus/src/lib.rs b/bridges/chains/chain-bridge-hub-cumulus/src/lib.rs
index a5c90ceba11..f626fa6df01 100644
--- a/bridges/chains/chain-bridge-hub-cumulus/src/lib.rs
+++ b/bridges/chains/chain-bridge-hub-cumulus/src/lib.rs
@@ -26,7 +26,7 @@ pub use bp_polkadot_core::{
 };
 
 use bp_messages::*;
-use bp_polkadot_core::SuffixedCommonSignedExtension;
+use bp_polkadot_core::SuffixedCommonTransactionExtension;
 use bp_runtime::extensions::{
 	BridgeRejectObsoleteHeadersAndMessages, RefundBridgedParachainMessagesSchema,
 };
@@ -167,7 +167,7 @@ pub const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = 1024;
 pub const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = 4096;
 
 /// Signed extension that is used by all bridge hubs.
-pub type SignedExtension = SuffixedCommonSignedExtension<(
+pub type TransactionExtension = SuffixedCommonTransactionExtension<(
 	BridgeRejectObsoleteHeadersAndMessages,
 	RefundBridgedParachainMessagesSchema,
 )>;
diff --git a/bridges/chains/chain-bridge-hub-rococo/src/lib.rs b/bridges/chains/chain-bridge-hub-rococo/src/lib.rs
index 538bc44019f..fda6a5f0b72 100644
--- a/bridges/chains/chain-bridge-hub-rococo/src/lib.rs
+++ b/bridges/chains/chain-bridge-hub-rococo/src/lib.rs
@@ -109,11 +109,11 @@ frame_support::parameter_types! {
 
 	/// Transaction fee that is paid at the Rococo BridgeHub for delivering single inbound message.
 	/// (initially was calculated by test `BridgeHubRococo::can_calculate_fee_for_standalone_message_delivery_transaction` + `33%`)
-	pub const BridgeHubRococoBaseDeliveryFeeInRocs: u128 = 297_644_174;
+	pub const BridgeHubRococoBaseDeliveryFeeInRocs: u128 = 297_685_840;
 
 	/// Transaction fee that is paid at the Rococo BridgeHub for delivering single outbound message confirmation.
 	/// (initially was calculated by test `BridgeHubRococo::can_calculate_fee_for_standalone_message_confirmation_transaction` + `33%`)
-	pub const BridgeHubRococoBaseConfirmationFeeInRocs: u128 = 56_740_432;
+	pub const BridgeHubRococoBaseConfirmationFeeInRocs: u128 = 56_782_099;
 }
 
 /// Wrapper over `BridgeHubRococo`'s `RuntimeCall` that can be used without a runtime.
diff --git a/bridges/chains/chain-bridge-hub-westend/src/lib.rs b/bridges/chains/chain-bridge-hub-westend/src/lib.rs
index 7a213fdb28c..e941b584023 100644
--- a/bridges/chains/chain-bridge-hub-westend/src/lib.rs
+++ b/bridges/chains/chain-bridge-hub-westend/src/lib.rs
@@ -98,11 +98,11 @@ frame_support::parameter_types! {
 
 	/// Transaction fee that is paid at the Westend BridgeHub for delivering single inbound message.
 	/// (initially was calculated by test `BridgeHubWestend::can_calculate_fee_for_standalone_message_delivery_transaction` + `33%`)
-	pub const BridgeHubWestendBaseDeliveryFeeInWnds: u128 = 89_293_427_116;
+	pub const BridgeHubWestendBaseDeliveryFeeInWnds: u128 = 89_305_927_116;
 
 	/// Transaction fee that is paid at the Westend BridgeHub for delivering single outbound message confirmation.
 	/// (initially was calculated by test `BridgeHubWestend::can_calculate_fee_for_standalone_message_confirmation_transaction` + `33%`)
-	pub const BridgeHubWestendBaseConfirmationFeeInWnds: u128 = 17_022_177_116;
+	pub const BridgeHubWestendBaseConfirmationFeeInWnds: u128 = 17_034_677_116;
 }
 
 /// Wrapper over `BridgeHubWestend`'s `RuntimeCall` that can be used without a runtime.
diff --git a/bridges/chains/chain-kusama/src/lib.rs b/bridges/chains/chain-kusama/src/lib.rs
index dcd0b23abbb..f1f30c4484e 100644
--- a/bridges/chains/chain-kusama/src/lib.rs
+++ b/bridges/chains/chain-kusama/src/lib.rs
@@ -61,8 +61,8 @@ impl ChainWithGrandpa for Kusama {
 	const AVERAGE_HEADER_SIZE: u32 = AVERAGE_HEADER_SIZE;
 }
 
-// The SignedExtension used by Kusama.
-pub use bp_polkadot_core::CommonSignedExtension as SignedExtension;
+// The TransactionExtension used by Kusama.
+pub use bp_polkadot_core::CommonTransactionExtension as TransactionExtension;
 
 /// Name of the parachains pallet in the Kusama runtime.
 pub const PARAS_PALLET_NAME: &str = "Paras";
diff --git a/bridges/chains/chain-polkadot-bulletin/src/lib.rs b/bridges/chains/chain-polkadot-bulletin/src/lib.rs
index d0093691972..c5c18beb2ca 100644
--- a/bridges/chains/chain-polkadot-bulletin/src/lib.rs
+++ b/bridges/chains/chain-polkadot-bulletin/src/lib.rs
@@ -25,7 +25,7 @@ use bp_runtime::{
 	decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis,
 	extensions::{
 		CheckEra, CheckGenesis, CheckNonZeroSender, CheckNonce, CheckSpecVersion, CheckTxVersion,
-		CheckWeight, GenericSignedExtension, GenericSignedExtensionSchema,
+		CheckWeight, GenericTransactionExtension, GenericTransactionExtensionSchema,
 	},
 	Chain, ChainId, TransactionEra,
 };
@@ -38,7 +38,8 @@ use frame_support::{
 use frame_system::limits;
 use scale_info::TypeInfo;
 use sp_runtime::{
-	traits::DispatchInfoOf, transaction_validity::TransactionValidityError, Perbill, StateVersion,
+	impl_tx_ext_default, traits::Dispatchable, transaction_validity::TransactionValidityError,
+	Perbill, StateVersion,
 };
 
 // This chain reuses most of Polkadot primitives.
@@ -73,10 +74,10 @@ pub const MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX: MessageNonce = 1024;
 pub const MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX: MessageNonce = 4096;
 
 /// This signed extension is used to ensure that the chain transactions are signed by proper
-pub type ValidateSigned = GenericSignedExtensionSchema<(), ()>;
+pub type ValidateSigned = GenericTransactionExtensionSchema<(), ()>;
 
 /// Signed extension schema, used by Polkadot Bulletin.
-pub type SignedExtensionSchema = GenericSignedExtension<(
+pub type TransactionExtensionSchema = GenericTransactionExtension<(
 	(
 		CheckNonZeroSender,
 		CheckSpecVersion,
@@ -89,34 +90,30 @@ pub type SignedExtensionSchema = GenericSignedExtension<(
 	ValidateSigned,
 )>;
 
-/// Signed extension, used by Polkadot Bulletin.
+/// Transaction extension, used by Polkadot Bulletin.
 #[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
-pub struct SignedExtension(SignedExtensionSchema);
+pub struct TransactionExtension(TransactionExtensionSchema);
 
-impl sp_runtime::traits::SignedExtension for SignedExtension {
+impl<C> sp_runtime::traits::TransactionExtension<C> for TransactionExtension
+where
+	C: Dispatchable,
+{
 	const IDENTIFIER: &'static str = "Not needed.";
-	type AccountId = ();
-	type Call = ();
-	type AdditionalSigned =
-		<SignedExtensionSchema as sp_runtime::traits::SignedExtension>::AdditionalSigned;
-	type Pre = ();
+	type Implicit =
+		<TransactionExtensionSchema as sp_runtime::traits::TransactionExtension<C>>::Implicit;
 
-	fn additional_signed(&self) -> Result<Self::AdditionalSigned, TransactionValidityError> {
-		self.0.additional_signed()
+	fn implicit(&self) -> Result<Self::Implicit, TransactionValidityError> {
+		<TransactionExtensionSchema as sp_runtime::traits::TransactionExtension<C>>::implicit(
+			&self.0,
+		)
 	}
+	type Pre = ();
+	type Val = ();
 
-	fn pre_dispatch(
-		self,
-		_who: &Self::AccountId,
-		_call: &Self::Call,
-		_info: &DispatchInfoOf<Self::Call>,
-		_len: usize,
-	) -> Result<Self::Pre, TransactionValidityError> {
-		Ok(())
-	}
+	impl_tx_ext_default!(C; weight validate prepare);
 }
 
-impl SignedExtension {
+impl TransactionExtension {
 	/// Create signed extension from its components.
 	pub fn from_params(
 		spec_version: u32,
@@ -125,7 +122,7 @@ impl SignedExtension {
 		genesis_hash: Hash,
 		nonce: Nonce,
 	) -> Self {
-		Self(GenericSignedExtension::new(
+		Self(GenericTransactionExtension::new(
 			(
 				(
 					(),              // non-zero sender
diff --git a/bridges/chains/chain-polkadot/src/lib.rs b/bridges/chains/chain-polkadot/src/lib.rs
index f4b262d4073..5d2f9e4aa9e 100644
--- a/bridges/chains/chain-polkadot/src/lib.rs
+++ b/bridges/chains/chain-polkadot/src/lib.rs
@@ -63,8 +63,8 @@ impl ChainWithGrandpa for Polkadot {
 	const AVERAGE_HEADER_SIZE: u32 = AVERAGE_HEADER_SIZE;
 }
 
-/// The SignedExtension used by Polkadot.
-pub type SignedExtension = SuffixedCommonSignedExtension<PrevalidateAttests>;
+/// The TransactionExtension used by Polkadot.
+pub type TransactionExtension = SuffixedCommonTransactionExtension<PrevalidateAttests>;
 
 /// Name of the parachains pallet in the Polkadot runtime.
 pub const PARAS_PALLET_NAME: &str = "Paras";
diff --git a/bridges/chains/chain-rococo/src/lib.rs b/bridges/chains/chain-rococo/src/lib.rs
index bfcafdf41ea..2827d1f137b 100644
--- a/bridges/chains/chain-rococo/src/lib.rs
+++ b/bridges/chains/chain-rococo/src/lib.rs
@@ -61,8 +61,8 @@ impl ChainWithGrandpa for Rococo {
 	const AVERAGE_HEADER_SIZE: u32 = AVERAGE_HEADER_SIZE;
 }
 
-// The SignedExtension used by Rococo.
-pub use bp_polkadot_core::CommonSignedExtension as SignedExtension;
+// The TransactionExtension used by Rococo.
+pub use bp_polkadot_core::CommonTransactionExtension as TransactionExtension;
 
 /// Name of the parachains pallet in the Rococo runtime.
 pub const PARAS_PALLET_NAME: &str = "Paras";
diff --git a/bridges/chains/chain-westend/src/lib.rs b/bridges/chains/chain-westend/src/lib.rs
index 2a247e03e59..2b0a609115b 100644
--- a/bridges/chains/chain-westend/src/lib.rs
+++ b/bridges/chains/chain-westend/src/lib.rs
@@ -61,8 +61,8 @@ impl ChainWithGrandpa for Westend {
 	const AVERAGE_HEADER_SIZE: u32 = AVERAGE_HEADER_SIZE;
 }
 
-// The SignedExtension used by Westend.
-pub use bp_polkadot_core::CommonSignedExtension as SignedExtension;
+// The TransactionExtension used by Westend.
+pub use bp_polkadot_core::CommonTransactionExtension as TransactionExtension;
 
 /// Name of the parachains pallet in the Rococo runtime.
 pub const PARAS_PALLET_NAME: &str = "Paras";
diff --git a/bridges/modules/relayers/Cargo.toml b/bridges/modules/relayers/Cargo.toml
index 0bf889bcca0..04e7b52ed86 100644
--- a/bridges/modules/relayers/Cargo.toml
+++ b/bridges/modules/relayers/Cargo.toml
@@ -79,6 +79,7 @@ runtime-benchmarks = [
 	"pallet-bridge-grandpa/runtime-benchmarks",
 	"pallet-bridge-messages/runtime-benchmarks",
 	"pallet-bridge-parachains/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"pallet-utility/runtime-benchmarks",
 	"sp-runtime/runtime-benchmarks",
 ]
diff --git a/bridges/modules/relayers/src/extension/mod.rs b/bridges/modules/relayers/src/extension/mod.rs
index 9a248eb8e79..710533c223a 100644
--- a/bridges/modules/relayers/src/extension/mod.rs
+++ b/bridges/modules/relayers/src/extension/mod.rs
@@ -33,6 +33,7 @@ use bp_runtime::{Chain, RangeInclusiveExt, StaticStrProvider};
 use codec::{Decode, Encode};
 use frame_support::{
 	dispatch::{DispatchInfo, PostDispatchInfo},
+	weights::Weight,
 	CloneNoBound, DefaultNoBound, EqNoBound, PartialEqNoBound, RuntimeDebugNoBound,
 };
 use frame_system::Config as SystemConfig;
@@ -44,10 +45,11 @@ use pallet_transaction_payment::{
 };
 use scale_info::TypeInfo;
 use sp_runtime::{
-	traits::{DispatchInfoOf, Dispatchable, PostDispatchInfoOf, SignedExtension, Zero},
-	transaction_validity::{
-		TransactionValidity, TransactionValidityError, ValidTransactionBuilder,
+	traits::{
+		AsSystemOriginSigner, DispatchInfoOf, Dispatchable, PostDispatchInfoOf,
+		TransactionExtension, ValidateResult, Zero,
 	},
+	transaction_validity::{InvalidTransaction, TransactionValidityError, ValidTransactionBuilder},
 	DispatchResult, RuntimeDebug,
 };
 use sp_std::{fmt::Debug, marker::PhantomData};
@@ -62,7 +64,7 @@ mod messages_adapter;
 mod parachain_adapter;
 mod priority;
 
-/// Data that is crafted in `pre_dispatch` method and used at `post_dispatch`.
+/// Data that is crafted in `validate`, passed to `prepare` and used at `post_dispatch` method.
 #[cfg_attr(test, derive(Debug, PartialEq))]
 pub struct PreDispatchData<
 	AccountId,
@@ -78,7 +80,7 @@ pub struct PreDispatchData<
 impl<AccountId, RemoteGrandpaChainBlockNumber: Debug, LaneId: Clone + Copy + Debug>
 	PreDispatchData<AccountId, RemoteGrandpaChainBlockNumber, LaneId>
 {
-	/// Returns mutable reference to pre-dispatch `finality_target` sent to the
+	/// Returns mutable reference to `finality_target` sent to the
 	/// `SubmitFinalityProof` call.
 	#[cfg(test)]
 	pub fn submit_finality_proof_info_mut(
@@ -119,11 +121,11 @@ pub enum RelayerAccountAction<AccountId, Reward, LaneId> {
 	TypeInfo,
 )]
 #[scale_info(skip_type_params(Runtime, Config, LaneId))]
-pub struct BridgeRelayersSignedExtension<Runtime, Config, LaneId>(
+pub struct BridgeRelayersTransactionExtension<Runtime, Config, LaneId>(
 	PhantomData<(Runtime, Config, LaneId)>,
 );
 
-impl<R, C, LaneId> BridgeRelayersSignedExtension<R, C, LaneId>
+impl<R, C, LaneId> BridgeRelayersTransactionExtension<R, C, LaneId>
 where
 	Self: 'static + Send + Sync,
 	R: RelayersConfig<LaneId = LaneId>
@@ -131,6 +133,7 @@ where
 		+ TransactionPaymentConfig,
 	C: ExtensionConfig<Runtime = R, LaneId = LaneId>,
 	R::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
+	<R::RuntimeCall as Dispatchable>::RuntimeOrigin: AsSystemOriginSigner<R::AccountId> + Clone,
 	<R as TransactionPaymentConfig>::OnChargeTransaction:
 		OnChargeTransaction<R, Balance = R::Reward>,
 	LaneId: Clone + Copy + Decode + Encode + Debug + TypeInfo,
@@ -145,13 +148,12 @@ where
 	/// virtually boosted. The relayer registration (we only boost priority for registered
 	/// relayer transactions) must be checked outside.
 	fn bundled_messages_for_priority_boost(
-		call_info: Option<&ExtensionCallInfo<C::RemoteGrandpaChainBlockNumber, LaneId>>,
+		parsed_call: &ExtensionCallInfo<C::RemoteGrandpaChainBlockNumber, LaneId>,
 	) -> Option<MessageNonce> {
 		// we only boost priority of message delivery transactions
-		let parsed_call = match call_info {
-			Some(parsed_call) if parsed_call.is_receive_messages_proof_call() => parsed_call,
-			_ => return None,
-		};
+		if !parsed_call.is_receive_messages_proof_call() {
+			return None;
+		}
 
 		// compute total number of messages in transaction
 		let bundled_messages = parsed_call.messages_call_info().bundled_messages().saturating_len();
@@ -169,9 +171,7 @@ where
 	/// Given post-dispatch information, analyze the outcome of relayer call and return
 	/// actions that need to be performed on relayer account.
 	fn analyze_call_result(
-		pre: Option<
-			Option<PreDispatchData<R::AccountId, C::RemoteGrandpaChainBlockNumber, LaneId>>,
-		>,
+		pre: Option<PreDispatchData<R::AccountId, C::RemoteGrandpaChainBlockNumber, LaneId>>,
 		info: &DispatchInfo,
 		post_info: &PostDispatchInfo,
 		len: usize,
@@ -179,7 +179,7 @@ where
 	) -> RelayerAccountAction<R::AccountId, R::Reward, LaneId> {
 		// We don't refund anything for transactions that we don't support.
 		let (relayer, call_info) = match pre {
-			Some(Some(pre)) => (pre.relayer, pre.call_info),
+			Some(pre) => (pre.relayer, pre.call_info),
 			_ => return RelayerAccountAction::None,
 		};
 
@@ -201,15 +201,14 @@ where
 		//
 		// we are not checking if relayer is registered here - it happens during the slash attempt
 		//
-		// there are couple of edge cases here:
+		// there are a couple of edge cases here:
 		//
 		// - when the relayer becomes registered during message dispatch: this is unlikely + relayer
 		//   should be ready for slashing after registration;
 		//
 		// - when relayer is registered after `validate` is called and priority is not boosted:
 		//   relayer should be ready for slashing after registration.
-		let may_slash_relayer =
-			Self::bundled_messages_for_priority_boost(Some(&call_info)).is_some();
+		let may_slash_relayer = Self::bundled_messages_for_priority_boost(&call_info).is_some();
 		let slash_relayer_if_delivery_result = may_slash_relayer
 			.then(|| RelayerAccountAction::Slash(relayer.clone(), reward_account_params))
 			.unwrap_or(RelayerAccountAction::None);
@@ -244,7 +243,7 @@ where
 		let post_info_len = len.saturating_sub(call_data.extra_size as usize);
 		let mut post_info_weight = post_info
 			.actual_weight
-			.unwrap_or(info.weight)
+			.unwrap_or(info.total_weight())
 			.saturating_sub(call_data.extra_weight);
 
 		// let's also replace the weight of slashing relayer with the weight of rewarding relayer
@@ -274,7 +273,8 @@ where
 	}
 }
 
-impl<R, C, LaneId> SignedExtension for BridgeRelayersSignedExtension<R, C, LaneId>
+impl<R, C, LaneId> TransactionExtension<R::RuntimeCall>
+	for BridgeRelayersTransactionExtension<R, C, LaneId>
 where
 	Self: 'static + Send + Sync,
 	R: RelayersConfig<LaneId = LaneId>
@@ -282,46 +282,50 @@ where
 		+ TransactionPaymentConfig,
 	C: ExtensionConfig<Runtime = R, LaneId = LaneId>,
 	R::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
+	<R::RuntimeCall as Dispatchable>::RuntimeOrigin: AsSystemOriginSigner<R::AccountId> + Clone,
 	<R as TransactionPaymentConfig>::OnChargeTransaction:
 		OnChargeTransaction<R, Balance = R::Reward>,
 	LaneId: Clone + Copy + Decode + Encode + Debug + TypeInfo,
 {
 	const IDENTIFIER: &'static str = C::IdProvider::STR;
-	type AccountId = R::AccountId;
-	type Call = R::RuntimeCall;
-	type AdditionalSigned = ();
+	type Implicit = ();
 	type Pre = Option<PreDispatchData<R::AccountId, C::RemoteGrandpaChainBlockNumber, LaneId>>;
+	type Val = Self::Pre;
 
-	fn additional_signed(&self) -> Result<(), TransactionValidityError> {
-		Ok(())
+	fn weight(&self, _call: &R::RuntimeCall) -> Weight {
+		Weight::zero()
 	}
 
 	fn validate(
 		&self,
-		who: &Self::AccountId,
-		call: &Self::Call,
-		_info: &DispatchInfoOf<Self::Call>,
+		origin: <R::RuntimeCall as Dispatchable>::RuntimeOrigin,
+		call: &R::RuntimeCall,
+		_info: &DispatchInfoOf<R::RuntimeCall>,
 		_len: usize,
-	) -> TransactionValidity {
-		// this is the only relevant line of code for the `pre_dispatch`
-		//
-		// we're not calling `validate` from `pre_dispatch` directly because of performance
-		// reasons, so if you're adding some code that may fail here, please check if it needs
-		// to be added to the `pre_dispatch` as well
-		let parsed_call = C::parse_and_check_for_obsolete_call(call)?;
+		_self_implicit: Self::Implicit,
+		_inherited_implication: &impl Encode,
+	) -> ValidateResult<Self::Val, R::RuntimeCall> {
+		// Prepare relevant data for `prepare`
+		let parsed_call = match C::parse_and_check_for_obsolete_call(call)? {
+			Some(parsed_call) => parsed_call,
+			None => return Ok((Default::default(), None, origin)),
+		};
+		// Those calls are only for signed transactions.
+		let relayer = origin.as_system_origin_signer().ok_or(InvalidTransaction::BadSigner)?;
+
+		let data = PreDispatchData { relayer: relayer.clone(), call_info: parsed_call };
 
-		// the following code just plays with transaction priority and never returns an error
+		// the following code just plays with transaction priority
 
 		// we only boost priority of presumably correct message delivery transactions
-		let bundled_messages = match Self::bundled_messages_for_priority_boost(parsed_call.as_ref())
-		{
+		let bundled_messages = match Self::bundled_messages_for_priority_boost(&data.call_info) {
 			Some(bundled_messages) => bundled_messages,
-			None => return Ok(Default::default()),
+			None => return Ok((Default::default(), Some(data), origin)),
 		};
 
 		// we only boost priority if relayer has staked required balance
-		if !RelayersPallet::<R>::is_registration_active(who) {
-			return Ok(Default::default())
+		if !RelayersPallet::<R>::is_registration_active(&data.relayer) {
+			return Ok((Default::default(), Some(data), origin))
 		}
 
 		// compute priority boost
@@ -334,48 +338,43 @@ where
 			"{}.{:?}: has boosted priority of message delivery transaction \
 			of relayer {:?}: {} messages -> {} priority",
 			Self::IDENTIFIER,
-			parsed_call.as_ref().map(|p| p.messages_call_info().lane_id()),
-			who,
+			data.call_info.messages_call_info().lane_id(),
+			data.relayer,
 			bundled_messages,
 			priority_boost,
 		);
 
-		valid_transaction.build()
+		let validity = valid_transaction.build()?;
+		Ok((validity, Some(data), origin))
 	}
 
-	fn pre_dispatch(
+	fn prepare(
 		self,
-		who: &Self::AccountId,
-		call: &Self::Call,
-		_info: &DispatchInfoOf<Self::Call>,
+		val: Self::Val,
+		_origin: &<R::RuntimeCall as Dispatchable>::RuntimeOrigin,
+		_call: &R::RuntimeCall,
+		_info: &DispatchInfoOf<R::RuntimeCall>,
 		_len: usize,
 	) -> Result<Self::Pre, TransactionValidityError> {
-		// this is a relevant piece of `validate` that we need here (in `pre_dispatch`)
-		let parsed_call = C::parse_and_check_for_obsolete_call(call)?;
-
-		Ok(parsed_call.map(|call_info| {
+		Ok(val.inspect(|data| {
 			log::trace!(
 				target: LOG_TARGET,
-				"{}.{:?}: parsed bridge transaction in pre-dispatch: {:?}",
+				"{}.{:?}: parsed bridge transaction in prepare: {:?}",
 				Self::IDENTIFIER,
-				call_info.messages_call_info().lane_id(),
-				call_info,
+				data.call_info.messages_call_info().lane_id(),
+				data.call_info,
 			);
-			PreDispatchData { relayer: who.clone(), call_info }
 		}))
 	}
 
-	fn post_dispatch(
-		pre: Option<Self::Pre>,
-		info: &DispatchInfoOf<Self::Call>,
-		post_info: &PostDispatchInfoOf<Self::Call>,
+	fn post_dispatch_details(
+		pre: Self::Pre,
+		info: &DispatchInfoOf<R::RuntimeCall>,
+		post_info: &PostDispatchInfoOf<R::RuntimeCall>,
 		len: usize,
 		result: &DispatchResult,
-	) -> Result<(), TransactionValidityError> {
-		let lane_id = pre
-			.as_ref()
-			.and_then(|p| p.as_ref())
-			.map(|p| p.call_info.messages_call_info().lane_id());
+	) -> Result<Weight, TransactionValidityError> {
+		let lane_id = pre.as_ref().map(|p| p.call_info.messages_call_info().lane_id());
 		let call_result = Self::analyze_call_result(pre, info, post_info, len, result);
 
 		match call_result {
@@ -399,7 +398,7 @@ where
 				),
 		}
 
-		Ok(())
+		Ok(Weight::zero())
 	}
 }
 
@@ -463,8 +462,8 @@ mod tests {
 	use pallet_bridge_parachains::{Call as ParachainsCall, Pallet as ParachainsPallet};
 	use pallet_utility::Call as UtilityCall;
 	use sp_runtime::{
-		traits::{ConstU64, Header as HeaderT},
-		transaction_validity::{InvalidTransaction, ValidTransaction},
+		traits::{ConstU64, DispatchTransaction, Header as HeaderT},
+		transaction_validity::{InvalidTransaction, TransactionValidity, ValidTransaction},
 		DispatchError,
 	};
 
@@ -496,7 +495,7 @@ mod tests {
 		ConstU64<1>,
 	>;
 	type TestGrandpaExtension =
-		BridgeRelayersSignedExtension<TestRuntime, TestGrandpaExtensionConfig, TestLaneIdType>;
+		BridgeRelayersTransactionExtension<TestRuntime, TestGrandpaExtensionConfig, TestLaneIdType>;
 	type TestExtensionConfig = parachain_adapter::WithParachainExtensionConfig<
 		StrTestExtension,
 		TestRuntime,
@@ -507,7 +506,7 @@ mod tests {
 		ConstU64<1>,
 	>;
 	type TestExtension =
-		BridgeRelayersSignedExtension<TestRuntime, TestExtensionConfig, TestLaneIdType>;
+		BridgeRelayersTransactionExtension<TestRuntime, TestExtensionConfig, TestLaneIdType>;
 	type TestMessagesExtensionConfig = messages_adapter::WithMessagesExtensionConfig<
 		StrTestMessagesExtension,
 		TestRuntime,
@@ -515,8 +514,11 @@ mod tests {
 		(),
 		ConstU64<1>,
 	>;
-	type TestMessagesExtension =
-		BridgeRelayersSignedExtension<TestRuntime, TestMessagesExtensionConfig, TestLaneIdType>;
+	type TestMessagesExtension = BridgeRelayersTransactionExtension<
+		TestRuntime,
+		TestMessagesExtensionConfig,
+		TestLaneIdType,
+	>;
 
 	fn initial_balance_of_relayer_account_at_this_chain() -> ThisChainBalance {
 		let test_stake: ThisChainBalance = Stake::get();
@@ -1067,18 +1069,39 @@ mod tests {
 	}
 
 	fn run_validate(call: RuntimeCall) -> TransactionValidity {
-		let extension: TestExtension = BridgeRelayersSignedExtension(PhantomData);
-		extension.validate(&relayer_account_at_this_chain(), &call, &DispatchInfo::default(), 0)
+		let extension: TestExtension = BridgeRelayersTransactionExtension(PhantomData);
+		extension
+			.validate_only(
+				Some(relayer_account_at_this_chain()).into(),
+				&call,
+				&DispatchInfo::default(),
+				0,
+			)
+			.map(|t| t.0)
 	}
 
 	fn run_grandpa_validate(call: RuntimeCall) -> TransactionValidity {
-		let extension: TestGrandpaExtension = BridgeRelayersSignedExtension(PhantomData);
-		extension.validate(&relayer_account_at_this_chain(), &call, &DispatchInfo::default(), 0)
+		let extension: TestGrandpaExtension = BridgeRelayersTransactionExtension(PhantomData);
+		extension
+			.validate_only(
+				Some(relayer_account_at_this_chain()).into(),
+				&call,
+				&DispatchInfo::default(),
+				0,
+			)
+			.map(|t| t.0)
 	}
 
 	fn run_messages_validate(call: RuntimeCall) -> TransactionValidity {
-		let extension: TestMessagesExtension = BridgeRelayersSignedExtension(PhantomData);
-		extension.validate(&relayer_account_at_this_chain(), &call, &DispatchInfo::default(), 0)
+		let extension: TestMessagesExtension = BridgeRelayersTransactionExtension(PhantomData);
+		extension
+			.validate_only(
+				Some(relayer_account_at_this_chain()).into(),
+				&call,
+				&DispatchInfo::default(),
+				0,
+			)
+			.map(|t| t.0)
 	}
 
 	fn ignore_priority(tx: TransactionValidity) -> TransactionValidity {
@@ -1095,8 +1118,15 @@ mod tests {
 		TransactionValidityError,
 	> {
 		sp_tracing::try_init_simple();
-		let extension: TestExtension = BridgeRelayersSignedExtension(PhantomData);
-		extension.pre_dispatch(&relayer_account_at_this_chain(), &call, &DispatchInfo::default(), 0)
+		let extension: TestExtension = BridgeRelayersTransactionExtension(PhantomData);
+		extension
+			.validate_and_prepare(
+				Some(relayer_account_at_this_chain()).into(),
+				&call,
+				&DispatchInfo::default(),
+				0,
+			)
+			.map(|(pre, _)| pre)
 	}
 
 	fn run_grandpa_pre_dispatch(
@@ -1105,8 +1135,15 @@ mod tests {
 		Option<PreDispatchData<ThisChainAccountId, BridgedChainBlockNumber, TestLaneIdType>>,
 		TransactionValidityError,
 	> {
-		let extension: TestGrandpaExtension = BridgeRelayersSignedExtension(PhantomData);
-		extension.pre_dispatch(&relayer_account_at_this_chain(), &call, &DispatchInfo::default(), 0)
+		let extension: TestGrandpaExtension = BridgeRelayersTransactionExtension(PhantomData);
+		extension
+			.validate_and_prepare(
+				Some(relayer_account_at_this_chain()).into(),
+				&call,
+				&DispatchInfo::default(),
+				0,
+			)
+			.map(|(pre, _)| pre)
 	}
 
 	fn run_messages_pre_dispatch(
@@ -1115,16 +1152,24 @@ mod tests {
 		Option<PreDispatchData<ThisChainAccountId, (), TestLaneIdType>>,
 		TransactionValidityError,
 	> {
-		let extension: TestMessagesExtension = BridgeRelayersSignedExtension(PhantomData);
-		extension.pre_dispatch(&relayer_account_at_this_chain(), &call, &DispatchInfo::default(), 0)
+		let extension: TestMessagesExtension = BridgeRelayersTransactionExtension(PhantomData);
+		extension
+			.validate_and_prepare(
+				Some(relayer_account_at_this_chain()).into(),
+				&call,
+				&DispatchInfo::default(),
+				0,
+			)
+			.map(|(pre, _)| pre)
 	}
 
 	fn dispatch_info() -> DispatchInfo {
 		DispatchInfo {
-			weight: Weight::from_parts(
+			call_weight: Weight::from_parts(
 				frame_support::weights::constants::WEIGHT_REF_TIME_PER_SECOND,
 				0,
 			),
+			extension_weight: Weight::zero(),
 			class: frame_support::dispatch::DispatchClass::Normal,
 			pays_fee: frame_support::dispatch::Pays::Yes,
 		}
@@ -1140,21 +1185,21 @@ mod tests {
 		>,
 		dispatch_result: DispatchResult,
 	) {
-		let post_dispatch_result = TestExtension::post_dispatch(
-			Some(pre_dispatch_data),
+		let post_dispatch_result = TestExtension::post_dispatch_details(
+			pre_dispatch_data,
 			&dispatch_info(),
 			&post_dispatch_info(),
 			1024,
 			&dispatch_result,
 		);
-		assert_eq!(post_dispatch_result, Ok(()));
+		assert_eq!(post_dispatch_result, Ok(Weight::zero()));
 	}
 
 	fn expected_delivery_reward() -> ThisChainBalance {
 		let mut post_dispatch_info = post_dispatch_info();
 		let extra_weight = <TestRuntime as RelayersConfig>::WeightInfo::extra_weight_of_successful_receive_messages_proof_call();
 		post_dispatch_info.actual_weight =
-			Some(dispatch_info().weight.saturating_sub(extra_weight));
+			Some(dispatch_info().call_weight.saturating_sub(extra_weight));
 		pallet_transaction_payment::Pallet::<TestRuntime>::compute_actual_fee(
 			1024,
 			&dispatch_info(),
@@ -1714,7 +1759,7 @@ mod tests {
 			initialize_environment(200, 200, 200);
 
 			let mut dispatch_info = dispatch_info();
-			dispatch_info.weight = Weight::from_parts(
+			dispatch_info.call_weight = Weight::from_parts(
 				frame_support::weights::constants::WEIGHT_REF_TIME_PER_SECOND * 2,
 				0,
 			);
@@ -1918,7 +1963,7 @@ mod tests {
 		dispatch_result: DispatchResult,
 	) -> RelayerAccountAction<ThisChainAccountId, ThisChainBalance, TestLaneIdType> {
 		TestExtension::analyze_call_result(
-			Some(Some(pre_dispatch_data)),
+			Some(pre_dispatch_data),
 			&dispatch_info(),
 			&post_dispatch_info(),
 			1024,
diff --git a/bridges/modules/relayers/src/extension/priority.rs b/bridges/modules/relayers/src/extension/priority.rs
index da188eaf5bd..e09e8627c67 100644
--- a/bridges/modules/relayers/src/extension/priority.rs
+++ b/bridges/modules/relayers/src/extension/priority.rs
@@ -206,14 +206,17 @@ mod integrity_tests {
 
 			// finally we are able to estimate transaction size and weight
 			let transaction_size = base_tx_size.saturating_add(tx_call_size);
-			let transaction_weight = Runtime::WeightInfo::submit_finality_proof_weight(
+			let transaction_weight = <Runtime as ::pallet_bridge_grandpa::Config<
+				GrandpaInstance,
+			>>::WeightInfo::submit_finality_proof_weight(
 				Runtime::BridgedChain::MAX_AUTHORITIES_COUNT * 2 / 3 + 1,
 				Runtime::BridgedChain::REASONABLE_HEADERS_IN_JUSTIFICATION_ANCESTRY,
 			);
 
 			pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::get_priority(
 				&DispatchInfo {
-					weight: transaction_weight,
+					call_weight: transaction_weight,
+					extension_weight: Default::default(),
 					class: DispatchClass::Normal,
 					pays_fee: Pays::Yes,
 				},
@@ -315,7 +318,8 @@ mod integrity_tests {
 
 			pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::get_priority(
 				&DispatchInfo {
-					weight: transaction_weight,
+					call_weight: transaction_weight,
+					extension_weight: Default::default(),
 					class: DispatchClass::Normal,
 					pays_fee: Pays::Yes,
 				},
@@ -385,20 +389,27 @@ mod integrity_tests {
 			// trie nodes to the proof (x0.5 because we expect some nodes to be reused)
 			let estimated_message_size = 512;
 			// let's say all our messages have the same dispatch weight
-			let estimated_message_dispatch_weight =
-				Runtime::WeightInfo::message_dispatch_weight(estimated_message_size);
+			let estimated_message_dispatch_weight = <Runtime as pallet_bridge_messages::Config<
+				MessagesInstance,
+			>>::WeightInfo::message_dispatch_weight(
+				estimated_message_size
+			);
 			// messages proof argument size is (for every message) messages size + some additional
 			// trie nodes. Some of them are reused by different messages, so let's take 2/3 of
 			// default "overhead" constant
-			let messages_proof_size = Runtime::WeightInfo::expected_extra_storage_proof_size()
-				.saturating_mul(2)
-				.saturating_div(3)
-				.saturating_add(estimated_message_size)
-				.saturating_mul(messages as _);
+			let messages_proof_size = <Runtime as pallet_bridge_messages::Config<
+				MessagesInstance,
+			>>::WeightInfo::expected_extra_storage_proof_size()
+			.saturating_mul(2)
+			.saturating_div(3)
+			.saturating_add(estimated_message_size)
+			.saturating_mul(messages as _);
 
 			// finally we are able to estimate transaction size and weight
 			let transaction_size = base_tx_size.saturating_add(messages_proof_size);
-			let transaction_weight = Runtime::WeightInfo::receive_messages_proof_weight(
+			let transaction_weight = <Runtime as pallet_bridge_messages::Config<
+				MessagesInstance,
+			>>::WeightInfo::receive_messages_proof_weight(
 				&PreComputedSize(transaction_size as _),
 				messages as _,
 				estimated_message_dispatch_weight.saturating_mul(messages),
@@ -406,7 +417,8 @@ mod integrity_tests {
 
 			pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::get_priority(
 				&DispatchInfo {
-					weight: transaction_weight,
+					call_weight: transaction_weight,
+					extension_weight: Default::default(),
 					class: DispatchClass::Normal,
 					pays_fee: Pays::Yes,
 				},
diff --git a/bridges/primitives/polkadot-core/src/lib.rs b/bridges/primitives/polkadot-core/src/lib.rs
index e83be59b238..a8abdb59bea 100644
--- a/bridges/primitives/polkadot-core/src/lib.rs
+++ b/bridges/primitives/polkadot-core/src/lib.rs
@@ -24,8 +24,8 @@ use bp_runtime::{
 	self,
 	extensions::{
 		ChargeTransactionPayment, CheckEra, CheckGenesis, CheckNonZeroSender, CheckNonce,
-		CheckSpecVersion, CheckTxVersion, CheckWeight, GenericSignedExtension,
-		SignedExtensionSchema,
+		CheckSpecVersion, CheckTxVersion, CheckWeight, GenericTransactionExtension,
+		TransactionExtensionSchema,
 	},
 	EncodedOrDecodedCall, StorageMapKeyProvider, TransactionEra,
 };
@@ -229,8 +229,12 @@ pub type SignedBlock = generic::SignedBlock<Block>;
 pub type Balance = u128;
 
 /// Unchecked Extrinsic type.
-pub type UncheckedExtrinsic<Call, SignedExt> =
-	generic::UncheckedExtrinsic<AccountAddress, EncodedOrDecodedCall<Call>, Signature, SignedExt>;
+pub type UncheckedExtrinsic<Call, TransactionExt> = generic::UncheckedExtrinsic<
+	AccountAddress,
+	EncodedOrDecodedCall<Call>,
+	Signature,
+	TransactionExt,
+>;
 
 /// Account address, used by the Polkadot-like chain.
 pub type Address = MultiAddress<AccountId, ()>;
@@ -275,7 +279,7 @@ impl AccountInfoStorageMapKeyProvider {
 }
 
 /// Extra signed extension data that is used by most chains.
-pub type CommonSignedExtra = (
+pub type CommonTransactionExtra = (
 	CheckNonZeroSender,
 	CheckSpecVersion,
 	CheckTxVersion,
@@ -286,12 +290,12 @@ pub type CommonSignedExtra = (
 	ChargeTransactionPayment<Balance>,
 );
 
-/// Extra signed extension data that starts with `CommonSignedExtra`.
-pub type SuffixedCommonSignedExtension<Suffix> =
-	GenericSignedExtension<(CommonSignedExtra, Suffix)>;
+/// Extra transaction extension data that starts with `CommonTransactionExtra`.
+pub type SuffixedCommonTransactionExtension<Suffix> =
+	GenericTransactionExtension<(CommonTransactionExtra, Suffix)>;
 
-/// Helper trait to define some extra methods on `SuffixedCommonSignedExtension`.
-pub trait SuffixedCommonSignedExtensionExt<Suffix: SignedExtensionSchema> {
+/// Helper trait to define some extra methods on `SuffixedCommonTransactionExtension`.
+pub trait SuffixedCommonTransactionExtensionExt<Suffix: TransactionExtensionSchema> {
 	/// Create signed extension from its components.
 	fn from_params(
 		spec_version: u32,
@@ -300,7 +304,7 @@ pub trait SuffixedCommonSignedExtensionExt<Suffix: SignedExtensionSchema> {
 		genesis_hash: Hash,
 		nonce: Nonce,
 		tip: Balance,
-		extra: (Suffix::Payload, Suffix::AdditionalSigned),
+		extra: (Suffix::Payload, Suffix::Implicit),
 	) -> Self;
 
 	/// Return transaction nonce.
@@ -310,9 +314,10 @@ pub trait SuffixedCommonSignedExtensionExt<Suffix: SignedExtensionSchema> {
 	fn tip(&self) -> Balance;
 }
 
-impl<Suffix> SuffixedCommonSignedExtensionExt<Suffix> for SuffixedCommonSignedExtension<Suffix>
+impl<Suffix> SuffixedCommonTransactionExtensionExt<Suffix>
+	for SuffixedCommonTransactionExtension<Suffix>
 where
-	Suffix: SignedExtensionSchema,
+	Suffix: TransactionExtensionSchema,
 {
 	fn from_params(
 		spec_version: u32,
@@ -321,9 +326,9 @@ where
 		genesis_hash: Hash,
 		nonce: Nonce,
 		tip: Balance,
-		extra: (Suffix::Payload, Suffix::AdditionalSigned),
+		extra: (Suffix::Payload, Suffix::Implicit),
 	) -> Self {
-		GenericSignedExtension::new(
+		GenericTransactionExtension::new(
 			(
 				(
 					(),              // non-zero sender
@@ -365,7 +370,7 @@ where
 }
 
 /// Signed extension that is used by most chains.
-pub type CommonSignedExtension = SuffixedCommonSignedExtension<()>;
+pub type CommonTransactionExtension = SuffixedCommonTransactionExtension<()>;
 
 #[cfg(test)]
 mod tests {
diff --git a/bridges/primitives/relayers/src/extension.rs b/bridges/primitives/relayers/src/extension.rs
index a9fa4df27ea..8fd0f151e2a 100644
--- a/bridges/primitives/relayers/src/extension.rs
+++ b/bridges/primitives/relayers/src/extension.rs
@@ -138,7 +138,7 @@ pub trait ExtensionConfig {
 	/// Lane identifier type.
 	type LaneId: Clone + Copy + Decode + Encode + Debug;
 
-	/// Given runtime call, check if it is supported by the signed extension. Additionally,
+	/// Given runtime call, check if it is supported by the transaction extension. Additionally,
 	/// check if call (or any of batched calls) are obsolete.
 	fn parse_and_check_for_obsolete_call(
 		call: &<Self::Runtime as SystemConfig>::RuntimeCall,
diff --git a/bridges/primitives/runtime/src/extensions.rs b/bridges/primitives/runtime/src/extensions.rs
index d896bc92eff..25553f9c7b2 100644
--- a/bridges/primitives/runtime/src/extensions.rs
+++ b/bridges/primitives/runtime/src/extensions.rs
@@ -20,135 +20,131 @@ use codec::{Compact, Decode, Encode};
 use impl_trait_for_tuples::impl_for_tuples;
 use scale_info::{StaticTypeInfo, TypeInfo};
 use sp_runtime::{
-	traits::{DispatchInfoOf, SignedExtension},
+	impl_tx_ext_default,
+	traits::{Dispatchable, TransactionExtension},
 	transaction_validity::TransactionValidityError,
 };
 use sp_std::{fmt::Debug, marker::PhantomData};
 
-/// Trait that describes some properties of a `SignedExtension` that are needed in order to send a
-/// transaction to the chain.
-pub trait SignedExtensionSchema: Encode + Decode + Debug + Eq + Clone + StaticTypeInfo {
+/// Trait that describes some properties of a `TransactionExtension` that are needed in order to
+/// send a transaction to the chain.
+pub trait TransactionExtensionSchema:
+	Encode + Decode + Debug + Eq + Clone + StaticTypeInfo
+{
 	/// A type of the data encoded as part of the transaction.
 	type Payload: Encode + Decode + Debug + Eq + Clone + StaticTypeInfo;
 	/// Parameters which are part of the payload used to produce transaction signature,
 	/// but don't end up in the transaction itself (i.e. inherent part of the runtime).
-	type AdditionalSigned: Encode + Debug + Eq + Clone + StaticTypeInfo;
+	type Implicit: Encode + Decode + Debug + Eq + Clone + StaticTypeInfo;
 }
 
-impl SignedExtensionSchema for () {
+impl TransactionExtensionSchema for () {
 	type Payload = ();
-	type AdditionalSigned = ();
+	type Implicit = ();
 }
 
-/// An implementation of `SignedExtensionSchema` using generic params.
+/// An implementation of `TransactionExtensionSchema` using generic params.
 #[derive(Encode, Decode, Clone, Debug, PartialEq, Eq, TypeInfo)]
-pub struct GenericSignedExtensionSchema<P, S>(PhantomData<(P, S)>);
+pub struct GenericTransactionExtensionSchema<P, S>(PhantomData<(P, S)>);
 
-impl<P, S> SignedExtensionSchema for GenericSignedExtensionSchema<P, S>
+impl<P, S> TransactionExtensionSchema for GenericTransactionExtensionSchema<P, S>
 where
 	P: Encode + Decode + Debug + Eq + Clone + StaticTypeInfo,
-	S: Encode + Debug + Eq + Clone + StaticTypeInfo,
+	S: Encode + Decode + Debug + Eq + Clone + StaticTypeInfo,
 {
 	type Payload = P;
-	type AdditionalSigned = S;
+	type Implicit = S;
 }
 
-/// The `SignedExtensionSchema` for `frame_system::CheckNonZeroSender`.
-pub type CheckNonZeroSender = GenericSignedExtensionSchema<(), ()>;
+/// The `TransactionExtensionSchema` for `frame_system::CheckNonZeroSender`.
+pub type CheckNonZeroSender = GenericTransactionExtensionSchema<(), ()>;
 
-/// The `SignedExtensionSchema` for `frame_system::CheckSpecVersion`.
-pub type CheckSpecVersion = GenericSignedExtensionSchema<(), u32>;
+/// The `TransactionExtensionSchema` for `frame_system::CheckSpecVersion`.
+pub type CheckSpecVersion = GenericTransactionExtensionSchema<(), u32>;
 
-/// The `SignedExtensionSchema` for `frame_system::CheckTxVersion`.
-pub type CheckTxVersion = GenericSignedExtensionSchema<(), u32>;
+/// The `TransactionExtensionSchema` for `frame_system::CheckTxVersion`.
+pub type CheckTxVersion = GenericTransactionExtensionSchema<(), u32>;
 
-/// The `SignedExtensionSchema` for `frame_system::CheckGenesis`.
-pub type CheckGenesis<Hash> = GenericSignedExtensionSchema<(), Hash>;
+/// The `TransactionExtensionSchema` for `frame_system::CheckGenesis`.
+pub type CheckGenesis<Hash> = GenericTransactionExtensionSchema<(), Hash>;
 
-/// The `SignedExtensionSchema` for `frame_system::CheckEra`.
-pub type CheckEra<Hash> = GenericSignedExtensionSchema<sp_runtime::generic::Era, Hash>;
+/// The `TransactionExtensionSchema` for `frame_system::CheckEra`.
+pub type CheckEra<Hash> = GenericTransactionExtensionSchema<sp_runtime::generic::Era, Hash>;
 
-/// The `SignedExtensionSchema` for `frame_system::CheckNonce`.
-pub type CheckNonce<TxNonce> = GenericSignedExtensionSchema<Compact<TxNonce>, ()>;
+/// The `TransactionExtensionSchema` for `frame_system::CheckNonce`.
+pub type CheckNonce<TxNonce> = GenericTransactionExtensionSchema<Compact<TxNonce>, ()>;
 
-/// The `SignedExtensionSchema` for `frame_system::CheckWeight`.
-pub type CheckWeight = GenericSignedExtensionSchema<(), ()>;
+/// The `TransactionExtensionSchema` for `frame_system::CheckWeight`.
+pub type CheckWeight = GenericTransactionExtensionSchema<(), ()>;
 
-/// The `SignedExtensionSchema` for `pallet_transaction_payment::ChargeTransactionPayment`.
-pub type ChargeTransactionPayment<Balance> = GenericSignedExtensionSchema<Compact<Balance>, ()>;
+/// The `TransactionExtensionSchema` for `pallet_transaction_payment::ChargeTransactionPayment`.
+pub type ChargeTransactionPayment<Balance> =
+	GenericTransactionExtensionSchema<Compact<Balance>, ()>;
 
-/// The `SignedExtensionSchema` for `polkadot-runtime-common::PrevalidateAttests`.
-pub type PrevalidateAttests = GenericSignedExtensionSchema<(), ()>;
+/// The `TransactionExtensionSchema` for `polkadot-runtime-common::PrevalidateAttests`.
+pub type PrevalidateAttests = GenericTransactionExtensionSchema<(), ()>;
 
-/// The `SignedExtensionSchema` for `BridgeRejectObsoleteHeadersAndMessages`.
-pub type BridgeRejectObsoleteHeadersAndMessages = GenericSignedExtensionSchema<(), ()>;
+/// The `TransactionExtensionSchema` for `BridgeRejectObsoleteHeadersAndMessages`.
+pub type BridgeRejectObsoleteHeadersAndMessages = GenericTransactionExtensionSchema<(), ()>;
 
-/// The `SignedExtensionSchema` for `RefundBridgedParachainMessages`.
+/// The `TransactionExtensionSchema` for `RefundBridgedParachainMessages`.
 /// This schema is dedicated for `RefundBridgedParachainMessages` signed extension as
 /// wildcard/placeholder, which relies on the scale encoding for `()` or `((), ())`, or `((), (),
 /// ())` is the same. So runtime can contains any kind of tuple:
 /// `(BridgeRefundBridgeHubRococoMessages)`
 /// `(BridgeRefundBridgeHubRococoMessages, BridgeRefundBridgeHubWestendMessages)`
 /// `(BridgeRefundParachainMessages1, ..., BridgeRefundParachainMessagesN)`
-pub type RefundBridgedParachainMessagesSchema = GenericSignedExtensionSchema<(), ()>;
+pub type RefundBridgedParachainMessagesSchema = GenericTransactionExtensionSchema<(), ()>;
 
 #[impl_for_tuples(1, 12)]
-impl SignedExtensionSchema for Tuple {
+impl TransactionExtensionSchema for Tuple {
 	for_tuples!( type Payload = ( #( Tuple::Payload ),* ); );
-	for_tuples!( type AdditionalSigned = ( #( Tuple::AdditionalSigned ),* ); );
+	for_tuples!( type Implicit = ( #( Tuple::Implicit ),* ); );
 }
 
 /// A simplified version of signed extensions meant for producing signed transactions
 /// and signed payloads in the client code.
 #[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
-pub struct GenericSignedExtension<S: SignedExtensionSchema> {
+pub struct GenericTransactionExtension<S: TransactionExtensionSchema> {
 	/// A payload that is included in the transaction.
 	pub payload: S::Payload,
 	#[codec(skip)]
 	// It may be set to `None` if extensions are decoded. We are never reconstructing transactions
-	// (and it makes no sense to do that) => decoded version of `SignedExtensions` is only used to
-	// read fields of the `payload`. And when resigning transaction, we're reconstructing
-	// `SignedExtensions` from scratch.
-	additional_signed: Option<S::AdditionalSigned>,
+	// (and it makes no sense to do that) => decoded version of `TransactionExtensions` is only
+	// used to read fields of the `payload`. And when resigning transaction, we're reconstructing
+	// `TransactionExtensions` from scratch.
+	implicit: Option<S::Implicit>,
 }
 
-impl<S: SignedExtensionSchema> GenericSignedExtension<S> {
-	/// Create new `GenericSignedExtension` object.
-	pub fn new(payload: S::Payload, additional_signed: Option<S::AdditionalSigned>) -> Self {
-		Self { payload, additional_signed }
+impl<S: TransactionExtensionSchema> GenericTransactionExtension<S> {
+	/// Create new `GenericTransactionExtension` object.
+	pub fn new(payload: S::Payload, implicit: Option<S::Implicit>) -> Self {
+		Self { payload, implicit }
 	}
 }
 
-impl<S> SignedExtension for GenericSignedExtension<S>
+impl<S, C> TransactionExtension<C> for GenericTransactionExtension<S>
 where
-	S: SignedExtensionSchema,
+	C: Dispatchable,
+	S: TransactionExtensionSchema,
 	S::Payload: Send + Sync,
-	S::AdditionalSigned: Send + Sync,
+	S::Implicit: Send + Sync,
 {
 	const IDENTIFIER: &'static str = "Not needed.";
-	type AccountId = ();
-	type Call = ();
-	type AdditionalSigned = S::AdditionalSigned;
-	type Pre = ();
+	type Implicit = S::Implicit;
 
-	fn additional_signed(&self) -> Result<Self::AdditionalSigned, TransactionValidityError> {
+	fn implicit(&self) -> Result<Self::Implicit, TransactionValidityError> {
 		// we shall not ever see this error in relay, because we are never signing decoded
 		// transactions. Instead we're constructing and signing new transactions. So the error code
 		// is kinda random here
-		self.additional_signed.clone().ok_or(
-			frame_support::unsigned::TransactionValidityError::Unknown(
+		self.implicit
+			.clone()
+			.ok_or(frame_support::unsigned::TransactionValidityError::Unknown(
 				frame_support::unsigned::UnknownTransaction::Custom(0xFF),
-			),
-		)
+			))
 	}
+	type Pre = ();
+	type Val = ();
 
-	fn pre_dispatch(
-		self,
-		_who: &Self::AccountId,
-		_call: &Self::Call,
-		_info: &DispatchInfoOf<Self::Call>,
-		_len: usize,
-	) -> Result<Self::Pre, TransactionValidityError> {
-		Ok(())
-	}
+	impl_tx_ext_default!(C; weight validate prepare);
 }
diff --git a/bridges/relays/lib-substrate-relay/src/messages/mod.rs b/bridges/relays/lib-substrate-relay/src/messages/mod.rs
index f7031648bc3..b4ee57ed774 100644
--- a/bridges/relays/lib-substrate-relay/src/messages/mod.rs
+++ b/bridges/relays/lib-substrate-relay/src/messages/mod.rs
@@ -428,7 +428,7 @@ where
 				"Prepared {} -> {} messages delivery call. Weight: {}/{}, size: {}/{}",
 				P::SourceChain::NAME,
 				P::TargetChain::NAME,
-				call.get_dispatch_info().weight,
+				call.get_dispatch_info().call_weight,
 				P::TargetChain::max_extrinsic_weight(),
 				call.encode().len(),
 				P::TargetChain::max_extrinsic_size(),
@@ -521,7 +521,7 @@ where
 				"Prepared {} -> {} delivery confirmation transaction. Weight: {}/{}, size: {}/{}",
 				P::TargetChain::NAME,
 				P::SourceChain::NAME,
-				call.get_dispatch_info().weight,
+				call.get_dispatch_info().call_weight,
 				P::SourceChain::max_extrinsic_weight(),
 				call.encode().len(),
 				P::SourceChain::max_extrinsic_size(),
diff --git a/bridges/snowbridge/pallets/ethereum-client/Cargo.toml b/bridges/snowbridge/pallets/ethereum-client/Cargo.toml
index 666ac3fbc8a..262d9a7f380 100644
--- a/bridges/snowbridge/pallets/ethereum-client/Cargo.toml
+++ b/bridges/snowbridge/pallets/ethereum-client/Cargo.toml
@@ -49,13 +49,7 @@ serde = { workspace = true, default-features = true }
 
 [features]
 default = ["std"]
-fuzzing = [
-	"hex-literal",
-	"pallet-timestamp",
-	"serde",
-	"serde_json",
-	"sp-io",
-]
+fuzzing = ["hex-literal", "pallet-timestamp", "serde", "serde_json", "sp-io"]
 std = [
 	"codec/std",
 	"frame-support/std",
diff --git a/bridges/snowbridge/pallets/ethereum-client/fixtures/Cargo.toml b/bridges/snowbridge/pallets/ethereum-client/fixtures/Cargo.toml
index bd417687573..87f0cf9a551 100644
--- a/bridges/snowbridge/pallets/ethereum-client/fixtures/Cargo.toml
+++ b/bridges/snowbridge/pallets/ethereum-client/fixtures/Cargo.toml
@@ -29,6 +29,4 @@ std = [
 	"sp-core/std",
 	"sp-std/std",
 ]
-runtime-benchmarks = [
-	"snowbridge-core/runtime-benchmarks",
-]
+runtime-benchmarks = ["snowbridge-core/runtime-benchmarks"]
diff --git a/bridges/snowbridge/pallets/inbound-queue/fixtures/Cargo.toml b/bridges/snowbridge/pallets/inbound-queue/fixtures/Cargo.toml
index b66b57c3620..6162a17728b 100644
--- a/bridges/snowbridge/pallets/inbound-queue/fixtures/Cargo.toml
+++ b/bridges/snowbridge/pallets/inbound-queue/fixtures/Cargo.toml
@@ -29,6 +29,4 @@ std = [
 	"sp-core/std",
 	"sp-std/std",
 ]
-runtime-benchmarks = [
-	"snowbridge-core/runtime-benchmarks",
-]
+runtime-benchmarks = ["snowbridge-core/runtime-benchmarks"]
diff --git a/bridges/snowbridge/pallets/outbound-queue/merkle-tree/Cargo.toml b/bridges/snowbridge/pallets/outbound-queue/merkle-tree/Cargo.toml
index 9d4cffc98d7..16241428df8 100644
--- a/bridges/snowbridge/pallets/outbound-queue/merkle-tree/Cargo.toml
+++ b/bridges/snowbridge/pallets/outbound-queue/merkle-tree/Cargo.toml
@@ -30,9 +30,4 @@ sp-tracing = { workspace = true, default-features = true }
 
 [features]
 default = ["std"]
-std = [
-	"codec/std",
-	"scale-info/std",
-	"sp-core/std",
-	"sp-runtime/std",
-]
+std = ["codec/std", "scale-info/std", "sp-core/std", "sp-runtime/std"]
diff --git a/cumulus/pallets/parachain-system/src/validate_block/implementation.rs b/cumulus/pallets/parachain-system/src/validate_block/implementation.rs
index c4c8440e518..2c531c39acc 100644
--- a/cumulus/pallets/parachain-system/src/validate_block/implementation.rs
+++ b/cumulus/pallets/parachain-system/src/validate_block/implementation.rs
@@ -33,7 +33,7 @@ use frame_support::traits::{ExecuteBlock, ExtrinsicCall, Get, IsSubType};
 use sp_core::storage::{ChildInfo, StateVersion};
 use sp_externalities::{set_and_run_with_externalities, Externalities};
 use sp_io::KillStorageResult;
-use sp_runtime::traits::{Block as BlockT, Extrinsic, HashingFor, Header as HeaderT};
+use sp_runtime::traits::{Block as BlockT, ExtrinsicLike, HashingFor, Header as HeaderT};
 use sp_trie::{MemoryDB, ProofSizeProvider};
 use trie_recorder::SizeOnlyRecorderProvider;
 
@@ -96,7 +96,7 @@ pub fn validate_block<
 ) -> ValidationResult
 where
 	B::Extrinsic: ExtrinsicCall,
-	<B::Extrinsic as Extrinsic>::Call: IsSubType<crate::Call<PSC>>,
+	<B::Extrinsic as ExtrinsicCall>::Call: IsSubType<crate::Call<PSC>>,
 {
 	let block_data = codec::decode_from_bytes::<ParachainBlockData<B>>(block_data)
 		.expect("Invalid parachain block data");
@@ -240,16 +240,13 @@ fn extract_parachain_inherent_data<B: BlockT, PSC: crate::Config>(
 ) -> &ParachainInherentData
 where
 	B::Extrinsic: ExtrinsicCall,
-	<B::Extrinsic as Extrinsic>::Call: IsSubType<crate::Call<PSC>>,
+	<B::Extrinsic as ExtrinsicCall>::Call: IsSubType<crate::Call<PSC>>,
 {
 	block
 		.extrinsics()
 		.iter()
 		// Inherents are at the front of the block and are unsigned.
-		//
-		// If `is_signed` is returning `None`, we keep it safe and assume that it is "signed".
-		// We are searching for unsigned transactions anyway.
-		.take_while(|e| !e.is_signed().unwrap_or(true))
+		.take_while(|e| e.is_bare())
 		.filter_map(|e| e.call().is_sub_type())
 		.find_map(|c| match c {
 			crate::Call::set_validation_data { data: validation_data } => Some(validation_data),
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml b/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml
index 00f2cf8f636..42adaba7a27 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml
+++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml
@@ -117,6 +117,7 @@ runtime-benchmarks = [
 	"frame-system-benchmarking/runtime-benchmarks",
 	"frame-system/runtime-benchmarks",
 	"pallet-asset-conversion-ops/runtime-benchmarks",
+	"pallet-asset-conversion-tx-payment/runtime-benchmarks",
 	"pallet-asset-conversion/runtime-benchmarks",
 	"pallet-assets-freezer/runtime-benchmarks",
 	"pallet-assets/runtime-benchmarks",
@@ -128,6 +129,7 @@ runtime-benchmarks = [
 	"pallet-nfts/runtime-benchmarks",
 	"pallet-proxy/runtime-benchmarks",
 	"pallet-timestamp/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"pallet-uniques/runtime-benchmarks",
 	"pallet-utility/runtime-benchmarks",
 	"pallet-xcm-benchmarks/runtime-benchmarks",
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs
index eb3e26764f6..64fdf488372 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs
+++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs
@@ -175,6 +175,7 @@ impl frame_system::Config for Runtime {
 	type Version = Version;
 	type AccountData = pallet_balances::AccountData<Balance>;
 	type SystemWeightInfo = weights::frame_system::WeightInfo<Runtime>;
+	type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo<Runtime>;
 	type SS58Prefix = SS58Prefix;
 	type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
 	type MaxConsumers = frame_support::traits::ConstU32<16>;
@@ -229,6 +230,7 @@ impl pallet_transaction_payment::Config for Runtime {
 	type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
 	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
 	type OperationalFeeMultiplier = ConstU8<5>;
+	type WeightInfo = weights::pallet_transaction_payment::WeightInfo<Runtime>;
 }
 
 parameter_types! {
@@ -818,6 +820,9 @@ impl pallet_asset_conversion_tx_payment::Config for Runtime {
 		AssetConversion,
 		ResolveAssetTo<StakingPot, NativeAndAssets>,
 	>;
+	type WeightInfo = weights::pallet_asset_conversion_tx_payment::WeightInfo<Runtime>;
+	#[cfg(feature = "runtime-benchmarks")]
+	type BenchmarkHelper = AssetConversionTxHelper;
 }
 
 parameter_types! {
@@ -998,8 +1003,8 @@ pub type Block = generic::Block<Header, UncheckedExtrinsic>;
 pub type SignedBlock = generic::SignedBlock<Block>;
 /// BlockId type as expected by this runtime.
 pub type BlockId = generic::BlockId<Block>;
-/// The SignedExtension to the basic transaction logic.
-pub type SignedExtra = (
+/// The extension to the basic transaction logic.
+pub type TxExtension = (
 	frame_system::CheckNonZeroSender<Runtime>,
 	frame_system::CheckSpecVersion<Runtime>,
 	frame_system::CheckTxVersion<Runtime>,
@@ -1013,7 +1018,7 @@ pub type SignedExtra = (
 );
 /// Unchecked extrinsic type as expected by this runtime.
 pub type UncheckedExtrinsic =
-	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
 /// Migrations to apply on runtime upgrade.
 pub type Migrations = (
 	InitStorageVersions,
@@ -1100,14 +1105,81 @@ pub type Executive = frame_executive::Executive<
 
 type XcmTrustedQueryResult = Result<bool, xcm_runtime_apis::trusted_query::Error>;
 
+#[cfg(feature = "runtime-benchmarks")]
+pub struct AssetConversionTxHelper;
+
+#[cfg(feature = "runtime-benchmarks")]
+impl
+	pallet_asset_conversion_tx_payment::BenchmarkHelperTrait<
+		AccountId,
+		cumulus_primitives_core::Location,
+		cumulus_primitives_core::Location,
+	> for AssetConversionTxHelper
+{
+	fn create_asset_id_parameter(seed: u32) -> (Location, Location) {
+		// Use a different parachain' foreign assets pallet so that the asset is indeed foreign.
+		let asset_id = Location::new(
+			1,
+			[
+				cumulus_primitives_core::Junction::Parachain(3000),
+				cumulus_primitives_core::Junction::PalletInstance(53),
+				cumulus_primitives_core::Junction::GeneralIndex(seed.into()),
+			],
+		);
+		(asset_id.clone(), asset_id)
+	}
+
+	fn setup_balances_and_pool(asset_id: cumulus_primitives_core::Location, account: AccountId) {
+		use frame_support::{assert_ok, traits::fungibles::Mutate};
+		assert_ok!(ForeignAssets::force_create(
+			RuntimeOrigin::root(),
+			asset_id.clone().into(),
+			account.clone().into(), /* owner */
+			true,                   /* is_sufficient */
+			1,
+		));
+
+		let lp_provider = account.clone();
+		use frame_support::traits::Currency;
+		let _ = Balances::deposit_creating(&lp_provider, u64::MAX.into());
+		assert_ok!(ForeignAssets::mint_into(
+			asset_id.clone().into(),
+			&lp_provider,
+			u64::MAX.into()
+		));
+
+		let token_native = alloc::boxed::Box::new(TokenLocation::get());
+		let token_second = alloc::boxed::Box::new(asset_id);
+
+		assert_ok!(AssetConversion::create_pool(
+			RuntimeOrigin::signed(lp_provider.clone()),
+			token_native.clone(),
+			token_second.clone()
+		));
+
+		assert_ok!(AssetConversion::add_liquidity(
+			RuntimeOrigin::signed(lp_provider.clone()),
+			token_native,
+			token_second,
+			(u32::MAX / 8).into(), // 1 desired
+			u32::MAX.into(),       // 2 desired
+			1,                     // 1 min
+			1,                     // 2 min
+			lp_provider,
+		));
+	}
+}
+
 #[cfg(feature = "runtime-benchmarks")]
 mod benches {
 	frame_benchmarking::define_benchmarks!(
 		[frame_system, SystemBench::<Runtime>]
+		[frame_system_extensions, SystemExtensionsBench::<Runtime>]
 		[pallet_assets, Local]
 		[pallet_assets, Foreign]
 		[pallet_assets, Pool]
 		[pallet_asset_conversion, AssetConversion]
+		[pallet_asset_conversion_tx_payment, AssetTxPayment]
 		[pallet_balances, Balances]
 		[pallet_message_queue, MessageQueue]
 		[pallet_multisig, Multisig]
@@ -1118,6 +1190,7 @@ mod benches {
 		[pallet_uniques, Uniques]
 		[pallet_utility, Utility]
 		[pallet_timestamp, Timestamp]
+		[pallet_transaction_payment, TransactionPayment]
 		[pallet_collator_selection, CollatorSelection]
 		[cumulus_pallet_parachain_system, ParachainSystem]
 		[cumulus_pallet_xcmp_queue, XcmpQueue]
@@ -1445,6 +1518,7 @@ impl_runtime_apis! {
 			use frame_benchmarking::{Benchmarking, BenchmarkList};
 			use frame_support::traits::StorageInfoTrait;
 			use frame_system_benchmarking::Pallet as SystemBench;
+			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
 			use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
 			use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
 			use pallet_xcm_bridge_hub_router::benchmarking::Pallet as XcmBridgeHubRouterBench;
@@ -1479,6 +1553,7 @@ impl_runtime_apis! {
 			use sp_storage::TrackedStorageKey;
 
 			use frame_system_benchmarking::Pallet as SystemBench;
+			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
 			impl frame_system_benchmarking::Config for Runtime {
 				fn setup_set_code_requirements(code: &alloc::vec::Vec<u8>) -> Result<(), BenchmarkError> {
 					ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32);
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/frame_system_extensions.rs
new file mode 100644
index 00000000000..182410f20ff
--- /dev/null
+++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/frame_system_extensions.rs
@@ -0,0 +1,132 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `frame_system_extensions`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
+//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-rococo-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/release/polkadot-parachain
+// benchmark
+// pallet
+// --wasm-execution=compiled
+// --pallet=frame_system_extensions
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --extrinsic=*
+// --steps=2
+// --repeat=2
+// --json
+// --header=./cumulus/file_header.txt
+// --output=./cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/
+// --chain=asset-hub-rococo-dev
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `frame_system_extensions`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> frame_system::ExtensionsWeightInfo for WeightInfo<T> {
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_genesis() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `54`
+		//  Estimated: `3509`
+		// Minimum execution time: 3_637_000 picoseconds.
+		Weight::from_parts(6_382_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_mortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 5_841_000 picoseconds.
+		Weight::from_parts(8_776_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_immortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 5_841_000 picoseconds.
+		Weight::from_parts(8_776_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	fn check_non_zero_sender() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 561_000 picoseconds.
+		Weight::from_parts(2_705_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_nonce() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 3_316_000 picoseconds.
+		Weight::from_parts(5_771_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_spec_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 511_000 picoseconds.
+		Weight::from_parts(2_575_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_tx_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 501_000 picoseconds.
+		Weight::from_parts(2_595_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	/// Storage: `System::AllExtrinsicsLen` (r:1 w:1)
+	/// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
+	/// Storage: `System::BlockWeight` (r:1 w:1)
+	/// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`)
+	fn check_weight() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `24`
+		//  Estimated: `1533`
+		// Minimum execution time: 3_687_000 picoseconds.
+		Weight::from_parts(6_192_000, 0)
+			.saturating_add(Weight::from_parts(0, 1533))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+}
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/mod.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/mod.rs
index f20790cde39..33f111009ed 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/mod.rs
+++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/mod.rs
@@ -19,8 +19,10 @@ pub mod cumulus_pallet_parachain_system;
 pub mod cumulus_pallet_xcmp_queue;
 pub mod extrinsic_weights;
 pub mod frame_system;
+pub mod frame_system_extensions;
 pub mod pallet_asset_conversion;
 pub mod pallet_asset_conversion_ops;
+pub mod pallet_asset_conversion_tx_payment;
 pub mod pallet_assets_foreign;
 pub mod pallet_assets_local;
 pub mod pallet_assets_pool;
@@ -33,6 +35,7 @@ pub mod pallet_nfts;
 pub mod pallet_proxy;
 pub mod pallet_session;
 pub mod pallet_timestamp;
+pub mod pallet_transaction_payment;
 pub mod pallet_uniques;
 pub mod pallet_utility;
 pub mod pallet_xcm;
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_asset_conversion_tx_payment.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_asset_conversion_tx_payment.rs
new file mode 100644
index 00000000000..0a639b368af
--- /dev/null
+++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_asset_conversion_tx_payment.rs
@@ -0,0 +1,92 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `pallet_asset_conversion_tx_payment`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
+//! DATE: 2024-01-04, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `Georges-MacBook-Pro.local`, CPU: `<UNKNOWN>`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-rococo-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/debug/polkadot-parachain
+// benchmark
+// pallet
+// --wasm-execution=compiled
+// --pallet=pallet_asset_conversion_tx_payment
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --extrinsic=*
+// --steps=2
+// --repeat=2
+// --json
+// --header=./cumulus/file_header.txt
+// --output=./cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/
+// --chain=asset-hub-rococo-dev
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `pallet_asset_conversion_tx_payment`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> pallet_asset_conversion_tx_payment::WeightInfo for WeightInfo<T> {
+	fn charge_asset_tx_payment_zero() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 7_000_000 picoseconds.
+		Weight::from_parts(10_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	/// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0)
+	/// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:0)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	fn charge_asset_tx_payment_native() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `4`
+		//  Estimated: `3593`
+		// Minimum execution time: 209_000_000 picoseconds.
+		Weight::from_parts(212_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 3593))
+			.saturating_add(T::DbWeight::get().reads(2))
+	}
+	/// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0)
+	/// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
+	/// Storage: `ForeignAssets::Asset` (r:1 w:1)
+	/// Proof: `ForeignAssets::Asset` (`max_values`: None, `max_size`: Some(808), added: 3283, mode: `MaxEncodedLen`)
+	/// Storage: `ForeignAssets::Account` (r:2 w:2)
+	/// Proof: `ForeignAssets::Account` (`max_values`: None, `max_size`: Some(732), added: 3207, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:2 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	fn charge_asset_tx_payment_asset() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `631`
+		//  Estimated: `7404`
+		// Minimum execution time: 1_228_000_000 picoseconds.
+		Weight::from_parts(1_268_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 7404))
+			.saturating_add(T::DbWeight::get().reads(6))
+			.saturating_add(T::DbWeight::get().writes(4))
+	}
+}
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_transaction_payment.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_transaction_payment.rs
new file mode 100644
index 00000000000..035f9a6dbe5
--- /dev/null
+++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_transaction_payment.rs
@@ -0,0 +1,67 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `pallet_transaction_payment`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
+//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-rococo-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/release/polkadot-parachain
+// benchmark
+// pallet
+// --wasm-execution=compiled
+// --pallet=pallet_transaction_payment
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --extrinsic=*
+// --steps=2
+// --repeat=2
+// --json
+// --header=./cumulus/file_header.txt
+// --output=./cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/
+// --chain=asset-hub-rococo-dev
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `pallet_transaction_payment`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> pallet_transaction_payment::WeightInfo for WeightInfo<T> {
+	/// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0)
+	/// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	fn charge_transaction_payment() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `4`
+		//  Estimated: `3593`
+		// Minimum execution time: 33_363_000 picoseconds.
+		Weight::from_parts(38_793_000, 0)
+			.saturating_add(Weight::from_parts(0, 3593))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+}
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml b/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml
index 72a125cee2a..5fa48381b67 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml
+++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/Cargo.toml
@@ -118,6 +118,7 @@ runtime-benchmarks = [
 	"frame-system-benchmarking/runtime-benchmarks",
 	"frame-system/runtime-benchmarks",
 	"pallet-asset-conversion-ops/runtime-benchmarks",
+	"pallet-asset-conversion-tx-payment/runtime-benchmarks",
 	"pallet-asset-conversion/runtime-benchmarks",
 	"pallet-assets-freezer/runtime-benchmarks",
 	"pallet-assets/runtime-benchmarks",
@@ -130,6 +131,7 @@ runtime-benchmarks = [
 	"pallet-proxy/runtime-benchmarks",
 	"pallet-state-trie-migration/runtime-benchmarks",
 	"pallet-timestamp/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"pallet-uniques/runtime-benchmarks",
 	"pallet-utility/runtime-benchmarks",
 	"pallet-xcm-benchmarks/runtime-benchmarks",
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
index 74e75ebb489..32d12174953 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
+++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
@@ -175,6 +175,7 @@ impl frame_system::Config for Runtime {
 	type Version = Version;
 	type AccountData = pallet_balances::AccountData<Balance>;
 	type SystemWeightInfo = weights::frame_system::WeightInfo<Runtime>;
+	type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo<Runtime>;
 	type SS58Prefix = SS58Prefix;
 	type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
 	type MaxConsumers = frame_support::traits::ConstU32<16>;
@@ -229,6 +230,7 @@ impl pallet_transaction_payment::Config for Runtime {
 	type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
 	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
 	type OperationalFeeMultiplier = ConstU8<5>;
+	type WeightInfo = weights::pallet_transaction_payment::WeightInfo<Runtime>;
 }
 
 parameter_types! {
@@ -811,6 +813,9 @@ impl pallet_asset_conversion_tx_payment::Config for Runtime {
 		AssetConversion,
 		ResolveAssetTo<StakingPot, NativeAndAssets>,
 	>;
+	type WeightInfo = weights::pallet_asset_conversion_tx_payment::WeightInfo<Runtime>;
+	#[cfg(feature = "runtime-benchmarks")]
+	type BenchmarkHelper = AssetConversionTxHelper;
 }
 
 parameter_types! {
@@ -994,8 +999,8 @@ pub type Block = generic::Block<Header, UncheckedExtrinsic>;
 pub type SignedBlock = generic::SignedBlock<Block>;
 /// BlockId type as expected by this runtime.
 pub type BlockId = generic::BlockId<Block>;
-/// The SignedExtension to the basic transaction logic.
-pub type SignedExtra = (
+/// The extension to the basic transaction logic.
+pub type TxExtension = (
 	frame_system::CheckNonZeroSender<Runtime>,
 	frame_system::CheckSpecVersion<Runtime>,
 	frame_system::CheckTxVersion<Runtime>,
@@ -1009,7 +1014,7 @@ pub type SignedExtra = (
 );
 /// Unchecked extrinsic type as expected by this runtime.
 pub type UncheckedExtrinsic =
-	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
 
 /// Migrations to apply on runtime upgrade.
 pub type Migrations = (
@@ -1148,14 +1153,86 @@ pub type Executive = frame_executive::Executive<
 	Migrations,
 >;
 
+#[cfg(feature = "runtime-benchmarks")]
+pub struct AssetConversionTxHelper;
+
+#[cfg(feature = "runtime-benchmarks")]
+impl
+	pallet_asset_conversion_tx_payment::BenchmarkHelperTrait<
+		AccountId,
+		cumulus_primitives_core::Location,
+		cumulus_primitives_core::Location,
+	> for AssetConversionTxHelper
+{
+	fn create_asset_id_parameter(
+		seed: u32,
+	) -> (cumulus_primitives_core::Location, cumulus_primitives_core::Location) {
+		// Use a different parachain' foreign assets pallet so that the asset is indeed foreign.
+		let asset_id = cumulus_primitives_core::Location::new(
+			1,
+			[
+				cumulus_primitives_core::Junction::Parachain(3000),
+				cumulus_primitives_core::Junction::PalletInstance(53),
+				cumulus_primitives_core::Junction::GeneralIndex(seed.into()),
+			],
+		);
+		(asset_id.clone(), asset_id)
+	}
+
+	fn setup_balances_and_pool(asset_id: cumulus_primitives_core::Location, account: AccountId) {
+		use frame_support::{assert_ok, traits::fungibles::Mutate};
+		assert_ok!(ForeignAssets::force_create(
+			RuntimeOrigin::root(),
+			asset_id.clone().into(),
+			account.clone().into(), /* owner */
+			true,                   /* is_sufficient */
+			1,
+		));
+
+		let lp_provider = account.clone();
+		use frame_support::traits::Currency;
+		let _ = Balances::deposit_creating(&lp_provider, u64::MAX.into());
+		assert_ok!(ForeignAssets::mint_into(
+			asset_id.clone().into(),
+			&lp_provider,
+			u64::MAX.into()
+		));
+
+		let token_native = alloc::boxed::Box::new(cumulus_primitives_core::Location::new(
+			1,
+			cumulus_primitives_core::Junctions::Here,
+		));
+		let token_second = alloc::boxed::Box::new(asset_id);
+
+		assert_ok!(AssetConversion::create_pool(
+			RuntimeOrigin::signed(lp_provider.clone()),
+			token_native.clone(),
+			token_second.clone()
+		));
+
+		assert_ok!(AssetConversion::add_liquidity(
+			RuntimeOrigin::signed(lp_provider.clone()),
+			token_native,
+			token_second,
+			(u32::MAX / 2).into(), // 1 desired
+			u32::MAX.into(),       // 2 desired
+			1,                     // 1 min
+			1,                     // 2 min
+			lp_provider,
+		));
+	}
+}
+
 #[cfg(feature = "runtime-benchmarks")]
 mod benches {
 	frame_benchmarking::define_benchmarks!(
 		[frame_system, SystemBench::<Runtime>]
+		[frame_system_extensions, SystemExtensionsBench::<Runtime>]
 		[pallet_assets, Local]
 		[pallet_assets, Foreign]
 		[pallet_assets, Pool]
 		[pallet_asset_conversion, AssetConversion]
+		[pallet_asset_conversion_tx_payment, AssetTxPayment]
 		[pallet_balances, Balances]
 		[pallet_message_queue, MessageQueue]
 		[pallet_multisig, Multisig]
@@ -1166,6 +1243,7 @@ mod benches {
 		[pallet_uniques, Uniques]
 		[pallet_utility, Utility]
 		[pallet_timestamp, Timestamp]
+		[pallet_transaction_payment, TransactionPayment]
 		[pallet_collator_selection, CollatorSelection]
 		[cumulus_pallet_parachain_system, ParachainSystem]
 		[cumulus_pallet_xcmp_queue, XcmpQueue]
@@ -1539,6 +1617,7 @@ impl_runtime_apis! {
 			use frame_benchmarking::{Benchmarking, BenchmarkList};
 			use frame_support::traits::StorageInfoTrait;
 			use frame_system_benchmarking::Pallet as SystemBench;
+			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
 			use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
 			use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
 			use pallet_xcm_bridge_hub_router::benchmarking::Pallet as XcmBridgeHubRouterBench;
@@ -1573,6 +1652,7 @@ impl_runtime_apis! {
 			use sp_storage::TrackedStorageKey;
 
 			use frame_system_benchmarking::Pallet as SystemBench;
+			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
 			impl frame_system_benchmarking::Config for Runtime {
 				fn setup_set_code_requirements(code: &alloc::vec::Vec<u8>) -> Result<(), BenchmarkError> {
 					ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32);
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/frame_system_extensions.rs
new file mode 100644
index 00000000000..e8dd9763c28
--- /dev/null
+++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/frame_system_extensions.rs
@@ -0,0 +1,132 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `frame_system_extensions`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
+//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-westend-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/release/polkadot-parachain
+// benchmark
+// pallet
+// --wasm-execution=compiled
+// --pallet=frame_system_extensions
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --extrinsic=*
+// --steps=2
+// --repeat=2
+// --json
+// --header=./cumulus/file_header.txt
+// --output=./cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/
+// --chain=asset-hub-westend-dev
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `frame_system_extensions`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> frame_system::ExtensionsWeightInfo for WeightInfo<T> {
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_genesis() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `54`
+		//  Estimated: `3509`
+		// Minimum execution time: 3_206_000 picoseconds.
+		Weight::from_parts(6_212_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_mortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 5_851_000 picoseconds.
+		Weight::from_parts(8_847_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_immortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 5_851_000 picoseconds.
+		Weight::from_parts(8_847_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	fn check_non_zero_sender() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 631_000 picoseconds.
+		Weight::from_parts(3_086_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_nonce() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 3_446_000 picoseconds.
+		Weight::from_parts(5_911_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_spec_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 481_000 picoseconds.
+		Weight::from_parts(2_916_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_tx_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 501_000 picoseconds.
+		Weight::from_parts(2_595_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	/// Storage: `System::AllExtrinsicsLen` (r:1 w:1)
+	/// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
+	/// Storage: `System::BlockWeight` (r:1 w:1)
+	/// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`)
+	fn check_weight() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `24`
+		//  Estimated: `1533`
+		// Minimum execution time: 3_927_000 picoseconds.
+		Weight::from_parts(6_613_000, 0)
+			.saturating_add(Weight::from_parts(0, 1533))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+}
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/mod.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/mod.rs
index 4eebb1f8d78..b0f986768f4 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/mod.rs
+++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/mod.rs
@@ -18,8 +18,10 @@ pub mod cumulus_pallet_parachain_system;
 pub mod cumulus_pallet_xcmp_queue;
 pub mod extrinsic_weights;
 pub mod frame_system;
+pub mod frame_system_extensions;
 pub mod pallet_asset_conversion;
 pub mod pallet_asset_conversion_ops;
+pub mod pallet_asset_conversion_tx_payment;
 pub mod pallet_assets_foreign;
 pub mod pallet_assets_local;
 pub mod pallet_assets_pool;
@@ -32,6 +34,7 @@ pub mod pallet_nfts;
 pub mod pallet_proxy;
 pub mod pallet_session;
 pub mod pallet_timestamp;
+pub mod pallet_transaction_payment;
 pub mod pallet_uniques;
 pub mod pallet_utility;
 pub mod pallet_xcm;
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_asset_conversion_tx_payment.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_asset_conversion_tx_payment.rs
new file mode 100644
index 00000000000..8fe302630fb
--- /dev/null
+++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_asset_conversion_tx_payment.rs
@@ -0,0 +1,92 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `pallet_asset_conversion_tx_payment`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
+//! DATE: 2024-01-04, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `Georges-MacBook-Pro.local`, CPU: `<UNKNOWN>`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-westend-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/debug/polkadot-parachain
+// benchmark
+// pallet
+// --wasm-execution=compiled
+// --pallet=pallet_asset_conversion_tx_payment
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --extrinsic=*
+// --steps=2
+// --repeat=2
+// --json
+// --header=./cumulus/file_header.txt
+// --output=./cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/
+// --chain=asset-hub-westend-dev
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `pallet_asset_conversion_tx_payment`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> pallet_asset_conversion_tx_payment::WeightInfo for WeightInfo<T> {
+	fn charge_asset_tx_payment_zero() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 8_000_000 picoseconds.
+		Weight::from_parts(9_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	/// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0)
+	/// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:0)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	fn charge_asset_tx_payment_native() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `4`
+		//  Estimated: `3593`
+		// Minimum execution time: 214_000_000 picoseconds.
+		Weight::from_parts(219_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 3593))
+			.saturating_add(T::DbWeight::get().reads(2))
+	}
+	/// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0)
+	/// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
+	/// Storage: `ForeignAssets::Asset` (r:1 w:1)
+	/// Proof: `ForeignAssets::Asset` (`max_values`: None, `max_size`: Some(808), added: 3283, mode: `MaxEncodedLen`)
+	/// Storage: `ForeignAssets::Account` (r:2 w:2)
+	/// Proof: `ForeignAssets::Account` (`max_values`: None, `max_size`: Some(732), added: 3207, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:2 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	fn charge_asset_tx_payment_asset() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `631`
+		//  Estimated: `7404`
+		// Minimum execution time: 1_211_000_000 picoseconds.
+		Weight::from_parts(1_243_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 7404))
+			.saturating_add(T::DbWeight::get().reads(6))
+			.saturating_add(T::DbWeight::get().writes(4))
+	}
+}
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_transaction_payment.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_transaction_payment.rs
new file mode 100644
index 00000000000..b4c78a78b48
--- /dev/null
+++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_transaction_payment.rs
@@ -0,0 +1,67 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `pallet_transaction_payment`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
+//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-westend-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/release/polkadot-parachain
+// benchmark
+// pallet
+// --wasm-execution=compiled
+// --pallet=pallet_transaction_payment
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --extrinsic=*
+// --steps=2
+// --repeat=2
+// --json
+// --header=./cumulus/file_header.txt
+// --output=./cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/
+// --chain=asset-hub-westend-dev
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `pallet_transaction_payment`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> pallet_transaction_payment::WeightInfo for WeightInfo<T> {
+	/// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0)
+	/// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	fn charge_transaction_payment() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `4`
+		//  Estimated: `3593`
+		// Minimum execution time: 40_847_000 picoseconds.
+		Weight::from_parts(49_674_000, 0)
+			.saturating_add(Weight::from_parts(0, 3593))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+}
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml
index fd5782d68e4..4af8a9f4385 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/Cargo.toml
@@ -241,6 +241,7 @@ runtime-benchmarks = [
 	"pallet-message-queue/runtime-benchmarks",
 	"pallet-multisig/runtime-benchmarks",
 	"pallet-timestamp/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"pallet-utility/runtime-benchmarks",
 	"pallet-xcm-benchmarks/runtime-benchmarks",
 	"pallet-xcm-bridge-hub/runtime-benchmarks",
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs
index c971fa59c68..c226ed9c4fa 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs
@@ -38,7 +38,7 @@ use frame_support::{
 use frame_system::{EnsureNever, EnsureRoot};
 use pallet_bridge_messages::LaneIdOf;
 use pallet_bridge_relayers::extension::{
-	BridgeRelayersSignedExtension, WithMessagesExtensionConfig,
+	BridgeRelayersTransactionExtension, WithMessagesExtensionConfig,
 };
 use pallet_xcm_bridge_hub::XcmAsPlainPayload;
 use polkadot_parachain_primitives::primitives::Sibling;
@@ -92,9 +92,9 @@ type FromRococoBulletinMessageBlobDispatcher = BridgeBlobDispatcher<
 	BridgeRococoToRococoBulletinMessagesPalletInstance,
 >;
 
-/// Signed extension that refunds relayers that are delivering messages from the Rococo Bulletin
-/// chain.
-pub type OnBridgeHubRococoRefundRococoBulletinMessages = BridgeRelayersSignedExtension<
+/// Transaction extension that refunds relayers that are delivering messages from the Rococo
+/// Bulletin chain.
+pub type OnBridgeHubRococoRefundRococoBulletinMessages = BridgeRelayersTransactionExtension<
 	Runtime,
 	WithMessagesExtensionConfig<
 		StrOnBridgeHubRococoRefundRococoBulletinMessages,
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs
index 8fe04572310..29ea4e05f29 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs
@@ -37,7 +37,7 @@ use frame_support::{parameter_types, traits::PalletInfoAccess};
 use frame_system::{EnsureNever, EnsureRoot};
 use pallet_bridge_messages::LaneIdOf;
 use pallet_bridge_relayers::extension::{
-	BridgeRelayersSignedExtension, WithMessagesExtensionConfig,
+	BridgeRelayersTransactionExtension, WithMessagesExtensionConfig,
 };
 use parachains_common::xcm_config::{AllSiblingSystemParachains, RelayOrOtherSystemParachains};
 use polkadot_parachain_primitives::primitives::Sibling;
@@ -84,8 +84,9 @@ pub type ToWestendBridgeHubMessagesDeliveryProof<MI> =
 type FromWestendMessageBlobDispatcher =
 	BridgeBlobDispatcher<XcmRouter, UniversalLocation, BridgeRococoToWestendMessagesPalletInstance>;
 
-/// Signed extension that refunds relayers that are delivering messages from the Westend parachain.
-pub type OnBridgeHubRococoRefundBridgeHubWestendMessages = BridgeRelayersSignedExtension<
+/// Transaction extension that refunds relayers that are delivering messages from the Westend
+/// parachain.
+pub type OnBridgeHubRococoRefundBridgeHubWestendMessages = BridgeRelayersTransactionExtension<
 	Runtime,
 	WithMessagesExtensionConfig<
 		StrOnBridgeHubRococoRefundBridgeHubWestendMessages,
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs
index cafd2b33fa8..259b0355916 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs
@@ -120,8 +120,8 @@ pub type SignedBlock = generic::SignedBlock<Block>;
 /// BlockId type as expected by this runtime.
 pub type BlockId = generic::BlockId<Block>;
 
-/// The SignedExtension to the basic transaction logic.
-pub type SignedExtra = (
+/// The TransactionExtension to the basic transaction logic.
+pub type TxExtension = (
 	frame_system::CheckNonZeroSender<Runtime>,
 	frame_system::CheckSpecVersion<Runtime>,
 	frame_system::CheckTxVersion<Runtime>,
@@ -132,13 +132,13 @@ pub type SignedExtra = (
 	pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
 	BridgeRejectObsoleteHeadersAndMessages,
 	(bridge_to_westend_config::OnBridgeHubRococoRefundBridgeHubWestendMessages,),
-	cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim<Runtime>,
 	frame_metadata_hash_extension::CheckMetadataHash<Runtime>,
+	cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim<Runtime>,
 );
 
 /// Unchecked extrinsic type as expected by this runtime.
 pub type UncheckedExtrinsic =
-	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
 
 /// Migrations to apply on runtime upgrade.
 pub type Migrations = (
@@ -298,6 +298,8 @@ impl frame_system::Config for Runtime {
 	type DbWeight = RocksDbWeight;
 	/// Weight information for the extrinsics of this pallet.
 	type SystemWeightInfo = weights::frame_system::WeightInfo<Runtime>;
+	/// Weight information for the extensions of this pallet.
+	type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo<Runtime>;
 	/// Block & extrinsics weights: base values and limits.
 	type BlockWeights = RuntimeBlockWeights;
 	/// The maximum length of a block (in bytes).
@@ -358,6 +360,7 @@ impl pallet_transaction_payment::Config for Runtime {
 	type WeightToFee = WeightToFee;
 	type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
 	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
+	type WeightInfo = weights::pallet_transaction_payment::WeightInfo<Runtime>;
 }
 
 parameter_types! {
@@ -650,12 +653,14 @@ bridge_runtime_common::generate_bridge_reject_obsolete_headers_and_messages! {
 mod benches {
 	frame_benchmarking::define_benchmarks!(
 		[frame_system, SystemBench::<Runtime>]
+		[frame_system_extensions, SystemExtensionsBench::<Runtime>]
 		[pallet_balances, Balances]
 		[pallet_message_queue, MessageQueue]
 		[pallet_multisig, Multisig]
 		[pallet_session, SessionBench::<Runtime>]
 		[pallet_utility, Utility]
 		[pallet_timestamp, Timestamp]
+		[pallet_transaction_payment, TransactionPayment]
 		[pallet_collator_selection, CollatorSelection]
 		[cumulus_pallet_parachain_system, ParachainSystem]
 		[cumulus_pallet_xcmp_queue, XcmpQueue]
@@ -1037,6 +1042,7 @@ impl_runtime_apis! {
 			use frame_benchmarking::{Benchmarking, BenchmarkList};
 			use frame_support::traits::StorageInfoTrait;
 			use frame_system_benchmarking::Pallet as SystemBench;
+			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
 			use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
 			use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
 
@@ -1069,6 +1075,7 @@ impl_runtime_apis! {
 			use sp_storage::TrackedStorageKey;
 
 			use frame_system_benchmarking::Pallet as SystemBench;
+			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
 			impl frame_system_benchmarking::Config for Runtime {
 				fn setup_set_code_requirements(code: &alloc::vec::Vec<u8>) -> Result<(), BenchmarkError> {
 					ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32);
@@ -1538,16 +1545,16 @@ mod tests {
 	use codec::Encode;
 	use sp_runtime::{
 		generic::Era,
-		traits::{SignedExtension, Zero},
+		traits::{TransactionExtension, Zero},
 	};
 
 	#[test]
-	fn ensure_signed_extension_definition_is_compatible_with_relay() {
-		use bp_polkadot_core::SuffixedCommonSignedExtensionExt;
+	fn ensure_transaction_extension_definition_is_compatible_with_relay() {
+		use bp_polkadot_core::SuffixedCommonTransactionExtensionExt;
 
 		sp_io::TestExternalities::default().execute_with(|| {
             frame_system::BlockHash::<Runtime>::insert(BlockNumber::zero(), Hash::default());
-            let payload: SignedExtra = (
+            let payload: TxExtension = (
                 frame_system::CheckNonZeroSender::new(),
                 frame_system::CheckSpecVersion::new(),
                 frame_system::CheckTxVersion::new(),
@@ -1560,13 +1567,13 @@ mod tests {
                 (
                     bridge_to_westend_config::OnBridgeHubRococoRefundBridgeHubWestendMessages::default(),
                 ),
-                cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim::new(),
                 frame_metadata_hash_extension::CheckMetadataHash::new(false),
+				cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim::new(),
             );
 
             // for BridgeHubRococo
             {
-                let bhr_indirect_payload = bp_bridge_hub_rococo::SignedExtension::from_params(
+                let bhr_indirect_payload = bp_bridge_hub_rococo::TransactionExtension::from_params(
                     VERSION.spec_version,
                     VERSION.transaction_version,
                     bp_runtime::TransactionEra::Immortal,
@@ -1577,8 +1584,8 @@ mod tests {
                 );
                 assert_eq!(payload.encode().split_last().unwrap().1, bhr_indirect_payload.encode());
                 assert_eq!(
-                    payload.additional_signed().unwrap().encode().split_last().unwrap().1,
-                    bhr_indirect_payload.additional_signed().unwrap().encode()
+                    TxExtension::implicit(&payload).unwrap().encode().split_last().unwrap().1,
+                    sp_runtime::traits::TransactionExtension::<RuntimeCall>::implicit(&bhr_indirect_payload).unwrap().encode()
                 )
             }
         });
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/frame_system_extensions.rs
new file mode 100644
index 00000000000..64eef1b4f74
--- /dev/null
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/frame_system_extensions.rs
@@ -0,0 +1,132 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `frame_system_extensions`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
+//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-rococo-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/release/polkadot-parachain
+// benchmark
+// pallet
+// --wasm-execution=compiled
+// --pallet=frame_system_extensions
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --extrinsic=*
+// --steps=2
+// --repeat=2
+// --json
+// --header=./cumulus/file_header.txt
+// --output=./cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/
+// --chain=bridge-hub-rococo-dev
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `frame_system_extensions`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> frame_system::ExtensionsWeightInfo for WeightInfo<T> {
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_genesis() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `54`
+		//  Estimated: `3509`
+		// Minimum execution time: 3_136_000 picoseconds.
+		Weight::from_parts(5_842_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_mortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 5_771_000 picoseconds.
+		Weight::from_parts(8_857_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_immortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 5_771_000 picoseconds.
+		Weight::from_parts(8_857_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	fn check_non_zero_sender() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 732_000 picoseconds.
+		Weight::from_parts(2_875_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_nonce() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 3_627_000 picoseconds.
+		Weight::from_parts(6_322_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_spec_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 471_000 picoseconds.
+		Weight::from_parts(2_455_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_tx_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 491_000 picoseconds.
+		Weight::from_parts(2_916_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	/// Storage: `System::AllExtrinsicsLen` (r:1 w:1)
+	/// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
+	/// Storage: `System::BlockWeight` (r:1 w:1)
+	/// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`)
+	fn check_weight() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `24`
+		//  Estimated: `1533`
+		// Minimum execution time: 3_798_000 picoseconds.
+		Weight::from_parts(6_272_000, 0)
+			.saturating_add(Weight::from_parts(0, 1533))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+}
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/mod.rs
index 517b3eb69fc..74796e626a2 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/mod.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/mod.rs
@@ -27,6 +27,7 @@ pub mod cumulus_pallet_parachain_system;
 pub mod cumulus_pallet_xcmp_queue;
 pub mod extrinsic_weights;
 pub mod frame_system;
+pub mod frame_system_extensions;
 pub mod pallet_balances;
 pub mod pallet_bridge_grandpa;
 pub mod pallet_bridge_messages_rococo_to_rococo_bulletin;
@@ -38,6 +39,7 @@ pub mod pallet_message_queue;
 pub mod pallet_multisig;
 pub mod pallet_session;
 pub mod pallet_timestamp;
+pub mod pallet_transaction_payment;
 pub mod pallet_utility;
 pub mod pallet_xcm;
 pub mod paritydb_weights;
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_transaction_payment.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_transaction_payment.rs
new file mode 100644
index 00000000000..71d17e7259f
--- /dev/null
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_transaction_payment.rs
@@ -0,0 +1,67 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `pallet_transaction_payment`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
+//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-rococo-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/release/polkadot-parachain
+// benchmark
+// pallet
+// --wasm-execution=compiled
+// --pallet=pallet_transaction_payment
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --extrinsic=*
+// --steps=2
+// --repeat=2
+// --json
+// --header=./cumulus/file_header.txt
+// --output=./cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/
+// --chain=bridge-hub-rococo-dev
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `pallet_transaction_payment`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> pallet_transaction_payment::WeightInfo for WeightInfo<T> {
+	/// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0)
+	/// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	fn charge_transaction_payment() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `3`
+		//  Estimated: `3593`
+		// Minimum execution time: 34_956_000 picoseconds.
+		Weight::from_parts(40_788_000, 0)
+			.saturating_add(Weight::from_parts(0, 3593))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+}
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs
index 7a0f1462e7a..8be2993c68f 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/snowbridge.rs
@@ -21,7 +21,7 @@ use bridge_hub_rococo_runtime::{
 	bridge_to_westend_config::OnBridgeHubRococoRefundBridgeHubWestendMessages,
 	xcm_config::XcmConfig, AllPalletsWithoutSystem, BridgeRejectObsoleteHeadersAndMessages,
 	Executive, MessageQueueServiceWeight, Runtime, RuntimeCall, RuntimeEvent, SessionKeys,
-	SignedExtra, UncheckedExtrinsic,
+	TxExtension, UncheckedExtrinsic,
 };
 use codec::{Decode, Encode};
 use cumulus_primitives_core::XcmError::{FailedToTransactAsset, NotHoldingFees};
@@ -170,7 +170,7 @@ fn construct_extrinsic(
 	call: RuntimeCall,
 ) -> UncheckedExtrinsic {
 	let account_id = AccountId32::from(sender.public());
-	let extra: SignedExtra = (
+	let tx_ext: TxExtension = (
 		frame_system::CheckNonZeroSender::<Runtime>::new(),
 		frame_system::CheckSpecVersion::<Runtime>::new(),
 		frame_system::CheckTxVersion::<Runtime>::new(),
@@ -183,12 +183,12 @@ fn construct_extrinsic(
 		pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(0),
 		BridgeRejectObsoleteHeadersAndMessages::default(),
 		(OnBridgeHubRococoRefundBridgeHubWestendMessages::default(),),
-		cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim::new(),
 		frame_metadata_hash_extension::CheckMetadataHash::<Runtime>::new(false),
+		cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim::new(),
 	);
-	let payload = SignedPayload::new(call.clone(), extra.clone()).unwrap();
+	let payload = SignedPayload::new(call.clone(), tx_ext.clone()).unwrap();
 	let signature = payload.using_encoded(|e| sender.sign(e));
-	UncheckedExtrinsic::new_signed(call, account_id.into(), Signature::Sr25519(signature), extra)
+	UncheckedExtrinsic::new_signed(call, account_id.into(), Signature::Sr25519(signature), tx_ext)
 }
 
 fn construct_and_apply_extrinsic(
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs
index 20bd5d12913..01674287fde 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs
@@ -18,13 +18,11 @@
 
 use bp_polkadot_core::Signature;
 use bridge_hub_rococo_runtime::{
-	bridge_common_config, bridge_to_bulletin_config,
-	bridge_to_ethereum_config::EthereumGatewayAddress,
-	bridge_to_westend_config,
-	xcm_config::{LocationToAccountId, RelayNetwork, TokenLocation, XcmConfig},
+	bridge_common_config, bridge_to_bulletin_config, bridge_to_westend_config,
+	xcm_config::{RelayNetwork, TokenLocation, XcmConfig},
 	AllPalletsWithoutSystem, BridgeRejectObsoleteHeadersAndMessages, Executive, ExistentialDeposit,
 	ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys,
-	SignedExtra, TransactionPayment, UncheckedExtrinsic,
+	TransactionPayment, TxExtension, UncheckedExtrinsic,
 };
 use bridge_hub_test_utils::SlotDurations;
 use codec::{Decode, Encode};
@@ -51,7 +49,7 @@ fn construct_extrinsic(
 	call: RuntimeCall,
 ) -> UncheckedExtrinsic {
 	let account_id = AccountId32::from(sender.public());
-	let extra: SignedExtra = (
+	let tx_ext: TxExtension = (
 		frame_system::CheckNonZeroSender::<Runtime>::new(),
 		frame_system::CheckSpecVersion::<Runtime>::new(),
 		frame_system::CheckTxVersion::<Runtime>::new(),
@@ -64,12 +62,13 @@ fn construct_extrinsic(
 		pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(0),
 		BridgeRejectObsoleteHeadersAndMessages::default(),
 		(bridge_to_westend_config::OnBridgeHubRococoRefundBridgeHubWestendMessages::default(),),
-		cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim::new(),
 		frame_metadata_hash_extension::CheckMetadataHash::new(false),
-	);
-	let payload = SignedPayload::new(call.clone(), extra.clone()).unwrap();
+		cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim::new(),
+	)
+		.into();
+	let payload = SignedPayload::new(call.clone(), tx_ext.clone()).unwrap();
 	let signature = payload.using_encoded(|e| sender.sign(e));
-	UncheckedExtrinsic::new_signed(call, account_id.into(), Signature::Sr25519(signature), extra)
+	UncheckedExtrinsic::new_signed(call, account_id.into(), Signature::Sr25519(signature), tx_ext)
 }
 
 fn construct_and_apply_extrinsic(
@@ -128,6 +127,9 @@ mod bridge_hub_westend_tests {
 		BridgeGrandpaWestendInstance, BridgeParachainWestendInstance, DeliveryRewardInBalance,
 		RelayersForLegacyLaneIdsMessagesInstance,
 	};
+	use bridge_hub_rococo_runtime::{
+		bridge_to_ethereum_config::EthereumGatewayAddress, xcm_config::LocationToAccountId,
+	};
 	use bridge_hub_test_utils::test_cases::from_parachain;
 	use bridge_to_westend_config::{
 		BridgeHubWestendLocation, WestendGlobalConsensusNetwork,
@@ -498,7 +500,10 @@ mod bridge_hub_bulletin_tests {
 	use super::*;
 	use bp_messages::{HashedLaneId, LaneIdType};
 	use bridge_common_config::BridgeGrandpaRococoBulletinInstance;
-	use bridge_hub_rococo_runtime::bridge_common_config::RelayersForPermissionlessLanesInstance;
+	use bridge_hub_rococo_runtime::{
+		bridge_common_config::RelayersForPermissionlessLanesInstance,
+		xcm_config::LocationToAccountId,
+	};
 	use bridge_hub_test_utils::test_cases::from_grandpa_chain;
 	use bridge_to_bulletin_config::{
 		RococoBulletinGlobalConsensusNetwork, RococoBulletinGlobalConsensusNetworkLocation,
@@ -818,9 +823,10 @@ fn location_conversion_works() {
 		let expected =
 			AccountId::from_string(tc.expected_account_id_str).expect("Invalid AccountId string");
 
-		let got = LocationToAccountHelper::<AccountId, LocationToAccountId>::convert_location(
-			tc.location.into(),
-		)
+		let got = LocationToAccountHelper::<
+			AccountId,
+			bridge_hub_rococo_runtime::xcm_config::LocationToAccountId,
+		>::convert_location(tc.location.into())
 		.unwrap();
 
 		assert_eq!(got, expected, "{}", tc.description);
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml
index 471158d9645..637e7c71064 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/Cargo.toml
@@ -238,6 +238,7 @@ runtime-benchmarks = [
 	"pallet-message-queue/runtime-benchmarks",
 	"pallet-multisig/runtime-benchmarks",
 	"pallet-timestamp/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"pallet-utility/runtime-benchmarks",
 	"pallet-xcm-benchmarks/runtime-benchmarks",
 	"pallet-xcm-bridge-hub/runtime-benchmarks",
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs
index e45654bc62b..aca51b320e9 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs
@@ -38,7 +38,7 @@ use frame_support::{
 use frame_system::{EnsureNever, EnsureRoot};
 use pallet_bridge_messages::LaneIdOf;
 use pallet_bridge_relayers::extension::{
-	BridgeRelayersSignedExtension, WithMessagesExtensionConfig,
+	BridgeRelayersTransactionExtension, WithMessagesExtensionConfig,
 };
 use parachains_common::xcm_config::{AllSiblingSystemParachains, RelayOrOtherSystemParachains};
 use polkadot_parachain_primitives::primitives::Sibling;
@@ -91,8 +91,9 @@ pub type ToRococoBridgeHubMessagesDeliveryProof<MI> =
 type FromRococoMessageBlobDispatcher =
 	BridgeBlobDispatcher<XcmRouter, UniversalLocation, BridgeWestendToRococoMessagesPalletInstance>;
 
-/// Signed extension that refunds relayers that are delivering messages from the Rococo parachain.
-pub type OnBridgeHubWestendRefundBridgeHubRococoMessages = BridgeRelayersSignedExtension<
+/// Transaction extension that refunds relayers that are delivering messages from the Rococo
+/// parachain.
+pub type OnBridgeHubWestendRefundBridgeHubRococoMessages = BridgeRelayersTransactionExtension<
 	Runtime,
 	WithMessagesExtensionConfig<
 		StrOnBridgeHubWestendRefundBridgeHubRococoMessages,
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs
index a18fc8accc9..85be26d1170 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs
@@ -116,8 +116,8 @@ pub type SignedBlock = generic::SignedBlock<Block>;
 /// BlockId type as expected by this runtime.
 pub type BlockId = generic::BlockId<Block>;
 
-/// The SignedExtension to the basic transaction logic.
-pub type SignedExtra = (
+/// The TransactionExtension to the basic transaction logic.
+pub type TxExtension = (
 	frame_system::CheckNonZeroSender<Runtime>,
 	frame_system::CheckSpecVersion<Runtime>,
 	frame_system::CheckTxVersion<Runtime>,
@@ -128,13 +128,13 @@ pub type SignedExtra = (
 	pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
 	BridgeRejectObsoleteHeadersAndMessages,
 	(bridge_to_rococo_config::OnBridgeHubWestendRefundBridgeHubRococoMessages,),
-	cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim<Runtime>,
 	frame_metadata_hash_extension::CheckMetadataHash<Runtime>,
+	cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim<Runtime>,
 );
 
 /// Unchecked extrinsic type as expected by this runtime.
 pub type UncheckedExtrinsic =
-	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
 
 /// Migrations to apply on runtime upgrade.
 pub type Migrations = (
@@ -283,6 +283,8 @@ impl frame_system::Config for Runtime {
 	type DbWeight = RocksDbWeight;
 	/// Weight information for the extrinsics of this pallet.
 	type SystemWeightInfo = weights::frame_system::WeightInfo<Runtime>;
+	/// Weight information for the transaction extensions of this pallet.
+	type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo<Runtime>;
 	/// Block & extrinsics weights: base values and limits.
 	type BlockWeights = RuntimeBlockWeights;
 	/// The maximum length of a block (in bytes).
@@ -343,6 +345,7 @@ impl pallet_transaction_payment::Config for Runtime {
 	type WeightToFee = WeightToFee;
 	type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
 	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
+	type WeightInfo = weights::pallet_transaction_payment::WeightInfo<Runtime>;
 }
 
 parameter_types! {
@@ -589,12 +592,14 @@ bridge_runtime_common::generate_bridge_reject_obsolete_headers_and_messages! {
 mod benches {
 	frame_benchmarking::define_benchmarks!(
 		[frame_system, SystemBench::<Runtime>]
+		[frame_system_extensions, SystemExtensionsBench::<Runtime>]
 		[pallet_balances, Balances]
 		[pallet_message_queue, MessageQueue]
 		[pallet_multisig, Multisig]
 		[pallet_session, SessionBench::<Runtime>]
 		[pallet_utility, Utility]
 		[pallet_timestamp, Timestamp]
+		[pallet_transaction_payment, TransactionPayment]
 		[pallet_collator_selection, CollatorSelection]
 		[cumulus_pallet_parachain_system, ParachainSystem]
 		[cumulus_pallet_xcmp_queue, XcmpQueue]
@@ -925,6 +930,7 @@ impl_runtime_apis! {
 			use frame_benchmarking::{Benchmarking, BenchmarkList};
 			use frame_support::traits::StorageInfoTrait;
 			use frame_system_benchmarking::Pallet as SystemBench;
+			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
 			use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
 			use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
 
@@ -954,6 +960,7 @@ impl_runtime_apis! {
 			use sp_storage::TrackedStorageKey;
 
 			use frame_system_benchmarking::Pallet as SystemBench;
+			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
 			impl frame_system_benchmarking::Config for Runtime {
 				fn setup_set_code_requirements(code: &alloc::vec::Vec<u8>) -> Result<(), BenchmarkError> {
 					ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32);
@@ -1359,16 +1366,16 @@ mod tests {
 	use codec::Encode;
 	use sp_runtime::{
 		generic::Era,
-		traits::{SignedExtension, Zero},
+		traits::{TransactionExtension, Zero},
 	};
 
 	#[test]
-	fn ensure_signed_extension_definition_is_compatible_with_relay() {
-		use bp_polkadot_core::SuffixedCommonSignedExtensionExt;
+	fn ensure_transaction_extension_definition_is_compatible_with_relay() {
+		use bp_polkadot_core::SuffixedCommonTransactionExtensionExt;
 
 		sp_io::TestExternalities::default().execute_with(|| {
             frame_system::BlockHash::<Runtime>::insert(BlockNumber::zero(), Hash::default());
-            let payload: SignedExtra = (
+            let payload: TxExtension = (
                 frame_system::CheckNonZeroSender::new(),
                 frame_system::CheckSpecVersion::new(),
                 frame_system::CheckTxVersion::new(),
@@ -1381,12 +1388,12 @@ mod tests {
                 (
                     bridge_to_rococo_config::OnBridgeHubWestendRefundBridgeHubRococoMessages::default(),
                 ),
+				frame_metadata_hash_extension::CheckMetadataHash::new(false),
                 cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim::new(),
-                frame_metadata_hash_extension::CheckMetadataHash::new(false),
             );
 
             {
-                let bh_indirect_payload = bp_bridge_hub_westend::SignedExtension::from_params(
+                let bh_indirect_payload = bp_bridge_hub_westend::TransactionExtension::from_params(
                     VERSION.spec_version,
                     VERSION.transaction_version,
                     bp_runtime::TransactionEra::Immortal,
@@ -1397,8 +1404,8 @@ mod tests {
                 );
                 assert_eq!(payload.encode().split_last().unwrap().1, bh_indirect_payload.encode());
                 assert_eq!(
-                    payload.additional_signed().unwrap().encode().split_last().unwrap().1,
-                    bh_indirect_payload.additional_signed().unwrap().encode()
+                    TxExtension::implicit(&payload).unwrap().encode().split_last().unwrap().1,
+                    sp_runtime::traits::TransactionExtension::<RuntimeCall>::implicit(&bh_indirect_payload).unwrap().encode()
                 )
             }
         });
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/frame_system_extensions.rs
new file mode 100644
index 00000000000..459b137d3b8
--- /dev/null
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/frame_system_extensions.rs
@@ -0,0 +1,132 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `frame_system_extensions`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
+//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-westend-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/release/polkadot-parachain
+// benchmark
+// pallet
+// --wasm-execution=compiled
+// --pallet=frame_system_extensions
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --extrinsic=*
+// --steps=2
+// --repeat=2
+// --json
+// --header=./cumulus/file_header.txt
+// --output=./cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/
+// --chain=bridge-hub-westend-dev
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `frame_system_extensions`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> frame_system::ExtensionsWeightInfo for WeightInfo<T> {
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_genesis() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `54`
+		//  Estimated: `3509`
+		// Minimum execution time: 3_166_000 picoseconds.
+		Weight::from_parts(6_021_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_mortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 5_651_000 picoseconds.
+		Weight::from_parts(9_177_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_immortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 5_651_000 picoseconds.
+		Weight::from_parts(9_177_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	fn check_non_zero_sender() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 601_000 picoseconds.
+		Weight::from_parts(2_805_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_nonce() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 3_727_000 picoseconds.
+		Weight::from_parts(6_051_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_spec_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 471_000 picoseconds.
+		Weight::from_parts(2_494_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_tx_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 521_000 picoseconds.
+		Weight::from_parts(2_655_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	/// Storage: `System::AllExtrinsicsLen` (r:1 w:1)
+	/// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
+	/// Storage: `System::BlockWeight` (r:1 w:1)
+	/// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`)
+	fn check_weight() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `24`
+		//  Estimated: `1533`
+		// Minimum execution time: 3_808_000 picoseconds.
+		Weight::from_parts(6_402_000, 0)
+			.saturating_add(Weight::from_parts(0, 1533))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+}
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/mod.rs
index d60529f9a23..c1c5c337aca 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/mod.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/mod.rs
@@ -27,6 +27,7 @@ pub mod cumulus_pallet_parachain_system;
 pub mod cumulus_pallet_xcmp_queue;
 pub mod extrinsic_weights;
 pub mod frame_system;
+pub mod frame_system_extensions;
 pub mod pallet_balances;
 pub mod pallet_bridge_grandpa;
 pub mod pallet_bridge_messages;
@@ -37,6 +38,7 @@ pub mod pallet_message_queue;
 pub mod pallet_multisig;
 pub mod pallet_session;
 pub mod pallet_timestamp;
+pub mod pallet_transaction_payment;
 pub mod pallet_utility;
 pub mod pallet_xcm;
 pub mod paritydb_weights;
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_transaction_payment.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_transaction_payment.rs
new file mode 100644
index 00000000000..92c53b91879
--- /dev/null
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_transaction_payment.rs
@@ -0,0 +1,67 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `pallet_transaction_payment`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
+//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-westend-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/release/polkadot-parachain
+// benchmark
+// pallet
+// --wasm-execution=compiled
+// --pallet=pallet_transaction_payment
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --extrinsic=*
+// --steps=2
+// --repeat=2
+// --json
+// --header=./cumulus/file_header.txt
+// --output=./cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/
+// --chain=bridge-hub-westend-dev
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `pallet_transaction_payment`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> pallet_transaction_payment::WeightInfo for WeightInfo<T> {
+	/// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0)
+	/// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	fn charge_transaction_payment() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `3`
+		//  Estimated: `3593`
+		// Minimum execution time: 40_286_000 picoseconds.
+		Weight::from_parts(45_816_000, 0)
+			.saturating_add(Weight::from_parts(0, 3593))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+}
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/snowbridge.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/snowbridge.rs
index c5f3871c079..1a1ce2a28ea 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/snowbridge.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/snowbridge.rs
@@ -22,7 +22,7 @@ use bp_polkadot_core::Signature;
 use bridge_hub_westend_runtime::{
 	bridge_to_rococo_config, xcm_config::XcmConfig, AllPalletsWithoutSystem,
 	BridgeRejectObsoleteHeadersAndMessages, Executive, MessageQueueServiceWeight, Runtime,
-	RuntimeCall, RuntimeEvent, SessionKeys, SignedExtra, UncheckedExtrinsic,
+	RuntimeCall, RuntimeEvent, SessionKeys, TxExtension, UncheckedExtrinsic,
 };
 use codec::{Decode, Encode};
 use cumulus_primitives_core::XcmError::{FailedToTransactAsset, NotHoldingFees};
@@ -171,7 +171,7 @@ fn construct_extrinsic(
 	call: RuntimeCall,
 ) -> UncheckedExtrinsic {
 	let account_id = AccountId32::from(sender.public());
-	let extra: SignedExtra = (
+	let extra: TxExtension = (
 		frame_system::CheckNonZeroSender::<Runtime>::new(),
 		frame_system::CheckSpecVersion::<Runtime>::new(),
 		frame_system::CheckTxVersion::<Runtime>::new(),
@@ -184,8 +184,8 @@ fn construct_extrinsic(
 		pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(0),
 		BridgeRejectObsoleteHeadersAndMessages::default(),
 		(bridge_to_rococo_config::OnBridgeHubWestendRefundBridgeHubRococoMessages::default(),),
-		cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim::new(),
 		frame_metadata_hash_extension::CheckMetadataHash::<Runtime>::new(false),
+		cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim::new(),
 	);
 	let payload = SignedPayload::new(call.clone(), extra.clone()).unwrap();
 	let signature = payload.using_encoded(|e| sender.sign(e));
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs
index c5a9b8c53a9..e5b67353c0f 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs
@@ -29,7 +29,7 @@ use bridge_hub_westend_runtime::{
 	xcm_config::{LocationToAccountId, RelayNetwork, WestendLocation, XcmConfig},
 	AllPalletsWithoutSystem, BridgeRejectObsoleteHeadersAndMessages, Executive, ExistentialDeposit,
 	ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys,
-	SignedExtra, TransactionPayment, UncheckedExtrinsic,
+	TransactionPayment, TxExtension, UncheckedExtrinsic,
 };
 use bridge_to_rococo_config::{
 	BridgeGrandpaRococoInstance, BridgeHubRococoLocation, BridgeParachainRococoInstance,
@@ -81,7 +81,7 @@ fn construct_extrinsic(
 	call: RuntimeCall,
 ) -> UncheckedExtrinsic {
 	let account_id = AccountId32::from(sender.public());
-	let extra: SignedExtra = (
+	let tx_ext: TxExtension = (
 		frame_system::CheckNonZeroSender::<Runtime>::new(),
 		frame_system::CheckSpecVersion::<Runtime>::new(),
 		frame_system::CheckTxVersion::<Runtime>::new(),
@@ -94,12 +94,13 @@ fn construct_extrinsic(
 		pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(0),
 		BridgeRejectObsoleteHeadersAndMessages::default(),
 		(bridge_to_rococo_config::OnBridgeHubWestendRefundBridgeHubRococoMessages::default(),),
-		cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim::new(),
 		frame_metadata_hash_extension::CheckMetadataHash::new(false),
-	);
-	let payload = SignedPayload::new(call.clone(), extra.clone()).unwrap();
+		cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim::new(),
+	)
+		.into();
+	let payload = SignedPayload::new(call.clone(), tx_ext.clone()).unwrap();
 	let signature = payload.using_encoded(|e| sender.sign(e));
-	UncheckedExtrinsic::new_signed(call, account_id.into(), Signature::Sr25519(signature), extra)
+	UncheckedExtrinsic::new_signed(call, account_id.into(), Signature::Sr25519(signature), tx_ext)
 }
 
 fn construct_and_apply_extrinsic(
diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs
index 9c5d6269dc0..24372f57ae7 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs
@@ -131,7 +131,7 @@ pub fn initialize_bridge_by_governance_works<Runtime, GrandpaPalletInstance>(
 		// execute XCM with Transacts to `initialize bridge` as governance does
 		assert_ok!(RuntimeHelper::<Runtime>::execute_as_governance(
 			initialize_call.encode(),
-			initialize_call.get_dispatch_info().weight,
+			initialize_call.get_dispatch_info().call_weight,
 		)
 		.ensure_complete());
 
@@ -172,7 +172,7 @@ pub fn change_bridge_grandpa_pallet_mode_by_governance_works<Runtime, GrandpaPal
 			// execute XCM with Transacts to `initialize bridge` as governance does
 			assert_ok!(RuntimeHelper::<Runtime>::execute_as_governance(
 				set_operating_mode_call.encode(),
-				set_operating_mode_call.get_dispatch_info().weight,
+				set_operating_mode_call.get_dispatch_info().call_weight,
 			)
 			.ensure_complete());
 
@@ -225,7 +225,7 @@ pub fn change_bridge_parachains_pallet_mode_by_governance_works<Runtime, Paracha
 			// execute XCM with Transacts to `initialize bridge` as governance does
 			assert_ok!(RuntimeHelper::<Runtime>::execute_as_governance(
 				set_operating_mode_call.encode(),
-				set_operating_mode_call.get_dispatch_info().weight,
+				set_operating_mode_call.get_dispatch_info().call_weight,
 			)
 			.ensure_complete());
 
@@ -278,7 +278,7 @@ pub fn change_bridge_messages_pallet_mode_by_governance_works<Runtime, MessagesP
 			// execute XCM with Transacts to `initialize bridge` as governance does
 			assert_ok!(RuntimeHelper::<Runtime>::execute_as_governance(
 				set_operating_mode_call.encode(),
-				set_operating_mode_call.get_dispatch_info().weight,
+				set_operating_mode_call.get_dispatch_info().call_weight,
 			)
 			.ensure_complete());
 
diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml b/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml
index 8a47af18524..e03fc934cea 100644
--- a/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml
+++ b/cumulus/parachains/runtimes/collectives/collectives-westend/Cargo.toml
@@ -124,6 +124,7 @@ runtime-benchmarks = [
 	"pallet-scheduler/runtime-benchmarks",
 	"pallet-state-trie-migration/runtime-benchmarks",
 	"pallet-timestamp/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"pallet-treasury/runtime-benchmarks",
 	"pallet-utility/runtime-benchmarks",
 	"pallet-xcm/runtime-benchmarks",
diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs
index b516c264e91..030ed930ed5 100644
--- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs
+++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs
@@ -185,6 +185,7 @@ impl frame_system::Config for Runtime {
 	type Version = Version;
 	type AccountData = pallet_balances::AccountData<Balance>;
 	type SystemWeightInfo = weights::frame_system::WeightInfo<Runtime>;
+	type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo<Runtime>;
 	type SS58Prefix = SS58Prefix;
 	type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
 	type MaxConsumers = frame_support::traits::ConstU32<16>;
@@ -239,6 +240,7 @@ impl pallet_transaction_payment::Config for Runtime {
 	type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
 	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
 	type OperationalFeeMultiplier = ConstU8<5>;
+	type WeightInfo = weights::pallet_transaction_payment::WeightInfo<Runtime>;
 }
 
 parameter_types! {
@@ -730,8 +732,8 @@ pub type Block = generic::Block<Header, UncheckedExtrinsic>;
 pub type SignedBlock = generic::SignedBlock<Block>;
 /// BlockId type as expected by this runtime.
 pub type BlockId = generic::BlockId<Block>;
-/// The SignedExtension to the basic transaction logic.
-pub type SignedExtra = (
+/// The extension to the basic transaction logic.
+pub type TxExtension = (
 	frame_system::CheckNonZeroSender<Runtime>,
 	frame_system::CheckSpecVersion<Runtime>,
 	frame_system::CheckTxVersion<Runtime>,
@@ -743,7 +745,7 @@ pub type SignedExtra = (
 );
 /// Unchecked extrinsic type as expected by this runtime.
 pub type UncheckedExtrinsic =
-	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
 /// All migrations executed on runtime upgrade as a nested tuple of types implementing
 /// `OnRuntimeUpgrade`. Included migrations must be idempotent.
 type Migrations = (
@@ -774,6 +776,7 @@ pub type Executive = frame_executive::Executive<
 mod benches {
 	frame_benchmarking::define_benchmarks!(
 		[frame_system, SystemBench::<Runtime>]
+		[frame_system_extensions, SystemExtensionsBench::<Runtime>]
 		[pallet_balances, Balances]
 		[pallet_message_queue, MessageQueue]
 		[pallet_multisig, Multisig]
@@ -781,6 +784,7 @@ mod benches {
 		[pallet_session, SessionBench::<Runtime>]
 		[pallet_utility, Utility]
 		[pallet_timestamp, Timestamp]
+		[pallet_transaction_payment, TransactionPayment]
 		[pallet_collator_selection, CollatorSelection]
 		[cumulus_pallet_parachain_system, ParachainSystem]
 		[cumulus_pallet_xcmp_queue, XcmpQueue]
@@ -1044,6 +1048,7 @@ impl_runtime_apis! {
 			use frame_benchmarking::{Benchmarking, BenchmarkList};
 			use frame_support::traits::StorageInfoTrait;
 			use frame_system_benchmarking::Pallet as SystemBench;
+			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
 			use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
 			use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
 
@@ -1061,6 +1066,7 @@ impl_runtime_apis! {
 			use sp_storage::TrackedStorageKey;
 
 			use frame_system_benchmarking::Pallet as SystemBench;
+			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
 			impl frame_system_benchmarking::Config for Runtime {
 				fn setup_set_code_requirements(code: &alloc::vec::Vec<u8>) -> Result<(), BenchmarkError> {
 					ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32);
diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/frame_system_extensions.rs
new file mode 100644
index 00000000000..f32f2730313
--- /dev/null
+++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/frame_system_extensions.rs
@@ -0,0 +1,132 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `frame_system_extensions`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
+//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("collectives-westend-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/release/polkadot-parachain
+// benchmark
+// pallet
+// --wasm-execution=compiled
+// --pallet=frame_system_extensions
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --extrinsic=*
+// --steps=2
+// --repeat=2
+// --json
+// --header=./cumulus/file_header.txt
+// --output=./cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/
+// --chain=collectives-westend-dev
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `frame_system_extensions`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> frame_system::ExtensionsWeightInfo for WeightInfo<T> {
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_genesis() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `54`
+		//  Estimated: `3509`
+		// Minimum execution time: 3_497_000 picoseconds.
+		Weight::from_parts(5_961_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_mortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 5_240_000 picoseconds.
+		Weight::from_parts(8_175_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_immortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 5_240_000 picoseconds.
+		Weight::from_parts(8_175_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	fn check_non_zero_sender() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 671_000 picoseconds.
+		Weight::from_parts(3_005_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_nonce() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 3_426_000 picoseconds.
+		Weight::from_parts(6_131_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_spec_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 501_000 picoseconds.
+		Weight::from_parts(2_715_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_tx_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 491_000 picoseconds.
+		Weight::from_parts(2_635_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	/// Storage: `System::AllExtrinsicsLen` (r:1 w:1)
+	/// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
+	/// Storage: `System::BlockWeight` (r:1 w:1)
+	/// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`)
+	fn check_weight() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `24`
+		//  Estimated: `1533`
+		// Minimum execution time: 3_958_000 picoseconds.
+		Weight::from_parts(6_753_000, 0)
+			.saturating_add(Weight::from_parts(0, 1533))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+}
diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/mod.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/mod.rs
index a9a298e547e..00b3bd92d5e 100644
--- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/mod.rs
+++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/mod.rs
@@ -18,6 +18,7 @@ pub mod cumulus_pallet_parachain_system;
 pub mod cumulus_pallet_xcmp_queue;
 pub mod extrinsic_weights;
 pub mod frame_system;
+pub mod frame_system_extensions;
 pub mod pallet_alliance;
 pub mod pallet_asset_rate;
 pub mod pallet_balances;
@@ -39,6 +40,7 @@ pub mod pallet_salary_fellowship_salary;
 pub mod pallet_scheduler;
 pub mod pallet_session;
 pub mod pallet_timestamp;
+pub mod pallet_transaction_payment;
 pub mod pallet_treasury;
 pub mod pallet_utility;
 pub mod pallet_xcm;
diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_transaction_payment.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_transaction_payment.rs
new file mode 100644
index 00000000000..5d077b89d56
--- /dev/null
+++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_transaction_payment.rs
@@ -0,0 +1,67 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `pallet_transaction_payment`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
+//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("collectives-westend-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/release/polkadot-parachain
+// benchmark
+// pallet
+// --wasm-execution=compiled
+// --pallet=pallet_transaction_payment
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --extrinsic=*
+// --steps=2
+// --repeat=2
+// --json
+// --header=./cumulus/file_header.txt
+// --output=./cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/
+// --chain=collectives-westend-dev
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `pallet_transaction_payment`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> pallet_transaction_payment::WeightInfo for WeightInfo<T> {
+	/// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0)
+	/// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	fn charge_transaction_payment() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `4`
+		//  Estimated: `3593`
+		// Minimum execution time: 39_815_000 picoseconds.
+		Weight::from_parts(46_067_000, 0)
+			.saturating_add(Weight::from_parts(0, 3593))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+}
diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/Cargo.toml b/cumulus/parachains/runtimes/contracts/contracts-rococo/Cargo.toml
index dfa75b8d3cf..c98ca7ba3e7 100644
--- a/cumulus/parachains/runtimes/contracts/contracts-rococo/Cargo.toml
+++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/Cargo.toml
@@ -161,6 +161,7 @@ runtime-benchmarks = [
 	"pallet-multisig/runtime-benchmarks",
 	"pallet-sudo/runtime-benchmarks",
 	"pallet-timestamp/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"pallet-utility/runtime-benchmarks",
 	"pallet-xcm/runtime-benchmarks",
 	"parachains-common/runtime-benchmarks",
diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs
index 6f79780dc17..0111b3d8522 100644
--- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs
+++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs
@@ -87,8 +87,8 @@ pub type Block = generic::Block<Header, UncheckedExtrinsic>;
 pub type SignedBlock = generic::SignedBlock<Block>;
 /// BlockId type as expected by this runtime.
 pub type BlockId = generic::BlockId<Block>;
-/// The SignedExtension to the basic transaction logic.
-pub type SignedExtra = (
+/// The extension to the basic transaction logic.
+pub type TxExtension = (
 	frame_system::CheckNonZeroSender<Runtime>,
 	frame_system::CheckSpecVersion<Runtime>,
 	frame_system::CheckTxVersion<Runtime>,
@@ -101,7 +101,7 @@ pub type SignedExtra = (
 );
 /// Unchecked extrinsic type as expected by this runtime.
 pub type UncheckedExtrinsic =
-	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
 
 /// Migrations to apply on runtime upgrade.
 pub type Migrations = (
@@ -250,6 +250,7 @@ impl pallet_transaction_payment::Config for Runtime {
 	type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
 	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
 	type OperationalFeeMultiplier = ConstU8<5>;
+	type WeightInfo = pallet_transaction_payment::weights::SubstrateWeight<Runtime>;
 }
 
 parameter_types! {
@@ -434,6 +435,7 @@ construct_runtime!(
 mod benches {
 	frame_benchmarking::define_benchmarks!(
 		[frame_system, SystemBench::<Runtime>]
+		[frame_system_extensions, SystemExtensionsBench::<Runtime>]
 		[pallet_balances, Balances]
 		[pallet_message_queue, MessageQueue]
 		[pallet_multisig, Multisig]
@@ -757,6 +759,7 @@ impl_runtime_apis! {
 			use frame_benchmarking::{Benchmarking, BenchmarkList};
 			use frame_support::traits::StorageInfoTrait;
 			use frame_system_benchmarking::Pallet as SystemBench;
+			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
 			use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
 			use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
 
@@ -774,6 +777,7 @@ impl_runtime_apis! {
 			use sp_storage::TrackedStorageKey;
 
 			use frame_system_benchmarking::Pallet as SystemBench;
+			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
 			impl frame_system_benchmarking::Config for Runtime {
 				fn setup_set_code_requirements(code: &alloc::vec::Vec<u8>) -> Result<(), BenchmarkError> {
 					ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32);
diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml b/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml
index 80417ea0036..a38b7400cfa 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml
+++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/Cargo.toml
@@ -163,6 +163,7 @@ runtime-benchmarks = [
 	"pallet-proxy/runtime-benchmarks",
 	"pallet-sudo/runtime-benchmarks",
 	"pallet-timestamp/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"pallet-utility/runtime-benchmarks",
 	"pallet-xcm-benchmarks/runtime-benchmarks",
 	"pallet-xcm/runtime-benchmarks",
diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs
index d34689deed6..1ce980fa549 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs
+++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs
@@ -98,8 +98,8 @@ pub type SignedBlock = generic::SignedBlock<Block>;
 /// BlockId type as expected by this runtime.
 pub type BlockId = generic::BlockId<Block>;
 
-/// The SignedExtension to the basic transaction logic.
-pub type SignedExtra = (
+/// The TransactionExtension to the basic transaction logic.
+pub type TxExtension = (
 	frame_system::CheckNonZeroSender<Runtime>,
 	frame_system::CheckSpecVersion<Runtime>,
 	frame_system::CheckTxVersion<Runtime>,
@@ -114,7 +114,7 @@ pub type SignedExtra = (
 
 /// Unchecked extrinsic type as expected by this runtime.
 pub type UncheckedExtrinsic =
-	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
 
 /// Migrations to apply on runtime upgrade.
 pub type Migrations = (
@@ -208,6 +208,8 @@ impl frame_system::Config for Runtime {
 	type DbWeight = RocksDbWeight;
 	/// Weight information for the extrinsics of this pallet.
 	type SystemWeightInfo = weights::frame_system::WeightInfo<Runtime>;
+	/// Weight information for the extensions of this pallet.
+	type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo<Runtime>;
 	/// Block & extrinsics weights: base values and limits.
 	type BlockWeights = RuntimeBlockWeights;
 	/// The maximum length of a block (in bytes).
@@ -265,6 +267,7 @@ impl pallet_transaction_payment::Config for Runtime {
 	type WeightToFee = WeightToFee;
 	type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
 	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
+	type WeightInfo = weights::pallet_transaction_payment::WeightInfo<Runtime>;
 }
 
 parameter_types! {
diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/frame_system_extensions.rs
new file mode 100644
index 00000000000..a4d09696a1a
--- /dev/null
+++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/frame_system_extensions.rs
@@ -0,0 +1,132 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `frame_system_extensions`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
+//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/release/polkadot-parachain
+// benchmark
+// pallet
+// --wasm-execution=compiled
+// --pallet=frame_system_extensions
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --extrinsic=*
+// --steps=2
+// --repeat=2
+// --json
+// --header=./cumulus/file_header.txt
+// --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/
+// --chain=coretime-rococo-dev
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `frame_system_extensions`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> frame_system::ExtensionsWeightInfo for WeightInfo<T> {
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_genesis() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `54`
+		//  Estimated: `3509`
+		// Minimum execution time: 3_637_000 picoseconds.
+		Weight::from_parts(6_382_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_mortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 5_841_000 picoseconds.
+		Weight::from_parts(8_776_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_immortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 5_841_000 picoseconds.
+		Weight::from_parts(8_776_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	fn check_non_zero_sender() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 561_000 picoseconds.
+		Weight::from_parts(2_705_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_nonce() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 3_316_000 picoseconds.
+		Weight::from_parts(5_771_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_spec_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 511_000 picoseconds.
+		Weight::from_parts(2_575_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_tx_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 501_000 picoseconds.
+		Weight::from_parts(2_595_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	/// Storage: `System::AllExtrinsicsLen` (r:1 w:1)
+	/// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
+	/// Storage: `System::BlockWeight` (r:1 w:1)
+	/// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`)
+	fn check_weight() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `24`
+		//  Estimated: `1533`
+		// Minimum execution time: 3_687_000 picoseconds.
+		Weight::from_parts(6_192_000, 0)
+			.saturating_add(Weight::from_parts(0, 1533))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+}
diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/mod.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/mod.rs
index 216f41a5a66..24c4f50e6ab 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/mod.rs
+++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/mod.rs
@@ -22,6 +22,7 @@ pub mod cumulus_pallet_parachain_system;
 pub mod cumulus_pallet_xcmp_queue;
 pub mod extrinsic_weights;
 pub mod frame_system;
+pub mod frame_system_extensions;
 pub mod pallet_balances;
 pub mod pallet_broker;
 pub mod pallet_collator_selection;
@@ -30,6 +31,7 @@ pub mod pallet_multisig;
 pub mod pallet_proxy;
 pub mod pallet_session;
 pub mod pallet_timestamp;
+pub mod pallet_transaction_payment;
 pub mod pallet_utility;
 pub mod pallet_xcm;
 pub mod paritydb_weights;
diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_transaction_payment.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_transaction_payment.rs
new file mode 100644
index 00000000000..29d48abab89
--- /dev/null
+++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_transaction_payment.rs
@@ -0,0 +1,67 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `pallet_transaction_payment`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
+//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/release/polkadot-parachain
+// benchmark
+// pallet
+// --wasm-execution=compiled
+// --pallet=pallet_transaction_payment
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --extrinsic=*
+// --steps=2
+// --repeat=2
+// --json
+// --header=./cumulus/file_header.txt
+// --output=./cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/
+// --chain=coretime-rococo-dev
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `pallet_transaction_payment`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> pallet_transaction_payment::WeightInfo for WeightInfo<T> {
+	/// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0)
+	/// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	fn charge_transaction_payment() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `4`
+		//  Estimated: `3593`
+		// Minimum execution time: 33_363_000 picoseconds.
+		Weight::from_parts(38_793_000, 0)
+			.saturating_add(Weight::from_parts(0, 3593))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+}
diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml b/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml
index 25bf777047d..149fa5d0b04 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml
+++ b/cumulus/parachains/runtimes/coretime/coretime-westend/Cargo.toml
@@ -161,6 +161,7 @@ runtime-benchmarks = [
 	"pallet-multisig/runtime-benchmarks",
 	"pallet-proxy/runtime-benchmarks",
 	"pallet-timestamp/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"pallet-utility/runtime-benchmarks",
 	"pallet-xcm-benchmarks/runtime-benchmarks",
 	"pallet-xcm/runtime-benchmarks",
diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs
index c3516df9aa1..632f2c657cf 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs
+++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs
@@ -98,8 +98,8 @@ pub type SignedBlock = generic::SignedBlock<Block>;
 /// BlockId type as expected by this runtime.
 pub type BlockId = generic::BlockId<Block>;
 
-/// The SignedExtension to the basic transaction logic.
-pub type SignedExtra = (
+/// The TransactionExtension to the basic transaction logic.
+pub type TxExtension = (
 	frame_system::CheckNonZeroSender<Runtime>,
 	frame_system::CheckSpecVersion<Runtime>,
 	frame_system::CheckTxVersion<Runtime>,
@@ -114,7 +114,7 @@ pub type SignedExtra = (
 
 /// Unchecked extrinsic type as expected by this runtime.
 pub type UncheckedExtrinsic =
-	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
 
 /// Migrations to apply on runtime upgrade.
 pub type Migrations = (
@@ -208,6 +208,8 @@ impl frame_system::Config for Runtime {
 	type DbWeight = RocksDbWeight;
 	/// Weight information for the extrinsics of this pallet.
 	type SystemWeightInfo = weights::frame_system::WeightInfo<Runtime>;
+	/// Weight information for the extensions of this pallet.
+	type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo<Runtime>;
 	/// Block & extrinsics weights: base values and limits.
 	type BlockWeights = RuntimeBlockWeights;
 	/// The maximum length of a block (in bytes).
@@ -266,6 +268,7 @@ impl pallet_transaction_payment::Config for Runtime {
 	type WeightToFee = WeightToFee;
 	type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
 	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
+	type WeightInfo = weights::pallet_transaction_payment::WeightInfo<Runtime>;
 }
 
 parameter_types! {
diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/frame_system_extensions.rs
new file mode 100644
index 00000000000..d928b73613a
--- /dev/null
+++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/frame_system_extensions.rs
@@ -0,0 +1,132 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `frame_system_extensions`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
+//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-westend-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/release/polkadot-parachain
+// benchmark
+// pallet
+// --wasm-execution=compiled
+// --pallet=frame_system_extensions
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --extrinsic=*
+// --steps=2
+// --repeat=2
+// --json
+// --header=./cumulus/file_header.txt
+// --output=./cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/
+// --chain=coretime-westend-dev
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `frame_system_extensions`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> frame_system::ExtensionsWeightInfo for WeightInfo<T> {
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_genesis() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `54`
+		//  Estimated: `3509`
+		// Minimum execution time: 3_637_000 picoseconds.
+		Weight::from_parts(6_382_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_mortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 5_841_000 picoseconds.
+		Weight::from_parts(8_776_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_immortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 5_841_000 picoseconds.
+		Weight::from_parts(8_776_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	fn check_non_zero_sender() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 561_000 picoseconds.
+		Weight::from_parts(2_705_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_nonce() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 3_316_000 picoseconds.
+		Weight::from_parts(5_771_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_spec_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 511_000 picoseconds.
+		Weight::from_parts(2_575_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_tx_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 501_000 picoseconds.
+		Weight::from_parts(2_595_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	/// Storage: `System::AllExtrinsicsLen` (r:1 w:1)
+	/// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
+	/// Storage: `System::BlockWeight` (r:1 w:1)
+	/// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`)
+	fn check_weight() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `24`
+		//  Estimated: `1533`
+		// Minimum execution time: 3_687_000 picoseconds.
+		Weight::from_parts(6_192_000, 0)
+			.saturating_add(Weight::from_parts(0, 1533))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+}
diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/mod.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/mod.rs
index 216f41a5a66..24c4f50e6ab 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/mod.rs
+++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/mod.rs
@@ -22,6 +22,7 @@ pub mod cumulus_pallet_parachain_system;
 pub mod cumulus_pallet_xcmp_queue;
 pub mod extrinsic_weights;
 pub mod frame_system;
+pub mod frame_system_extensions;
 pub mod pallet_balances;
 pub mod pallet_broker;
 pub mod pallet_collator_selection;
@@ -30,6 +31,7 @@ pub mod pallet_multisig;
 pub mod pallet_proxy;
 pub mod pallet_session;
 pub mod pallet_timestamp;
+pub mod pallet_transaction_payment;
 pub mod pallet_utility;
 pub mod pallet_xcm;
 pub mod paritydb_weights;
diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_transaction_payment.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_transaction_payment.rs
new file mode 100644
index 00000000000..f159f877afe
--- /dev/null
+++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_transaction_payment.rs
@@ -0,0 +1,67 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `pallet_transaction_payment`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
+//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-westend-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/release/polkadot-parachain
+// benchmark
+// pallet
+// --wasm-execution=compiled
+// --pallet=pallet_transaction_payment
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --extrinsic=*
+// --steps=2
+// --repeat=2
+// --json
+// --header=./cumulus/file_header.txt
+// --output=./cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/
+// --chain=coretime-westend-dev
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `pallet_transaction_payment`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> pallet_transaction_payment::WeightInfo for WeightInfo<T> {
+	/// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0)
+	/// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	fn charge_transaction_payment() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `4`
+		//  Estimated: `3593`
+		// Minimum execution time: 33_363_000 picoseconds.
+		Weight::from_parts(38_793_000, 0)
+			.saturating_add(Weight::from_parts(0, 3593))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+}
diff --git a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs
index bc76f174b50..ad656cdbb83 100644
--- a/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs
+++ b/cumulus/parachains/runtimes/glutton/glutton-westend/src/lib.rs
@@ -290,8 +290,8 @@ pub type Block = generic::Block<Header, UncheckedExtrinsic>;
 pub type SignedBlock = generic::SignedBlock<Block>;
 /// BlockId type as expected by this runtime.
 pub type BlockId = generic::BlockId<Block>;
-/// The SignedExtension to the basic transaction logic.
-pub type SignedExtra = (
+/// The extension to the basic transaction logic.
+pub type TxExtension = (
 	pallet_sudo::CheckOnlySudoAccount<Runtime>,
 	frame_system::CheckNonZeroSender<Runtime>,
 	frame_system::CheckSpecVersion<Runtime>,
@@ -303,7 +303,7 @@ pub type SignedExtra = (
 );
 /// Unchecked extrinsic type as expected by this runtime.
 pub type UncheckedExtrinsic =
-	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
 /// Executive: handles dispatch to the various modules.
 pub type Executive = frame_executive::Executive<
 	Runtime,
@@ -318,6 +318,7 @@ mod benches {
 	frame_benchmarking::define_benchmarks!(
 		[cumulus_pallet_parachain_system, ParachainSystem]
 		[frame_system, SystemBench::<Runtime>]
+		[frame_system_extensions, SystemExtensionsBench::<Runtime>]
 		[pallet_glutton, Glutton]
 		[pallet_message_queue, MessageQueue]
 		[pallet_timestamp, Timestamp]
@@ -447,6 +448,7 @@ impl_runtime_apis! {
 			use frame_benchmarking::{Benchmarking, BenchmarkList};
 			use frame_support::traits::StorageInfoTrait;
 			use frame_system_benchmarking::Pallet as SystemBench;
+			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
 
 			let mut list = Vec::<BenchmarkList>::new();
 			list_benchmarks!(list, extra);
@@ -463,6 +465,7 @@ impl_runtime_apis! {
 			use sp_storage::TrackedStorageKey;
 
 			use frame_system_benchmarking::Pallet as SystemBench;
+			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
 			impl frame_system_benchmarking::Config for Runtime {
 				fn setup_set_code_requirements(code: &alloc::vec::Vec<u8>) -> Result<(), BenchmarkError> {
 					ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32);
diff --git a/cumulus/parachains/runtimes/glutton/glutton-westend/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/glutton/glutton-westend/src/weights/frame_system_extensions.rs
new file mode 100644
index 00000000000..4fbbb8d6f78
--- /dev/null
+++ b/cumulus/parachains/runtimes/glutton/glutton-westend/src/weights/frame_system_extensions.rs
@@ -0,0 +1,130 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `frame_system_extensions`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
+//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("glutton-westend-dev-1300")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/release/polkadot-parachain
+// benchmark
+// pallet
+// --wasm-execution=compiled
+// --pallet=frame_system_extensions
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --extrinsic=*
+// --steps=2
+// --repeat=2
+// --json
+// --header=./cumulus/file_header.txt
+// --output=./cumulus/parachains/runtimes/glutton/glutton-westend/src/weights/
+// --chain=glutton-westend-dev-1300
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `frame_system_extensions`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> frame_system::ExtensionsWeightInfo for WeightInfo<T> {
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_genesis() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `54`
+		//  Estimated: `3509`
+		// Minimum execution time: 3_908_000 picoseconds.
+		Weight::from_parts(4_007_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_mortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 5_510_000 picoseconds.
+		Weight::from_parts(6_332_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_immortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 5_510_000 picoseconds.
+		Weight::from_parts(6_332_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	fn check_non_zero_sender() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 651_000 picoseconds.
+		Weight::from_parts(851_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_nonce() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 3_387_000 picoseconds.
+		Weight::from_parts(3_646_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_spec_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 491_000 picoseconds.
+		Weight::from_parts(651_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_tx_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 451_000 picoseconds.
+		Weight::from_parts(662_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	/// Storage: `System::AllExtrinsicsLen` (r:1 w:1)
+	/// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
+	fn check_weight() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `24`
+		//  Estimated: `1489`
+		// Minimum execution time: 3_537_000 picoseconds.
+		Weight::from_parts(4_208_000, 0)
+			.saturating_add(Weight::from_parts(0, 1489))
+			.saturating_add(T::DbWeight::get().reads(1))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+}
diff --git a/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml b/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml
index c969bb2985b..373b82639de 100644
--- a/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml
+++ b/cumulus/parachains/runtimes/people/people-rococo/Cargo.toml
@@ -157,6 +157,7 @@ runtime-benchmarks = [
 	"pallet-multisig/runtime-benchmarks",
 	"pallet-proxy/runtime-benchmarks",
 	"pallet-timestamp/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"pallet-utility/runtime-benchmarks",
 	"pallet-xcm-benchmarks/runtime-benchmarks",
 	"pallet-xcm/runtime-benchmarks",
diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs
index b2883a2bbf9..af8e72fa094 100644
--- a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs
+++ b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs
@@ -91,8 +91,8 @@ pub type SignedBlock = generic::SignedBlock<Block>;
 /// BlockId type as expected by this runtime.
 pub type BlockId = generic::BlockId<Block>;
 
-/// The SignedExtension to the basic transaction logic.
-pub type SignedExtra = (
+/// The TransactionExtension to the basic transaction logic.
+pub type TxExtension = (
 	frame_system::CheckNonZeroSender<Runtime>,
 	frame_system::CheckSpecVersion<Runtime>,
 	frame_system::CheckTxVersion<Runtime>,
@@ -106,7 +106,7 @@ pub type SignedExtra = (
 
 /// Unchecked extrinsic type as expected by this runtime.
 pub type UncheckedExtrinsic =
-	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
 
 /// Migrations to apply on runtime upgrade.
 pub type Migrations = (
@@ -189,6 +189,7 @@ impl frame_system::Config for Runtime {
 	type Version = Version;
 	type AccountData = pallet_balances::AccountData<Balance>;
 	type SystemWeightInfo = weights::frame_system::WeightInfo<Runtime>;
+	type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo<Runtime>;
 	type SS58Prefix = SS58Prefix;
 	type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
 	type MaxConsumers = ConstU32<16>;
@@ -241,6 +242,7 @@ impl pallet_transaction_payment::Config for Runtime {
 	type WeightToFee = WeightToFee;
 	type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
 	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
+	type WeightInfo = weights::pallet_transaction_payment::WeightInfo<Runtime>;
 }
 
 parameter_types! {
@@ -587,6 +589,7 @@ mod benches {
 		[pallet_session, SessionBench::<Runtime>]
 		[pallet_utility, Utility]
 		[pallet_timestamp, Timestamp]
+		[pallet_transaction_payment, TransactionPayment]
 		// Polkadot
 		[polkadot_runtime_common::identity_migrator, IdentityMigrator]
 		// Cumulus
diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/people/people-rococo/src/weights/frame_system_extensions.rs
new file mode 100644
index 00000000000..fb2b69e23e8
--- /dev/null
+++ b/cumulus/parachains/runtimes/people/people-rococo/src/weights/frame_system_extensions.rs
@@ -0,0 +1,132 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `frame_system_extensions`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
+//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("people-rococo-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/release/polkadot-parachain
+// benchmark
+// pallet
+// --wasm-execution=compiled
+// --pallet=frame_system_extensions
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --extrinsic=*
+// --steps=2
+// --repeat=2
+// --json
+// --header=./cumulus/file_header.txt
+// --output=./cumulus/parachains/runtimes/people/people-rococo/src/weights/
+// --chain=people-rococo-dev
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `frame_system_extensions`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> frame_system::ExtensionsWeightInfo for WeightInfo<T> {
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_genesis() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `54`
+		//  Estimated: `3509`
+		// Minimum execution time: 3_637_000 picoseconds.
+		Weight::from_parts(6_382_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_mortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 5_841_000 picoseconds.
+		Weight::from_parts(8_776_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_immortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 5_841_000 picoseconds.
+		Weight::from_parts(8_776_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	fn check_non_zero_sender() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 561_000 picoseconds.
+		Weight::from_parts(2_705_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_nonce() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 3_316_000 picoseconds.
+		Weight::from_parts(5_771_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_spec_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 511_000 picoseconds.
+		Weight::from_parts(2_575_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_tx_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 501_000 picoseconds.
+		Weight::from_parts(2_595_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	/// Storage: `System::AllExtrinsicsLen` (r:1 w:1)
+	/// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
+	/// Storage: `System::BlockWeight` (r:1 w:1)
+	/// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`)
+	fn check_weight() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `24`
+		//  Estimated: `1533`
+		// Minimum execution time: 3_687_000 picoseconds.
+		Weight::from_parts(6_192_000, 0)
+			.saturating_add(Weight::from_parts(0, 1533))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+}
diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/weights/mod.rs b/cumulus/parachains/runtimes/people/people-rococo/src/weights/mod.rs
index dce959e817b..58480231f06 100644
--- a/cumulus/parachains/runtimes/people/people-rococo/src/weights/mod.rs
+++ b/cumulus/parachains/runtimes/people/people-rococo/src/weights/mod.rs
@@ -20,6 +20,7 @@ pub mod cumulus_pallet_parachain_system;
 pub mod cumulus_pallet_xcmp_queue;
 pub mod extrinsic_weights;
 pub mod frame_system;
+pub mod frame_system_extensions;
 pub mod pallet_balances;
 pub mod pallet_collator_selection;
 pub mod pallet_identity;
@@ -28,6 +29,7 @@ pub mod pallet_multisig;
 pub mod pallet_proxy;
 pub mod pallet_session;
 pub mod pallet_timestamp;
+pub mod pallet_transaction_payment;
 pub mod pallet_utility;
 pub mod pallet_xcm;
 pub mod paritydb_weights;
diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_transaction_payment.rs b/cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_transaction_payment.rs
new file mode 100644
index 00000000000..555fd5a32fa
--- /dev/null
+++ b/cumulus/parachains/runtimes/people/people-rococo/src/weights/pallet_transaction_payment.rs
@@ -0,0 +1,67 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `pallet_transaction_payment`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
+//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("people-rococo-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/release/polkadot-parachain
+// benchmark
+// pallet
+// --wasm-execution=compiled
+// --pallet=pallet_transaction_payment
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --extrinsic=*
+// --steps=2
+// --repeat=2
+// --json
+// --header=./cumulus/file_header.txt
+// --output=./cumulus/parachains/runtimes/people/people-rococo/src/weights/
+// --chain=people-rococo-dev
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `pallet_transaction_payment`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> pallet_transaction_payment::WeightInfo for WeightInfo<T> {
+	/// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0)
+	/// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	fn charge_transaction_payment() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `4`
+		//  Estimated: `3593`
+		// Minimum execution time: 33_363_000 picoseconds.
+		Weight::from_parts(38_793_000, 0)
+			.saturating_add(Weight::from_parts(0, 3593))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+}
diff --git a/cumulus/parachains/runtimes/people/people-westend/Cargo.toml b/cumulus/parachains/runtimes/people/people-westend/Cargo.toml
index 64e956d8b6b..efb67adba49 100644
--- a/cumulus/parachains/runtimes/people/people-westend/Cargo.toml
+++ b/cumulus/parachains/runtimes/people/people-westend/Cargo.toml
@@ -157,6 +157,7 @@ runtime-benchmarks = [
 	"pallet-multisig/runtime-benchmarks",
 	"pallet-proxy/runtime-benchmarks",
 	"pallet-timestamp/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"pallet-utility/runtime-benchmarks",
 	"pallet-xcm-benchmarks/runtime-benchmarks",
 	"pallet-xcm/runtime-benchmarks",
diff --git a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs
index f4f2c1ac22b..d0b0bec2e87 100644
--- a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs
+++ b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs
@@ -91,8 +91,8 @@ pub type SignedBlock = generic::SignedBlock<Block>;
 /// BlockId type as expected by this runtime.
 pub type BlockId = generic::BlockId<Block>;
 
-/// The SignedExtension to the basic transaction logic.
-pub type SignedExtra = (
+/// The transactionExtension to the basic transaction logic.
+pub type TxExtension = (
 	frame_system::CheckNonZeroSender<Runtime>,
 	frame_system::CheckSpecVersion<Runtime>,
 	frame_system::CheckTxVersion<Runtime>,
@@ -106,7 +106,7 @@ pub type SignedExtra = (
 
 /// Unchecked extrinsic type as expected by this runtime.
 pub type UncheckedExtrinsic =
-	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
 
 /// Migrations to apply on runtime upgrade.
 pub type Migrations = (
@@ -188,6 +188,7 @@ impl frame_system::Config for Runtime {
 	type Version = Version;
 	type AccountData = pallet_balances::AccountData<Balance>;
 	type SystemWeightInfo = weights::frame_system::WeightInfo<Runtime>;
+	type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo<Runtime>;
 	type SS58Prefix = SS58Prefix;
 	type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
 	type MaxConsumers = ConstU32<16>;
@@ -240,6 +241,7 @@ impl pallet_transaction_payment::Config for Runtime {
 	type WeightToFee = WeightToFee;
 	type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
 	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
+	type WeightInfo = weights::pallet_transaction_payment::WeightInfo<Runtime>;
 }
 
 parameter_types! {
diff --git a/cumulus/parachains/runtimes/people/people-westend/src/weights/frame_system_extensions.rs b/cumulus/parachains/runtimes/people/people-westend/src/weights/frame_system_extensions.rs
new file mode 100644
index 00000000000..0a4b9e8e268
--- /dev/null
+++ b/cumulus/parachains/runtimes/people/people-westend/src/weights/frame_system_extensions.rs
@@ -0,0 +1,132 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `frame_system_extensions`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
+//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("people-westend-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/release/polkadot-parachain
+// benchmark
+// pallet
+// --wasm-execution=compiled
+// --pallet=frame_system_extensions
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --extrinsic=*
+// --steps=2
+// --repeat=2
+// --json
+// --header=./cumulus/file_header.txt
+// --output=./cumulus/parachains/runtimes/people/people-westend/src/weights/
+// --chain=people-westend-dev
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `frame_system_extensions`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> frame_system::ExtensionsWeightInfo for WeightInfo<T> {
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_genesis() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `54`
+		//  Estimated: `3509`
+		// Minimum execution time: 3_637_000 picoseconds.
+		Weight::from_parts(6_382_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_mortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 5_841_000 picoseconds.
+		Weight::from_parts(8_776_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_immortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 5_841_000 picoseconds.
+		Weight::from_parts(8_776_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	fn check_non_zero_sender() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 561_000 picoseconds.
+		Weight::from_parts(2_705_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_nonce() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 3_316_000 picoseconds.
+		Weight::from_parts(5_771_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_spec_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 511_000 picoseconds.
+		Weight::from_parts(2_575_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_tx_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 501_000 picoseconds.
+		Weight::from_parts(2_595_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	/// Storage: `System::AllExtrinsicsLen` (r:1 w:1)
+	/// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
+	/// Storage: `System::BlockWeight` (r:1 w:1)
+	/// Proof: `System::BlockWeight` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `MaxEncodedLen`)
+	fn check_weight() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `24`
+		//  Estimated: `1533`
+		// Minimum execution time: 3_687_000 picoseconds.
+		Weight::from_parts(6_192_000, 0)
+			.saturating_add(Weight::from_parts(0, 1533))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+}
diff --git a/cumulus/parachains/runtimes/people/people-westend/src/weights/mod.rs b/cumulus/parachains/runtimes/people/people-westend/src/weights/mod.rs
index dce959e817b..58480231f06 100644
--- a/cumulus/parachains/runtimes/people/people-westend/src/weights/mod.rs
+++ b/cumulus/parachains/runtimes/people/people-westend/src/weights/mod.rs
@@ -20,6 +20,7 @@ pub mod cumulus_pallet_parachain_system;
 pub mod cumulus_pallet_xcmp_queue;
 pub mod extrinsic_weights;
 pub mod frame_system;
+pub mod frame_system_extensions;
 pub mod pallet_balances;
 pub mod pallet_collator_selection;
 pub mod pallet_identity;
@@ -28,6 +29,7 @@ pub mod pallet_multisig;
 pub mod pallet_proxy;
 pub mod pallet_session;
 pub mod pallet_timestamp;
+pub mod pallet_transaction_payment;
 pub mod pallet_utility;
 pub mod pallet_xcm;
 pub mod paritydb_weights;
diff --git a/cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_transaction_payment.rs b/cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_transaction_payment.rs
new file mode 100644
index 00000000000..30e4524e586
--- /dev/null
+++ b/cumulus/parachains/runtimes/people/people-westend/src/weights/pallet_transaction_payment.rs
@@ -0,0 +1,67 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `pallet_transaction_payment`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
+//! DATE: 2023-12-21, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("people-westend-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/release/polkadot-parachain
+// benchmark
+// pallet
+// --wasm-execution=compiled
+// --pallet=pallet_transaction_payment
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --extrinsic=*
+// --steps=2
+// --repeat=2
+// --json
+// --header=./cumulus/file_header.txt
+// --output=./cumulus/parachains/runtimes/people/people-westend/src/weights/
+// --chain=people-westend-dev
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `pallet_transaction_payment`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> pallet_transaction_payment::WeightInfo for WeightInfo<T> {
+	/// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0)
+	/// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	fn charge_transaction_payment() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `4`
+		//  Estimated: `3593`
+		// Minimum execution time: 33_363_000 picoseconds.
+		Weight::from_parts(38_793_000, 0)
+			.saturating_add(Weight::from_parts(0, 3593))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+}
diff --git a/cumulus/parachains/runtimes/test-utils/src/lib.rs b/cumulus/parachains/runtimes/test-utils/src/lib.rs
index 3b38eee244f..36cf2bf4f83 100644
--- a/cumulus/parachains/runtimes/test-utils/src/lib.rs
+++ b/cumulus/parachains/runtimes/test-utils/src/lib.rs
@@ -475,7 +475,7 @@ impl<
 			BuyExecution { fees: buy_execution_fee.clone(), weight_limit: Unlimited },
 			Transact {
 				origin_kind: OriginKind::Xcm,
-				require_weight_at_most: call.get_dispatch_info().weight,
+				require_weight_at_most: call.get_dispatch_info().call_weight,
 				call: call.encode().into(),
 			},
 			ExpectTransactStatus(MaybeErrorCode::Success),
diff --git a/cumulus/parachains/runtimes/testing/penpal/Cargo.toml b/cumulus/parachains/runtimes/testing/penpal/Cargo.toml
index 96338b64558..14c4fe52038 100644
--- a/cumulus/parachains/runtimes/testing/penpal/Cargo.toml
+++ b/cumulus/parachains/runtimes/testing/penpal/Cargo.toml
@@ -162,6 +162,7 @@ runtime-benchmarks = [
 	"pallet-message-queue/runtime-benchmarks",
 	"pallet-sudo/runtime-benchmarks",
 	"pallet-timestamp/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"pallet-xcm/runtime-benchmarks",
 	"parachains-common/runtime-benchmarks",
 	"polkadot-parachain-primitives/runtime-benchmarks",
diff --git a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs
index 917b3b04a76..2dff159f7ee 100644
--- a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs
+++ b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs
@@ -129,8 +129,8 @@ pub type BlockId = generic::BlockId<Block>;
 // Id used for identifying assets.
 pub type AssetId = u32;
 
-/// The SignedExtension to the basic transaction logic.
-pub type SignedExtra = (
+/// The extension to the basic transaction logic.
+pub type TxExtension = (
 	frame_system::CheckNonZeroSender<Runtime>,
 	frame_system::CheckSpecVersion<Runtime>,
 	frame_system::CheckTxVersion<Runtime>,
@@ -143,7 +143,7 @@ pub type SignedExtra = (
 
 /// Unchecked extrinsic type as expected by this runtime.
 pub type UncheckedExtrinsic =
-	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
 
 pub type Migrations = (
 	pallet_balances::migration::MigrateToTrackInactive<Runtime, xcm_config::CheckingAccount>,
@@ -435,6 +435,7 @@ impl pallet_transaction_payment::Config for Runtime {
 	type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
 	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
 	type OperationalFeeMultiplier = ConstU8<5>;
+	type WeightInfo = ();
 }
 
 parameter_types! {
@@ -745,6 +746,19 @@ impl pallet_collator_selection::Config for Runtime {
 	type WeightInfo = ();
 }
 
+#[cfg(feature = "runtime-benchmarks")]
+pub struct AssetTxHelper;
+
+#[cfg(feature = "runtime-benchmarks")]
+impl pallet_asset_tx_payment::BenchmarkHelperTrait<AccountId, u32, u32> for AssetTxHelper {
+	fn create_asset_id_parameter(_id: u32) -> (u32, u32) {
+		unimplemented!("Penpal uses default weights");
+	}
+	fn setup_balances_and_pool(_asset_id: u32, _account: AccountId) {
+		unimplemented!("Penpal uses default weights");
+	}
+}
+
 impl pallet_asset_tx_payment::Config for Runtime {
 	type RuntimeEvent = RuntimeEvent;
 	type Fungibles = Assets;
@@ -757,6 +771,9 @@ impl pallet_asset_tx_payment::Config for Runtime {
 		>,
 		AssetsToBlockAuthor<Runtime, TrustBackedAssetsInstance>,
 	>;
+	type WeightInfo = ();
+	#[cfg(feature = "runtime-benchmarks")]
+	type BenchmarkHelper = AssetTxHelper;
 }
 
 impl pallet_sudo::Config for Runtime {
@@ -807,6 +824,7 @@ construct_runtime!(
 mod benches {
 	frame_benchmarking::define_benchmarks!(
 		[frame_system, SystemBench::<Runtime>]
+		[frame_system_extensions, SystemExtensionsBench::<Runtime>]
 		[pallet_balances, Balances]
 		[pallet_message_queue, MessageQueue]
 		[pallet_session, SessionBench::<Runtime>]
@@ -1087,6 +1105,7 @@ impl_runtime_apis! {
 			use frame_benchmarking::{Benchmarking, BenchmarkList};
 			use frame_support::traits::StorageInfoTrait;
 			use frame_system_benchmarking::Pallet as SystemBench;
+			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
 			use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
 
 			let mut list = Vec::<BenchmarkList>::new();
@@ -1103,6 +1122,7 @@ impl_runtime_apis! {
 			use sp_storage::TrackedStorageKey;
 
 			use frame_system_benchmarking::Pallet as SystemBench;
+			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
 			impl frame_system_benchmarking::Config for Runtime {}
 
 			use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
diff --git a/cumulus/parachains/runtimes/testing/rococo-parachain/Cargo.toml b/cumulus/parachains/runtimes/testing/rococo-parachain/Cargo.toml
index 9c905c87627..bbc1185db0d 100644
--- a/cumulus/parachains/runtimes/testing/rococo-parachain/Cargo.toml
+++ b/cumulus/parachains/runtimes/testing/rococo-parachain/Cargo.toml
@@ -126,6 +126,7 @@ runtime-benchmarks = [
 	"pallet-message-queue/runtime-benchmarks",
 	"pallet-sudo/runtime-benchmarks",
 	"pallet-timestamp/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"pallet-xcm/runtime-benchmarks",
 	"parachains-common/runtime-benchmarks",
 	"polkadot-parachain-primitives/runtime-benchmarks",
diff --git a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs
index 5abdc995c00..34bd45b6ef9 100644
--- a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs
+++ b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs
@@ -267,6 +267,7 @@ impl pallet_transaction_payment::Config for Runtime {
 	type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
 	type FeeMultiplierUpdate = ();
 	type OperationalFeeMultiplier = ConstU8<5>;
+	type WeightInfo = ();
 }
 
 impl pallet_sudo::Config for Runtime {
@@ -655,8 +656,8 @@ pub type Block = generic::Block<Header, UncheckedExtrinsic>;
 pub type SignedBlock = generic::SignedBlock<Block>;
 /// BlockId type as expected by this runtime.
 pub type BlockId = generic::BlockId<Block>;
-/// The SignedExtension to the basic transaction logic.
-pub type SignedExtra = (
+/// The extension to the basic transaction logic.
+pub type TxExtension = (
 	frame_system::CheckNonZeroSender<Runtime>,
 	frame_system::CheckSpecVersion<Runtime>,
 	frame_system::CheckTxVersion<Runtime>,
@@ -669,7 +670,7 @@ pub type SignedExtra = (
 );
 /// Unchecked extrinsic type as expected by this runtime.
 pub type UncheckedExtrinsic =
-	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
 /// Executive: handles dispatch to the various modules.
 pub type Executive = frame_executive::Executive<
 	Runtime,
diff --git a/cumulus/polkadot-omni-node/lib/Cargo.toml b/cumulus/polkadot-omni-node/lib/Cargo.toml
index 3dd482f4ada..a690229f169 100644
--- a/cumulus/polkadot-omni-node/lib/Cargo.toml
+++ b/cumulus/polkadot-omni-node/lib/Cargo.toml
@@ -105,6 +105,7 @@ runtime-benchmarks = [
 	"frame-benchmarking-cli/runtime-benchmarks",
 	"frame-benchmarking/runtime-benchmarks",
 	"frame-support/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"parachains-common/runtime-benchmarks",
 	"polkadot-cli/runtime-benchmarks",
 	"polkadot-primitives/runtime-benchmarks",
diff --git a/cumulus/primitives/storage-weight-reclaim/Cargo.toml b/cumulus/primitives/storage-weight-reclaim/Cargo.toml
index 3a98fdd017a..e1ae6743335 100644
--- a/cumulus/primitives/storage-weight-reclaim/Cargo.toml
+++ b/cumulus/primitives/storage-weight-reclaim/Cargo.toml
@@ -14,6 +14,7 @@ codec = { features = ["derive"], workspace = true }
 log = { workspace = true }
 scale-info = { features = ["derive"], workspace = true }
 
+frame-benchmarking = { optional = true, workspace = true }
 frame-support = { workspace = true }
 frame-system = { workspace = true }
 
@@ -24,8 +25,8 @@ cumulus-primitives-proof-size-hostfunction = { workspace = true }
 docify = { workspace = true }
 
 [dev-dependencies]
-sp-trie = { workspace = true }
 sp-io = { workspace = true }
+sp-trie = { workspace = true }
 cumulus-test-runtime = { workspace = true }
 
 [features]
@@ -34,6 +35,7 @@ std = [
 	"codec/std",
 	"cumulus-primitives-core/std",
 	"cumulus-primitives-proof-size-hostfunction/std",
+	"frame-benchmarking/std",
 	"frame-support/std",
 	"frame-system/std",
 	"log/std",
diff --git a/cumulus/primitives/storage-weight-reclaim/src/lib.rs b/cumulus/primitives/storage-weight-reclaim/src/lib.rs
index 2529297691e..5471640695c 100644
--- a/cumulus/primitives/storage-weight-reclaim/src/lib.rs
+++ b/cumulus/primitives/storage-weight-reclaim/src/lib.rs
@@ -30,11 +30,15 @@ use frame_support::{
 use frame_system::Config;
 use scale_info::TypeInfo;
 use sp_runtime::{
-	traits::{DispatchInfoOf, Dispatchable, PostDispatchInfoOf, SignedExtension},
+	impl_tx_ext_default,
+	traits::{DispatchInfoOf, Dispatchable, PostDispatchInfoOf, TransactionExtension},
 	transaction_validity::TransactionValidityError,
 	DispatchResult,
 };
 
+#[cfg(test)]
+mod tests;
+
 const LOG_TARGET: &'static str = "runtime::storage_reclaim";
 
 /// `StorageWeightReclaimer` is a mechanism for manually reclaiming storage weight.
@@ -43,7 +47,7 @@ const LOG_TARGET: &'static str = "runtime::storage_reclaim";
 /// reclaim  it computes the real consumed storage weight and refunds excess weight.
 ///
 /// # Example
-#[doc = docify::embed!("src/lib.rs", simple_reclaimer_example)]
+#[doc = docify::embed!("src/tests.rs", simple_reclaimer_example)]
 pub struct StorageWeightReclaimer {
 	previous_remaining_proof_size: u64,
 	previous_reported_proof_size: Option<u64>,
@@ -119,43 +123,35 @@ impl<T: Config + Send + Sync> core::fmt::Debug for StorageWeightReclaim<T> {
 	}
 }
 
-impl<T: Config + Send + Sync> SignedExtension for StorageWeightReclaim<T>
+impl<T: Config + Send + Sync> TransactionExtension<T::RuntimeCall> for StorageWeightReclaim<T>
 where
 	T::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
 {
 	const IDENTIFIER: &'static str = "StorageWeightReclaim";
-
-	type AccountId = T::AccountId;
-	type Call = T::RuntimeCall;
-	type AdditionalSigned = ();
+	type Implicit = ();
+	type Val = ();
 	type Pre = Option<u64>;
 
-	fn additional_signed(
-		&self,
-	) -> Result<Self::AdditionalSigned, sp_runtime::transaction_validity::TransactionValidityError>
-	{
-		Ok(())
-	}
-
-	fn pre_dispatch(
+	fn prepare(
 		self,
-		_who: &Self::AccountId,
-		_call: &Self::Call,
-		_info: &sp_runtime::traits::DispatchInfoOf<Self::Call>,
+		_val: Self::Val,
+		_origin: &T::RuntimeOrigin,
+		_call: &T::RuntimeCall,
+		_info: &DispatchInfoOf<T::RuntimeCall>,
 		_len: usize,
-	) -> Result<Self::Pre, sp_runtime::transaction_validity::TransactionValidityError> {
+	) -> Result<Self::Pre, TransactionValidityError> {
 		Ok(get_proof_size())
 	}
 
-	fn post_dispatch(
-		pre: Option<Self::Pre>,
-		info: &DispatchInfoOf<Self::Call>,
-		post_info: &PostDispatchInfoOf<Self::Call>,
+	fn post_dispatch_details(
+		pre: Self::Pre,
+		info: &DispatchInfoOf<T::RuntimeCall>,
+		post_info: &PostDispatchInfoOf<T::RuntimeCall>,
 		_len: usize,
 		_result: &DispatchResult,
-	) -> Result<(), TransactionValidityError> {
-		let Some(Some(pre_dispatch_proof_size)) = pre else {
-			return Ok(());
+	) -> Result<Weight, TransactionValidityError> {
+		let Some(pre_dispatch_proof_size) = pre else {
+			return Ok(Weight::zero());
 		};
 
 		let Some(post_dispatch_proof_size) = get_proof_size() else {
@@ -163,13 +159,13 @@ where
 				target: LOG_TARGET,
 				"Proof recording enabled during pre-dispatch, now disabled. This should not happen."
 			);
-			return Ok(())
+			return Ok(Weight::zero())
 		};
 		// Unspent weight according to the `actual_weight` from `PostDispatchInfo`
 		// This unspent weight will be refunded by the `CheckWeight` extension, so we need to
 		// account for that.
 		let unspent = post_info.calc_unspent(info).proof_size();
-		let benchmarked_weight = info.weight.proof_size().saturating_sub(unspent);
+		let benchmarked_weight = info.total_weight().proof_size().saturating_sub(unspent);
 		let consumed_weight = post_dispatch_proof_size.saturating_sub(pre_dispatch_proof_size);
 
 		let storage_size_diff = benchmarked_weight.abs_diff(consumed_weight as u64);
@@ -209,678 +205,8 @@ where
 				current.accrue(Weight::from_parts(0, missing_from_node), info.class);
 			}
 		});
-		Ok(())
-	}
-}
-
-#[cfg(test)]
-mod tests {
-	use super::*;
-	use core::marker::PhantomData;
-	use frame_support::{
-		assert_ok,
-		dispatch::{DispatchClass, PerDispatchClass},
-		weights::{Weight, WeightMeter},
-	};
-	use frame_system::{BlockWeight, CheckWeight};
-	use sp_runtime::{AccountId32, BuildStorage};
-	use sp_trie::proof_size_extension::ProofSizeExt;
-
-	type Test = cumulus_test_runtime::Runtime;
-	const CALL: &<Test as Config>::RuntimeCall =
-		&cumulus_test_runtime::RuntimeCall::System(frame_system::Call::set_heap_pages {
-			pages: 0u64,
-		});
-	const ALICE: AccountId32 = AccountId32::new([1u8; 32]);
-	const LEN: usize = 150;
-
-	pub fn new_test_ext() -> sp_io::TestExternalities {
-		let ext: sp_io::TestExternalities = cumulus_test_runtime::RuntimeGenesisConfig::default()
-			.build_storage()
-			.unwrap()
-			.into();
-		ext
-	}
-
-	struct TestRecorder {
-		return_values: Box<[usize]>,
-		counter: std::sync::atomic::AtomicUsize,
-	}
-
-	impl TestRecorder {
-		fn new(values: &[usize]) -> Self {
-			TestRecorder { return_values: values.into(), counter: Default::default() }
-		}
-	}
-
-	impl sp_trie::ProofSizeProvider for TestRecorder {
-		fn estimate_encoded_size(&self) -> usize {
-			let counter = self.counter.fetch_add(1, core::sync::atomic::Ordering::Relaxed);
-			self.return_values[counter]
-		}
-	}
-
-	fn setup_test_externalities(proof_values: &[usize]) -> sp_io::TestExternalities {
-		let mut test_ext = new_test_ext();
-		let test_recorder = TestRecorder::new(proof_values);
-		test_ext.register_extension(ProofSizeExt::new(test_recorder));
-		test_ext
-	}
-
-	fn set_current_storage_weight(new_weight: u64) {
-		BlockWeight::<Test>::mutate(|current_weight| {
-			current_weight.set(Weight::from_parts(0, new_weight), DispatchClass::Normal);
-		});
-	}
-
-	fn get_storage_weight() -> PerDispatchClass<Weight> {
-		BlockWeight::<Test>::get()
-	}
-
-	#[test]
-	fn basic_refund() {
-		// The real cost will be 100 bytes of storage size
-		let mut test_ext = setup_test_externalities(&[0, 100]);
-
-		test_ext.execute_with(|| {
-			set_current_storage_weight(1000);
-
-			// Benchmarked storage weight: 500
-			let info = DispatchInfo { weight: Weight::from_parts(0, 500), ..Default::default() };
-			let post_info = PostDispatchInfo::default();
-
-			// Should add 500 + 150 (len) to weight.
-			assert_ok!(CheckWeight::<Test>::do_pre_dispatch(&info, LEN));
-
-			let pre = StorageWeightReclaim::<Test>(PhantomData)
-				.pre_dispatch(&ALICE, CALL, &info, LEN)
-				.unwrap();
-			assert_eq!(pre, Some(0));
-
-			assert_ok!(CheckWeight::<Test>::post_dispatch(None, &info, &post_info, 0, &Ok(())));
-			// We expect a refund of 400
-			assert_ok!(StorageWeightReclaim::<Test>::post_dispatch(
-				Some(pre),
-				&info,
-				&post_info,
-				LEN,
-				&Ok(())
-			));
-
-			assert_eq!(get_storage_weight().total().proof_size(), 1250);
-		})
-	}
-
-	#[test]
-	fn underestimating_refund() {
-		// We fixed a bug where `pre dispatch info weight > consumed weight > post info weight`
-		// resulted in error.
-
-		// The real cost will be 100 bytes of storage size
-		let mut test_ext = setup_test_externalities(&[0, 100]);
-
-		test_ext.execute_with(|| {
-			set_current_storage_weight(1000);
-
-			// Benchmarked storage weight: 500
-			let info = DispatchInfo { weight: Weight::from_parts(0, 101), ..Default::default() };
-			let post_info = PostDispatchInfo {
-				actual_weight: Some(Weight::from_parts(0, 99)),
-				pays_fee: Default::default(),
-			};
-
-			assert_ok!(CheckWeight::<Test>::do_pre_dispatch(&info, LEN));
-
-			let pre = StorageWeightReclaim::<Test>(PhantomData)
-				.pre_dispatch(&ALICE, CALL, &info, LEN)
-				.unwrap();
-			assert_eq!(pre, Some(0));
-
-			assert_ok!(CheckWeight::<Test>::post_dispatch(None, &info, &post_info, 0, &Ok(())));
-			// We expect an accrue of 1
-			assert_ok!(StorageWeightReclaim::<Test>::post_dispatch(
-				Some(pre),
-				&info,
-				&post_info,
-				LEN,
-				&Ok(())
-			));
-
-			assert_eq!(get_storage_weight().total().proof_size(), 1250);
-		})
-	}
-
-	#[test]
-	fn sets_to_node_storage_proof_if_higher() {
-		// The storage proof reported by the proof recorder is higher than what is stored on
-		// the runtime side.
-		{
-			let mut test_ext = setup_test_externalities(&[1000, 1005]);
-
-			test_ext.execute_with(|| {
-				// Stored in BlockWeight is 5
-				set_current_storage_weight(5);
-
-				// Benchmarked storage weight: 10
-				let info = DispatchInfo { weight: Weight::from_parts(0, 10), ..Default::default() };
-				let post_info = PostDispatchInfo::default();
-
-				assert_ok!(CheckWeight::<Test>::do_pre_dispatch(&info, LEN));
-
-				let pre = StorageWeightReclaim::<Test>(PhantomData)
-					.pre_dispatch(&ALICE, CALL, &info, LEN)
-					.unwrap();
-				assert_eq!(pre, Some(1000));
-
-				assert_ok!(CheckWeight::<Test>::post_dispatch(None, &info, &post_info, 0, &Ok(())));
-				assert_ok!(StorageWeightReclaim::<Test>::post_dispatch(
-					Some(pre),
-					&info,
-					&post_info,
-					LEN,
-					&Ok(())
-				));
-
-				// We expect that the storage weight was set to the node-side proof size (1005) +
-				// extrinsics length (150)
-				assert_eq!(get_storage_weight().total().proof_size(), 1155);
-			})
-		}
-
-		// In this second scenario the proof size on the node side is only lower
-		// after reclaim happened.
-		{
-			let mut test_ext = setup_test_externalities(&[175, 180]);
-			test_ext.execute_with(|| {
-				set_current_storage_weight(85);
-
-				// Benchmarked storage weight: 100
-				let info =
-					DispatchInfo { weight: Weight::from_parts(0, 100), ..Default::default() };
-				let post_info = PostDispatchInfo::default();
-
-				// After this pre_dispatch, the BlockWeight proof size will be
-				// 85 (initial) + 100 (benched) + 150 (tx length) = 335
-				assert_ok!(CheckWeight::<Test>::do_pre_dispatch(&info, LEN));
-
-				let pre = StorageWeightReclaim::<Test>(PhantomData)
-					.pre_dispatch(&ALICE, CALL, &info, LEN)
-					.unwrap();
-				assert_eq!(pre, Some(175));
-
-				assert_ok!(CheckWeight::<Test>::post_dispatch(None, &info, &post_info, 0, &Ok(())));
-
-				// First we will reclaim 95, which leaves us with 240 BlockWeight. This is lower
-				// than 180 (proof size hf) + 150 (length), so we expect it to be set to 330.
-				assert_ok!(StorageWeightReclaim::<Test>::post_dispatch(
-					Some(pre),
-					&info,
-					&post_info,
-					LEN,
-					&Ok(())
-				));
-
-				// We expect that the storage weight was set to the node-side proof weight
-				assert_eq!(get_storage_weight().total().proof_size(), 330);
-			})
-		}
-	}
-
-	#[test]
-	fn does_nothing_without_extension() {
-		let mut test_ext = new_test_ext();
-
-		// Proof size extension not registered
-		test_ext.execute_with(|| {
-			set_current_storage_weight(1000);
-
-			// Benchmarked storage weight: 500
-			let info = DispatchInfo { weight: Weight::from_parts(0, 500), ..Default::default() };
-			let post_info = PostDispatchInfo::default();
-
-			// Adds 500 + 150 (len) weight
-			assert_ok!(CheckWeight::<Test>::do_pre_dispatch(&info, LEN));
-
-			let pre = StorageWeightReclaim::<Test>(PhantomData)
-				.pre_dispatch(&ALICE, CALL, &info, LEN)
-				.unwrap();
-			assert_eq!(pre, None);
-
-			assert_ok!(CheckWeight::<Test>::post_dispatch(None, &info, &post_info, 0, &Ok(())));
-			assert_ok!(StorageWeightReclaim::<Test>::post_dispatch(
-				Some(pre),
-				&info,
-				&post_info,
-				LEN,
-				&Ok(())
-			));
-
-			assert_eq!(get_storage_weight().total().proof_size(), 1650);
-		})
-	}
-
-	#[test]
-	fn negative_refund_is_added_to_weight() {
-		let mut test_ext = setup_test_externalities(&[100, 300]);
-
-		test_ext.execute_with(|| {
-			set_current_storage_weight(1000);
-			// Benchmarked storage weight: 100
-			let info = DispatchInfo { weight: Weight::from_parts(0, 100), ..Default::default() };
-			let post_info = PostDispatchInfo::default();
-
-			// Weight added should be 100 + 150 (len)
-			assert_ok!(CheckWeight::<Test>::do_pre_dispatch(&info, LEN));
-
-			let pre = StorageWeightReclaim::<Test>(PhantomData)
-				.pre_dispatch(&ALICE, CALL, &info, LEN)
-				.unwrap();
-			assert_eq!(pre, Some(100));
-
-			// We expect no refund
-			assert_ok!(CheckWeight::<Test>::post_dispatch(None, &info, &post_info, 0, &Ok(())));
-			assert_ok!(StorageWeightReclaim::<Test>::post_dispatch(
-				Some(pre),
-				&info,
-				&post_info,
-				LEN,
-				&Ok(())
-			));
-
-			assert_eq!(
-				get_storage_weight().total().proof_size(),
-				1100 + LEN as u64 + info.weight.proof_size()
-			);
-		})
-	}
-
-	#[test]
-	fn test_zero_proof_size() {
-		let mut test_ext = setup_test_externalities(&[0, 0]);
-
-		test_ext.execute_with(|| {
-			let info = DispatchInfo { weight: Weight::from_parts(0, 500), ..Default::default() };
-			let post_info = PostDispatchInfo::default();
-
-			assert_ok!(CheckWeight::<Test>::do_pre_dispatch(&info, LEN));
-
-			let pre = StorageWeightReclaim::<Test>(PhantomData)
-				.pre_dispatch(&ALICE, CALL, &info, LEN)
-				.unwrap();
-			assert_eq!(pre, Some(0));
-
-			assert_ok!(CheckWeight::<Test>::post_dispatch(None, &info, &post_info, 0, &Ok(())));
-			assert_ok!(StorageWeightReclaim::<Test>::post_dispatch(
-				Some(pre),
-				&info,
-				&post_info,
-				LEN,
-				&Ok(())
-			));
-
-			// Proof size should be exactly equal to extrinsic length
-			assert_eq!(get_storage_weight().total().proof_size(), LEN as u64);
-		});
-	}
-
-	#[test]
-	fn test_larger_pre_dispatch_proof_size() {
-		let mut test_ext = setup_test_externalities(&[300, 100]);
-
-		test_ext.execute_with(|| {
-			set_current_storage_weight(1300);
-
-			let info = DispatchInfo { weight: Weight::from_parts(0, 500), ..Default::default() };
-			let post_info = PostDispatchInfo::default();
-
-			// Adds 500 + 150 (len) weight, total weight is 1950
-			assert_ok!(CheckWeight::<Test>::do_pre_dispatch(&info, LEN));
-
-			let pre = StorageWeightReclaim::<Test>(PhantomData)
-				.pre_dispatch(&ALICE, CALL, &info, LEN)
-				.unwrap();
-			assert_eq!(pre, Some(300));
-
-			// Refund 500 unspent weight according to `post_info`, total weight is now 1650
-			assert_ok!(CheckWeight::<Test>::post_dispatch(None, &info, &post_info, 0, &Ok(())));
-			// Recorded proof size is negative -200, total weight is now 1450
-			assert_ok!(StorageWeightReclaim::<Test>::post_dispatch(
-				Some(pre),
-				&info,
-				&post_info,
-				LEN,
-				&Ok(())
-			));
-
-			assert_eq!(get_storage_weight().total().proof_size(), 1450);
-		});
-	}
-
-	#[test]
-	fn test_incorporates_check_weight_unspent_weight() {
-		let mut test_ext = setup_test_externalities(&[100, 300]);
-
-		test_ext.execute_with(|| {
-			set_current_storage_weight(1000);
-
-			// Benchmarked storage weight: 300
-			let info = DispatchInfo { weight: Weight::from_parts(100, 300), ..Default::default() };
-
-			// Actual weight is 50
-			let post_info = PostDispatchInfo {
-				actual_weight: Some(Weight::from_parts(50, 250)),
-				pays_fee: Default::default(),
-			};
-
-			// Should add 300 + 150 (len) of weight
-			assert_ok!(CheckWeight::<Test>::do_pre_dispatch(&info, LEN));
-
-			let pre = StorageWeightReclaim::<Test>(PhantomData)
-				.pre_dispatch(&ALICE, CALL, &info, LEN)
-				.unwrap();
-			assert_eq!(pre, Some(100));
-
-			// The `CheckWeight` extension will refund `actual_weight` from `PostDispatchInfo`
-			// we always need to call `post_dispatch` to verify that they interoperate correctly.
-			assert_ok!(CheckWeight::<Test>::post_dispatch(None, &info, &post_info, 0, &Ok(())));
-			assert_ok!(StorageWeightReclaim::<Test>::post_dispatch(
-				Some(pre),
-				&info,
-				&post_info,
-				LEN,
-				&Ok(())
-			));
-
-			// Reclaimed 100
-			assert_eq!(get_storage_weight().total().proof_size(), 1350);
-		})
-	}
-
-	#[test]
-	fn test_incorporates_check_weight_unspent_weight_on_negative() {
-		let mut test_ext = setup_test_externalities(&[100, 300]);
-
-		test_ext.execute_with(|| {
-			set_current_storage_weight(1000);
-			// Benchmarked storage weight: 50
-			let info = DispatchInfo { weight: Weight::from_parts(100, 50), ..Default::default() };
-
-			// Actual weight is 25
-			let post_info = PostDispatchInfo {
-				actual_weight: Some(Weight::from_parts(50, 25)),
-				pays_fee: Default::default(),
-			};
-
-			// Adds 50 + 150 (len) weight, total weight 1200
-			assert_ok!(CheckWeight::<Test>::do_pre_dispatch(&info, LEN));
-
-			let pre = StorageWeightReclaim::<Test>(PhantomData)
-				.pre_dispatch(&ALICE, CALL, &info, LEN)
-				.unwrap();
-			assert_eq!(pre, Some(100));
-
-			// The `CheckWeight` extension will refund `actual_weight` from `PostDispatchInfo`
-			// we always need to call `post_dispatch` to verify that they interoperate correctly.
-
-			// Refunds unspent 25 weight according to `post_info`, 1175
-			assert_ok!(CheckWeight::<Test>::post_dispatch(None, &info, &post_info, 0, &Ok(())));
-			// Adds 200 - 25 (unspent) == 175 weight, total weight 1350
-			assert_ok!(StorageWeightReclaim::<Test>::post_dispatch(
-				Some(pre),
-				&info,
-				&post_info,
-				LEN,
-				&Ok(())
-			));
-
-			assert_eq!(get_storage_weight().total().proof_size(), 1350);
-		})
-	}
-
-	#[test]
-	fn test_nothing_relcaimed() {
-		let mut test_ext = setup_test_externalities(&[0, 100]);
-
-		test_ext.execute_with(|| {
-			set_current_storage_weight(0);
-			// Benchmarked storage weight: 100
-			let info = DispatchInfo { weight: Weight::from_parts(100, 100), ..Default::default() };
-
-			// Actual proof size is 100
-			let post_info = PostDispatchInfo {
-				actual_weight: Some(Weight::from_parts(50, 100)),
-				pays_fee: Default::default(),
-			};
-
-			// Adds benchmarked weight 100 + 150 (len), total weight is now 250
-			assert_ok!(CheckWeight::<Test>::do_pre_dispatch(&info, LEN));
-
-			// Weight should go up by 150 len + 100 proof size weight, total weight 250
-			assert_eq!(get_storage_weight().total().proof_size(), 250);
-
-			let pre = StorageWeightReclaim::<Test>(PhantomData)
-				.pre_dispatch(&ALICE, CALL, &info, LEN)
-				.unwrap();
-			// Should return `setup_test_externalities` proof recorder value: 100.
-			assert_eq!(pre, Some(0));
-
-			// The `CheckWeight` extension will refund `actual_weight` from `PostDispatchInfo`
-			// we always need to call `post_dispatch` to verify that they interoperate correctly.
-			// Nothing to refund, unspent is 0, total weight 250
-			assert_ok!(CheckWeight::<Test>::post_dispatch(None, &info, &post_info, LEN, &Ok(())));
-			// `setup_test_externalities` proof recorder value: 200, so this means the extrinsic
-			// actually used 100 proof size.
-			// Nothing to refund or add, weight matches proof recorder
-			assert_ok!(StorageWeightReclaim::<Test>::post_dispatch(
-				Some(pre),
-				&info,
-				&post_info,
-				LEN,
-				&Ok(())
-			));
-
-			// Check block len weight was not reclaimed:
-			// 100 weight + 150 extrinsic len == 250 proof size
-			assert_eq!(get_storage_weight().total().proof_size(), 250);
-		})
-	}
-
-	#[test]
-	fn test_incorporates_check_weight_unspent_weight_reverse_order() {
-		let mut test_ext = setup_test_externalities(&[100, 300]);
-
-		test_ext.execute_with(|| {
-			set_current_storage_weight(1000);
-
-			// Benchmarked storage weight: 300
-			let info = DispatchInfo { weight: Weight::from_parts(100, 300), ..Default::default() };
-
-			// Actual weight is 50
-			let post_info = PostDispatchInfo {
-				actual_weight: Some(Weight::from_parts(50, 250)),
-				pays_fee: Default::default(),
-			};
-
-			// Adds 300 + 150 (len) weight, total weight 1450
-			assert_ok!(CheckWeight::<Test>::do_pre_dispatch(&info, LEN));
-
-			let pre = StorageWeightReclaim::<Test>(PhantomData)
-				.pre_dispatch(&ALICE, CALL, &info, LEN)
-				.unwrap();
-			assert_eq!(pre, Some(100));
-
-			// This refunds 100 - 50(unspent), total weight is now 1400
-			assert_ok!(StorageWeightReclaim::<Test>::post_dispatch(
-				Some(pre),
-				&info,
-				&post_info,
-				LEN,
-				&Ok(())
-			));
-			// `CheckWeight` gets called after `StorageWeightReclaim` this time.
-			// The `CheckWeight` extension will refund `actual_weight` from `PostDispatchInfo`
-			// we always need to call `post_dispatch` to verify that they interoperate correctly.
-			assert_ok!(CheckWeight::<Test>::post_dispatch(None, &info, &post_info, 0, &Ok(())));
-
-			// Above call refunds 50 (unspent), total weight is 1350 now
-			assert_eq!(get_storage_weight().total().proof_size(), 1350);
-		})
-	}
-
-	#[test]
-	fn test_incorporates_check_weight_unspent_weight_on_negative_reverse_order() {
-		let mut test_ext = setup_test_externalities(&[100, 300]);
-
-		test_ext.execute_with(|| {
-			set_current_storage_weight(1000);
-			// Benchmarked storage weight: 50
-			let info = DispatchInfo { weight: Weight::from_parts(100, 50), ..Default::default() };
-
-			// Actual weight is 25
-			let post_info = PostDispatchInfo {
-				actual_weight: Some(Weight::from_parts(50, 25)),
-				pays_fee: Default::default(),
-			};
-
-			// Adds 50 + 150 (len) weight, total weight is 1200
-			assert_ok!(CheckWeight::<Test>::do_pre_dispatch(&info, LEN));
-
-			let pre = StorageWeightReclaim::<Test>(PhantomData)
-				.pre_dispatch(&ALICE, CALL, &info, LEN)
-				.unwrap();
-			assert_eq!(pre, Some(100));
-
-			// Adds additional 150 weight recorded
-			assert_ok!(StorageWeightReclaim::<Test>::post_dispatch(
-				Some(pre),
-				&info,
-				&post_info,
-				LEN,
-				&Ok(())
-			));
-			// `CheckWeight` gets called after `StorageWeightReclaim` this time.
-			// The `CheckWeight` extension will refund `actual_weight` from `PostDispatchInfo`
-			// we always need to call `post_dispatch` to verify that they interoperate correctly.
-			assert_ok!(CheckWeight::<Test>::post_dispatch(None, &info, &post_info, 0, &Ok(())));
-
-			assert_eq!(get_storage_weight().total().proof_size(), 1350);
-		})
-	}
-
-	#[test]
-	fn storage_size_reported_correctly() {
-		let mut test_ext = setup_test_externalities(&[1000]);
-		test_ext.execute_with(|| {
-			assert_eq!(get_proof_size(), Some(1000));
-		});
-
-		let mut test_ext = new_test_ext();
-
-		let test_recorder = TestRecorder::new(&[0]);
-
-		test_ext.register_extension(ProofSizeExt::new(test_recorder));
-
-		test_ext.execute_with(|| {
-			assert_eq!(get_proof_size(), Some(0));
-		});
-	}
-
-	#[test]
-	fn storage_size_disabled_reported_correctly() {
-		let mut test_ext = setup_test_externalities(&[PROOF_RECORDING_DISABLED as usize]);
-
-		test_ext.execute_with(|| {
-			assert_eq!(get_proof_size(), None);
-		});
-	}
-
-	#[test]
-	fn test_reclaim_helper() {
-		let mut test_ext = setup_test_externalities(&[1000, 1300, 1800]);
-
-		test_ext.execute_with(|| {
-			let mut remaining_weight_meter = WeightMeter::with_limit(Weight::from_parts(0, 2000));
-			let mut reclaim_helper = StorageWeightReclaimer::new(&remaining_weight_meter);
-			remaining_weight_meter.consume(Weight::from_parts(0, 500));
-			let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter);
-
-			assert_eq!(reclaimed, Some(Weight::from_parts(0, 200)));
-
-			remaining_weight_meter.consume(Weight::from_parts(0, 800));
-			let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter);
-			assert_eq!(reclaimed, Some(Weight::from_parts(0, 300)));
-			assert_eq!(remaining_weight_meter.remaining(), Weight::from_parts(0, 1200));
-		});
+		Ok(Weight::zero())
 	}
 
-	#[test]
-	fn test_reclaim_helper_does_not_reclaim_negative() {
-		// Benchmarked weight does not change at all
-		let mut test_ext = setup_test_externalities(&[1000, 1300]);
-
-		test_ext.execute_with(|| {
-			let mut remaining_weight_meter = WeightMeter::with_limit(Weight::from_parts(0, 1000));
-			let mut reclaim_helper = StorageWeightReclaimer::new(&remaining_weight_meter);
-			let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter);
-
-			assert_eq!(reclaimed, Some(Weight::from_parts(0, 0)));
-			assert_eq!(remaining_weight_meter.remaining(), Weight::from_parts(0, 1000));
-		});
-
-		// Benchmarked weight increases less than storage proof consumes
-		let mut test_ext = setup_test_externalities(&[1000, 1300]);
-
-		test_ext.execute_with(|| {
-			let mut remaining_weight_meter = WeightMeter::with_limit(Weight::from_parts(0, 1000));
-			let mut reclaim_helper = StorageWeightReclaimer::new(&remaining_weight_meter);
-			remaining_weight_meter.consume(Weight::from_parts(0, 0));
-			let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter);
-
-			assert_eq!(reclaimed, Some(Weight::from_parts(0, 0)));
-		});
-	}
-
-	/// Just here for doc purposes
-	fn get_benched_weight() -> Weight {
-		Weight::from_parts(0, 5)
-	}
-
-	/// Just here for doc purposes
-	fn do_work() {}
-
-	#[docify::export_content(simple_reclaimer_example)]
-	fn reclaim_with_weight_meter() {
-		let mut remaining_weight_meter = WeightMeter::with_limit(Weight::from_parts(10, 10));
-
-		let benched_weight = get_benched_weight();
-
-		// It is important to instantiate the `StorageWeightReclaimer` before we consume the weight
-		// for a piece of work from the weight meter.
-		let mut reclaim_helper = StorageWeightReclaimer::new(&remaining_weight_meter);
-
-		if remaining_weight_meter.try_consume(benched_weight).is_ok() {
-			// Perform some work that takes has `benched_weight` storage weight.
-			do_work();
-
-			// Reclaimer will detect that we only consumed 2 bytes, so 3 bytes are reclaimed.
-			let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter);
-
-			// We reclaimed 3 bytes of storage size!
-			assert_eq!(reclaimed, Some(Weight::from_parts(0, 3)));
-			assert_eq!(get_storage_weight().total().proof_size(), 10);
-			assert_eq!(remaining_weight_meter.remaining(), Weight::from_parts(10, 8));
-		}
-	}
-
-	#[test]
-	fn test_reclaim_helper_works_with_meter() {
-		// The node will report 12 - 10 = 2 consumed storage size between the calls.
-		let mut test_ext = setup_test_externalities(&[10, 12]);
-
-		test_ext.execute_with(|| {
-			// Initial storage size is 10.
-			set_current_storage_weight(10);
-			reclaim_with_weight_meter();
-		});
-	}
+	impl_tx_ext_default!(T::RuntimeCall; weight validate);
 }
diff --git a/cumulus/primitives/storage-weight-reclaim/src/tests.rs b/cumulus/primitives/storage-weight-reclaim/src/tests.rs
new file mode 100644
index 00000000000..c5552b0f0a3
--- /dev/null
+++ b/cumulus/primitives/storage-weight-reclaim/src/tests.rs
@@ -0,0 +1,706 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use super::*;
+use core::marker::PhantomData;
+use frame_support::{
+	assert_ok,
+	dispatch::{DispatchClass, PerDispatchClass},
+	weights::{Weight, WeightMeter},
+};
+use frame_system::{BlockWeight, CheckWeight};
+use sp_runtime::{traits::DispatchTransaction, AccountId32, BuildStorage};
+use sp_trie::proof_size_extension::ProofSizeExt;
+
+type Test = cumulus_test_runtime::Runtime;
+const CALL: &<Test as Config>::RuntimeCall =
+	&cumulus_test_runtime::RuntimeCall::System(frame_system::Call::set_heap_pages { pages: 0u64 });
+const ALICE: AccountId32 = AccountId32::new([1u8; 32]);
+const LEN: usize = 150;
+
+fn new_test_ext() -> sp_io::TestExternalities {
+	let ext: sp_io::TestExternalities = cumulus_test_runtime::RuntimeGenesisConfig::default()
+		.build_storage()
+		.unwrap()
+		.into();
+	ext
+}
+
+struct TestRecorder {
+	return_values: Box<[usize]>,
+	counter: core::sync::atomic::AtomicUsize,
+}
+
+impl TestRecorder {
+	fn new(values: &[usize]) -> Self {
+		TestRecorder { return_values: values.into(), counter: Default::default() }
+	}
+}
+
+impl sp_trie::ProofSizeProvider for TestRecorder {
+	fn estimate_encoded_size(&self) -> usize {
+		let counter = self.counter.fetch_add(1, core::sync::atomic::Ordering::Relaxed);
+		self.return_values[counter]
+	}
+}
+
+fn setup_test_externalities(proof_values: &[usize]) -> sp_io::TestExternalities {
+	let mut test_ext = new_test_ext();
+	let test_recorder = TestRecorder::new(proof_values);
+	test_ext.register_extension(ProofSizeExt::new(test_recorder));
+	test_ext
+}
+
+fn set_current_storage_weight(new_weight: u64) {
+	BlockWeight::<Test>::mutate(|current_weight| {
+		current_weight.set(Weight::from_parts(0, new_weight), DispatchClass::Normal);
+	});
+}
+
+fn get_storage_weight() -> PerDispatchClass<Weight> {
+	BlockWeight::<Test>::get()
+}
+
+#[test]
+fn basic_refund() {
+	// The real cost will be 100 bytes of storage size
+	let mut test_ext = setup_test_externalities(&[0, 100]);
+
+	test_ext.execute_with(|| {
+		set_current_storage_weight(1000);
+
+		// Benchmarked storage weight: 500
+		let info = DispatchInfo { call_weight: Weight::from_parts(0, 500), ..Default::default() };
+		let post_info = PostDispatchInfo::default();
+
+		// Should add 500 + 150 (len) to weight.
+		let (_, next_len) = CheckWeight::<Test>::do_validate(&info, LEN).unwrap();
+		assert_ok!(CheckWeight::<Test>::do_prepare(&info, LEN, next_len));
+
+		let (pre, _) = StorageWeightReclaim::<Test>(PhantomData)
+			.validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN)
+			.unwrap();
+		assert_eq!(pre, Some(0));
+
+		assert_ok!(CheckWeight::<Test>::post_dispatch_details((), &info, &post_info, 0, &Ok(()),));
+		// We expect a refund of 400
+		assert_ok!(StorageWeightReclaim::<Test>::post_dispatch_details(
+			pre,
+			&info,
+			&post_info,
+			LEN,
+			&Ok(()),
+		));
+
+		assert_eq!(get_storage_weight().total().proof_size(), 1250);
+	})
+}
+
+#[test]
+fn underestimating_refund() {
+	// We fixed a bug where `pre dispatch info weight > consumed weight > post info weight`
+	// resulted in error.
+
+	// The real cost will be 100 bytes of storage size
+	let mut test_ext = setup_test_externalities(&[0, 100]);
+
+	test_ext.execute_with(|| {
+		set_current_storage_weight(1000);
+
+		// Benchmarked storage weight: 500
+		let info = DispatchInfo { call_weight: Weight::from_parts(0, 101), ..Default::default() };
+		let post_info = PostDispatchInfo {
+			actual_weight: Some(Weight::from_parts(0, 99)),
+			pays_fee: Default::default(),
+		};
+
+		let (_, next_len) = CheckWeight::<Test>::do_validate(&info, LEN).unwrap();
+		assert_ok!(CheckWeight::<Test>::do_prepare(&info, LEN, next_len));
+
+		let (pre, _) = StorageWeightReclaim::<Test>(PhantomData)
+			.validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN)
+			.unwrap();
+		assert_eq!(pre, Some(0));
+
+		assert_ok!(CheckWeight::<Test>::post_dispatch_details((), &info, &post_info, 0, &Ok(())));
+		// We expect an accrue of 1
+		assert_ok!(StorageWeightReclaim::<Test>::post_dispatch_details(
+			pre,
+			&info,
+			&post_info,
+			LEN,
+			&Ok(())
+		));
+
+		assert_eq!(get_storage_weight().total().proof_size(), 1250);
+	})
+}
+
+#[test]
+fn sets_to_node_storage_proof_if_higher() {
+	// The storage proof reported by the proof recorder is higher than what is stored on
+	// the runtime side.
+	{
+		let mut test_ext = setup_test_externalities(&[1000, 1005]);
+
+		test_ext.execute_with(|| {
+			// Stored in BlockWeight is 5
+			set_current_storage_weight(5);
+
+			// Benchmarked storage weight: 10
+			let info =
+				DispatchInfo { call_weight: Weight::from_parts(0, 10), ..Default::default() };
+			let post_info = PostDispatchInfo::default();
+
+			let (_, next_len) = CheckWeight::<Test>::do_validate(&info, LEN).unwrap();
+			assert_ok!(CheckWeight::<Test>::do_prepare(&info, LEN, next_len));
+
+			let (pre, _) = StorageWeightReclaim::<Test>(PhantomData)
+				.validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN)
+				.unwrap();
+			assert_eq!(pre, Some(1000));
+
+			assert_ok!(CheckWeight::<Test>::post_dispatch_details(
+				(),
+				&info,
+				&post_info,
+				0,
+				&Ok(())
+			));
+			assert_ok!(StorageWeightReclaim::<Test>::post_dispatch_details(
+				pre,
+				&info,
+				&post_info,
+				LEN,
+				&Ok(())
+			));
+
+			// We expect that the storage weight was set to the node-side proof size (1005) +
+			// extrinsics length (150)
+			assert_eq!(get_storage_weight().total().proof_size(), 1155);
+		})
+	}
+
+	// In this second scenario the proof size on the node side is only lower
+	// after reclaim happened.
+	{
+		let mut test_ext = setup_test_externalities(&[175, 180]);
+		test_ext.execute_with(|| {
+			set_current_storage_weight(85);
+
+			// Benchmarked storage weight: 100
+			let info =
+				DispatchInfo { call_weight: Weight::from_parts(0, 100), ..Default::default() };
+			let post_info = PostDispatchInfo::default();
+
+			// After this pre_dispatch, the BlockWeight proof size will be
+			// 85 (initial) + 100 (benched) + 150 (tx length) = 335
+			let (_, next_len) = CheckWeight::<Test>::do_validate(&info, LEN).unwrap();
+			assert_ok!(CheckWeight::<Test>::do_prepare(&info, LEN, next_len));
+
+			let (pre, _) = StorageWeightReclaim::<Test>(PhantomData)
+				.validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN)
+				.unwrap();
+			assert_eq!(pre, Some(175));
+
+			assert_ok!(CheckWeight::<Test>::post_dispatch_details(
+				(),
+				&info,
+				&post_info,
+				0,
+				&Ok(())
+			));
+
+			// First we will reclaim 95, which leaves us with 240 BlockWeight. This is lower
+			// than 180 (proof size hf) + 150 (length), so we expect it to be set to 330.
+			assert_ok!(StorageWeightReclaim::<Test>::post_dispatch_details(
+				pre,
+				&info,
+				&post_info,
+				LEN,
+				&Ok(())
+			));
+
+			// We expect that the storage weight was set to the node-side proof weight
+			assert_eq!(get_storage_weight().total().proof_size(), 330);
+		})
+	}
+}
+
+#[test]
+fn does_nothing_without_extension() {
+	let mut test_ext = new_test_ext();
+
+	// Proof size extension not registered
+	test_ext.execute_with(|| {
+		set_current_storage_weight(1000);
+
+		// Benchmarked storage weight: 500
+		let info = DispatchInfo { call_weight: Weight::from_parts(0, 500), ..Default::default() };
+		let post_info = PostDispatchInfo::default();
+
+		// Adds 500 + 150 (len) weight
+		let (_, next_len) = CheckWeight::<Test>::do_validate(&info, LEN).unwrap();
+		assert_ok!(CheckWeight::<Test>::do_prepare(&info, LEN, next_len));
+
+		let (pre, _) = StorageWeightReclaim::<Test>(PhantomData)
+			.validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN)
+			.unwrap();
+		assert_eq!(pre, None);
+
+		assert_ok!(CheckWeight::<Test>::post_dispatch_details((), &info, &post_info, 0, &Ok(()),));
+		assert_ok!(StorageWeightReclaim::<Test>::post_dispatch_details(
+			pre,
+			&info,
+			&post_info,
+			LEN,
+			&Ok(()),
+		));
+
+		assert_eq!(get_storage_weight().total().proof_size(), 1650);
+	})
+}
+
+#[test]
+fn negative_refund_is_added_to_weight() {
+	let mut test_ext = setup_test_externalities(&[100, 300]);
+
+	test_ext.execute_with(|| {
+		set_current_storage_weight(1000);
+		// Benchmarked storage weight: 100
+		let info = DispatchInfo { call_weight: Weight::from_parts(0, 100), ..Default::default() };
+		let post_info = PostDispatchInfo::default();
+
+		// Weight added should be 100 + 150 (len)
+		let (_, next_len) = CheckWeight::<Test>::do_validate(&info, LEN).unwrap();
+		assert_ok!(CheckWeight::<Test>::do_prepare(&info, LEN, next_len));
+
+		let (pre, _) = StorageWeightReclaim::<Test>(PhantomData)
+			.validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN)
+			.unwrap();
+		assert_eq!(pre, Some(100));
+
+		// We expect no refund
+		assert_ok!(CheckWeight::<Test>::post_dispatch_details((), &info, &post_info, 0, &Ok(()),));
+		assert_ok!(StorageWeightReclaim::<Test>::post_dispatch_details(
+			pre,
+			&info,
+			&post_info,
+			LEN,
+			&Ok(()),
+		));
+
+		assert_eq!(
+			get_storage_weight().total().proof_size(),
+			1100 + LEN as u64 + info.total_weight().proof_size()
+		);
+	})
+}
+
+#[test]
+fn test_zero_proof_size() {
+	let mut test_ext = setup_test_externalities(&[0, 0]);
+
+	test_ext.execute_with(|| {
+		let info = DispatchInfo { call_weight: Weight::from_parts(0, 500), ..Default::default() };
+		let post_info = PostDispatchInfo::default();
+
+		let (_, next_len) = CheckWeight::<Test>::do_validate(&info, LEN).unwrap();
+		assert_ok!(CheckWeight::<Test>::do_prepare(&info, LEN, next_len));
+
+		let (pre, _) = StorageWeightReclaim::<Test>(PhantomData)
+			.validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN)
+			.unwrap();
+		assert_eq!(pre, Some(0));
+
+		assert_ok!(CheckWeight::<Test>::post_dispatch_details((), &info, &post_info, 0, &Ok(()),));
+		assert_ok!(StorageWeightReclaim::<Test>::post_dispatch_details(
+			pre,
+			&info,
+			&post_info,
+			LEN,
+			&Ok(()),
+		));
+
+		// Proof size should be exactly equal to extrinsic length
+		assert_eq!(get_storage_weight().total().proof_size(), LEN as u64);
+	});
+}
+
+#[test]
+fn test_larger_pre_dispatch_proof_size() {
+	let mut test_ext = setup_test_externalities(&[300, 100]);
+
+	test_ext.execute_with(|| {
+		set_current_storage_weight(1300);
+
+		let info = DispatchInfo { call_weight: Weight::from_parts(0, 500), ..Default::default() };
+		let post_info = PostDispatchInfo::default();
+
+		// Adds 500 + 150 (len) weight, total weight is 1950
+		let (_, next_len) = CheckWeight::<Test>::do_validate(&info, LEN).unwrap();
+		assert_ok!(CheckWeight::<Test>::do_prepare(&info, LEN, next_len));
+
+		let (pre, _) = StorageWeightReclaim::<Test>(PhantomData)
+			.validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN)
+			.unwrap();
+		assert_eq!(pre, Some(300));
+
+		// Refund 500 unspent weight according to `post_info`, total weight is now 1650
+		assert_ok!(CheckWeight::<Test>::post_dispatch_details((), &info, &post_info, 0, &Ok(()),));
+		// Recorded proof size is negative -200, total weight is now 1450
+		assert_ok!(StorageWeightReclaim::<Test>::post_dispatch_details(
+			pre,
+			&info,
+			&post_info,
+			LEN,
+			&Ok(()),
+		));
+
+		assert_eq!(get_storage_weight().total().proof_size(), 1450);
+	});
+}
+
+#[test]
+fn test_incorporates_check_weight_unspent_weight() {
+	let mut test_ext = setup_test_externalities(&[100, 300]);
+
+	test_ext.execute_with(|| {
+		set_current_storage_weight(1000);
+
+		// Benchmarked storage weight: 300
+		let info = DispatchInfo { call_weight: Weight::from_parts(100, 300), ..Default::default() };
+
+		// Actual weight is 50
+		let post_info = PostDispatchInfo {
+			actual_weight: Some(Weight::from_parts(50, 250)),
+			pays_fee: Default::default(),
+		};
+
+		// Should add 300 + 150 (len) of weight
+		let (_, next_len) = CheckWeight::<Test>::do_validate(&info, LEN).unwrap();
+		assert_ok!(CheckWeight::<Test>::do_prepare(&info, LEN, next_len));
+
+		let (pre, _) = StorageWeightReclaim::<Test>(PhantomData)
+			.validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN)
+			.unwrap();
+		assert_eq!(pre, Some(100));
+
+		// The `CheckWeight` extension will refunt `actual_weight` from `PostDispatchInfo`
+		// we always need to call `post_dispatch` to verify that they interoperate correctly.
+		assert_ok!(CheckWeight::<Test>::post_dispatch_details((), &info, &post_info, 0, &Ok(()),));
+		assert_ok!(StorageWeightReclaim::<Test>::post_dispatch_details(
+			pre,
+			&info,
+			&post_info,
+			LEN,
+			&Ok(()),
+		));
+
+		// Reclaimed 100
+		assert_eq!(get_storage_weight().total().proof_size(), 1350);
+	})
+}
+
+#[test]
+fn test_incorporates_check_weight_unspent_weight_on_negative() {
+	let mut test_ext = setup_test_externalities(&[100, 300]);
+
+	test_ext.execute_with(|| {
+		set_current_storage_weight(1000);
+		// Benchmarked storage weight: 50
+		let info = DispatchInfo { call_weight: Weight::from_parts(100, 50), ..Default::default() };
+
+		// Actual weight is 25
+		let post_info = PostDispatchInfo {
+			actual_weight: Some(Weight::from_parts(50, 25)),
+			pays_fee: Default::default(),
+		};
+
+		// Adds 50 + 150 (len) weight, total weight 1200
+		let (_, next_len) = CheckWeight::<Test>::do_validate(&info, LEN).unwrap();
+		assert_ok!(CheckWeight::<Test>::do_prepare(&info, LEN, next_len));
+
+		let (pre, _) = StorageWeightReclaim::<Test>(PhantomData)
+			.validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN)
+			.unwrap();
+		assert_eq!(pre, Some(100));
+
+		// The `CheckWeight` extension will refunt `actual_weight` from `PostDispatchInfo`
+		// we always need to call `post_dispatch` to verify that they interoperate correctly.
+		// Refunds unspent 25 weight according to `post_info`, 1175
+		assert_ok!(CheckWeight::<Test>::post_dispatch_details((), &info, &post_info, 0, &Ok(()),));
+		// Adds 200 - 25 (unspent) == 175 weight, total weight 1350
+		assert_ok!(StorageWeightReclaim::<Test>::post_dispatch_details(
+			pre,
+			&info,
+			&post_info,
+			LEN,
+			&Ok(()),
+		));
+
+		assert_eq!(get_storage_weight().total().proof_size(), 1350);
+	})
+}
+
+#[test]
+fn test_nothing_relcaimed() {
+	let mut test_ext = setup_test_externalities(&[0, 100]);
+
+	test_ext.execute_with(|| {
+		set_current_storage_weight(0);
+		// Benchmarked storage weight: 100
+		let info = DispatchInfo { call_weight: Weight::from_parts(100, 100), ..Default::default() };
+
+		// Actual proof size is 100
+		let post_info = PostDispatchInfo {
+			actual_weight: Some(Weight::from_parts(50, 100)),
+			pays_fee: Default::default(),
+		};
+
+		// Adds benchmarked weight 100 + 150 (len), total weight is now 250
+		let (_, next_len) = CheckWeight::<Test>::do_validate(&info, LEN).unwrap();
+		assert_ok!(CheckWeight::<Test>::do_prepare(&info, LEN, next_len));
+
+		// Weight should go up by 150 len + 100 proof size weight, total weight 250
+		assert_eq!(get_storage_weight().total().proof_size(), 250);
+
+		let (pre, _) = StorageWeightReclaim::<Test>(PhantomData)
+			.validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN)
+			.unwrap();
+		// Should return `setup_test_externalities` proof recorder value: 100.
+		assert_eq!(pre, Some(0));
+
+		// The `CheckWeight` extension will refund `actual_weight` from `PostDispatchInfo`
+		// we always need to call `post_dispatch` to verify that they interoperate correctly.
+		// Nothing to refund, unspent is 0, total weight 250
+		assert_ok!(CheckWeight::<Test>::post_dispatch_details((), &info, &post_info, LEN, &Ok(())));
+		// `setup_test_externalities` proof recorder value: 200, so this means the extrinsic
+		// actually used 100 proof size.
+		// Nothing to refund or add, weight matches proof recorder
+		assert_ok!(StorageWeightReclaim::<Test>::post_dispatch_details(
+			pre,
+			&info,
+			&post_info,
+			LEN,
+			&Ok(())
+		));
+
+		// Check block len weight was not reclaimed:
+		// 100 weight + 150 extrinsic len == 250 proof size
+		assert_eq!(get_storage_weight().total().proof_size(), 250);
+	})
+}
+
+#[test]
+fn test_incorporates_check_weight_unspent_weight_reverse_order() {
+	let mut test_ext = setup_test_externalities(&[100, 300]);
+
+	test_ext.execute_with(|| {
+		set_current_storage_weight(1000);
+
+		// Benchmarked storage weight: 300
+		let info = DispatchInfo { call_weight: Weight::from_parts(100, 300), ..Default::default() };
+
+		// Actual weight is 50
+		let post_info = PostDispatchInfo {
+			actual_weight: Some(Weight::from_parts(50, 250)),
+			pays_fee: Default::default(),
+		};
+
+		// Adds 300 + 150 (len) weight, total weight 1450
+		let (_, next_len) = CheckWeight::<Test>::do_validate(&info, LEN).unwrap();
+		assert_ok!(CheckWeight::<Test>::do_prepare(&info, LEN, next_len));
+
+		let (pre, _) = StorageWeightReclaim::<Test>(PhantomData)
+			.validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN)
+			.unwrap();
+		assert_eq!(pre, Some(100));
+
+		// This refunds 100 - 50(unspent), total weight is now 1400
+		assert_ok!(StorageWeightReclaim::<Test>::post_dispatch_details(
+			pre,
+			&info,
+			&post_info,
+			LEN,
+			&Ok(()),
+		));
+		// `CheckWeight` gets called after `StorageWeightReclaim` this time.
+		// The `CheckWeight` extension will refunt `actual_weight` from `PostDispatchInfo`
+		// we always need to call `post_dispatch` to verify that they interoperate correctly.
+		assert_ok!(CheckWeight::<Test>::post_dispatch_details((), &info, &post_info, 0, &Ok(()),));
+
+		// Above call refunds 50 (unspent), total weight is 1350 now
+		assert_eq!(get_storage_weight().total().proof_size(), 1350);
+	})
+}
+
+#[test]
+fn test_incorporates_check_weight_unspent_weight_on_negative_reverse_order() {
+	let mut test_ext = setup_test_externalities(&[100, 300]);
+
+	test_ext.execute_with(|| {
+		set_current_storage_weight(1000);
+		// Benchmarked storage weight: 50
+		let info = DispatchInfo { call_weight: Weight::from_parts(100, 50), ..Default::default() };
+
+		// Actual weight is 25
+		let post_info = PostDispatchInfo {
+			actual_weight: Some(Weight::from_parts(50, 25)),
+			pays_fee: Default::default(),
+		};
+
+		// Adds 50 + 150 (len) weight, total weight is 1200
+		let (_, next_len) = CheckWeight::<Test>::do_validate(&info, LEN).unwrap();
+		assert_ok!(CheckWeight::<Test>::do_prepare(&info, LEN, next_len));
+
+		let (pre, _) = StorageWeightReclaim::<Test>(PhantomData)
+			.validate_and_prepare(Some(ALICE.clone()).into(), CALL, &info, LEN)
+			.unwrap();
+		assert_eq!(pre, Some(100));
+
+		// Adds additional 150 weight recorded
+		assert_ok!(StorageWeightReclaim::<Test>::post_dispatch_details(
+			pre,
+			&info,
+			&post_info,
+			LEN,
+			&Ok(()),
+		));
+		// `CheckWeight` gets called after `StorageWeightReclaim` this time.
+		// The `CheckWeight` extension will refunt `actual_weight` from `PostDispatchInfo`
+		// we always need to call `post_dispatch` to verify that they interoperate correctly.
+		assert_ok!(CheckWeight::<Test>::post_dispatch_details((), &info, &post_info, 0, &Ok(()),));
+
+		assert_eq!(get_storage_weight().total().proof_size(), 1350);
+	})
+}
+
+#[test]
+fn storage_size_reported_correctly() {
+	let mut test_ext = setup_test_externalities(&[1000]);
+	test_ext.execute_with(|| {
+		assert_eq!(get_proof_size(), Some(1000));
+	});
+
+	let mut test_ext = new_test_ext();
+
+	let test_recorder = TestRecorder::new(&[0]);
+
+	test_ext.register_extension(ProofSizeExt::new(test_recorder));
+
+	test_ext.execute_with(|| {
+		assert_eq!(get_proof_size(), Some(0));
+	});
+}
+
+#[test]
+fn storage_size_disabled_reported_correctly() {
+	let mut test_ext = setup_test_externalities(&[PROOF_RECORDING_DISABLED as usize]);
+
+	test_ext.execute_with(|| {
+		assert_eq!(get_proof_size(), None);
+	});
+}
+
+#[test]
+fn test_reclaim_helper() {
+	let mut test_ext = setup_test_externalities(&[1000, 1300, 1800]);
+
+	test_ext.execute_with(|| {
+		let mut remaining_weight_meter = WeightMeter::with_limit(Weight::from_parts(0, 2000));
+		let mut reclaim_helper = StorageWeightReclaimer::new(&remaining_weight_meter);
+		remaining_weight_meter.consume(Weight::from_parts(0, 500));
+		let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter);
+
+		assert_eq!(reclaimed, Some(Weight::from_parts(0, 200)));
+
+		remaining_weight_meter.consume(Weight::from_parts(0, 800));
+		let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter);
+		assert_eq!(reclaimed, Some(Weight::from_parts(0, 300)));
+		assert_eq!(remaining_weight_meter.remaining(), Weight::from_parts(0, 1200));
+	});
+}
+
+#[test]
+fn test_reclaim_helper_does_not_reclaim_negative() {
+	// Benchmarked weight does not change at all
+	let mut test_ext = setup_test_externalities(&[1000, 1300]);
+
+	test_ext.execute_with(|| {
+		let mut remaining_weight_meter = WeightMeter::with_limit(Weight::from_parts(0, 1000));
+		let mut reclaim_helper = StorageWeightReclaimer::new(&remaining_weight_meter);
+		let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter);
+
+		assert_eq!(reclaimed, Some(Weight::from_parts(0, 0)));
+		assert_eq!(remaining_weight_meter.remaining(), Weight::from_parts(0, 1000));
+	});
+
+	// Benchmarked weight increases less than storage proof consumes
+	let mut test_ext = setup_test_externalities(&[1000, 1300]);
+
+	test_ext.execute_with(|| {
+		let mut remaining_weight_meter = WeightMeter::with_limit(Weight::from_parts(0, 1000));
+		let mut reclaim_helper = StorageWeightReclaimer::new(&remaining_weight_meter);
+		remaining_weight_meter.consume(Weight::from_parts(0, 0));
+		let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter);
+
+		assert_eq!(reclaimed, Some(Weight::from_parts(0, 0)));
+	});
+}
+
+/// Just here for doc purposes
+fn get_benched_weight() -> Weight {
+	Weight::from_parts(0, 5)
+}
+
+/// Just here for doc purposes
+fn do_work() {}
+
+#[docify::export_content(simple_reclaimer_example)]
+fn reclaim_with_weight_meter() {
+	let mut remaining_weight_meter = WeightMeter::with_limit(Weight::from_parts(10, 10));
+
+	let benched_weight = get_benched_weight();
+
+	// It is important to instantiate the `StorageWeightReclaimer` before we consume the weight
+	// for a piece of work from the weight meter.
+	let mut reclaim_helper = StorageWeightReclaimer::new(&remaining_weight_meter);
+
+	if remaining_weight_meter.try_consume(benched_weight).is_ok() {
+		// Perform some work that takes has `benched_weight` storage weight.
+		do_work();
+
+		// Reclaimer will detect that we only consumed 2 bytes, so 3 bytes are reclaimed.
+		let reclaimed = reclaim_helper.reclaim_with_meter(&mut remaining_weight_meter);
+
+		// We reclaimed 3 bytes of storage size!
+		assert_eq!(reclaimed, Some(Weight::from_parts(0, 3)));
+		assert_eq!(get_storage_weight().total().proof_size(), 10);
+		assert_eq!(remaining_weight_meter.remaining(), Weight::from_parts(10, 8));
+	}
+}
+
+#[test]
+fn test_reclaim_helper_works_with_meter() {
+	// The node will report 12 - 10 = 2 consumed storage size between the calls.
+	let mut test_ext = setup_test_externalities(&[10, 12]);
+
+	test_ext.execute_with(|| {
+		// Initial storage size is 10.
+		set_current_storage_weight(10);
+		reclaim_with_weight_meter();
+	});
+}
diff --git a/cumulus/test/client/Cargo.toml b/cumulus/test/client/Cargo.toml
index fbbaab73ce7..33023816c71 100644
--- a/cumulus/test/client/Cargo.toml
+++ b/cumulus/test/client/Cargo.toml
@@ -53,6 +53,7 @@ runtime-benchmarks = [
 	"cumulus-test-service/runtime-benchmarks",
 	"frame-system/runtime-benchmarks",
 	"pallet-balances/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"polkadot-parachain-primitives/runtime-benchmarks",
 	"polkadot-primitives/runtime-benchmarks",
 	"sc-service/runtime-benchmarks",
diff --git a/cumulus/test/client/src/lib.rs b/cumulus/test/client/src/lib.rs
index f26413e441e..eaf81699f6d 100644
--- a/cumulus/test/client/src/lib.rs
+++ b/cumulus/test/client/src/lib.rs
@@ -25,7 +25,7 @@ pub use polkadot_parachain_primitives::primitives::{
 	BlockData, HeadData, ValidationParams, ValidationResult,
 };
 use runtime::{
-	Balance, Block, BlockHashCount, Runtime, RuntimeCall, Signature, SignedExtra, SignedPayload,
+	Balance, Block, BlockHashCount, Runtime, RuntimeCall, Signature, SignedPayload, TxExtension,
 	UncheckedExtrinsic, VERSION,
 };
 use sc_consensus_aura::standalone::{seal, slot_author};
@@ -117,7 +117,7 @@ impl DefaultTestClientBuilderExt for TestClientBuilder {
 
 /// Create an unsigned extrinsic from a runtime call.
 pub fn generate_unsigned(function: impl Into<RuntimeCall>) -> UncheckedExtrinsic {
-	UncheckedExtrinsic::new_unsigned(function.into())
+	UncheckedExtrinsic::new_bare(function.into())
 }
 
 /// Create a signed extrinsic from a runtime call and sign
@@ -135,7 +135,7 @@ pub fn generate_extrinsic_with_pair(
 	let period =
 		BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2) as u64;
 	let tip = 0;
-	let extra: SignedExtra = (
+	let tx_ext: TxExtension = (
 		frame_system::CheckNonZeroSender::<Runtime>::new(),
 		frame_system::CheckSpecVersion::<Runtime>::new(),
 		frame_system::CheckGenesis::<Runtime>::new(),
@@ -144,13 +144,14 @@ pub fn generate_extrinsic_with_pair(
 		frame_system::CheckWeight::<Runtime>::new(),
 		pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),
 		cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim::<Runtime>::new(),
-	);
+	)
+		.into();
 
 	let function = function.into();
 
 	let raw_payload = SignedPayload::from_raw(
 		function.clone(),
-		extra.clone(),
+		tx_ext.clone(),
 		((), VERSION.spec_version, genesis_block, current_block_hash, (), (), (), ()),
 	);
 	let signature = raw_payload.using_encoded(|e| origin.sign(e));
@@ -159,7 +160,7 @@ pub fn generate_extrinsic_with_pair(
 		function,
 		origin.public().into(),
 		Signature::Sr25519(signature),
-		extra,
+		tx_ext,
 	)
 }
 
diff --git a/cumulus/test/runtime/src/lib.rs b/cumulus/test/runtime/src/lib.rs
index 92a6ab73a2e..5443bb5f526 100644
--- a/cumulus/test/runtime/src/lib.rs
+++ b/cumulus/test/runtime/src/lib.rs
@@ -279,6 +279,7 @@ impl pallet_transaction_payment::Config for Runtime {
 	type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
 	type FeeMultiplierUpdate = ();
 	type OperationalFeeMultiplier = ConstU8<5>;
+	type WeightInfo = pallet_transaction_payment::weights::SubstrateWeight<Runtime>;
 }
 
 impl pallet_sudo::Config for Runtime {
@@ -371,8 +372,8 @@ pub type Block = generic::Block<Header, UncheckedExtrinsic>;
 pub type SignedBlock = generic::SignedBlock<Block>;
 /// BlockId type as expected by this runtime.
 pub type BlockId = generic::BlockId<Block>;
-/// The SignedExtension to the basic transaction logic.
-pub type SignedExtra = (
+/// The extension to the basic transaction logic.
+pub type TxExtension = (
 	frame_system::CheckNonZeroSender<Runtime>,
 	frame_system::CheckSpecVersion<Runtime>,
 	frame_system::CheckGenesis<Runtime>,
@@ -384,7 +385,7 @@ pub type SignedExtra = (
 );
 /// Unchecked extrinsic type as expected by this runtime.
 pub type UncheckedExtrinsic =
-	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
 /// Executive: handles dispatch to the various modules.
 pub type Executive = frame_executive::Executive<
 	Runtime,
@@ -395,7 +396,7 @@ pub type Executive = frame_executive::Executive<
 	TestOnRuntimeUpgrade,
 >;
 /// The payload being signed in transactions.
-pub type SignedPayload = generic::SignedPayload<RuntimeCall, SignedExtra>;
+pub type SignedPayload = generic::SignedPayload<RuntimeCall, TxExtension>;
 
 pub struct TestOnRuntimeUpgrade;
 
diff --git a/cumulus/test/service/Cargo.toml b/cumulus/test/service/Cargo.toml
index a1b70c52395..3ef9424b9ed 100644
--- a/cumulus/test/service/Cargo.toml
+++ b/cumulus/test/service/Cargo.toml
@@ -110,6 +110,7 @@ runtime-benchmarks = [
 	"cumulus-test-client/runtime-benchmarks",
 	"frame-system/runtime-benchmarks",
 	"pallet-timestamp/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"parachains-common/runtime-benchmarks",
 	"polkadot-cli/runtime-benchmarks",
 	"polkadot-primitives/runtime-benchmarks",
diff --git a/cumulus/test/service/src/bench_utils.rs b/cumulus/test/service/src/bench_utils.rs
index 67ffbdd1d21..76717b4136f 100644
--- a/cumulus/test/service/src/bench_utils.rs
+++ b/cumulus/test/service/src/bench_utils.rs
@@ -68,12 +68,11 @@ pub fn extrinsic_set_time(client: &TestClient) -> OpaqueExtrinsic {
 	let best_number = client.usage_info().chain.best_number;
 
 	let timestamp = best_number as u64 * cumulus_test_runtime::MinimumPeriod::get();
-	cumulus_test_runtime::UncheckedExtrinsic {
-		signature: None,
-		function: cumulus_test_runtime::RuntimeCall::Timestamp(pallet_timestamp::Call::set {
+	cumulus_test_runtime::UncheckedExtrinsic::new_bare(
+		cumulus_test_runtime::RuntimeCall::Timestamp(pallet_timestamp::Call::set {
 			now: timestamp,
 		}),
-	}
+	)
 	.into()
 }
 
@@ -101,12 +100,11 @@ pub fn extrinsic_set_validation_data(
 		horizontal_messages: Default::default(),
 	};
 
-	cumulus_test_runtime::UncheckedExtrinsic {
-		signature: None,
-		function: cumulus_test_runtime::RuntimeCall::ParachainSystem(
+	cumulus_test_runtime::UncheckedExtrinsic::new_bare(
+		cumulus_test_runtime::RuntimeCall::ParachainSystem(
 			cumulus_pallet_parachain_system::Call::set_validation_data { data },
 		),
-	}
+	)
 	.into()
 }
 
diff --git a/cumulus/test/service/src/lib.rs b/cumulus/test/service/src/lib.rs
index a13399d3a40..a3e519a68b9 100644
--- a/cumulus/test/service/src/lib.rs
+++ b/cumulus/test/service/src/lib.rs
@@ -969,7 +969,7 @@ pub fn construct_extrinsic(
 		.map(|c| c / 2)
 		.unwrap_or(2) as u64;
 	let tip = 0;
-	let extra: runtime::SignedExtra = (
+	let tx_ext: runtime::TxExtension = (
 		frame_system::CheckNonZeroSender::<runtime::Runtime>::new(),
 		frame_system::CheckSpecVersion::<runtime::Runtime>::new(),
 		frame_system::CheckGenesis::<runtime::Runtime>::new(),
@@ -981,10 +981,11 @@ pub fn construct_extrinsic(
 		frame_system::CheckWeight::<runtime::Runtime>::new(),
 		pallet_transaction_payment::ChargeTransactionPayment::<runtime::Runtime>::from(tip),
 		cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim::<runtime::Runtime>::new(),
-	);
+	)
+		.into();
 	let raw_payload = runtime::SignedPayload::from_raw(
 		function.clone(),
-		extra.clone(),
+		tx_ext.clone(),
 		((), runtime::VERSION.spec_version, genesis_block, current_block_hash, (), (), (), ()),
 	);
 	let signature = raw_payload.using_encoded(|e| caller.sign(e));
@@ -992,7 +993,7 @@ pub fn construct_extrinsic(
 		function,
 		caller.public().into(),
 		runtime::Signature::Sr25519(signature),
-		extra,
+		tx_ext,
 	)
 }
 
diff --git a/docs/sdk/Cargo.toml b/docs/sdk/Cargo.toml
index adc1c1a8efb..b86ce986820 100644
--- a/docs/sdk/Cargo.toml
+++ b/docs/sdk/Cargo.toml
@@ -39,6 +39,7 @@ subkey = { workspace = true, default-features = true }
 frame-system = { workspace = true }
 frame-support = { workspace = true }
 frame-executive = { workspace = true }
+pallet-example-authorization-tx-extension = { workspace = true, default-features = true }
 pallet-example-single-block-migrations = { workspace = true, default-features = true }
 frame-metadata-hash-extension = { workspace = true, default-features = true }
 log = { workspace = true, default-features = true }
diff --git a/docs/sdk/src/guides/enable_pov_reclaim.rs b/docs/sdk/src/guides/enable_pov_reclaim.rs
index 13b27d18956..cb6960b3df4 100644
--- a/docs/sdk/src/guides/enable_pov_reclaim.rs
+++ b/docs/sdk/src/guides/enable_pov_reclaim.rs
@@ -58,9 +58,9 @@
 //! > that this step in the guide was not
 //! > set up correctly.
 //!
-//! ## 3. Add the SignedExtension to your runtime
+//! ## 3. Add the TransactionExtension to your runtime
 //!
-//! In your runtime, you will find a list of SignedExtensions.
+//! In your runtime, you will find a list of TransactionExtensions.
 //! To enable the reclaiming,
 //! add [`StorageWeightReclaim`](cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim)
 //! to that list. For maximum efficiency, make sure that `StorageWeightReclaim` is last in the list.
diff --git a/docs/sdk/src/reference_docs/extrinsic_encoding.rs b/docs/sdk/src/reference_docs/extrinsic_encoding.rs
index 31ce92c67e9..1d4b0405b32 100644
--- a/docs/sdk/src/reference_docs/extrinsic_encoding.rs
+++ b/docs/sdk/src/reference_docs/extrinsic_encoding.rs
@@ -12,7 +12,7 @@
 //!
 //! What follows is a description of how extrinsics based on this
 //! [`sp_runtime::generic::UncheckedExtrinsic`] type are encoded into bytes. Specifically, we are
-//! looking at how extrinsics with a format version of 4 are encoded. This version is itself a part
+//! looking at how extrinsics with a format version of 5 are encoded. This version is itself a part
 //! of the payload, and if it changes, it indicates that something about the encoding may have
 //! changed.
 //!
@@ -24,7 +24,8 @@
 //! ```text
 //! extrinsic_bytes = concat(
 //!     compact_encoded_length,
-//!     version_and_maybe_signature,
+//!     version_and_extrinsic_type,
+//! 	maybe_extension_data,
 //!     call_data
 //! )
 //! ```
@@ -56,18 +57,38 @@
 //!     version_and_signed,
 //!     from_address,
 //!     signature,
-//!     signed_extensions_extra,
+//!     transaction_extensions_extra,
 //! )
 //! ```
 //!
 //! Each of the details to be concatenated together is explained below:
 //!
-//! ### version_and_signed
+//! ## version_and_extrinsic_type
 //!
-//! This is one byte, equal to `0x84` or `0b1000_0100` (i.e. an upper 1 bit to denote that it is
-//! signed, and then the transaction version, 4, in the lower bits).
+//! This byte has 2 components:
+//! - the 2 most significant bits represent the extrinsic type:
+//!     - bare - `0b00`
+//!     - signed - `0b10`
+//!     - general - `0b01`
+//! - the 6 least significant bits represent the extrinsic format version (currently 5)
 //!
-//! ### from_address
+//! ### Bare extrinsics
+//!
+//! If the extrinsic is _bare_, then `version_and_extrinsic_type` will be just the _transaction
+//! protocol version_, which is 5 (or `0b0000_0101`). Bare extrinsics do not carry any other
+//! extension data, so `maybe_extension_data` would not be included in the payload and the
+//! `version_and_extrinsic_type` would always be followed by the encoded call bytes.
+//!
+//! ### Signed extrinsics
+//!
+//! If the extrinsic is _signed_ (all extrinsics submitted from users used to be signed up until
+//! version 4), then `version_and_extrinsic_type` is obtained by having a MSB of `1` on the
+//! _transaction protocol version_ byte (which translates to `0b1000_0101`).
+//!
+//! Additionally, _signed_ extrinsics also carry with them address and signature information encoded
+//! as follows:
+//!
+//! #### from_address
 //!
 //! This is the [SCALE encoded][frame::deps::codec] address of the sender of the extrinsic. The
 //! address is the first generic parameter of [`sp_runtime::generic::UncheckedExtrinsic`], and so
@@ -78,7 +99,7 @@
 //! signed extrinsic to be submitted to a Polkadot node, you'll always use the
 //! [`sp_runtime::MultiAddress::Id`] variant to wrap your `AccountId32`.
 //!
-//! ### signature
+//! #### signature
 //!
 //! This is the [SCALE encoded][frame::deps::codec] signature. The signature type is configured via
 //! the third generic parameter of [`sp_runtime::generic::UncheckedExtrinsic`], which determines the
@@ -90,32 +111,41 @@
 //! The signature type used on the Polkadot relay chain is [`sp_runtime::MultiSignature`]; the
 //! variants there are the types of signature that can be provided.
 //!
-//! ### signed_extensions_extra
+//! ### General extrinsics
+//!
+//! If the extrinsic is _general_ (it doesn't carry a signature in the payload, only extension
+//! data), then `version_and_extrinsic_type` is obtained by logical OR between the general
+//! transaction type bits and the _transaction protocol version_ byte (which translates to
+//! `0b0100_0101`).
 //!
-//! This is the concatenation of the [SCALE encoded][frame::deps::codec] bytes representing each of
-//! the [_signed extensions_][sp_runtime::traits::SignedExtension], and are configured by the
-//! fourth generic parameter of [`sp_runtime::generic::UncheckedExtrinsic`]. Learn more about
-//! signed extensions [here][crate::reference_docs::signed_extensions].
+//! ### transaction_extensions_extra
 //!
-//! When it comes to constructing an extrinsic, each signed extension has two things that we are
-//! interested in here:
+//! This is the concatenation of the [SCALE encoded][frame::deps::codec] bytes representing first a
+//! single byte describing the extension version (this is bumped whenever a change occurs in the
+//! transaction extension pipeline) followed by the bytes of each of the [_transaction
+//! extensions_][sp_runtime::traits::TransactionExtension], and are configured by the fourth generic
+//! parameter of [`sp_runtime::generic::UncheckedExtrinsic`]. Learn more about transaction
+//! extensions [here][crate::reference_docs::transaction_extensions].
 //!
-//! - The actual SCALE encoding of the signed extension type itself; this is what will form our
-//!   `signed_extensions_extra` bytes.
-//! - An `AdditionalSigned` type. This is SCALE encoded into the `signed_extensions_additional` data
-//!   of the _signed payload_ (see below).
+//! When it comes to constructing an extrinsic, each transaction extension has two things that we
+//! are interested in here:
+//!
+//! - The actual SCALE encoding of the transaction extension type itself; this is what will form our
+//!   `transaction_extensions_extra` bytes.
+//! - An `Implicit` type. This is SCALE encoded into the `transaction_extensions_implicit` data (see
+//!   below).
 //!
 //! Either (or both) of these can encode to zero bytes.
 //!
-//! Each chain configures the set of signed extensions that it uses in its runtime configuration.
-//! At the time of writing, Polkadot configures them
+//! Each chain configures the set of transaction extensions that it uses in its runtime
+//! configuration. At the time of writing, Polkadot configures them
 //! [here](https://github.com/polkadot-fellows/runtimes/blob/1dc04eb954eadf8aadb5d83990b89662dbb5a074/relay/polkadot/src/lib.rs#L1432C25-L1432C25).
-//! Some of the common signed extensions are defined
-//! [here][frame::deps::frame_system#signed-extensions].
+//! Some of the common transaction extensions are defined
+//! [here][frame::deps::frame_system#transaction-extensions].
 //!
-//! Information about exactly which signed extensions are present on a chain and in what order is
-//! also a part of the metadata for the chain. For V15 metadata, it can be
-//! [found here][frame::deps::frame_support::__private::metadata::v15::ExtrinsicMetadata].
+//! Information about exactly which transaction extensions are present on a chain and in what order
+//! is also a part of the metadata for the chain. For V15 metadata, it can be [found
+//! here][frame::deps::frame_support::__private::metadata::v15::ExtrinsicMetadata].
 //!
 //! ## call_data
 //!
@@ -150,53 +180,63 @@
 //!   are typically provided as values to the inner enum.
 //!
 //! Information about the pallets that exist for a chain (including their indexes), the calls
-//! available in each pallet (including their indexes), and the arguments required for each call
-//! can be found in the metadata for the chain. For V15 metadata, this information
-//! [is here][frame::deps::frame_support::__private::metadata::v15::PalletMetadata].
+//! available in each pallet (including their indexes), and the arguments required for each call can
+//! be found in the metadata for the chain. For V15 metadata, this information [is
+//! here][frame::deps::frame_support::__private::metadata::v15::PalletMetadata].
 //!
 //! # The Signed Payload Format
 //!
-//! All extrinsics submitted to a node from the outside world (also known as _transactions_) need to
-//! be _signed_. The data that needs to be signed for some extrinsic is called the _signed payload_,
-//! and its shape is described by the following pseudo-code:
+//! All _signed_ extrinsics submitted to a node from the outside world (also known as
+//! _transactions_) need to be _signed_. The data that needs to be signed for some extrinsic is
+//! called the _signed payload_, and its shape is described by the following pseudo-code:
 //!
 //! ```text
-//! signed_payload = concat(
-//!     call_data,
-//!     signed_extensions_extra,
-//!     signed_extensions_additional,
+//! signed_payload = blake2_256(
+//! 	concat(
+//!     	call_data,
+//!     	transaction_extensions_extra,
+//!     	transaction_extensions_implicit,
+//! 	)
 //! )
-//!
-//! if length(signed_payload) > 256 {
-//!     signed_payload = blake2_256(signed_payload)
-//! }
 //! ```
 //!
-//! The bytes representing `call_data` and `signed_extensions_extra` can be obtained as described
-//! above. `signed_extensions_additional` is constructed by SCALE encoding the
-//! ["additional signed" data][sp_runtime::traits::SignedExtension::AdditionalSigned] for each
-//! signed extension that the chain is using, in order.
+//! The bytes representing `call_data` and `transaction_extensions_extra` can be obtained as
+//! descibed above. `transaction_extensions_implicit` is constructed by SCALE encoding the
+//! ["implicit" data][sp_runtime::traits::TransactionExtension::Implicit] for each transaction
+//! extension that the chain is using, in order.
+//!
+//! Once we've concatenated those together, we hash the result using a Blake2 256bit hasher.
+//!
+//! The [`sp_runtime::generic::SignedPayload`] type takes care of assembling the correct payload for
+//! us, given `call_data` and a tuple of transaction extensions.
 //!
-//! Once we've concatenated those together, we hash the result if it's greater than 256 bytes in
-//! length using a Blake2 256bit hasher.
+//! # The General Transaction Format
 //!
-//! The [`sp_runtime::generic::SignedPayload`] type takes care of assembling the correct payload
-//! for us, given `call_data` and a tuple of signed extensions.
+//! A General transaction does not have a signature method hardcoded in the check logic of the
+//! extrinsic, such as a traditionally signed transaction. Instead, general transactions should have
+//! one or more extensions in the transaction extension pipeline that auhtorize origins in some way,
+//! one of which could be the traditional signature check that happens for all signed transactions
+//! in the [Checkable](sp_runtime::traits::Checkable) implementation of
+//! [UncheckedExtrinsic](sp_runtime::generic::UncheckedExtrinsic). Therefore, it is up to each
+//! extension to define the format of the payload it will try to check and authorize the right
+//! origin type. For an example, look into the [authorization example pallet
+//! extensions](pallet_example_authorization_tx_extension::extensions)
 //!
 //! # Example Encoding
 //!
-//! Using [`sp_runtime::generic::UncheckedExtrinsic`], we can construct and encode an extrinsic
-//! as follows:
+//! Using [`sp_runtime::generic::UncheckedExtrinsic`], we can construct and encode an extrinsic as
+//! follows:
 #![doc = docify::embed!("./src/reference_docs/extrinsic_encoding.rs", encoding_example)]
 
 #[docify::export]
 pub mod call_data {
 	use codec::{Decode, Encode};
+	use sp_runtime::{traits::Dispatchable, DispatchResultWithInfo};
 
 	// The outer enum composes calls within
 	// different pallets together. We have two
 	// pallets, "PalletA" and "PalletB".
-	#[derive(Encode, Decode)]
+	#[derive(Encode, Decode, Clone)]
 	pub enum Call {
 		#[codec(index = 0)]
 		PalletA(PalletACall),
@@ -207,23 +247,33 @@ pub mod call_data {
 	// An inner enum represents the calls within
 	// a specific pallet. "PalletA" has one call,
 	// "Foo".
-	#[derive(Encode, Decode)]
+	#[derive(Encode, Decode, Clone)]
 	pub enum PalletACall {
 		#[codec(index = 0)]
 		Foo(String),
 	}
 
-	#[derive(Encode, Decode)]
+	#[derive(Encode, Decode, Clone)]
 	pub enum PalletBCall {
 		#[codec(index = 0)]
 		Bar(String),
 	}
+
+	impl Dispatchable for Call {
+		type RuntimeOrigin = ();
+		type Config = ();
+		type Info = ();
+		type PostInfo = ();
+		fn dispatch(self, _origin: Self::RuntimeOrigin) -> DispatchResultWithInfo<Self::PostInfo> {
+			Ok(())
+		}
+	}
 }
 
 #[docify::export]
 pub mod encoding_example {
 	use super::call_data::{Call, PalletACall};
-	use crate::reference_docs::signed_extensions::signed_extensions_example;
+	use crate::reference_docs::transaction_extensions::transaction_extensions_example;
 	use codec::Encode;
 	use sp_core::crypto::AccountId32;
 	use sp_keyring::sr25519::Keyring;
@@ -232,34 +282,40 @@ pub mod encoding_example {
 		MultiAddress, MultiSignature,
 	};
 
-	// Define some signed extensions to use. We'll use a couple of examples
-	// from the signed extensions reference doc.
-	type SignedExtensions =
-		(signed_extensions_example::AddToPayload, signed_extensions_example::AddToSignaturePayload);
+	// Define some transaction extensions to use. We'll use a couple of examples
+	// from the transaction extensions reference doc.
+	type TransactionExtensions = (
+		transaction_extensions_example::AddToPayload,
+		transaction_extensions_example::AddToSignaturePayload,
+	);
 
 	// We'll use `UncheckedExtrinsic` to encode our extrinsic for us. We set
 	// the address and signature type to those used on Polkadot, use our custom
-	// `Call` type, and use our custom set of `SignedExtensions`.
-	type Extrinsic =
-		UncheckedExtrinsic<MultiAddress<AccountId32, ()>, Call, MultiSignature, SignedExtensions>;
+	// `Call` type, and use our custom set of `TransactionExtensions`.
+	type Extrinsic = UncheckedExtrinsic<
+		MultiAddress<AccountId32, ()>,
+		Call,
+		MultiSignature,
+		TransactionExtensions,
+	>;
 
 	pub fn encode_demo_extrinsic() -> Vec<u8> {
 		// The "from" address will be our Alice dev account.
 		let from_address = MultiAddress::<AccountId32, ()>::Id(Keyring::Alice.to_account_id());
 
-		// We provide some values for our expected signed extensions.
-		let signed_extensions = (
-			signed_extensions_example::AddToPayload(1),
-			signed_extensions_example::AddToSignaturePayload,
+		// We provide some values for our expected transaction extensions.
+		let transaction_extensions = (
+			transaction_extensions_example::AddToPayload(1),
+			transaction_extensions_example::AddToSignaturePayload,
 		);
 
 		// Construct our call data:
 		let call_data = Call::PalletA(PalletACall::Foo("Hello".to_string()));
 
 		// The signed payload. This takes care of encoding the call_data,
-		// signed_extensions_extra and signed_extensions_additional, and hashing
+		// transaction_extensions_extra and transaction_extensions_implicit, and hashing
 		// the result if it's > 256 bytes:
-		let signed_payload = SignedPayload::new(&call_data, signed_extensions.clone());
+		let signed_payload = SignedPayload::new(call_data.clone(), transaction_extensions.clone());
 
 		// Sign the signed payload with our Alice dev account's private key,
 		// and wrap the signature into the expected type:
@@ -269,7 +325,7 @@ pub mod encoding_example {
 		};
 
 		// Now, we can build and encode our extrinsic:
-		let ext = Extrinsic::new_signed(call_data, from_address, signature, signed_extensions);
+		let ext = Extrinsic::new_signed(call_data, from_address, signature, transaction_extensions);
 
 		let encoded_ext = ext.encode();
 		encoded_ext
diff --git a/docs/sdk/src/reference_docs/frame_runtime_types.rs b/docs/sdk/src/reference_docs/frame_runtime_types.rs
index e99106ade87..ec7196cea66 100644
--- a/docs/sdk/src/reference_docs/frame_runtime_types.rs
+++ b/docs/sdk/src/reference_docs/frame_runtime_types.rs
@@ -134,7 +134,7 @@
 //! * [`crate::reference_docs::frame_origin`] explores further details about the usage of
 //!   `RuntimeOrigin`.
 //! * [`RuntimeCall`] is a particularly interesting composite enum as it dictates the encoding of an
-//!   extrinsic. See [`crate::reference_docs::signed_extensions`] for more information.
+//!   extrinsic. See [`crate::reference_docs::transaction_extensions`] for more information.
 //! * See the documentation of [`construct_runtime`].
 //! * See the corresponding lecture in the [pba-book](https://polkadot-blockchain-academy.github.io/pba-book/frame/outer-enum/page.html).
 //!
diff --git a/docs/sdk/src/reference_docs/mod.rs b/docs/sdk/src/reference_docs/mod.rs
index 7f2edb08d46..9cf5605a88b 100644
--- a/docs/sdk/src/reference_docs/mod.rs
+++ b/docs/sdk/src/reference_docs/mod.rs
@@ -40,9 +40,12 @@ pub mod runtime_vs_smart_contract;
 /// Learn about how extrinsics are encoded to be transmitted to a node and stored in blocks.
 pub mod extrinsic_encoding;
 
-/// Learn about the signed extensions that form a part of extrinsics.
+/// Deprecated in favor of transaction extensions.
 pub mod signed_extensions;
 
+/// Learn about the transaction extensions that form a part of extrinsics.
+pub mod transaction_extensions;
+
 /// Learn about *Origins*, a topic in FRAME that enables complex account abstractions to be built.
 pub mod frame_origin;
 
diff --git a/docs/sdk/src/reference_docs/signed_extensions.rs b/docs/sdk/src/reference_docs/signed_extensions.rs
index c644aeaa416..6e44fea88de 100644
--- a/docs/sdk/src/reference_docs/signed_extensions.rs
+++ b/docs/sdk/src/reference_docs/signed_extensions.rs
@@ -1,131 +1,2 @@
-//! Signed extensions are, briefly, a means for different chains to extend the "basic" extrinsic
-//! format with custom data that can be checked by the runtime.
-//!
-//! # FRAME provided signed extensions
-//!
-//! FRAME by default already provides the following signed extensions:
-//!
-//! - [`CheckGenesis`](frame_system::CheckGenesis): Ensures that a transaction was sent for the same
-//!   network. Determined based on genesis.
-//!
-//! - [`CheckMortality`](frame_system::CheckMortality): Extends a transaction with a configurable
-//!   mortality.
-//!
-//! - [`CheckNonZeroSender`](frame_system::CheckNonZeroSender): Ensures that the sender of a
-//!   transaction is not the *all zero account* (all bytes of the accountid are zero).
-//!
-//! - [`CheckNonce`](frame_system::CheckNonce): Extends a transaction with a nonce to prevent replay
-//!   of transactions and to provide ordering of transactions.
-//!
-//! - [`CheckSpecVersion`](frame_system::CheckSpecVersion): Ensures that a transaction was built for
-//!   the currently active runtime.
-//!
-//! - [`CheckTxVersion`](frame_system::CheckTxVersion): Ensures that the transaction signer used the
-//!   correct encoding of the call.
-//!
-//! - [`CheckWeight`](frame_system::CheckWeight): Ensures that the transaction fits into the block
-//!   before dispatching it.
-//!
-//! - [`ChargeTransactionPayment`](pallet_transaction_payment::ChargeTransactionPayment): Charges
-//!   transaction fees from the signer based on the weight of the call using the native token.
-//!
-//! - [`ChargeAssetTxPayment`](pallet_asset_tx_payment::ChargeAssetTxPayment): Charges transaction
-//!   fees from the signer based on the weight of the call using any supported asset (including the
-//!   native token).
-//!
-//! - [`ChargeAssetTxPayment`(using
-//!   conversion)](pallet_asset_conversion_tx_payment::ChargeAssetTxPayment): Charges transaction
-//!   fees from the signer based on the weight of the call using any supported asset (including the
-//!   native token). The asset is converted to the native token using a pool.
-//!
-//! - [`SkipCheckIfFeeless`](pallet_skip_feeless_payment::SkipCheckIfFeeless): Allows transactions
-//!   to be processed without paying any fee. This requires that the `call` that should be
-//!   dispatched is augmented with the [`feeless_if`](frame_support::pallet_macros::feeless_if)
-//!   attribute.
-//!
-//! - [`CheckMetadataHash`](frame_metadata_hash_extension::CheckMetadataHash): Extends transactions
-//!   to include the so-called metadata hash. This is required by chains to support the generic
-//!   Ledger application and other similar offline wallets.
-//!
-//! - [`StorageWeightReclaim`](cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim): A
-//!   signed extension for parachains that reclaims unused storage weight after executing a
-//!   transaction.
-//!
-//! For more information about these extensions, follow the link to the type documentation.
-//!
-//! # Building a custom signed extension
-//!
-//! Defining a couple of very simple signed extensions looks like the following:
-#![doc = docify::embed!("./src/reference_docs/signed_extensions.rs", signed_extensions_example)]
-
-#[docify::export]
-pub mod signed_extensions_example {
-	use codec::{Decode, Encode};
-	use scale_info::TypeInfo;
-	use sp_runtime::traits::SignedExtension;
-
-	// This doesn't actually check anything, but simply allows
-	// some arbitrary `u32` to be added to the extrinsic payload
-	#[derive(Debug, Encode, Decode, Clone, Eq, PartialEq, TypeInfo)]
-	pub struct AddToPayload(pub u32);
-
-	impl SignedExtension for AddToPayload {
-		const IDENTIFIER: &'static str = "AddToPayload";
-		type AccountId = ();
-		type Call = ();
-		type AdditionalSigned = ();
-		type Pre = ();
-
-		fn additional_signed(
-			&self,
-		) -> Result<
-			Self::AdditionalSigned,
-			sp_runtime::transaction_validity::TransactionValidityError,
-		> {
-			Ok(())
-		}
-
-		fn pre_dispatch(
-			self,
-			_who: &Self::AccountId,
-			_call: &Self::Call,
-			_info: &sp_runtime::traits::DispatchInfoOf<Self::Call>,
-			_len: usize,
-		) -> Result<Self::Pre, sp_runtime::transaction_validity::TransactionValidityError> {
-			Ok(())
-		}
-	}
-
-	// This is the opposite; nothing will be added to the extrinsic payload,
-	// but the AdditionalSigned type (`1234u32`) will be added to the
-	// payload to be signed.
-	#[derive(Debug, Encode, Decode, Clone, Eq, PartialEq, TypeInfo)]
-	pub struct AddToSignaturePayload;
-
-	impl SignedExtension for AddToSignaturePayload {
-		const IDENTIFIER: &'static str = "AddToSignaturePayload";
-		type AccountId = ();
-		type Call = ();
-		type AdditionalSigned = u32;
-		type Pre = ();
-
-		fn additional_signed(
-			&self,
-		) -> Result<
-			Self::AdditionalSigned,
-			sp_runtime::transaction_validity::TransactionValidityError,
-		> {
-			Ok(1234)
-		}
-
-		fn pre_dispatch(
-			self,
-			_who: &Self::AccountId,
-			_call: &Self::Call,
-			_info: &sp_runtime::traits::DispatchInfoOf<Self::Call>,
-			_len: usize,
-		) -> Result<Self::Pre, sp_runtime::transaction_validity::TransactionValidityError> {
-			Ok(())
-		}
-	}
-}
+//! `SignedExtension`s are deprecated in favor of
+//! [`TransactionExtension`s](crate::reference_docs::transaction_extensions).
diff --git a/docs/sdk/src/reference_docs/transaction_extensions.rs b/docs/sdk/src/reference_docs/transaction_extensions.rs
new file mode 100644
index 00000000000..0f8198e8372
--- /dev/null
+++ b/docs/sdk/src/reference_docs/transaction_extensions.rs
@@ -0,0 +1,103 @@
+//! Transaction extensions are, briefly, a means for different chains to extend the "basic"
+//! extrinsic format with custom data that can be checked by the runtime.
+//!
+//! # FRAME provided transaction extensions
+//!
+//! FRAME by default already provides the following transaction extensions:
+//!
+//! - [`CheckGenesis`](frame_system::CheckGenesis): Ensures that a transaction was sent for the same
+//!   network. Determined based on genesis.
+//!
+//! - [`CheckMortality`](frame_system::CheckMortality): Extends a transaction with a configurable
+//!   mortality.
+//!
+//! - [`CheckNonZeroSender`](frame_system::CheckNonZeroSender): Ensures that the sender of a
+//!   transaction is not the *all zero account* (all bytes of the accountid are zero).
+//!
+//! - [`CheckNonce`](frame_system::CheckNonce): Extends a transaction with a nonce to prevent replay
+//!   of transactions and to provide ordering of transactions.
+//!
+//! - [`CheckSpecVersion`](frame_system::CheckSpecVersion): Ensures that a transaction was built for
+//!   the currently active runtime.
+//!
+//! - [`CheckTxVersion`](frame_system::CheckTxVersion): Ensures that the transaction signer used the
+//!   correct encoding of the call.
+//!
+//! - [`CheckWeight`](frame_system::CheckWeight): Ensures that the transaction fits into the block
+//!   before dispatching it.
+//!
+//! - [`ChargeTransactionPayment`](pallet_transaction_payment::ChargeTransactionPayment): Charges
+//!   transaction fees from the signer based on the weight of the call using the native token.
+//!
+//! - [`ChargeAssetTxPayment`](pallet_asset_tx_payment::ChargeAssetTxPayment): Charges transaction
+//!   fees from the signer based on the weight of the call using any supported asset (including the
+//!   native token).
+//!
+//! - [`ChargeAssetTxPayment`(using
+//!   conversion)](pallet_asset_conversion_tx_payment::ChargeAssetTxPayment): Charges transaction
+//!   fees from the signer based on the weight of the call using any supported asset (including the
+//!   native token). The asset is converted to the native token using a pool.
+//!
+//! - [`SkipCheckIfFeeless`](pallet_skip_feeless_payment::SkipCheckIfFeeless): Allows transactions
+//!   to be processed without paying any fee. This requires that the `call` that should be
+//!   dispatched is augmented with the [`feeless_if`](frame_support::pallet_macros::feeless_if)
+//!   attribute.
+//!
+//! - [`CheckMetadataHash`](frame_metadata_hash_extension::CheckMetadataHash): Extends transactions
+//!   to include the so-called metadata hash. This is required by chains to support the generic
+//!   Ledger application and other similar offline wallets.
+//!
+//! - [`StorageWeightReclaim`](cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim): A
+//!   transaction extension for parachains that reclaims unused storage weight after executing a
+//!   transaction.
+//!
+//! For more information about these extensions, follow the link to the type documentation.
+//!
+//! # Building a custom transaction extension
+//!
+//! Defining a couple of very simple transaction extensions looks like the following:
+#![doc = docify::embed!("./src/reference_docs/transaction_extensions.rs", transaction_extensions_example)]
+
+#[docify::export]
+pub mod transaction_extensions_example {
+	use codec::{Decode, Encode};
+	use scale_info::TypeInfo;
+	use sp_runtime::{
+		impl_tx_ext_default,
+		traits::{Dispatchable, TransactionExtension},
+		transaction_validity::TransactionValidityError,
+	};
+
+	// This doesn't actually check anything, but simply allows
+	// some arbitrary `u32` to be added to the extrinsic payload
+	#[derive(Debug, Encode, Decode, Clone, Eq, PartialEq, TypeInfo)]
+	pub struct AddToPayload(pub u32);
+
+	impl<Call: Dispatchable> TransactionExtension<Call> for AddToPayload {
+		const IDENTIFIER: &'static str = "AddToPayload";
+		type Implicit = ();
+		type Pre = ();
+		type Val = ();
+
+		impl_tx_ext_default!(Call; weight validate prepare);
+	}
+
+	// This is the opposite; nothing will be added to the extrinsic payload,
+	// but the Implicit type (`1234u32`) will be added to the
+	// payload to be signed.
+	#[derive(Debug, Encode, Decode, Clone, Eq, PartialEq, TypeInfo)]
+	pub struct AddToSignaturePayload;
+
+	impl<Call: Dispatchable> TransactionExtension<Call> for AddToSignaturePayload {
+		const IDENTIFIER: &'static str = "AddToSignaturePayload";
+		type Implicit = u32;
+
+		fn implicit(&self) -> Result<Self::Implicit, TransactionValidityError> {
+			Ok(1234)
+		}
+		type Pre = ();
+		type Val = ();
+
+		impl_tx_ext_default!(Call; weight validate prepare);
+	}
+}
diff --git a/polkadot/node/service/Cargo.toml b/polkadot/node/service/Cargo.toml
index 8d50b54b2fd..3edb3f4dadb 100644
--- a/polkadot/node/service/Cargo.toml
+++ b/polkadot/node/service/Cargo.toml
@@ -200,6 +200,7 @@ runtime-benchmarks = [
 	"frame-benchmarking-cli/runtime-benchmarks",
 	"frame-benchmarking/runtime-benchmarks",
 	"frame-system/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"polkadot-primitives/runtime-benchmarks",
 	"polkadot-runtime-parachains/runtime-benchmarks",
 	"polkadot-test-client/runtime-benchmarks",
@@ -217,7 +218,10 @@ try-runtime = [
 	"sp-runtime/try-runtime",
 	"westend-runtime?/try-runtime",
 ]
-fast-runtime = ["rococo-runtime?/fast-runtime", "westend-runtime?/fast-runtime"]
+fast-runtime = [
+	"rococo-runtime?/fast-runtime",
+	"westend-runtime?/fast-runtime",
+]
 
 malus = ["full-node"]
 runtime-metrics = [
diff --git a/polkadot/node/service/src/benchmarking.rs b/polkadot/node/service/src/benchmarking.rs
index 4dcff207841..186bea3960e 100644
--- a/polkadot/node/service/src/benchmarking.rs
+++ b/polkadot/node/service/src/benchmarking.rs
@@ -189,7 +189,7 @@ fn westend_sign_call(
 	use sp_core::Pair;
 	use westend_runtime as runtime;
 
-	let extra: runtime::SignedExtra = (
+	let tx_ext: runtime::TxExtension = (
 		frame_system::CheckNonZeroSender::<runtime::Runtime>::new(),
 		frame_system::CheckSpecVersion::<runtime::Runtime>::new(),
 		frame_system::CheckTxVersion::<runtime::Runtime>::new(),
@@ -202,11 +202,12 @@ fn westend_sign_call(
 		frame_system::CheckWeight::<runtime::Runtime>::new(),
 		pallet_transaction_payment::ChargeTransactionPayment::<runtime::Runtime>::from(0),
 		frame_metadata_hash_extension::CheckMetadataHash::<runtime::Runtime>::new(false),
-	);
+	)
+		.into();
 
 	let payload = runtime::SignedPayload::from_raw(
 		call.clone(),
-		extra.clone(),
+		tx_ext.clone(),
 		(
 			(),
 			runtime::VERSION.spec_version,
@@ -225,7 +226,7 @@ fn westend_sign_call(
 		call,
 		sp_runtime::AccountId32::from(acc.public()).into(),
 		polkadot_core_primitives::Signature::Sr25519(signature),
-		extra,
+		tx_ext,
 	)
 	.into()
 }
@@ -243,7 +244,7 @@ fn rococo_sign_call(
 	use rococo_runtime as runtime;
 	use sp_core::Pair;
 
-	let extra: runtime::SignedExtra = (
+	let tx_ext: runtime::TxExtension = (
 		frame_system::CheckNonZeroSender::<runtime::Runtime>::new(),
 		frame_system::CheckSpecVersion::<runtime::Runtime>::new(),
 		frame_system::CheckTxVersion::<runtime::Runtime>::new(),
@@ -256,11 +257,12 @@ fn rococo_sign_call(
 		frame_system::CheckWeight::<runtime::Runtime>::new(),
 		pallet_transaction_payment::ChargeTransactionPayment::<runtime::Runtime>::from(0),
 		frame_metadata_hash_extension::CheckMetadataHash::<runtime::Runtime>::new(false),
-	);
+	)
+		.into();
 
 	let payload = runtime::SignedPayload::from_raw(
 		call.clone(),
-		extra.clone(),
+		tx_ext.clone(),
 		(
 			(),
 			runtime::VERSION.spec_version,
@@ -279,7 +281,7 @@ fn rococo_sign_call(
 		call,
 		sp_runtime::AccountId32::from(acc.public()).into(),
 		polkadot_core_primitives::Signature::Sr25519(signature),
-		extra,
+		tx_ext,
 	)
 	.into()
 }
diff --git a/polkadot/node/test/service/Cargo.toml b/polkadot/node/test/service/Cargo.toml
index 8eb6105f98e..4ef9d88621f 100644
--- a/polkadot/node/test/service/Cargo.toml
+++ b/polkadot/node/test/service/Cargo.toml
@@ -71,6 +71,7 @@ runtime-benchmarks = [
 	"frame-system/runtime-benchmarks",
 	"pallet-balances/runtime-benchmarks",
 	"pallet-staking/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"polkadot-parachain-primitives/runtime-benchmarks",
 	"polkadot-primitives/runtime-benchmarks",
 	"polkadot-runtime-common/runtime-benchmarks",
diff --git a/polkadot/node/test/service/src/lib.rs b/polkadot/node/test/service/src/lib.rs
index aa7295dddc5..6e09bb9e431 100644
--- a/polkadot/node/test/service/src/lib.rs
+++ b/polkadot/node/test/service/src/lib.rs
@@ -32,7 +32,7 @@ use polkadot_service::{
 	Error, FullClient, IsParachainNode, NewFull, OverseerGen, PrometheusConfig,
 };
 use polkadot_test_runtime::{
-	ParasCall, ParasSudoWrapperCall, Runtime, SignedExtra, SignedPayload, SudoCall,
+	ParasCall, ParasSudoWrapperCall, Runtime, SignedPayload, SudoCall, TxExtension,
 	UncheckedExtrinsic, VERSION,
 };
 
@@ -414,7 +414,7 @@ pub fn construct_extrinsic(
 	let period =
 		BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2) as u64;
 	let tip = 0;
-	let extra: SignedExtra = (
+	let tx_ext: TxExtension = (
 		frame_system::CheckNonZeroSender::<Runtime>::new(),
 		frame_system::CheckSpecVersion::<Runtime>::new(),
 		frame_system::CheckTxVersion::<Runtime>::new(),
@@ -423,10 +423,11 @@ pub fn construct_extrinsic(
 		frame_system::CheckNonce::<Runtime>::from(nonce),
 		frame_system::CheckWeight::<Runtime>::new(),
 		pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),
-	);
+	)
+		.into();
 	let raw_payload = SignedPayload::from_raw(
 		function.clone(),
-		extra.clone(),
+		tx_ext.clone(),
 		(
 			(),
 			VERSION.spec_version,
@@ -443,7 +444,7 @@ pub fn construct_extrinsic(
 		function.clone(),
 		polkadot_test_runtime::Address::Id(caller.public().into()),
 		polkadot_primitives::Signature::Sr25519(signature),
-		extra.clone(),
+		tx_ext.clone(),
 	)
 }
 
diff --git a/polkadot/runtime/common/Cargo.toml b/polkadot/runtime/common/Cargo.toml
index ad082f179b2..01b56b31cf2 100644
--- a/polkadot/runtime/common/Cargo.toml
+++ b/polkadot/runtime/common/Cargo.toml
@@ -131,6 +131,7 @@ runtime-benchmarks = [
 	"pallet-identity/runtime-benchmarks",
 	"pallet-staking/runtime-benchmarks",
 	"pallet-timestamp/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"pallet-treasury/runtime-benchmarks",
 	"pallet-vesting/runtime-benchmarks",
 	"polkadot-primitives/runtime-benchmarks",
diff --git a/polkadot/runtime/common/src/assigned_slots/mod.rs b/polkadot/runtime/common/src/assigned_slots/mod.rs
index 96c98c45954..65942c127b1 100644
--- a/polkadot/runtime/common/src/assigned_slots/mod.rs
+++ b/polkadot/runtime/common/src/assigned_slots/mod.rs
@@ -665,12 +665,21 @@ mod tests {
 		}
 	);
 
-	impl<C> frame_system::offchain::SendTransactionTypes<C> for Test
+	impl<C> frame_system::offchain::CreateTransactionBase<C> for Test
 	where
 		RuntimeCall: From<C>,
 	{
 		type Extrinsic = UncheckedExtrinsic;
-		type OverarchingCall = RuntimeCall;
+		type RuntimeCall = RuntimeCall;
+	}
+
+	impl<C> frame_system::offchain::CreateInherent<C> for Test
+	where
+		RuntimeCall: From<C>,
+	{
+		fn create_inherent(call: Self::RuntimeCall) -> Self::Extrinsic {
+			UncheckedExtrinsic::new_bare(call)
+		}
 	}
 
 	#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
diff --git a/polkadot/runtime/common/src/claims.rs b/polkadot/runtime/common/src/claims.rs
index 32686d1a0bf..2b36c19efce 100644
--- a/polkadot/runtime/common/src/claims.rs
+++ b/polkadot/runtime/common/src/claims.rs
@@ -33,7 +33,11 @@ use scale_info::TypeInfo;
 use serde::{self, Deserialize, Deserializer, Serialize, Serializer};
 use sp_io::{crypto::secp256k1_ecdsa_recover, hashing::keccak_256};
 use sp_runtime::{
-	traits::{CheckedSub, DispatchInfoOf, SignedExtension, Zero},
+	impl_tx_ext_default,
+	traits::{
+		AsSystemOriginSigner, AsTransactionAuthorizedOrigin, CheckedSub, DispatchInfoOf,
+		Dispatchable, TransactionExtension, Zero,
+	},
 	transaction_validity::{
 		InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction,
 	},
@@ -51,6 +55,7 @@ pub trait WeightInfo {
 	fn claim_attest() -> Weight;
 	fn attest() -> Weight;
 	fn move_claim() -> Weight;
+	fn prevalidate_attests() -> Weight;
 }
 
 pub struct TestWeightInfo;
@@ -70,6 +75,9 @@ impl WeightInfo for TestWeightInfo {
 	fn move_claim() -> Weight {
 		Weight::zero()
 	}
+	fn prevalidate_attests() -> Weight {
+		Weight::zero()
+	}
 }
 
 /// The kind of statement an account needs to make for a claim to be valid.
@@ -400,7 +408,7 @@ pub mod pallet {
 		/// Attest to a statement, needed to finalize the claims process.
 		///
 		/// WARNING: Insecure unless your chain includes `PrevalidateAttests` as a
-		/// `SignedExtension`.
+		/// `TransactionExtension`.
 		///
 		/// Unsigned Validation:
 		/// A call to attest is deemed valid if the sender has a `Preclaim` registered
@@ -611,58 +619,56 @@ impl<T: Config> PrevalidateAttests<T>
 where
 	<T as frame_system::Config>::RuntimeCall: IsSubType<Call<T>>,
 {
-	/// Create new `SignedExtension` to check runtime version.
+	/// Create new `TransactionExtension` to check runtime version.
 	pub fn new() -> Self {
 		Self(core::marker::PhantomData)
 	}
 }
 
-impl<T: Config> SignedExtension for PrevalidateAttests<T>
+impl<T: Config> TransactionExtension<T::RuntimeCall> for PrevalidateAttests<T>
 where
 	<T as frame_system::Config>::RuntimeCall: IsSubType<Call<T>>,
+	<<T as frame_system::Config>::RuntimeCall as Dispatchable>::RuntimeOrigin:
+		AsSystemOriginSigner<T::AccountId> + AsTransactionAuthorizedOrigin + Clone,
 {
-	type AccountId = T::AccountId;
-	type Call = <T as frame_system::Config>::RuntimeCall;
-	type AdditionalSigned = ();
-	type Pre = ();
 	const IDENTIFIER: &'static str = "PrevalidateAttests";
+	type Implicit = ();
+	type Pre = ();
+	type Val = ();
 
-	fn additional_signed(&self) -> Result<Self::AdditionalSigned, TransactionValidityError> {
-		Ok(())
-	}
-
-	fn pre_dispatch(
-		self,
-		who: &Self::AccountId,
-		call: &Self::Call,
-		info: &DispatchInfoOf<Self::Call>,
-		len: usize,
-	) -> Result<Self::Pre, TransactionValidityError> {
-		self.validate(who, call, info, len).map(|_| ())
+	fn weight(&self, call: &T::RuntimeCall) -> Weight {
+		if let Some(Call::attest { .. }) = call.is_sub_type() {
+			T::WeightInfo::prevalidate_attests()
+		} else {
+			Weight::zero()
+		}
 	}
 
-	// <weight>
-	// The weight of this logic is included in the `attest` dispatchable.
-	// </weight>
 	fn validate(
 		&self,
-		who: &Self::AccountId,
-		call: &Self::Call,
-		_info: &DispatchInfoOf<Self::Call>,
+		origin: <T::RuntimeCall as Dispatchable>::RuntimeOrigin,
+		call: &T::RuntimeCall,
+		_info: &DispatchInfoOf<T::RuntimeCall>,
 		_len: usize,
-	) -> TransactionValidity {
-		if let Some(local_call) = call.is_sub_type() {
-			if let Call::attest { statement: attested_statement } = local_call {
-				let signer = Preclaims::<T>::get(who)
-					.ok_or(InvalidTransaction::Custom(ValidityError::SignerHasNoClaim.into()))?;
-				if let Some(s) = Signing::<T>::get(signer) {
-					let e = InvalidTransaction::Custom(ValidityError::InvalidStatement.into());
-					ensure!(&attested_statement[..] == s.to_text(), e);
-				}
+		_self_implicit: Self::Implicit,
+		_inherited_implication: &impl Encode,
+	) -> Result<
+		(ValidTransaction, Self::Val, <T::RuntimeCall as Dispatchable>::RuntimeOrigin),
+		TransactionValidityError,
+	> {
+		if let Some(Call::attest { statement: attested_statement }) = call.is_sub_type() {
+			let who = origin.as_system_origin_signer().ok_or(InvalidTransaction::BadSigner)?;
+			let signer = Preclaims::<T>::get(who)
+				.ok_or(InvalidTransaction::Custom(ValidityError::SignerHasNoClaim.into()))?;
+			if let Some(s) = Signing::<T>::get(signer) {
+				let e = InvalidTransaction::Custom(ValidityError::InvalidStatement.into());
+				ensure!(&attested_statement[..] == s.to_text(), e);
 			}
 		}
-		Ok(ValidTransaction::default())
+		Ok((ValidTransaction::default(), (), origin))
 	}
+
+	impl_tx_ext_default!(T::RuntimeCall; prepare);
 }
 
 #[cfg(any(test, feature = "runtime-benchmarks"))]
@@ -713,8 +719,11 @@ mod tests {
 	};
 	use pallet_balances;
 	use sp_runtime::{
-		traits::Identity, transaction_validity::TransactionLongevity, BuildStorage,
-		DispatchError::BadOrigin, TokenError,
+		traits::{DispatchTransaction, Identity},
+		transaction_validity::TransactionLongevity,
+		BuildStorage,
+		DispatchError::BadOrigin,
+		TokenError,
 	};
 
 	type Block = frame_system::mocking::MockBlock<Test>;
@@ -1055,8 +1064,8 @@ mod tests {
 			});
 			let di = c.get_dispatch_info();
 			assert_eq!(di.pays_fee, Pays::No);
-			let r = p.validate(&42, &c, &di, 20);
-			assert_eq!(r, TransactionValidity::Ok(ValidTransaction::default()));
+			let r = p.validate_only(Some(42).into(), &c, &di, 20);
+			assert_eq!(r.unwrap().0, ValidTransaction::default());
 		});
 	}
 
@@ -1068,13 +1077,13 @@ mod tests {
 				statement: StatementKind::Regular.to_text().to_vec(),
 			});
 			let di = c.get_dispatch_info();
-			let r = p.validate(&42, &c, &di, 20);
+			let r = p.validate_only(Some(42).into(), &c, &di, 20);
 			assert!(r.is_err());
 			let c = RuntimeCall::Claims(ClaimsCall::attest {
 				statement: StatementKind::Saft.to_text().to_vec(),
 			});
 			let di = c.get_dispatch_info();
-			let r = p.validate(&69, &c, &di, 20);
+			let r = p.validate_only(Some(69).into(), &c, &di, 20);
 			assert!(r.is_err());
 		});
 	}
@@ -1432,10 +1441,16 @@ mod benchmarking {
 	use super::*;
 	use crate::claims::Call;
 	use frame_benchmarking::{account, benchmarks};
-	use frame_support::traits::UnfilteredDispatchable;
+	use frame_support::{
+		dispatch::{DispatchInfo, GetDispatchInfo},
+		traits::UnfilteredDispatchable,
+	};
 	use frame_system::RawOrigin;
 	use secp_utils::*;
-	use sp_runtime::{traits::ValidateUnsigned, DispatchResult};
+	use sp_runtime::{
+		traits::{DispatchTransaction, ValidateUnsigned},
+		DispatchResult,
+	};
 
 	const SEED: u32 = 0;
 
@@ -1471,6 +1486,12 @@ mod benchmarking {
 	}
 
 	benchmarks! {
+		where_clause { where <T as frame_system::Config>::RuntimeCall: IsSubType<Call<T>> + From<Call<T>>,
+			<T as frame_system::Config>::RuntimeCall: Dispatchable<Info = DispatchInfo> + GetDispatchInfo,
+			<<T as frame_system::Config>::RuntimeCall as Dispatchable>::RuntimeOrigin: AsSystemOriginSigner<T::AccountId> + AsTransactionAuthorizedOrigin + Clone,
+			<<T as frame_system::Config>::RuntimeCall as Dispatchable>::PostInfo: Default,
+		}
+
 		// Benchmark `claim` including `validate_unsigned` logic.
 		claim {
 			let c = MAX_CLAIMS;
@@ -1574,24 +1595,9 @@ mod benchmarking {
 			Preclaims::<T>::insert(&account, eth_address);
 			assert_eq!(Claims::<T>::get(eth_address), Some(VALUE.into()));
 
-			let call = super::Call::<T>::attest { statement: StatementKind::Regular.to_text().to_vec() };
-			// We have to copy the validate statement here because of trait issues... :(
-			let validate = |who: &T::AccountId, call: &super::Call<T>| -> DispatchResult {
-				if let Call::attest{ statement: attested_statement } = call {
-					let signer = Preclaims::<T>::get(who).ok_or("signer has no claim")?;
-					if let Some(s) = Signing::<T>::get(signer) {
-						ensure!(&attested_statement[..] == s.to_text(), "invalid statement");
-					}
-				}
-				Ok(())
-			};
-			let call_enc = call.encode();
-		}: {
-			let call = <Call<T> as Decode>::decode(&mut &*call_enc)
-				.expect("call is encoded above, encoding must be correct");
-			validate(&account, &call)?;
-			call.dispatch_bypass_filter(RawOrigin::Signed(account).into())?;
-		}
+			let stmt = StatementKind::Regular.to_text().to_vec();
+		}:
+		_(RawOrigin::Signed(account), stmt)
 		verify {
 			assert_eq!(Claims::<T>::get(eth_address), None);
 		}
@@ -1649,6 +1655,42 @@ mod benchmarking {
 			}
 		}
 
+		prevalidate_attests {
+			let c = MAX_CLAIMS;
+
+			for i in 0 .. c / 2 {
+				create_claim::<T>(c)?;
+				create_claim_attest::<T>(u32::MAX - c)?;
+			}
+
+			let ext = PrevalidateAttests::<T>::new();
+			let call = super::Call::attest {
+				statement: StatementKind::Regular.to_text().to_vec(),
+			};
+			let call: <T as frame_system::Config>::RuntimeCall = call.into();
+			let info = call.get_dispatch_info();
+			let attest_c = u32::MAX - c;
+			let secret_key = libsecp256k1::SecretKey::parse(&keccak_256(&attest_c.encode())).unwrap();
+			let eth_address = eth(&secret_key);
+			let account: T::AccountId = account("user", c, SEED);
+			let vesting = Some((100_000u32.into(), 1_000u32.into(), 100u32.into()));
+			let statement = StatementKind::Regular;
+			let signature = sig::<T>(&secret_key, &account.encode(), statement.to_text());
+			super::Pallet::<T>::mint_claim(RawOrigin::Root.into(), eth_address, VALUE.into(), vesting, Some(statement))?;
+			Preclaims::<T>::insert(&account, eth_address);
+			assert_eq!(Claims::<T>::get(eth_address), Some(VALUE.into()));
+		}: {
+			assert!(ext.test_run(
+				RawOrigin::Signed(account).into(),
+				&call,
+				&info,
+				0,
+				|_| {
+					Ok(Default::default())
+				}
+			).unwrap().is_ok());
+		}
+
 		impl_benchmark_test_suite!(
 			Pallet,
 			crate::claims::tests::new_test_ext(),
diff --git a/polkadot/runtime/common/src/integration_tests.rs b/polkadot/runtime/common/src/integration_tests.rs
index 7a689a517ea..bfeed04a919 100644
--- a/polkadot/runtime/common/src/integration_tests.rs
+++ b/polkadot/runtime/common/src/integration_tests.rs
@@ -98,12 +98,21 @@ frame_support::construct_runtime!(
 	}
 );
 
-impl<C> frame_system::offchain::SendTransactionTypes<C> for Test
+impl<C> frame_system::offchain::CreateTransactionBase<C> for Test
 where
 	RuntimeCall: From<C>,
 {
 	type Extrinsic = UncheckedExtrinsic;
-	type OverarchingCall = RuntimeCall;
+	type RuntimeCall = RuntimeCall;
+}
+
+impl<C> frame_system::offchain::CreateInherent<C> for Test
+where
+	RuntimeCall: From<C>,
+{
+	fn create_inherent(call: Self::RuntimeCall) -> Self::Extrinsic {
+		UncheckedExtrinsic::new_bare(call)
+	}
 }
 
 use crate::{auctions::Error as AuctionsError, crowdloan::Error as CrowdloanError};
diff --git a/polkadot/runtime/common/src/paras_registrar/mod.rs b/polkadot/runtime/common/src/paras_registrar/mod.rs
index 07f02e92656..2ead621dedf 100644
--- a/polkadot/runtime/common/src/paras_registrar/mod.rs
+++ b/polkadot/runtime/common/src/paras_registrar/mod.rs
@@ -752,12 +752,21 @@ mod tests {
 		}
 	);
 
-	impl<C> frame_system::offchain::SendTransactionTypes<C> for Test
+	impl<C> frame_system::offchain::CreateTransactionBase<C> for Test
 	where
 		RuntimeCall: From<C>,
 	{
 		type Extrinsic = UncheckedExtrinsic;
-		type OverarchingCall = RuntimeCall;
+		type RuntimeCall = RuntimeCall;
+	}
+
+	impl<C> frame_system::offchain::CreateInherent<C> for Test
+	where
+		RuntimeCall: From<C>,
+	{
+		fn create_inherent(call: Self::RuntimeCall) -> Self::Extrinsic {
+			UncheckedExtrinsic::new_bare(call)
+		}
 	}
 
 	const NORMAL_RATIO: Perbill = Perbill::from_percent(75);
diff --git a/polkadot/runtime/parachains/src/disputes/slashing.rs b/polkadot/runtime/parachains/src/disputes/slashing.rs
index 4b76fb47e1f..2e09ea667f7 100644
--- a/polkadot/runtime/parachains/src/disputes/slashing.rs
+++ b/polkadot/runtime/parachains/src/disputes/slashing.rs
@@ -653,7 +653,7 @@ impl<I, R, L> Default for SlashingReportHandler<I, R, L> {
 
 impl<T, R, L> HandleReports<T> for SlashingReportHandler<T::KeyOwnerIdentification, R, L>
 where
-	T: Config + frame_system::offchain::SendTransactionTypes<Call<T>>,
+	T: Config + frame_system::offchain::CreateInherent<Call<T>>,
 	R: ReportOffence<
 		T::AccountId,
 		T::KeyOwnerIdentification,
@@ -685,7 +685,7 @@ where
 		dispute_proof: DisputeProof,
 		key_owner_proof: <T as Config>::KeyOwnerProof,
 	) -> Result<(), sp_runtime::TryRuntimeError> {
-		use frame_system::offchain::SubmitTransaction;
+		use frame_system::offchain::{CreateInherent, SubmitTransaction};
 
 		let session_index = dispute_proof.time_slot.session_index;
 		let validator_index = dispute_proof.validator_index.0;
@@ -696,7 +696,8 @@ where
 			key_owner_proof,
 		};
 
-		match SubmitTransaction::<T, Call<T>>::submit_unsigned_transaction(call.into()) {
+		let xt = <T as CreateInherent<Call<T>>>::create_inherent(call.into());
+		match SubmitTransaction::<T, Call<T>>::submit_transaction(xt) {
 			Ok(()) => {
 				log::info!(
 					target: LOG_TARGET,
diff --git a/polkadot/runtime/parachains/src/mock.rs b/polkadot/runtime/parachains/src/mock.rs
index 75c9e3a5c9b..80751a2b7a0 100644
--- a/polkadot/runtime/parachains/src/mock.rs
+++ b/polkadot/runtime/parachains/src/mock.rs
@@ -90,12 +90,21 @@ frame_support::construct_runtime!(
 	}
 );
 
-impl<C> frame_system::offchain::SendTransactionTypes<C> for Test
+impl<C> frame_system::offchain::CreateTransactionBase<C> for Test
 where
 	RuntimeCall: From<C>,
 {
 	type Extrinsic = UncheckedExtrinsic;
-	type OverarchingCall = RuntimeCall;
+	type RuntimeCall = RuntimeCall;
+}
+
+impl<C> frame_system::offchain::CreateInherent<C> for Test
+where
+	RuntimeCall: From<C>,
+{
+	fn create_inherent(call: Self::RuntimeCall) -> Self::Extrinsic {
+		UncheckedExtrinsic::new_bare(call)
+	}
 }
 
 parameter_types! {
diff --git a/polkadot/runtime/parachains/src/paras/mod.rs b/polkadot/runtime/parachains/src/paras/mod.rs
index 5048656e636..e0f244dbd86 100644
--- a/polkadot/runtime/parachains/src/paras/mod.rs
+++ b/polkadot/runtime/parachains/src/paras/mod.rs
@@ -615,7 +615,7 @@ pub mod pallet {
 		frame_system::Config
 		+ configuration::Config
 		+ shared::Config
-		+ frame_system::offchain::SendTransactionTypes<Call<Self>>
+		+ frame_system::offchain::CreateInherent<Call<Self>>
 	{
 		type RuntimeEvent: From<Event> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
 
@@ -2177,9 +2177,8 @@ impl<T: Config> Pallet<T> {
 	) {
 		use frame_system::offchain::SubmitTransaction;
 
-		if let Err(e) = SubmitTransaction::<T, Call<T>>::submit_unsigned_transaction(
-			Call::include_pvf_check_statement { stmt, signature }.into(),
-		) {
+		let xt = T::create_inherent(Call::include_pvf_check_statement { stmt, signature }.into());
+		if let Err(e) = SubmitTransaction::<T, Call<T>>::submit_transaction(xt) {
 			log::error!(target: LOG_TARGET, "Error submitting pvf check statement: {:?}", e,);
 		}
 	}
diff --git a/polkadot/runtime/rococo/Cargo.toml b/polkadot/runtime/rococo/Cargo.toml
index 7becf6376c3..6bcb0da3d99 100644
--- a/polkadot/runtime/rococo/Cargo.toml
+++ b/polkadot/runtime/rococo/Cargo.toml
@@ -256,6 +256,7 @@ runtime-benchmarks = [
 	"pallet-sudo/runtime-benchmarks",
 	"pallet-timestamp/runtime-benchmarks",
 	"pallet-tips/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"pallet-treasury/runtime-benchmarks",
 	"pallet-utility/runtime-benchmarks",
 	"pallet-vesting/runtime-benchmarks",
diff --git a/polkadot/runtime/rococo/constants/src/weights/block_weights.rs b/polkadot/runtime/rococo/constants/src/weights/block_weights.rs
index e2aa4a6cab7..f7dc2f19316 100644
--- a/polkadot/runtime/rococo/constants/src/weights/block_weights.rs
+++ b/polkadot/runtime/rococo/constants/src/weights/block_weights.rs
@@ -14,13 +14,13 @@
 // You should have received a copy of the GNU General Public License
 // along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
 
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-05-26 (Y/M/D)
-//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29 (Y/M/D)
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
 //!
 //! SHORT-NAME: `block`, LONG-NAME: `BlockExecution`, RUNTIME: `Development`
 //! WARMUPS: `10`, REPEAT: `100`
-//! WEIGHT-PATH: `runtime/rococo/constants/src/weights/`
+//! WEIGHT-PATH: `./polkadot/runtime/rococo/constants/src/weights/`
 //! WEIGHT-METRIC: `Average`, WEIGHT-MUL: `1.0`, WEIGHT-ADD: `0`
 
 // Executed Command:
@@ -28,12 +28,11 @@
 //   benchmark
 //   overhead
 //   --chain=rococo-dev
-//   --execution=wasm
 //   --wasm-execution=compiled
-//   --weight-path=runtime/rococo/constants/src/weights/
+//   --weight-path=./polkadot/runtime/rococo/constants/src/weights/
 //   --warmup=10
 //   --repeat=100
-//   --header=./file_header.txt
+//   --header=./polkadot/file_header.txt
 
 use sp_core::parameter_types;
 use sp_weights::{constants::WEIGHT_REF_TIME_PER_NANOS, Weight};
@@ -43,17 +42,17 @@ parameter_types! {
 	/// Calculated by multiplying the *Average* with `1.0` and adding `0`.
 	///
 	/// Stats nanoseconds:
-	///   Min, Max: 408_659, 450_716
-	///   Average:  417_412
-	///   Median:   411_177
-	///   Std-Dev:  12242.31
+	///   Min, Max: 440_142, 476_907
+	///   Average:  450_240
+	///   Median:   448_633
+	///   Std-Dev:  7301.18
 	///
 	/// Percentiles nanoseconds:
-	///   99th: 445_142
-	///   95th: 442_275
-	///   75th: 414_217
+	///   99th: 470_733
+	///   95th: 465_082
+	///   75th: 452_536
 	pub const BlockExecutionWeight: Weight =
-		Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(417_412), 0);
+		Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(450_240), 0);
 }
 
 #[cfg(test)]
diff --git a/polkadot/runtime/rococo/constants/src/weights/extrinsic_weights.rs b/polkadot/runtime/rococo/constants/src/weights/extrinsic_weights.rs
index adce840ebbc..000cee8a237 100644
--- a/polkadot/runtime/rococo/constants/src/weights/extrinsic_weights.rs
+++ b/polkadot/runtime/rococo/constants/src/weights/extrinsic_weights.rs
@@ -14,13 +14,13 @@
 // You should have received a copy of the GNU General Public License
 // along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
 
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-05-26 (Y/M/D)
-//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29 (Y/M/D)
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
 //!
 //! SHORT-NAME: `extrinsic`, LONG-NAME: `ExtrinsicBase`, RUNTIME: `Development`
 //! WARMUPS: `10`, REPEAT: `100`
-//! WEIGHT-PATH: `runtime/rococo/constants/src/weights/`
+//! WEIGHT-PATH: `./polkadot/runtime/rococo/constants/src/weights/`
 //! WEIGHT-METRIC: `Average`, WEIGHT-MUL: `1.0`, WEIGHT-ADD: `0`
 
 // Executed Command:
@@ -28,12 +28,11 @@
 //   benchmark
 //   overhead
 //   --chain=rococo-dev
-//   --execution=wasm
 //   --wasm-execution=compiled
-//   --weight-path=runtime/rococo/constants/src/weights/
+//   --weight-path=./polkadot/runtime/rococo/constants/src/weights/
 //   --warmup=10
 //   --repeat=100
-//   --header=./file_header.txt
+//   --header=./polkadot/file_header.txt
 
 use sp_core::parameter_types;
 use sp_weights::{constants::WEIGHT_REF_TIME_PER_NANOS, Weight};
@@ -43,17 +42,17 @@ parameter_types! {
 	/// Calculated by multiplying the *Average* with `1.0` and adding `0`.
 	///
 	/// Stats nanoseconds:
-	///   Min, Max: 97_574, 100_119
-	///   Average:  98_236
-	///   Median:   98_179
-	///   Std-Dev:  394.9
+	///   Min, Max: 92_961, 94_143
+	///   Average:  93_369
+	///   Median:   93_331
+	///   Std-Dev:  217.39
 	///
 	/// Percentiles nanoseconds:
-	///   99th: 99_893
-	///   95th: 98_850
-	///   75th: 98_318
+	///   99th: 93_848
+	///   95th: 93_691
+	///   75th: 93_514
 	pub const ExtrinsicBaseWeight: Weight =
-		Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(98_236), 0);
+		Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(93_369), 0);
 }
 
 #[cfg(test)]
diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs
index 1b5f7b5157d..6266febaa0b 100644
--- a/polkadot/runtime/rococo/src/lib.rs
+++ b/polkadot/runtime/rococo/src/lib.rs
@@ -102,9 +102,8 @@ use sp_core::{ConstU128, ConstU8, Get, OpaqueMetadata, H256};
 use sp_runtime::{
 	create_runtime_str, generic, impl_opaque_keys,
 	traits::{
-		AccountIdConversion, BlakeTwo256, Block as BlockT, ConstU32, ConvertInto,
-		Extrinsic as ExtrinsicT, IdentityLookup, Keccak256, OpaqueKeys, SaturatedConversion,
-		Verify,
+		AccountIdConversion, BlakeTwo256, Block as BlockT, ConstU32, ConvertInto, IdentityLookup,
+		Keccak256, OpaqueKeys, SaturatedConversion, Verify,
 	},
 	transaction_validity::{TransactionPriority, TransactionSource, TransactionValidity},
 	ApplyExtrinsicResult, FixedU128, KeyTypeId, Perbill, Percent, Permill, RuntimeDebug,
@@ -219,6 +218,7 @@ impl frame_system::Config for Runtime {
 	type Version = Version;
 	type AccountData = pallet_balances::AccountData<Balance>;
 	type SystemWeightInfo = weights::frame_system::WeightInfo<Runtime>;
+	type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo<Runtime>;
 	type SS58Prefix = SS58Prefix;
 	type MaxConsumers = frame_support::traits::ConstU32<16>;
 }
@@ -418,6 +418,7 @@ impl pallet_transaction_payment::Config for Runtime {
 	type WeightToFee = WeightToFee;
 	type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
 	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
+	type WeightInfo = weights::pallet_transaction_payment::WeightInfo<Runtime>;
 }
 
 parameter_types! {
@@ -606,18 +607,33 @@ impl pallet_grandpa::Config for Runtime {
 		pallet_grandpa::EquivocationReportSystem<Self, Offences, Historical, ReportLongevity>;
 }
 
-/// Submits a transaction with the node's public and signature type. Adheres to the signed extension
-/// format of the chain.
+impl frame_system::offchain::SigningTypes for Runtime {
+	type Public = <Signature as Verify>::Signer;
+	type Signature = Signature;
+}
+
+impl<LocalCall> frame_system::offchain::CreateTransactionBase<LocalCall> for Runtime
+where
+	RuntimeCall: From<LocalCall>,
+{
+	type Extrinsic = UncheckedExtrinsic;
+	type RuntimeCall = RuntimeCall;
+}
+
+/// Submits a transaction with the node's public and signature type. Adheres to the signed
+/// extension format of the chain.
 impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Runtime
 where
 	RuntimeCall: From<LocalCall>,
 {
-	fn create_transaction<C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>>(
+	fn create_signed_transaction<
+		C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>,
+	>(
 		call: RuntimeCall,
 		public: <Signature as Verify>::Signer,
 		account: AccountId,
 		nonce: <Runtime as frame_system::Config>::Nonce,
-	) -> Option<(RuntimeCall, <UncheckedExtrinsic as ExtrinsicT>::SignaturePayload)> {
+	) -> Option<UncheckedExtrinsic> {
 		use sp_runtime::traits::StaticLookup;
 		// take the biggest period possible.
 		let period =
@@ -629,7 +645,7 @@ where
 			// so the actual block number is `n`.
 			.saturating_sub(1);
 		let tip = 0;
-		let extra: SignedExtra = (
+		let tx_ext: TxExtension = (
 			frame_system::CheckNonZeroSender::<Runtime>::new(),
 			frame_system::CheckSpecVersion::<Runtime>::new(),
 			frame_system::CheckTxVersion::<Runtime>::new(),
@@ -642,31 +658,39 @@ where
 			frame_system::CheckWeight::<Runtime>::new(),
 			pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),
 			frame_metadata_hash_extension::CheckMetadataHash::new(true),
-		);
-
-		let raw_payload = SignedPayload::new(call, extra)
+		)
+			.into();
+		let raw_payload = SignedPayload::new(call, tx_ext)
 			.map_err(|e| {
 				log::warn!("Unable to create signed payload: {:?}", e);
 			})
 			.ok()?;
 		let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?;
-		let (call, extra, _) = raw_payload.deconstruct();
+		let (call, tx_ext, _) = raw_payload.deconstruct();
 		let address = <Runtime as frame_system::Config>::Lookup::unlookup(account);
-		Some((call, (address, signature, extra)))
+		let transaction = UncheckedExtrinsic::new_signed(call, address, signature, tx_ext);
+		Some(transaction)
 	}
 }
 
-impl frame_system::offchain::SigningTypes for Runtime {
-	type Public = <Signature as Verify>::Signer;
-	type Signature = Signature;
+impl<LocalCall> frame_system::offchain::CreateTransaction<LocalCall> for Runtime
+where
+	RuntimeCall: From<LocalCall>,
+{
+	type Extension = TxExtension;
+
+	fn create_transaction(call: RuntimeCall, tx_ext: Self::Extension) -> UncheckedExtrinsic {
+		UncheckedExtrinsic::new_transaction(call, tx_ext)
+	}
 }
 
-impl<C> frame_system::offchain::SendTransactionTypes<C> for Runtime
+impl<LocalCall> frame_system::offchain::CreateInherent<LocalCall> for Runtime
 where
-	RuntimeCall: From<C>,
+	RuntimeCall: From<LocalCall>,
 {
-	type Extrinsic = UncheckedExtrinsic;
-	type OverarchingCall = RuntimeCall;
+	fn create_inherent(call: RuntimeCall) -> UncheckedExtrinsic {
+		UncheckedExtrinsic::new_bare(call)
+	}
 }
 
 parameter_types! {
@@ -1538,8 +1562,8 @@ pub type Block = generic::Block<Header, UncheckedExtrinsic>;
 pub type SignedBlock = generic::SignedBlock<Block>;
 /// `BlockId` type as expected by this runtime.
 pub type BlockId = generic::BlockId<Block>;
-/// The `SignedExtension` to the basic transaction logic.
-pub type SignedExtra = (
+/// The extension to the basic transaction logic.
+pub type TxExtension = (
 	frame_system::CheckNonZeroSender<Runtime>,
 	frame_system::CheckSpecVersion<Runtime>,
 	frame_system::CheckTxVersion<Runtime>,
@@ -1553,7 +1577,10 @@ pub type SignedExtra = (
 
 /// Unchecked extrinsic type as expected by this runtime.
 pub type UncheckedExtrinsic =
-	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
+/// Unchecked signature payload type as expected by this runtime.
+pub type UncheckedSignaturePayload =
+	generic::UncheckedSignaturePayload<Address, Signature, TxExtension>;
 
 /// All migrations that will run on the next runtime upgrade.
 ///
@@ -1697,7 +1724,7 @@ pub type Executive = frame_executive::Executive<
 	Migrations,
 >;
 /// The payload being signed in transactions.
-pub type SignedPayload = generic::SignedPayload<RuntimeCall, SignedExtra>;
+pub type SignedPayload = generic::SignedPayload<RuntimeCall, TxExtension>;
 
 parameter_types! {
 	// The deposit configuration for the singed migration. Specially if you want to allow any signed account to do the migration (see `SignedFilter`, these deposits should be high)
@@ -1771,7 +1798,9 @@ mod benches {
 		[pallet_scheduler, Scheduler]
 		[pallet_sudo, Sudo]
 		[frame_system, SystemBench::<Runtime>]
+		[frame_system_extensions, SystemExtensionsBench::<Runtime>]
 		[pallet_timestamp, Timestamp]
+		[pallet_transaction_payment, TransactionPayment]
 		[pallet_treasury, Treasury]
 		[pallet_utility, Utility]
 		[pallet_vesting, Vesting]
@@ -2358,6 +2387,7 @@ sp_api::impl_runtime_apis! {
 			use frame_support::traits::StorageInfoTrait;
 
 			use frame_system_benchmarking::Pallet as SystemBench;
+			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
 			use frame_benchmarking::baseline::Pallet as Baseline;
 
 			use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
@@ -2378,6 +2408,7 @@ sp_api::impl_runtime_apis! {
 			use frame_support::traits::WhitelistedStorageKeys;
 			use frame_benchmarking::{Benchmarking, BenchmarkBatch, BenchmarkError};
 			use frame_system_benchmarking::Pallet as SystemBench;
+			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
 			use frame_benchmarking::baseline::Pallet as Baseline;
 			use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
 			use sp_storage::TrackedStorageKey;
diff --git a/polkadot/runtime/rococo/src/weights/frame_benchmarking_baseline.rs b/polkadot/runtime/rococo/src/weights/frame_benchmarking_baseline.rs
index dfba0cfc4aa..0f68a5c6fb3 100644
--- a/polkadot/runtime/rococo/src/weights/frame_benchmarking_baseline.rs
+++ b/polkadot/runtime/rococo/src/weights/frame_benchmarking_baseline.rs
@@ -16,11 +16,11 @@
 
 //! Autogenerated weights for `frame_benchmarking::baseline`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
-//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
 // ./target/production/polkadot
@@ -29,12 +29,15 @@
 // --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
 // --pallet=frame_benchmarking::baseline
 // --extrinsic=*
 // --execution=wasm
 // --wasm-execution=compiled
-// --header=./file_header.txt
-// --output=./runtime/rococo/src/weights/frame_benchmarking_baseline.rs
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/frame_benchmarking_baseline.rs
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -52,8 +55,8 @@ impl<T: frame_system::Config> frame_benchmarking::baseline::WeightInfo for Weigh
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 157_000 picoseconds.
-		Weight::from_parts(175_233, 0)
+		// Minimum execution time: 172_000 picoseconds.
+		Weight::from_parts(199_481, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 	}
 	/// The range of component `i` is `[0, 1000000]`.
@@ -61,8 +64,8 @@ impl<T: frame_system::Config> frame_benchmarking::baseline::WeightInfo for Weigh
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 149_000 picoseconds.
-		Weight::from_parts(183_285, 0)
+		// Minimum execution time: 171_000 picoseconds.
+		Weight::from_parts(197_821, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 	}
 	/// The range of component `i` is `[0, 1000000]`.
@@ -70,8 +73,8 @@ impl<T: frame_system::Config> frame_benchmarking::baseline::WeightInfo for Weigh
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 158_000 picoseconds.
-		Weight::from_parts(184_720, 0)
+		// Minimum execution time: 172_000 picoseconds.
+		Weight::from_parts(200_942, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 	}
 	/// The range of component `i` is `[0, 1000000]`.
@@ -79,16 +82,16 @@ impl<T: frame_system::Config> frame_benchmarking::baseline::WeightInfo for Weigh
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 152_000 picoseconds.
-		Weight::from_parts(177_496, 0)
+		// Minimum execution time: 170_000 picoseconds.
+		Weight::from_parts(196_906, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 	}
 	fn hashing() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 19_907_376_000 picoseconds.
-		Weight::from_parts(19_988_727_000, 0)
+		// Minimum execution time: 23_346_876_000 picoseconds.
+		Weight::from_parts(23_363_744_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 	}
 	/// The range of component `i` is `[0, 100]`.
@@ -96,10 +99,10 @@ impl<T: frame_system::Config> frame_benchmarking::baseline::WeightInfo for Weigh
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 198_000 picoseconds.
-		Weight::from_parts(228_000, 0)
+		// Minimum execution time: 201_000 picoseconds.
+		Weight::from_parts(219_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
-			// Standard Error: 20_467
-			.saturating_add(Weight::from_parts(47_443_635, 0).saturating_mul(i.into()))
+			// Standard Error: 14_372
+			.saturating_add(Weight::from_parts(45_375_800, 0).saturating_mul(i.into()))
 	}
 }
diff --git a/polkadot/runtime/rococo/src/weights/frame_system.rs b/polkadot/runtime/rococo/src/weights/frame_system.rs
index 2e49483dcc6..1742a761ca7 100644
--- a/polkadot/runtime/rococo/src/weights/frame_system.rs
+++ b/polkadot/runtime/rococo/src/weights/frame_system.rs
@@ -16,11 +16,11 @@
 
 //! Autogenerated weights for `frame_system`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
-//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
 // ./target/production/polkadot
@@ -29,12 +29,15 @@
 // --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
 // --pallet=frame_system
 // --extrinsic=*
 // --execution=wasm
 // --wasm-execution=compiled
-// --header=./file_header.txt
-// --output=./runtime/rococo/src/weights/
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -52,91 +55,91 @@ impl<T: frame_system::Config> frame_system::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 2_283_000 picoseconds.
-		Weight::from_parts(2_305_000, 0)
+		// Minimum execution time: 1_541_000 picoseconds.
+		Weight::from_parts(2_581_470, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 			// Standard Error: 0
-			.saturating_add(Weight::from_parts(366, 0).saturating_mul(b.into()))
+			.saturating_add(Weight::from_parts(387, 0).saturating_mul(b.into()))
 	}
 	/// The range of component `b` is `[0, 3932160]`.
 	fn remark_with_event(b: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 7_435_000 picoseconds.
-		Weight::from_parts(7_581_000, 0)
+		// Minimum execution time: 5_060_000 picoseconds.
+		Weight::from_parts(5_167_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
-			// Standard Error: 0
-			.saturating_add(Weight::from_parts(1_408, 0).saturating_mul(b.into()))
+			// Standard Error: 1
+			.saturating_add(Weight::from_parts(1_696, 0).saturating_mul(b.into()))
 	}
-	/// Storage: System Digest (r:1 w:1)
-	/// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: unknown `0x3a686561707061676573` (r:0 w:1)
-	/// Proof Skipped: unknown `0x3a686561707061676573` (r:0 w:1)
+	/// Storage: `System::Digest` (r:1 w:1)
+	/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: UNKNOWN KEY `0x3a686561707061676573` (r:0 w:1)
+	/// Proof: UNKNOWN KEY `0x3a686561707061676573` (r:0 w:1)
 	fn set_heap_pages() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `1485`
-		// Minimum execution time: 4_010_000 picoseconds.
-		Weight::from_parts(4_112_000, 0)
+		// Minimum execution time: 2_649_000 picoseconds.
+		Weight::from_parts(2_909_000, 0)
 			.saturating_add(Weight::from_parts(0, 1485))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
-	/// Storage: System Digest (r:1 w:1)
-	/// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: unknown `0x3a636f6465` (r:0 w:1)
-	/// Proof Skipped: unknown `0x3a636f6465` (r:0 w:1)
+	/// Storage: `System::Digest` (r:1 w:1)
+	/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: UNKNOWN KEY `0x3a636f6465` (r:0 w:1)
+	/// Proof: UNKNOWN KEY `0x3a636f6465` (r:0 w:1)
 	fn set_code() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `1485`
-		// Minimum execution time: 80_405_511_000 picoseconds.
-		Weight::from_parts(83_066_478_000, 0)
+		// Minimum execution time: 88_417_540_000 picoseconds.
+		Weight::from_parts(91_809_291_000, 0)
 			.saturating_add(Weight::from_parts(0, 1485))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
-	/// Storage: Skipped Metadata (r:0 w:0)
-	/// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `Skipped::Metadata` (r:0 w:0)
+	/// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	/// The range of component `i` is `[0, 1000]`.
 	fn set_storage(i: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 2_210_000 picoseconds.
-		Weight::from_parts(2_247_000, 0)
+		// Minimum execution time: 1_538_000 picoseconds.
+		Weight::from_parts(1_589_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
-			// Standard Error: 2_058
-			.saturating_add(Weight::from_parts(673_943, 0).saturating_mul(i.into()))
+			// Standard Error: 1_740
+			.saturating_add(Weight::from_parts(730_941, 0).saturating_mul(i.into()))
 			.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into())))
 	}
-	/// Storage: Skipped Metadata (r:0 w:0)
-	/// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `Skipped::Metadata` (r:0 w:0)
+	/// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	/// The range of component `i` is `[0, 1000]`.
 	fn kill_storage(i: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 2_125_000 picoseconds.
-		Weight::from_parts(2_154_000, 0)
+		// Minimum execution time: 1_567_000 picoseconds.
+		Weight::from_parts(1_750_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
-			// Standard Error: 816
-			.saturating_add(Weight::from_parts(491_194, 0).saturating_mul(i.into()))
+			// Standard Error: 835
+			.saturating_add(Weight::from_parts(543_218, 0).saturating_mul(i.into()))
 			.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into())))
 	}
-	/// Storage: Skipped Metadata (r:0 w:0)
-	/// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `Skipped::Metadata` (r:0 w:0)
+	/// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	/// The range of component `p` is `[0, 1000]`.
 	fn kill_prefix(p: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `129 + p * (69 ±0)`
-		//  Estimated: `125 + p * (70 ±0)`
-		// Minimum execution time: 4_002_000 picoseconds.
-		Weight::from_parts(4_145_000, 0)
-			.saturating_add(Weight::from_parts(0, 125))
-			// Standard Error: 1_108
-			.saturating_add(Weight::from_parts(1_014_971, 0).saturating_mul(p.into()))
+		//  Measured:  `80 + p * (69 ±0)`
+		//  Estimated: `83 + p * (70 ±0)`
+		// Minimum execution time: 3_412_000 picoseconds.
+		Weight::from_parts(3_448_000, 0)
+			.saturating_add(Weight::from_parts(0, 83))
+			// Standard Error: 1_395
+			.saturating_add(Weight::from_parts(1_142_347, 0).saturating_mul(p.into()))
 			.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(p.into())))
 			.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into())))
 			.saturating_add(Weight::from_parts(0, 70).saturating_mul(p.into()))
@@ -147,8 +150,8 @@ impl<T: frame_system::Config> frame_system::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 33_027_000 picoseconds.
-		Weight::from_parts(33_027_000, 0)
+		// Minimum execution time: 9_178_000 picoseconds.
+		Weight::from_parts(9_780_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
@@ -162,8 +165,8 @@ impl<T: frame_system::Config> frame_system::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `22`
 		//  Estimated: `1518`
-		// Minimum execution time: 118_101_992_000 picoseconds.
-		Weight::from_parts(118_101_992_000, 0)
+		// Minimum execution time: 94_523_563_000 picoseconds.
+		Weight::from_parts(96_983_131_000, 0)
 			.saturating_add(Weight::from_parts(0, 1518))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(3))
diff --git a/polkadot/runtime/rococo/src/weights/frame_system_extensions.rs b/polkadot/runtime/rococo/src/weights/frame_system_extensions.rs
new file mode 100644
index 00000000000..99dac1ba75f
--- /dev/null
+++ b/polkadot/runtime/rococo/src/weights/frame_system_extensions.rs
@@ -0,0 +1,134 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Polkadot.
+
+// Polkadot is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Polkadot is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `frame_system_extensions`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/production/polkadot
+// benchmark
+// pallet
+// --chain=rococo-dev
+// --steps=50
+// --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --pallet=frame_system_extensions
+// --extrinsic=*
+// --execution=wasm
+// --wasm-execution=compiled
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `frame_system_extensions`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> frame_system::ExtensionsWeightInfo for WeightInfo<T> {
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_genesis() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `54`
+		//  Estimated: `3509`
+		// Minimum execution time: 3_262_000 picoseconds.
+		Weight::from_parts(3_497_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_mortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 5_416_000 picoseconds.
+		Weight::from_parts(5_690_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_immortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 5_416_000 picoseconds.
+		Weight::from_parts(5_690_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	fn check_non_zero_sender() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 471_000 picoseconds.
+		Weight::from_parts(552_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	fn check_nonce() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `101`
+		//  Estimated: `3593`
+		// Minimum execution time: 4_847_000 picoseconds.
+		Weight::from_parts(5_091_000, 0)
+			.saturating_add(Weight::from_parts(0, 3593))
+			.saturating_add(T::DbWeight::get().reads(1))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+	fn check_spec_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 388_000 picoseconds.
+		Weight::from_parts(421_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_tx_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 378_000 picoseconds.
+		Weight::from_parts(440_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	/// Storage: `System::AllExtrinsicsLen` (r:1 w:1)
+	/// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
+	fn check_weight() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `24`
+		//  Estimated: `1489`
+		// Minimum execution time: 3_402_000 picoseconds.
+		Weight::from_parts(3_627_000, 0)
+			.saturating_add(Weight::from_parts(0, 1489))
+			.saturating_add(T::DbWeight::get().reads(1))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+}
diff --git a/polkadot/runtime/rococo/src/weights/mod.rs b/polkadot/runtime/rococo/src/weights/mod.rs
index 020f8e22594..99477baeb28 100644
--- a/polkadot/runtime/rococo/src/weights/mod.rs
+++ b/polkadot/runtime/rococo/src/weights/mod.rs
@@ -16,6 +16,7 @@
 //! A list of the different weight modules for our runtime.
 
 pub mod frame_system;
+pub mod frame_system_extensions;
 pub mod pallet_asset_rate;
 pub mod pallet_balances_balances;
 pub mod pallet_balances_nis_counterpart_balances;
@@ -39,6 +40,7 @@ pub mod pallet_scheduler;
 pub mod pallet_session;
 pub mod pallet_sudo;
 pub mod pallet_timestamp;
+pub mod pallet_transaction_payment;
 pub mod pallet_treasury;
 pub mod pallet_utility;
 pub mod pallet_vesting;
diff --git a/polkadot/runtime/rococo/src/weights/pallet_asset_rate.rs b/polkadot/runtime/rococo/src/weights/pallet_asset_rate.rs
index da2d1958cef..56b1e2cbc57 100644
--- a/polkadot/runtime/rococo/src/weights/pallet_asset_rate.rs
+++ b/polkadot/runtime/rococo/src/weights/pallet_asset_rate.rs
@@ -16,25 +16,28 @@
 
 //! Autogenerated weights for `pallet_asset_rate`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-07-03, STEPS: `50`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `cob`, CPU: `<UNKNOWN>`
-//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
-// ./target/debug/polkadot
+// ./target/production/polkadot
 // benchmark
 // pallet
 // --chain=rococo-dev
 // --steps=50
-// --repeat=2
+// --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
 // --pallet=pallet_asset_rate
 // --extrinsic=*
+// --execution=wasm
 // --wasm-execution=compiled
-// --heap-pages=4096
-// --output=./runtime/rococo/src/weights/
-// --header=./file_header.txt
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -47,39 +50,39 @@ use core::marker::PhantomData;
 /// Weight functions for `pallet_asset_rate`.
 pub struct WeightInfo<T>(PhantomData<T>);
 impl<T: frame_system::Config> pallet_asset_rate::WeightInfo for WeightInfo<T> {
-	/// Storage: AssetRate ConversionRateToNative (r:1 w:1)
-	/// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(1237), added: 3712, mode: MaxEncodedLen)
+	/// Storage: `AssetRate::ConversionRateToNative` (r:1 w:1)
+	/// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(1238), added: 3713, mode: `MaxEncodedLen`)
 	fn create() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `42`
-		//  Estimated: `4702`
-		// Minimum execution time: 143_000_000 picoseconds.
-		Weight::from_parts(155_000_000, 0)
-			.saturating_add(Weight::from_parts(0, 4702))
+		//  Measured:  `142`
+		//  Estimated: `4703`
+		// Minimum execution time: 10_277_000 picoseconds.
+		Weight::from_parts(10_487_000, 0)
+			.saturating_add(Weight::from_parts(0, 4703))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: AssetRate ConversionRateToNative (r:1 w:1)
-	/// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(1237), added: 3712, mode: MaxEncodedLen)
+	/// Storage: `AssetRate::ConversionRateToNative` (r:1 w:1)
+	/// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(1238), added: 3713, mode: `MaxEncodedLen`)
 	fn update() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `110`
-		//  Estimated: `4702`
-		// Minimum execution time: 156_000_000 picoseconds.
-		Weight::from_parts(172_000_000, 0)
-			.saturating_add(Weight::from_parts(0, 4702))
+		//  Measured:  `210`
+		//  Estimated: `4703`
+		// Minimum execution time: 10_917_000 picoseconds.
+		Weight::from_parts(11_249_000, 0)
+			.saturating_add(Weight::from_parts(0, 4703))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: AssetRate ConversionRateToNative (r:1 w:1)
-	/// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(1237), added: 3712, mode: MaxEncodedLen)
+	/// Storage: `AssetRate::ConversionRateToNative` (r:1 w:1)
+	/// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(1238), added: 3713, mode: `MaxEncodedLen`)
 	fn remove() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `110`
-		//  Estimated: `4702`
-		// Minimum execution time: 150_000_000 picoseconds.
-		Weight::from_parts(160_000_000, 0)
-			.saturating_add(Weight::from_parts(0, 4702))
+		//  Measured:  `210`
+		//  Estimated: `4703`
+		// Minimum execution time: 11_332_000 picoseconds.
+		Weight::from_parts(11_866_000, 0)
+			.saturating_add(Weight::from_parts(0, 4703))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
diff --git a/polkadot/runtime/rococo/src/weights/pallet_balances_balances.rs b/polkadot/runtime/rococo/src/weights/pallet_balances_balances.rs
index d37bb9369c6..c3c3315edff 100644
--- a/polkadot/runtime/rococo/src/weights/pallet_balances_balances.rs
+++ b/polkadot/runtime/rococo/src/weights/pallet_balances_balances.rs
@@ -23,17 +23,19 @@
 //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
-// target/production/polkadot
+// ./target/production/polkadot
 // benchmark
 // pallet
+// --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --pallet=pallet_balances
 // --extrinsic=*
+// --execution=wasm
 // --wasm-execution=compiled
-// --heap-pages=4096
-// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json
-// --pallet=pallet_balances
-// --chain=rococo-dev
 // --header=./polkadot/file_header.txt
 // --output=./polkadot/runtime/rococo/src/weights/
 
diff --git a/polkadot/runtime/rococo/src/weights/pallet_balances_nis_counterpart_balances.rs b/polkadot/runtime/rococo/src/weights/pallet_balances_nis_counterpart_balances.rs
index 706653aeb76..697e51faf53 100644
--- a/polkadot/runtime/rococo/src/weights/pallet_balances_nis_counterpart_balances.rs
+++ b/polkadot/runtime/rococo/src/weights/pallet_balances_nis_counterpart_balances.rs
@@ -23,17 +23,19 @@
 //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
-// target/production/polkadot
+// ./target/production/polkadot
 // benchmark
 // pallet
+// --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --pallet=pallet_balances
 // --extrinsic=*
+// --execution=wasm
 // --wasm-execution=compiled
-// --heap-pages=4096
-// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json
-// --pallet=pallet_balances
-// --chain=rococo-dev
 // --header=./polkadot/file_header.txt
 // --output=./polkadot/runtime/rococo/src/weights/
 
diff --git a/polkadot/runtime/rococo/src/weights/pallet_bounties.rs b/polkadot/runtime/rococo/src/weights/pallet_bounties.rs
index 38d3645316f..8f8be5f2386 100644
--- a/polkadot/runtime/rococo/src/weights/pallet_bounties.rs
+++ b/polkadot/runtime/rococo/src/weights/pallet_bounties.rs
@@ -16,11 +16,11 @@
 
 //! Autogenerated weights for `pallet_bounties`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
-//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
 // ./target/production/polkadot
@@ -29,12 +29,15 @@
 // --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
 // --pallet=pallet_bounties
 // --extrinsic=*
 // --execution=wasm
 // --wasm-execution=compiled
-// --header=./file_header.txt
-// --output=./runtime/rococo/src/weights/
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -47,118 +50,181 @@ use core::marker::PhantomData;
 /// Weight functions for `pallet_bounties`.
 pub struct WeightInfo<T>(PhantomData<T>);
 impl<T: frame_system::Config> pallet_bounties::WeightInfo for WeightInfo<T> {
-	/// Storage: Bounties BountyCount (r:1 w:1)
-	/// Proof: Bounties BountyCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
-	/// Storage: System Account (r:1 w:1)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
-	/// Storage: Bounties BountyDescriptions (r:0 w:1)
-	/// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(16400), added: 18875, mode: MaxEncodedLen)
-	/// Storage: Bounties Bounties (r:0 w:1)
-	/// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen)
+	/// Storage: `Bounties::BountyCount` (r:1 w:1)
+	/// Proof: `Bounties::BountyCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `Bounties::BountyDescriptions` (r:0 w:1)
+	/// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`)
+	/// Storage: `Bounties::Bounties` (r:0 w:1)
+	/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
 	/// The range of component `d` is `[0, 16384]`.
 	fn propose_bounty(d: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `210`
 		//  Estimated: `3593`
-		// Minimum execution time: 28_907_000 picoseconds.
-		Weight::from_parts(31_356_074, 0)
+		// Minimum execution time: 21_772_000 picoseconds.
+		Weight::from_parts(22_861_341, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
-			// Standard Error: 18
-			.saturating_add(Weight::from_parts(606, 0).saturating_mul(d.into()))
+			// Standard Error: 3
+			.saturating_add(Weight::from_parts(721, 0).saturating_mul(d.into()))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(4))
 	}
+	/// Storage: `Bounties::Bounties` (r:1 w:1)
+	/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
+	/// Storage: `Bounties::BountyApprovals` (r:1 w:1)
+	/// Proof: `Bounties::BountyApprovals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`)
 	fn approve_bounty() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `0`
-		//  Estimated: `0`
-		// Minimum execution time: 0_000 picoseconds.
-		Weight::from_parts(0, 0)
-			.saturating_add(Weight::from_parts(0, 0))
+		//  Measured:  `302`
+		//  Estimated: `3642`
+		// Minimum execution time: 11_218_000 picoseconds.
+		Weight::from_parts(11_796_000, 0)
+			.saturating_add(Weight::from_parts(0, 3642))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(2))
 	}
+	/// Storage: `Bounties::Bounties` (r:1 w:1)
+	/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
 	fn propose_curator() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `0`
-		//  Estimated: `0`
-		// Minimum execution time: 0_000 picoseconds.
-		Weight::from_parts(0, 0)
-			.saturating_add(Weight::from_parts(0, 0))
+		//  Measured:  `322`
+		//  Estimated: `3642`
+		// Minimum execution time: 10_959_000 picoseconds.
+		Weight::from_parts(11_658_000, 0)
+			.saturating_add(Weight::from_parts(0, 3642))
+			.saturating_add(T::DbWeight::get().reads(1))
+			.saturating_add(T::DbWeight::get().writes(1))
 	}
+	/// Storage: `Bounties::Bounties` (r:1 w:1)
+	/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
 	fn unassign_curator() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `0`
-		//  Estimated: `0`
-		// Minimum execution time: 0_000 picoseconds.
-		Weight::from_parts(0, 0)
-			.saturating_add(Weight::from_parts(0, 0))
+		//  Measured:  `498`
+		//  Estimated: `3642`
+		// Minimum execution time: 37_419_000 picoseconds.
+		Weight::from_parts(38_362_000, 0)
+			.saturating_add(Weight::from_parts(0, 3642))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(2))
 	}
+	/// Storage: `Bounties::Bounties` (r:1 w:1)
+	/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
 	fn accept_curator() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `0`
-		//  Estimated: `0`
-		// Minimum execution time: 0_000 picoseconds.
-		Weight::from_parts(0, 0)
-			.saturating_add(Weight::from_parts(0, 0))
+		//  Measured:  `494`
+		//  Estimated: `3642`
+		// Minimum execution time: 27_328_000 picoseconds.
+		Weight::from_parts(27_661_000, 0)
+			.saturating_add(Weight::from_parts(0, 3642))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(2))
 	}
+	/// Storage: `Bounties::Bounties` (r:1 w:1)
+	/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
+	/// Storage: `ChildBounties::ParentChildBounties` (r:1 w:0)
+	/// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`)
 	fn award_bounty() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `0`
-		//  Estimated: `0`
-		// Minimum execution time: 0_000 picoseconds.
-		Weight::from_parts(0, 0)
-			.saturating_add(Weight::from_parts(0, 0))
+		//  Measured:  `400`
+		//  Estimated: `3642`
+		// Minimum execution time: 16_067_000 picoseconds.
+		Weight::from_parts(16_865_000, 0)
+			.saturating_add(Weight::from_parts(0, 3642))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(1))
 	}
+	/// Storage: `Bounties::Bounties` (r:1 w:1)
+	/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:3 w:3)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1)
+	/// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`)
+	/// Storage: `Bounties::BountyDescriptions` (r:0 w:1)
+	/// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`)
 	fn claim_bounty() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `0`
-		//  Estimated: `0`
-		// Minimum execution time: 0_000 picoseconds.
-		Weight::from_parts(0, 0)
-			.saturating_add(Weight::from_parts(0, 0))
+		//  Measured:  `764`
+		//  Estimated: `8799`
+		// Minimum execution time: 101_153_000 picoseconds.
+		Weight::from_parts(102_480_000, 0)
+			.saturating_add(Weight::from_parts(0, 8799))
+			.saturating_add(T::DbWeight::get().reads(5))
+			.saturating_add(T::DbWeight::get().writes(6))
 	}
-	/// Storage: Bounties Bounties (r:1 w:1)
-	/// Proof: Bounties Bounties (max_values: None, max_size: Some(177), added: 2652, mode: MaxEncodedLen)
-	/// Storage: ChildBounties ParentChildBounties (r:1 w:0)
-	/// Proof: ChildBounties ParentChildBounties (max_values: None, max_size: Some(16), added: 2491, mode: MaxEncodedLen)
-	/// Storage: System Account (r:1 w:1)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
-	/// Storage: Bounties BountyDescriptions (r:0 w:1)
-	/// Proof: Bounties BountyDescriptions (max_values: None, max_size: Some(16400), added: 18875, mode: MaxEncodedLen)
+	/// Storage: `Bounties::Bounties` (r:1 w:1)
+	/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
+	/// Storage: `ChildBounties::ParentChildBounties` (r:1 w:0)
+	/// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `Bounties::BountyDescriptions` (r:0 w:1)
+	/// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`)
 	fn close_bounty_proposed() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `482`
+		//  Measured:  `444`
 		//  Estimated: `3642`
-		// Minimum execution time: 46_020_000 picoseconds.
-		Weight::from_parts(46_711_000, 0)
+		// Minimum execution time: 38_838_000 picoseconds.
+		Weight::from_parts(39_549_000, 0)
 			.saturating_add(Weight::from_parts(0, 3642))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(3))
 	}
+	/// Storage: `Bounties::Bounties` (r:1 w:1)
+	/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
+	/// Storage: `ChildBounties::ParentChildBounties` (r:1 w:0)
+	/// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:2 w:2)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `Bounties::BountyDescriptions` (r:0 w:1)
+	/// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`)
 	fn close_bounty_active() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `0`
-		//  Estimated: `0`
-		// Minimum execution time: 0_000 picoseconds.
-		Weight::from_parts(0, 0)
-			.saturating_add(Weight::from_parts(0, 0))
+		//  Measured:  `680`
+		//  Estimated: `6196`
+		// Minimum execution time: 68_592_000 picoseconds.
+		Weight::from_parts(70_727_000, 0)
+			.saturating_add(Weight::from_parts(0, 6196))
+			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().writes(4))
 	}
+	/// Storage: `Bounties::Bounties` (r:1 w:1)
+	/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
 	fn extend_bounty_expiry() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `0`
-		//  Estimated: `0`
-		// Minimum execution time: 0_000 picoseconds.
-		Weight::from_parts(0, 0)
-			.saturating_add(Weight::from_parts(0, 0))
+		//  Measured:  `358`
+		//  Estimated: `3642`
+		// Minimum execution time: 11_272_000 picoseconds.
+		Weight::from_parts(11_592_000, 0)
+			.saturating_add(Weight::from_parts(0, 3642))
+			.saturating_add(T::DbWeight::get().reads(1))
+			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Bounties BountyApprovals (r:1 w:1)
-	/// Proof: Bounties BountyApprovals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen)
+	/// Storage: `Bounties::BountyApprovals` (r:1 w:1)
+	/// Proof: `Bounties::BountyApprovals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`)
+	/// Storage: `Bounties::Bounties` (r:100 w:100)
+	/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:200 w:200)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
 	/// The range of component `b` is `[0, 100]`.
-	fn spend_funds(_b: u32, ) -> Weight {
+	fn spend_funds(b: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `0`
-		//  Estimated: `1887`
-		// Minimum execution time: 0_000 picoseconds.
-		Weight::from_parts(2_405_233, 0)
+		//  Measured:  `0 + b * (297 ±0)`
+		//  Estimated: `1887 + b * (5206 ±0)`
+		// Minimum execution time: 2_844_000 picoseconds.
+		Weight::from_parts(2_900_000, 0)
 			.saturating_add(Weight::from_parts(0, 1887))
+			// Standard Error: 9_467
+			.saturating_add(Weight::from_parts(32_326_595, 0).saturating_mul(b.into()))
+			.saturating_add(T::DbWeight::get().reads(1))
+			.saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(b.into())))
+			.saturating_add(T::DbWeight::get().writes(1))
+			.saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(b.into())))
+			.saturating_add(Weight::from_parts(0, 5206).saturating_mul(b.into()))
 	}
 }
diff --git a/polkadot/runtime/rococo/src/weights/pallet_child_bounties.rs b/polkadot/runtime/rococo/src/weights/pallet_child_bounties.rs
index e8c798d45e7..47ae3a5c90d 100644
--- a/polkadot/runtime/rococo/src/weights/pallet_child_bounties.rs
+++ b/polkadot/runtime/rococo/src/weights/pallet_child_bounties.rs
@@ -16,11 +16,11 @@
 
 //! Autogenerated weights for `pallet_child_bounties`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
-//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
 // ./target/production/polkadot
@@ -29,12 +29,15 @@
 // --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
 // --pallet=pallet_child_bounties
 // --extrinsic=*
 // --execution=wasm
 // --wasm-execution=compiled
-// --header=./file_header.txt
-// --output=./runtime/rococo/src/weights/
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -47,69 +50,153 @@ use core::marker::PhantomData;
 /// Weight functions for `pallet_child_bounties`.
 pub struct WeightInfo<T>(PhantomData<T>);
 impl<T: frame_system::Config> pallet_child_bounties::WeightInfo for WeightInfo<T> {
+	/// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1)
+	/// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`)
+	/// Storage: `Bounties::Bounties` (r:1 w:0)
+	/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:2 w:2)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `ChildBounties::ChildBountyCount` (r:1 w:1)
+	/// Proof: `ChildBounties::ChildBountyCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
+	/// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1)
+	/// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`)
+	/// Storage: `ChildBounties::ChildBounties` (r:0 w:1)
+	/// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`)
 	/// The range of component `d` is `[0, 16384]`.
-	fn add_child_bounty(_d: u32, ) -> Weight {
+	fn add_child_bounty(d: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `0`
-		//  Estimated: `0`
-		// Minimum execution time: 0_000 picoseconds.
-		Weight::from_parts(0, 0)
-			.saturating_add(Weight::from_parts(0, 0))
+		//  Measured:  `540`
+		//  Estimated: `6196`
+		// Minimum execution time: 57_964_000 picoseconds.
+		Weight::from_parts(59_559_565, 0)
+			.saturating_add(Weight::from_parts(0, 6196))
+			// Standard Error: 11
+			.saturating_add(Weight::from_parts(697, 0).saturating_mul(d.into()))
+			.saturating_add(T::DbWeight::get().reads(5))
+			.saturating_add(T::DbWeight::get().writes(6))
 	}
+	/// Storage: `Bounties::Bounties` (r:1 w:0)
+	/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
+	/// Storage: `ChildBounties::ChildBounties` (r:1 w:1)
+	/// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`)
+	/// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1)
+	/// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`)
 	fn propose_curator() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `0`
-		//  Estimated: `0`
-		// Minimum execution time: 0_000 picoseconds.
-		Weight::from_parts(0, 0)
-			.saturating_add(Weight::from_parts(0, 0))
+		//  Measured:  `594`
+		//  Estimated: `3642`
+		// Minimum execution time: 17_527_000 picoseconds.
+		Weight::from_parts(18_257_000, 0)
+			.saturating_add(Weight::from_parts(0, 3642))
+			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().writes(2))
 	}
+	/// Storage: `Bounties::Bounties` (r:1 w:0)
+	/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
+	/// Storage: `ChildBounties::ChildBounties` (r:1 w:1)
+	/// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
 	fn accept_curator() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `0`
-		//  Estimated: `0`
-		// Minimum execution time: 0_000 picoseconds.
-		Weight::from_parts(0, 0)
-			.saturating_add(Weight::from_parts(0, 0))
+		//  Measured:  `740`
+		//  Estimated: `3642`
+		// Minimum execution time: 29_354_000 picoseconds.
+		Weight::from_parts(30_629_000, 0)
+			.saturating_add(Weight::from_parts(0, 3642))
+			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().writes(2))
 	}
+	/// Storage: `ChildBounties::ChildBounties` (r:1 w:1)
+	/// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`)
+	/// Storage: `Bounties::Bounties` (r:1 w:0)
+	/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
 	fn unassign_curator() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `0`
-		//  Estimated: `0`
-		// Minimum execution time: 0_000 picoseconds.
-		Weight::from_parts(0, 0)
-			.saturating_add(Weight::from_parts(0, 0))
+		//  Measured:  `740`
+		//  Estimated: `3642`
+		// Minimum execution time: 40_643_000 picoseconds.
+		Weight::from_parts(42_072_000, 0)
+			.saturating_add(Weight::from_parts(0, 3642))
+			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().writes(2))
 	}
+	/// Storage: `Bounties::Bounties` (r:1 w:0)
+	/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
+	/// Storage: `ChildBounties::ChildBounties` (r:1 w:1)
+	/// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`)
 	fn award_child_bounty() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `0`
-		//  Estimated: `0`
-		// Minimum execution time: 0_000 picoseconds.
-		Weight::from_parts(0, 0)
-			.saturating_add(Weight::from_parts(0, 0))
+		//  Measured:  `637`
+		//  Estimated: `3642`
+		// Minimum execution time: 18_616_000 picoseconds.
+		Weight::from_parts(19_316_000, 0)
+			.saturating_add(Weight::from_parts(0, 3642))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(1))
 	}
+	/// Storage: `ChildBounties::ChildBounties` (r:1 w:1)
+	/// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:3 w:3)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1)
+	/// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`)
+	/// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1)
+	/// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`)
 	fn claim_child_bounty() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `0`
-		//  Estimated: `0`
-		// Minimum execution time: 0_000 picoseconds.
-		Weight::from_parts(0, 0)
-			.saturating_add(Weight::from_parts(0, 0))
+		//  Measured:  `576`
+		//  Estimated: `8799`
+		// Minimum execution time: 96_376_000 picoseconds.
+		Weight::from_parts(98_476_000, 0)
+			.saturating_add(Weight::from_parts(0, 8799))
+			.saturating_add(T::DbWeight::get().reads(5))
+			.saturating_add(T::DbWeight::get().writes(6))
 	}
+	/// Storage: `Bounties::Bounties` (r:1 w:0)
+	/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
+	/// Storage: `ChildBounties::ChildBounties` (r:1 w:1)
+	/// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`)
+	/// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1)
+	/// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`)
+	/// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1)
+	/// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:2 w:2)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1)
+	/// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`)
 	fn close_child_bounty_added() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `0`
-		//  Estimated: `0`
-		// Minimum execution time: 0_000 picoseconds.
-		Weight::from_parts(0, 0)
-			.saturating_add(Weight::from_parts(0, 0))
+		//  Measured:  `840`
+		//  Estimated: `6196`
+		// Minimum execution time: 64_640_000 picoseconds.
+		Weight::from_parts(66_174_000, 0)
+			.saturating_add(Weight::from_parts(0, 6196))
+			.saturating_add(T::DbWeight::get().reads(6))
+			.saturating_add(T::DbWeight::get().writes(6))
 	}
+	/// Storage: `Bounties::Bounties` (r:1 w:0)
+	/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
+	/// Storage: `ChildBounties::ChildBounties` (r:1 w:1)
+	/// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:3 w:3)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1)
+	/// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`)
+	/// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1)
+	/// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`)
+	/// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1)
+	/// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`)
 	fn close_child_bounty_active() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `0`
-		//  Estimated: `0`
-		// Minimum execution time: 0_000 picoseconds.
-		Weight::from_parts(0, 0)
-			.saturating_add(Weight::from_parts(0, 0))
+		//  Measured:  `1027`
+		//  Estimated: `8799`
+		// Minimum execution time: 78_159_000 picoseconds.
+		Weight::from_parts(79_820_000, 0)
+			.saturating_add(Weight::from_parts(0, 8799))
+			.saturating_add(T::DbWeight::get().reads(7))
+			.saturating_add(T::DbWeight::get().writes(7))
 	}
 }
diff --git a/polkadot/runtime/rococo/src/weights/pallet_conviction_voting.rs b/polkadot/runtime/rococo/src/weights/pallet_conviction_voting.rs
index ba505737f1b..5d92c158df4 100644
--- a/polkadot/runtime/rococo/src/weights/pallet_conviction_voting.rs
+++ b/polkadot/runtime/rococo/src/weights/pallet_conviction_voting.rs
@@ -16,17 +16,17 @@
 
 //! Autogenerated weights for `pallet_conviction_voting`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `runner-e8ezs4ez-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
-//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
 // ./target/production/polkadot
 // benchmark
 // pallet
-// --chain=kusama-dev
+// --chain=rococo-dev
 // --steps=50
 // --repeat=20
 // --no-storage-info
@@ -36,8 +36,8 @@
 // --extrinsic=*
 // --execution=wasm
 // --wasm-execution=compiled
-// --header=./file_header.txt
-// --output=./runtime/kusama/src/weights/
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -50,144 +50,152 @@ use core::marker::PhantomData;
 /// Weight functions for `pallet_conviction_voting`.
 pub struct WeightInfo<T>(PhantomData<T>);
 impl<T: frame_system::Config> pallet_conviction_voting::WeightInfo for WeightInfo<T> {
-	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
-	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
-	/// Storage: ConvictionVoting VotingFor (r:1 w:1)
-	/// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen)
-	/// Storage: ConvictionVoting ClassLocksFor (r:1 w:1)
-	/// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(311), added: 2786, mode: MaxEncodedLen)
-	/// Storage: Balances Locks (r:1 w:1)
-	/// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen)
-	/// Storage: Balances Freezes (r:1 w:0)
-	/// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen)
-	/// Storage: Scheduler Agenda (r:1 w:1)
-	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	/// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1)
+	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
+	/// Storage: `ConvictionVoting::VotingFor` (r:1 w:1)
+	/// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`)
+	/// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1)
+	/// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(311), added: 2786, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Locks` (r:1 w:1)
+	/// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Freezes` (r:1 w:0)
+	/// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`)
+	/// Storage: `Scheduler::Agenda` (r:1 w:1)
+	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	fn vote_new() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `13445`
+		//  Measured:  `13407`
 		//  Estimated: `42428`
-		// Minimum execution time: 151_077_000 picoseconds.
-		Weight::from_parts(165_283_000, 0)
+		// Minimum execution time: 128_378_000 picoseconds.
+		Weight::from_parts(131_028_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
 			.saturating_add(T::DbWeight::get().reads(6))
 			.saturating_add(T::DbWeight::get().writes(5))
 	}
-	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
-	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
-	/// Storage: ConvictionVoting VotingFor (r:1 w:1)
-	/// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen)
-	/// Storage: ConvictionVoting ClassLocksFor (r:1 w:1)
-	/// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(311), added: 2786, mode: MaxEncodedLen)
-	/// Storage: Balances Locks (r:1 w:1)
-	/// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen)
-	/// Storage: Balances Freezes (r:1 w:0)
-	/// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen)
-	/// Storage: Scheduler Agenda (r:2 w:2)
-	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	/// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1)
+	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
+	/// Storage: `ConvictionVoting::VotingFor` (r:1 w:1)
+	/// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`)
+	/// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1)
+	/// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(311), added: 2786, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Locks` (r:1 w:1)
+	/// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Freezes` (r:1 w:0)
+	/// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`)
+	/// Storage: `Scheduler::Agenda` (r:2 w:2)
+	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
+	/// Storage: `Scheduler::Retries` (r:0 w:1)
+	/// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
 	fn vote_existing() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `14166`
+		//  Measured:  `14128`
 		//  Estimated: `83866`
-		// Minimum execution time: 232_420_000 picoseconds.
-		Weight::from_parts(244_439_000, 0)
+		// Minimum execution time: 155_379_000 picoseconds.
+		Weight::from_parts(161_597_000, 0)
 			.saturating_add(Weight::from_parts(0, 83866))
 			.saturating_add(T::DbWeight::get().reads(7))
-			.saturating_add(T::DbWeight::get().writes(6))
+			.saturating_add(T::DbWeight::get().writes(7))
 	}
-	/// Storage: ConvictionVoting VotingFor (r:1 w:1)
-	/// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen)
-	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
-	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
-	/// Storage: Scheduler Agenda (r:2 w:2)
-	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	/// Storage: `ConvictionVoting::VotingFor` (r:1 w:1)
+	/// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`)
+	/// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1)
+	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
+	/// Storage: `Scheduler::Agenda` (r:2 w:2)
+	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
+	/// Storage: `Scheduler::Retries` (r:0 w:1)
+	/// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
 	fn remove_vote() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `13918`
 		//  Estimated: `83866`
-		// Minimum execution time: 205_017_000 picoseconds.
-		Weight::from_parts(216_594_000, 0)
+		// Minimum execution time: 130_885_000 picoseconds.
+		Weight::from_parts(138_080_000, 0)
 			.saturating_add(Weight::from_parts(0, 83866))
 			.saturating_add(T::DbWeight::get().reads(4))
-			.saturating_add(T::DbWeight::get().writes(4))
+			.saturating_add(T::DbWeight::get().writes(5))
 	}
-	/// Storage: ConvictionVoting VotingFor (r:1 w:1)
-	/// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen)
-	/// Storage: Referenda ReferendumInfoFor (r:1 w:0)
-	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: `ConvictionVoting::VotingFor` (r:1 w:1)
+	/// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`)
+	/// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0)
+	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
 	fn remove_other_vote() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `13004`
+		//  Measured:  `13005`
 		//  Estimated: `30706`
-		// Minimum execution time: 84_226_000 picoseconds.
-		Weight::from_parts(91_255_000, 0)
+		// Minimum execution time: 71_743_000 picoseconds.
+		Weight::from_parts(75_170_000, 0)
 			.saturating_add(Weight::from_parts(0, 30706))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: ConvictionVoting VotingFor (r:2 w:2)
-	/// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen)
-	/// Storage: Referenda ReferendumInfoFor (r:512 w:512)
-	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
-	/// Storage: Scheduler Agenda (r:2 w:2)
-	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
-	/// Storage: ConvictionVoting ClassLocksFor (r:1 w:1)
-	/// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(311), added: 2786, mode: MaxEncodedLen)
-	/// Storage: Balances Locks (r:1 w:1)
-	/// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen)
-	/// Storage: Balances Freezes (r:1 w:0)
-	/// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen)
+	/// Storage: `ConvictionVoting::VotingFor` (r:2 w:2)
+	/// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`)
+	/// Storage: `Referenda::ReferendumInfoFor` (r:512 w:512)
+	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
+	/// Storage: `Scheduler::Agenda` (r:2 w:2)
+	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
+	/// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1)
+	/// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(311), added: 2786, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Locks` (r:1 w:1)
+	/// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Freezes` (r:1 w:0)
+	/// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`)
+	/// Storage: `Scheduler::Retries` (r:0 w:50)
+	/// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
 	/// The range of component `r` is `[0, 512]`.
 	fn delegate(r: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `29640 + r * (365 ±0)`
+		//  Measured:  `29602 + r * (365 ±0)`
 		//  Estimated: `83866 + r * (3411 ±0)`
-		// Minimum execution time: 78_708_000 picoseconds.
-		Weight::from_parts(2_053_488_615, 0)
+		// Minimum execution time: 58_504_000 picoseconds.
+		Weight::from_parts(814_301_018, 0)
 			.saturating_add(Weight::from_parts(0, 83866))
-			// Standard Error: 179_271
-			.saturating_add(Weight::from_parts(47_806_482, 0).saturating_mul(r.into()))
+			// Standard Error: 59_961
+			.saturating_add(Weight::from_parts(20_002_833, 0).saturating_mul(r.into()))
 			.saturating_add(T::DbWeight::get().reads(7))
 			.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into())))
-			.saturating_add(T::DbWeight::get().writes(6))
+			.saturating_add(T::DbWeight::get().writes(45))
 			.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into())))
 			.saturating_add(Weight::from_parts(0, 3411).saturating_mul(r.into()))
 	}
-	/// Storage: ConvictionVoting VotingFor (r:2 w:2)
-	/// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen)
-	/// Storage: Referenda ReferendumInfoFor (r:512 w:512)
-	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
-	/// Storage: Scheduler Agenda (r:2 w:2)
-	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	/// Storage: `ConvictionVoting::VotingFor` (r:2 w:2)
+	/// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`)
+	/// Storage: `Referenda::ReferendumInfoFor` (r:512 w:512)
+	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
+	/// Storage: `Scheduler::Agenda` (r:2 w:2)
+	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
+	/// Storage: `Scheduler::Retries` (r:0 w:50)
+	/// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
 	/// The range of component `r` is `[0, 512]`.
 	fn undelegate(r: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `29555 + r * (365 ±0)`
 		//  Estimated: `83866 + r * (3411 ±0)`
-		// Minimum execution time: 45_232_000 picoseconds.
-		Weight::from_parts(2_045_021_014, 0)
+		// Minimum execution time: 34_970_000 picoseconds.
+		Weight::from_parts(771_155_804, 0)
 			.saturating_add(Weight::from_parts(0, 83866))
-			// Standard Error: 185_130
-			.saturating_add(Weight::from_parts(47_896_011, 0).saturating_mul(r.into()))
+			// Standard Error: 57_795
+			.saturating_add(Weight::from_parts(19_781_645, 0).saturating_mul(r.into()))
 			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(r.into())))
-			.saturating_add(T::DbWeight::get().writes(4))
+			.saturating_add(T::DbWeight::get().writes(43))
 			.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(r.into())))
 			.saturating_add(Weight::from_parts(0, 3411).saturating_mul(r.into()))
 	}
-	/// Storage: ConvictionVoting VotingFor (r:1 w:1)
-	/// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen)
-	/// Storage: ConvictionVoting ClassLocksFor (r:1 w:1)
-	/// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(311), added: 2786, mode: MaxEncodedLen)
-	/// Storage: Balances Locks (r:1 w:1)
-	/// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen)
-	/// Storage: Balances Freezes (r:1 w:0)
-	/// Proof: Balances Freezes (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen)
+	/// Storage: `ConvictionVoting::VotingFor` (r:1 w:1)
+	/// Proof: `ConvictionVoting::VotingFor` (`max_values`: None, `max_size`: Some(27241), added: 29716, mode: `MaxEncodedLen`)
+	/// Storage: `ConvictionVoting::ClassLocksFor` (r:1 w:1)
+	/// Proof: `ConvictionVoting::ClassLocksFor` (`max_values`: None, `max_size`: Some(311), added: 2786, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Locks` (r:1 w:1)
+	/// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Freezes` (r:1 w:0)
+	/// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`)
 	fn unlock() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `12218`
+		//  Measured:  `12180`
 		//  Estimated: `30706`
-		// Minimum execution time: 116_446_000 picoseconds.
-		Weight::from_parts(124_043_000, 0)
+		// Minimum execution time: 89_648_000 picoseconds.
+		Weight::from_parts(97_144_000, 0)
 			.saturating_add(Weight::from_parts(0, 30706))
 			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(3))
diff --git a/polkadot/runtime/rococo/src/weights/pallet_identity.rs b/polkadot/runtime/rococo/src/weights/pallet_identity.rs
index b334e21ea03..6df16351f2c 100644
--- a/polkadot/runtime/rococo/src/weights/pallet_identity.rs
+++ b/polkadot/runtime/rococo/src/weights/pallet_identity.rs
@@ -16,11 +16,11 @@
 
 //! Autogenerated weights for `pallet_identity`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
-//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
 // ./target/production/polkadot
@@ -29,12 +29,15 @@
 // --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
 // --pallet=pallet_identity
 // --extrinsic=*
 // --execution=wasm
 // --wasm-execution=compiled
-// --header=./file_header.txt
-// --output=./runtime/rococo/src/weights/
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -47,290 +50,291 @@ use core::marker::PhantomData;
 /// Weight functions for `pallet_identity`.
 pub struct WeightInfo<T>(PhantomData<T>);
 impl<T: frame_system::Config> pallet_identity::WeightInfo for WeightInfo<T> {
-	/// Storage: Identity Registrars (r:1 w:1)
-	/// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen)
+	/// Storage: `Identity::Registrars` (r:1 w:1)
+	/// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`)
 	/// The range of component `r` is `[1, 19]`.
 	fn add_registrar(r: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `32 + r * (57 ±0)`
 		//  Estimated: `2626`
-		// Minimum execution time: 12_290_000 picoseconds.
-		Weight::from_parts(12_664_362, 0)
+		// Minimum execution time: 7_673_000 picoseconds.
+		Weight::from_parts(8_351_866, 0)
 			.saturating_add(Weight::from_parts(0, 2626))
-			// Standard Error: 1_347
-			.saturating_add(Weight::from_parts(88_179, 0).saturating_mul(r.into()))
+			// Standard Error: 1_302
+			.saturating_add(Weight::from_parts(79_198, 0).saturating_mul(r.into()))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Identity IdentityOf (r:1 w:1)
-	/// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen)
+	/// Storage: `Identity::IdentityOf` (r:1 w:1)
+	/// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`)
 	/// The range of component `r` is `[1, 20]`.
 	fn set_identity(r: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `442 + r * (5 ±0)`
-		//  Estimated: `11003`
-		// Minimum execution time: 31_373_000 picoseconds.
-		Weight::from_parts(30_435_545, 0)
-			.saturating_add(Weight::from_parts(0, 11003))
-			// Standard Error: 2_307
-			.saturating_add(Weight::from_parts(92_753, 0).saturating_mul(r.into()))
+		//  Measured:  `6978 + r * (5 ±0)`
+		//  Estimated: `11037`
+		// Minimum execution time: 111_646_000 picoseconds.
+		Weight::from_parts(113_254_991, 0)
+			.saturating_add(Weight::from_parts(0, 11037))
+			// Standard Error: 6_611
+			.saturating_add(Weight::from_parts(162_119, 0).saturating_mul(r.into()))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Identity IdentityOf (r:1 w:0)
-	/// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen)
-	/// Storage: Identity SubsOf (r:1 w:1)
-	/// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen)
-	/// Storage: Identity SuperOf (r:100 w:100)
-	/// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen)
+	/// Storage: `Identity::IdentityOf` (r:1 w:0)
+	/// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`)
+	/// Storage: `Identity::SubsOf` (r:1 w:1)
+	/// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`)
+	/// Storage: `Identity::SuperOf` (r:100 w:100)
+	/// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`)
 	/// The range of component `s` is `[0, 100]`.
 	fn set_subs_new(s: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `101`
-		//  Estimated: `11003 + s * (2589 ±0)`
-		// Minimum execution time: 9_251_000 picoseconds.
-		Weight::from_parts(22_039_210, 0)
-			.saturating_add(Weight::from_parts(0, 11003))
-			// Standard Error: 40_779
-			.saturating_add(Weight::from_parts(2_898_525, 0).saturating_mul(s.into()))
+		//  Estimated: `11037 + s * (2589 ±0)`
+		// Minimum execution time: 8_010_000 picoseconds.
+		Weight::from_parts(19_868_412, 0)
+			.saturating_add(Weight::from_parts(0, 11037))
+			// Standard Error: 5_018
+			.saturating_add(Weight::from_parts(3_115_007, 0).saturating_mul(s.into()))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(s.into())))
 			.saturating_add(T::DbWeight::get().writes(1))
 			.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into())))
 			.saturating_add(Weight::from_parts(0, 2589).saturating_mul(s.into()))
 	}
-	/// Storage: Identity IdentityOf (r:1 w:0)
-	/// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen)
-	/// Storage: Identity SubsOf (r:1 w:1)
-	/// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen)
-	/// Storage: Identity SuperOf (r:0 w:100)
-	/// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen)
+	/// Storage: `Identity::IdentityOf` (r:1 w:0)
+	/// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`)
+	/// Storage: `Identity::SubsOf` (r:1 w:1)
+	/// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`)
+	/// Storage: `Identity::SuperOf` (r:0 w:100)
+	/// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`)
 	/// The range of component `p` is `[0, 100]`.
 	fn set_subs_old(p: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `194 + p * (32 ±0)`
-		//  Estimated: `11003`
-		// Minimum execution time: 9_329_000 picoseconds.
-		Weight::from_parts(24_055_061, 0)
-			.saturating_add(Weight::from_parts(0, 11003))
-			// Standard Error: 3_428
-			.saturating_add(Weight::from_parts(1_130_604, 0).saturating_mul(p.into()))
+		//  Estimated: `11037`
+		// Minimum execution time: 8_111_000 picoseconds.
+		Weight::from_parts(19_482_392, 0)
+			.saturating_add(Weight::from_parts(0, 11037))
+			// Standard Error: 3_156
+			.saturating_add(Weight::from_parts(1_305_890, 0).saturating_mul(p.into()))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
 			.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into())))
 	}
-	/// Storage: Identity SubsOf (r:1 w:1)
-	/// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen)
-	/// Storage: Identity IdentityOf (r:1 w:1)
-	/// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen)
-	/// Storage: Identity SuperOf (r:0 w:100)
-	/// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen)
+	/// Storage: `Identity::SubsOf` (r:1 w:1)
+	/// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`)
+	/// Storage: `Identity::IdentityOf` (r:1 w:1)
+	/// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`)
+	/// Storage: `Identity::SuperOf` (r:0 w:100)
+	/// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`)
 	/// The range of component `r` is `[1, 20]`.
 	/// The range of component `s` is `[0, 100]`.
-	fn clear_identity(_r: u32, s: u32, ) -> Weight {
+	fn clear_identity(r: u32, s: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `469 + r * (5 ±0) + s * (32 ±0) + x * (66 ±0)`
-		//  Estimated: `11003`
-		// Minimum execution time: 53_365_000 picoseconds.
-		Weight::from_parts(35_391_422, 0)
-			.saturating_add(Weight::from_parts(0, 11003))
-			// Standard Error: 1_353
-			.saturating_add(Weight::from_parts(1_074_019, 0).saturating_mul(s.into()))
+		//  Measured:  `7070 + r * (5 ±0) + s * (32 ±0)`
+		//  Estimated: `11037`
+		// Minimum execution time: 54_107_000 picoseconds.
+		Weight::from_parts(56_347_715, 0)
+			.saturating_add(Weight::from_parts(0, 11037))
+			// Standard Error: 10_944
+			.saturating_add(Weight::from_parts(191_321, 0).saturating_mul(r.into()))
+			// Standard Error: 2_135
+			.saturating_add(Weight::from_parts(1_295_872, 0).saturating_mul(s.into()))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
 			.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into())))
 	}
-	/// Storage: Identity Registrars (r:1 w:0)
-	/// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen)
-	/// Storage: Identity IdentityOf (r:1 w:1)
-	/// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen)
+	/// Storage: `Identity::Registrars` (r:1 w:0)
+	/// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`)
+	/// Storage: `Identity::IdentityOf` (r:1 w:1)
+	/// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`)
 	/// The range of component `r` is `[1, 20]`.
 	fn request_judgement(r: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `367 + r * (57 ±0) + x * (66 ±0)`
-		//  Estimated: `11003`
-		// Minimum execution time: 32_509_000 picoseconds.
-		Weight::from_parts(31_745_585, 0)
-			.saturating_add(Weight::from_parts(0, 11003))
-			// Standard Error: 2_214
-			.saturating_add(Weight::from_parts(83_822, 0).saturating_mul(r.into()))
-
+		//  Measured:  `6968 + r * (57 ±0)`
+		//  Estimated: `11037`
+		// Minimum execution time: 75_780_000 picoseconds.
+		Weight::from_parts(76_869_773, 0)
+			.saturating_add(Weight::from_parts(0, 11037))
+			// Standard Error: 5_456
+			.saturating_add(Weight::from_parts(135_316, 0).saturating_mul(r.into()))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Identity IdentityOf (r:1 w:1)
-	/// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen)
+	/// Storage: `Identity::IdentityOf` (r:1 w:1)
+	/// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`)
 	/// The range of component `r` is `[1, 20]`.
 	fn cancel_request(r: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `398 + x * (66 ±0)`
-		//  Estimated: `11003`
-		// Minimum execution time: 29_609_000 picoseconds.
-		Weight::from_parts(28_572_602, 0)
-			.saturating_add(Weight::from_parts(0, 11003))
-			// Standard Error: 2_528
-			.saturating_add(Weight::from_parts(85_593, 0).saturating_mul(r.into()))
+		//  Measured:  `6999`
+		//  Estimated: `11037`
+		// Minimum execution time: 75_769_000 picoseconds.
+		Weight::from_parts(76_805_143, 0)
+			.saturating_add(Weight::from_parts(0, 11037))
+			// Standard Error: 3_598
+			.saturating_add(Weight::from_parts(84_593, 0).saturating_mul(r.into()))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Identity Registrars (r:1 w:1)
-	/// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen)
+	/// Storage: `Identity::Registrars` (r:1 w:1)
+	/// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`)
 	/// The range of component `r` is `[1, 19]`.
 	fn set_fee(r: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `89 + r * (57 ±0)`
 		//  Estimated: `2626`
-		// Minimum execution time: 7_793_000 picoseconds.
-		Weight::from_parts(8_173_888, 0)
+		// Minimum execution time: 5_357_000 picoseconds.
+		Weight::from_parts(5_732_132, 0)
 			.saturating_add(Weight::from_parts(0, 2626))
-			// Standard Error: 1_569
-			.saturating_add(Weight::from_parts(72_367, 0).saturating_mul(r.into()))
+			// Standard Error: 927
+			.saturating_add(Weight::from_parts(70_832, 0).saturating_mul(r.into()))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Identity Registrars (r:1 w:1)
-	/// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen)
+	/// Storage: `Identity::Registrars` (r:1 w:1)
+	/// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`)
 	/// The range of component `r` is `[1, 19]`.
 	fn set_account_id(r: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `89 + r * (57 ±0)`
 		//  Estimated: `2626`
-		// Minimum execution time: 7_708_000 picoseconds.
-		Weight::from_parts(8_091_149, 0)
+		// Minimum execution time: 5_484_000 picoseconds.
+		Weight::from_parts(5_892_704, 0)
 			.saturating_add(Weight::from_parts(0, 2626))
-			// Standard Error: 869
-			.saturating_add(Weight::from_parts(87_993, 0).saturating_mul(r.into()))
+			// Standard Error: 947
+			.saturating_add(Weight::from_parts(71_231, 0).saturating_mul(r.into()))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Identity Registrars (r:1 w:1)
-	/// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen)
+	/// Storage: `Identity::Registrars` (r:1 w:1)
+	/// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`)
 	/// The range of component `r` is `[1, 19]`.
 	fn set_fields(r: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `89 + r * (57 ±0)`
 		//  Estimated: `2626`
-		// Minimum execution time: 7_601_000 picoseconds.
-		Weight::from_parts(8_038_414, 0)
+		// Minimum execution time: 5_310_000 picoseconds.
+		Weight::from_parts(5_766_651, 0)
 			.saturating_add(Weight::from_parts(0, 2626))
-			// Standard Error: 1_041
-			.saturating_add(Weight::from_parts(82_588, 0).saturating_mul(r.into()))
+			// Standard Error: 916
+			.saturating_add(Weight::from_parts(74_776, 0).saturating_mul(r.into()))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Identity Registrars (r:1 w:0)
-	/// Proof: Identity Registrars (max_values: Some(1), max_size: Some(1141), added: 1636, mode: MaxEncodedLen)
-	/// Storage: Identity IdentityOf (r:1 w:1)
-	/// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen)
+	/// Storage: `Identity::Registrars` (r:1 w:0)
+	/// Proof: `Identity::Registrars` (`max_values`: Some(1), `max_size`: Some(1141), added: 1636, mode: `MaxEncodedLen`)
+	/// Storage: `Identity::IdentityOf` (r:1 w:1)
+	/// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`)
 	/// The range of component `r` is `[1, 19]`.
 	fn provide_judgement(r: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `445 + r * (57 ±0) + x * (66 ±0)`
-		//  Estimated: `11003`
-		// Minimum execution time: 23_114_000 picoseconds.
-		Weight::from_parts(22_076_548, 0)
-			.saturating_add(Weight::from_parts(0, 11003))
-			// Standard Error: 2_881
-			.saturating_add(Weight::from_parts(109_812, 0).saturating_mul(r.into()))
+		//  Measured:  `7046 + r * (57 ±0)`
+		//  Estimated: `11037`
+		// Minimum execution time: 98_200_000 picoseconds.
+		Weight::from_parts(100_105_482, 0)
+			.saturating_add(Weight::from_parts(0, 11037))
+			// Standard Error: 6_152
+			.saturating_add(Weight::from_parts(58_906, 0).saturating_mul(r.into()))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Identity SubsOf (r:1 w:1)
-	/// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen)
-	/// Storage: Identity IdentityOf (r:1 w:1)
-	/// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen)
-	/// Storage: System Account (r:1 w:1)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
-	/// Storage: Identity SuperOf (r:0 w:100)
-	/// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen)
+	/// Storage: `Identity::SubsOf` (r:1 w:1)
+	/// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`)
+	/// Storage: `Identity::IdentityOf` (r:1 w:1)
+	/// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `Identity::SuperOf` (r:0 w:100)
+	/// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`)
 	/// The range of component `r` is `[1, 20]`.
 	/// The range of component `s` is `[0, 100]`.
 	fn kill_identity(r: u32, s: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `676 + r * (5 ±0) + s * (32 ±0) + x * (66 ±0)`
-		//  Estimated: `11003`
-		// Minimum execution time: 70_007_000 picoseconds.
-		Weight::from_parts(50_186_495, 0)
-			.saturating_add(Weight::from_parts(0, 11003))
-			// Standard Error: 6_533
-			.saturating_add(Weight::from_parts(15_486, 0).saturating_mul(r.into()))
-			// Standard Error: 1_275
-			.saturating_add(Weight::from_parts(1_085_117, 0).saturating_mul(s.into()))
+		//  Measured:  `7277 + r * (5 ±0) + s * (32 ±0)`
+		//  Estimated: `11037`
+		// Minimum execution time: 64_647_000 picoseconds.
+		Weight::from_parts(68_877_027, 0)
+			.saturating_add(Weight::from_parts(0, 11037))
+			// Standard Error: 9_965
+			.saturating_add(Weight::from_parts(135_044, 0).saturating_mul(r.into()))
+			// Standard Error: 1_944
+			.saturating_add(Weight::from_parts(1_388_151, 0).saturating_mul(s.into()))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(3))
 			.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into())))
 	}
-	/// Storage: Identity IdentityOf (r:1 w:0)
-	/// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen)
-	/// Storage: Identity SuperOf (r:1 w:1)
-	/// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen)
-	/// Storage: Identity SubsOf (r:1 w:1)
-	/// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen)
+	/// Storage: `Identity::IdentityOf` (r:1 w:0)
+	/// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`)
+	/// Storage: `Identity::SuperOf` (r:1 w:1)
+	/// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`)
+	/// Storage: `Identity::SubsOf` (r:1 w:1)
+	/// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`)
 	/// The range of component `s` is `[0, 99]`.
 	fn add_sub(s: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `475 + s * (36 ±0)`
-		//  Estimated: `11003`
-		// Minimum execution time: 28_453_000 picoseconds.
-		Weight::from_parts(33_165_934, 0)
-			.saturating_add(Weight::from_parts(0, 11003))
-			// Standard Error: 1_217
-			.saturating_add(Weight::from_parts(65_401, 0).saturating_mul(s.into()))
+		//  Estimated: `11037`
+		// Minimum execution time: 23_550_000 picoseconds.
+		Weight::from_parts(29_439_842, 0)
+			.saturating_add(Weight::from_parts(0, 11037))
+			// Standard Error: 1_453
+			.saturating_add(Weight::from_parts(96_324, 0).saturating_mul(s.into()))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
-	/// Storage: Identity IdentityOf (r:1 w:0)
-	/// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen)
-	/// Storage: Identity SuperOf (r:1 w:1)
-	/// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen)
+	/// Storage: `Identity::IdentityOf` (r:1 w:0)
+	/// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`)
+	/// Storage: `Identity::SuperOf` (r:1 w:1)
+	/// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`)
 	/// The range of component `s` is `[1, 100]`.
 	fn rename_sub(s: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `591 + s * (3 ±0)`
-		//  Estimated: `11003`
-		// Minimum execution time: 12_846_000 picoseconds.
-		Weight::from_parts(14_710_284, 0)
-			.saturating_add(Weight::from_parts(0, 11003))
-			// Standard Error: 496
-			.saturating_add(Weight::from_parts(19_539, 0).saturating_mul(s.into()))
+		//  Estimated: `11037`
+		// Minimum execution time: 13_704_000 picoseconds.
+		Weight::from_parts(15_241_441, 0)
+			.saturating_add(Weight::from_parts(0, 11037))
+			// Standard Error: 498
+			.saturating_add(Weight::from_parts(40_973, 0).saturating_mul(s.into()))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Identity IdentityOf (r:1 w:0)
-	/// Proof: Identity IdentityOf (max_values: None, max_size: Some(7538), added: 10013, mode: MaxEncodedLen)
-	/// Storage: Identity SuperOf (r:1 w:1)
-	/// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen)
-	/// Storage: Identity SubsOf (r:1 w:1)
-	/// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen)
+	/// Storage: `Identity::IdentityOf` (r:1 w:0)
+	/// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`)
+	/// Storage: `Identity::SuperOf` (r:1 w:1)
+	/// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`)
+	/// Storage: `Identity::SubsOf` (r:1 w:1)
+	/// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`)
 	/// The range of component `s` is `[1, 100]`.
 	fn remove_sub(s: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `638 + s * (35 ±0)`
-		//  Estimated: `11003`
-		// Minimum execution time: 32_183_000 picoseconds.
-		Weight::from_parts(35_296_731, 0)
-			.saturating_add(Weight::from_parts(0, 11003))
-			// Standard Error: 854
-			.saturating_add(Weight::from_parts(52_028, 0).saturating_mul(s.into()))
+		//  Estimated: `11037`
+		// Minimum execution time: 29_310_000 picoseconds.
+		Weight::from_parts(31_712_666, 0)
+			.saturating_add(Weight::from_parts(0, 11037))
+			// Standard Error: 967
+			.saturating_add(Weight::from_parts(81_250, 0).saturating_mul(s.into()))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
-	/// Storage: Identity SuperOf (r:1 w:1)
-	/// Proof: Identity SuperOf (max_values: None, max_size: Some(114), added: 2589, mode: MaxEncodedLen)
-	/// Storage: Identity SubsOf (r:1 w:1)
-	/// Proof: Identity SubsOf (max_values: None, max_size: Some(3258), added: 5733, mode: MaxEncodedLen)
-	/// Storage: System Account (r:1 w:0)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
+	/// Storage: `Identity::SuperOf` (r:1 w:1)
+	/// Proof: `Identity::SuperOf` (`max_values`: None, `max_size`: Some(114), added: 2589, mode: `MaxEncodedLen`)
+	/// Storage: `Identity::SubsOf` (r:1 w:1)
+	/// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:0)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
 	/// The range of component `s` is `[0, 99]`.
 	fn quit_sub(s: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `704 + s * (37 ±0)`
 		//  Estimated: `6723`
-		// Minimum execution time: 24_941_000 picoseconds.
-		Weight::from_parts(27_433_059, 0)
+		// Minimum execution time: 22_906_000 picoseconds.
+		Weight::from_parts(24_638_729, 0)
 			.saturating_add(Weight::from_parts(0, 6723))
-			// Standard Error: 856
-			.saturating_add(Weight::from_parts(57_463, 0).saturating_mul(s.into()))
+			// Standard Error: 645
+			.saturating_add(Weight::from_parts(75_121, 0).saturating_mul(s.into()))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
@@ -340,90 +344,93 @@ impl<T: frame_system::Config> pallet_identity::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 13_873_000 picoseconds.
-		Weight::from_parts(13_873_000, 0)
+		// Minimum execution time: 6_056_000 picoseconds.
+		Weight::from_parts(6_349_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: `Identity::UsernameAuthorities` (r:0 w:1)
+	/// Storage: `Identity::UsernameAuthorities` (r:1 w:1)
 	/// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
 	fn remove_username_authority() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `0`
-		//  Estimated: `0`
-		// Minimum execution time: 10_653_000 picoseconds.
-		Weight::from_parts(10_653_000, 0)
-			.saturating_add(Weight::from_parts(0, 0))
+		//  Measured:  `80`
+		//  Estimated: `3517`
+		// Minimum execution time: 9_003_000 picoseconds.
+		Weight::from_parts(9_276_000, 0)
+			.saturating_add(Weight::from_parts(0, 3517))
+			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
 	/// Storage: `Identity::UsernameAuthorities` (r:1 w:1)
 	/// Proof: `Identity::UsernameAuthorities` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
 	/// Storage: `Identity::AccountOfUsername` (r:1 w:1)
-	/// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`)
+	/// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`)
+	/// Storage: `Identity::PendingUsernames` (r:1 w:0)
+	/// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`)
 	/// Storage: `Identity::IdentityOf` (r:1 w:1)
 	/// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`)
 	fn set_username_for() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `80`
 		//  Estimated: `11037`
-		// Minimum execution time: 75_928_000 picoseconds.
-		Weight::from_parts(75_928_000, 0)
+		// Minimum execution time: 64_724_000 picoseconds.
+		Weight::from_parts(66_597_000, 0)
 			.saturating_add(Weight::from_parts(0, 11037))
-			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(3))
 	}
 	/// Storage: `Identity::PendingUsernames` (r:1 w:1)
-	/// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(77), added: 2552, mode: `MaxEncodedLen`)
+	/// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`)
 	/// Storage: `Identity::IdentityOf` (r:1 w:1)
 	/// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`)
 	/// Storage: `Identity::AccountOfUsername` (r:0 w:1)
-	/// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`)
+	/// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`)
 	fn accept_username() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `106`
+		//  Measured:  `115`
 		//  Estimated: `11037`
-		// Minimum execution time: 38_157_000 picoseconds.
-		Weight::from_parts(38_157_000, 0)
+		// Minimum execution time: 19_538_000 picoseconds.
+		Weight::from_parts(20_204_000, 0)
 			.saturating_add(Weight::from_parts(0, 11037))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(3))
 	}
 	/// Storage: `Identity::PendingUsernames` (r:1 w:1)
-	/// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(77), added: 2552, mode: `MaxEncodedLen`)
+	/// Proof: `Identity::PendingUsernames` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`)
 	fn remove_expired_approval() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `106`
-		//  Estimated: `3542`
-		// Minimum execution time: 46_821_000 picoseconds.
-		Weight::from_parts(46_821_000, 0)
-			.saturating_add(Weight::from_parts(0, 3542))
+		//  Measured:  `115`
+		//  Estimated: `3550`
+		// Minimum execution time: 16_000_000 picoseconds.
+		Weight::from_parts(19_354_000, 0)
+			.saturating_add(Weight::from_parts(0, 3550))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
 	/// Storage: `Identity::AccountOfUsername` (r:1 w:0)
-	/// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`)
+	/// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`)
 	/// Storage: `Identity::IdentityOf` (r:1 w:1)
 	/// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`)
 	fn set_primary_username() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `247`
+		//  Measured:  `257`
 		//  Estimated: `11037`
-		// Minimum execution time: 22_515_000 picoseconds.
-		Weight::from_parts(22_515_000, 0)
+		// Minimum execution time: 15_298_000 picoseconds.
+		Weight::from_parts(15_760_000, 0)
 			.saturating_add(Weight::from_parts(0, 11037))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
 	/// Storage: `Identity::AccountOfUsername` (r:1 w:1)
-	/// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`)
+	/// Proof: `Identity::AccountOfUsername` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`)
 	/// Storage: `Identity::IdentityOf` (r:1 w:0)
 	/// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`)
 	fn remove_dangling_username() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `126`
+		//  Measured:  `98`
 		//  Estimated: `11037`
-		// Minimum execution time: 15_997_000 picoseconds.
-		Weight::from_parts(15_997_000, 0)
+		// Minimum execution time: 10_829_000 picoseconds.
+		Weight::from_parts(11_113_000, 0)
 			.saturating_add(Weight::from_parts(0, 11037))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
diff --git a/polkadot/runtime/rococo/src/weights/pallet_indices.rs b/polkadot/runtime/rococo/src/weights/pallet_indices.rs
index 99ffd3210ed..434db97d4a7 100644
--- a/polkadot/runtime/rococo/src/weights/pallet_indices.rs
+++ b/polkadot/runtime/rococo/src/weights/pallet_indices.rs
@@ -16,11 +16,11 @@
 
 //! Autogenerated weights for `pallet_indices`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
-//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
 // ./target/production/polkadot
@@ -29,12 +29,15 @@
 // --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
 // --pallet=pallet_indices
 // --extrinsic=*
 // --execution=wasm
 // --wasm-execution=compiled
-// --header=./file_header.txt
-// --output=./runtime/rococo/src/weights/
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -47,66 +50,66 @@ use core::marker::PhantomData;
 /// Weight functions for `pallet_indices`.
 pub struct WeightInfo<T>(PhantomData<T>);
 impl<T: frame_system::Config> pallet_indices::WeightInfo for WeightInfo<T> {
-	/// Storage: Indices Accounts (r:1 w:1)
-	/// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen)
+	/// Storage: `Indices::Accounts` (r:1 w:1)
+	/// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`)
 	fn claim() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `142`
+		//  Measured:  `4`
 		//  Estimated: `3534`
-		// Minimum execution time: 25_107_000 picoseconds.
-		Weight::from_parts(25_655_000, 0)
+		// Minimum execution time: 18_092_000 picoseconds.
+		Weight::from_parts(18_533_000, 0)
 			.saturating_add(Weight::from_parts(0, 3534))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Indices Accounts (r:1 w:1)
-	/// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen)
-	/// Storage: System Account (r:1 w:1)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
+	/// Storage: `Indices::Accounts` (r:1 w:1)
+	/// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
 	fn transfer() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `341`
+		//  Measured:  `203`
 		//  Estimated: `3593`
-		// Minimum execution time: 36_208_000 picoseconds.
-		Weight::from_parts(36_521_000, 0)
+		// Minimum execution time: 31_616_000 picoseconds.
+		Weight::from_parts(32_556_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
-	/// Storage: Indices Accounts (r:1 w:1)
-	/// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen)
+	/// Storage: `Indices::Accounts` (r:1 w:1)
+	/// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`)
 	fn free() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `238`
+		//  Measured:  `100`
 		//  Estimated: `3534`
-		// Minimum execution time: 25_915_000 picoseconds.
-		Weight::from_parts(26_220_000, 0)
+		// Minimum execution time: 19_593_000 picoseconds.
+		Weight::from_parts(20_100_000, 0)
 			.saturating_add(Weight::from_parts(0, 3534))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Indices Accounts (r:1 w:1)
-	/// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen)
-	/// Storage: System Account (r:1 w:1)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
+	/// Storage: `Indices::Accounts` (r:1 w:1)
+	/// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
 	fn force_transfer() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `341`
+		//  Measured:  `203`
 		//  Estimated: `3593`
-		// Minimum execution time: 28_232_000 picoseconds.
-		Weight::from_parts(28_845_000, 0)
+		// Minimum execution time: 21_429_000 picoseconds.
+		Weight::from_parts(22_146_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
-	/// Storage: Indices Accounts (r:1 w:1)
-	/// Proof: Indices Accounts (max_values: None, max_size: Some(69), added: 2544, mode: MaxEncodedLen)
+	/// Storage: `Indices::Accounts` (r:1 w:1)
+	/// Proof: `Indices::Accounts` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`)
 	fn freeze() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `238`
+		//  Measured:  `100`
 		//  Estimated: `3534`
-		// Minimum execution time: 27_282_000 picoseconds.
-		Weight::from_parts(27_754_000, 0)
+		// Minimum execution time: 20_425_000 picoseconds.
+		Weight::from_parts(21_023_000, 0)
 			.saturating_add(Weight::from_parts(0, 3534))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
diff --git a/polkadot/runtime/rococo/src/weights/pallet_message_queue.rs b/polkadot/runtime/rococo/src/weights/pallet_message_queue.rs
index e1e360d374a..6ebfcd060b6 100644
--- a/polkadot/runtime/rococo/src/weights/pallet_message_queue.rs
+++ b/polkadot/runtime/rococo/src/weights/pallet_message_queue.rs
@@ -16,11 +16,11 @@
 
 //! Autogenerated weights for `pallet_message_queue`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
-//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
 // ./target/production/polkadot
@@ -29,12 +29,15 @@
 // --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
 // --pallet=pallet_message_queue
 // --extrinsic=*
 // --execution=wasm
 // --wasm-execution=compiled
-// --header=./file_header.txt
-// --output=./runtime/rococo/src/weights/
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -47,150 +50,149 @@ use core::marker::PhantomData;
 /// Weight functions for `pallet_message_queue`.
 pub struct WeightInfo<T>(PhantomData<T>);
 impl<T: frame_system::Config> pallet_message_queue::WeightInfo for WeightInfo<T> {
-	/// Storage: MessageQueue ServiceHead (r:1 w:0)
-	/// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(6), added: 501, mode: MaxEncodedLen)
-	/// Storage: MessageQueue BookStateFor (r:2 w:2)
-	/// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen)
+	/// Storage: `MessageQueue::ServiceHead` (r:1 w:0)
+	/// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(6), added: 501, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::BookStateFor` (r:2 w:2)
+	/// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`)
 	fn ready_ring_knit() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `248`
+		//  Measured:  `281`
 		//  Estimated: `6050`
-		// Minimum execution time: 12_106_000 picoseconds.
-		Weight::from_parts(12_387_000, 0)
+		// Minimum execution time: 12_830_000 picoseconds.
+		Weight::from_parts(13_476_000, 0)
 			.saturating_add(Weight::from_parts(0, 6050))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
-	/// Storage: MessageQueue BookStateFor (r:2 w:2)
-	/// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen)
-	/// Storage: MessageQueue ServiceHead (r:1 w:1)
-	/// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(6), added: 501, mode: MaxEncodedLen)
+	/// Storage: `MessageQueue::BookStateFor` (r:2 w:2)
+	/// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::ServiceHead` (r:1 w:1)
+	/// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(6), added: 501, mode: `MaxEncodedLen`)
 	fn ready_ring_unknit() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `248`
+		//  Measured:  `281`
 		//  Estimated: `6050`
-		// Minimum execution time: 11_227_000 picoseconds.
-		Weight::from_parts(11_616_000, 0)
+		// Minimum execution time: 11_583_000 picoseconds.
+		Weight::from_parts(11_902_000, 0)
 			.saturating_add(Weight::from_parts(0, 6050))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(3))
 	}
-	/// Storage: MessageQueue BookStateFor (r:1 w:1)
-	/// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen)
+	/// Storage: `MessageQueue::BookStateFor` (r:1 w:1)
+	/// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`)
 	fn service_queue_base() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `42`
 		//  Estimated: `3520`
-		// Minimum execution time: 5_052_000 picoseconds.
-		Weight::from_parts(5_216_000, 0)
+		// Minimum execution time: 3_801_000 picoseconds.
+		Weight::from_parts(3_943_000, 0)
 			.saturating_add(Weight::from_parts(0, 3520))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: MessageQueue Pages (r:1 w:1)
-	/// Proof: MessageQueue Pages (max_values: None, max_size: Some(32818), added: 35293, mode: MaxEncodedLen)
+	/// Storage: `MessageQueue::Pages` (r:1 w:1)
+	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(32818), added: 35293, mode: `MaxEncodedLen`)
 	fn service_page_base_completion() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `115`
 		//  Estimated: `36283`
-		// Minimum execution time: 6_522_000 picoseconds.
-		Weight::from_parts(6_794_000, 0)
+		// Minimum execution time: 5_517_000 picoseconds.
+		Weight::from_parts(5_861_000, 0)
 			.saturating_add(Weight::from_parts(0, 36283))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: MessageQueue Pages (r:1 w:1)
-	/// Proof: MessageQueue Pages (max_values: None, max_size: Some(32818), added: 35293, mode: MaxEncodedLen)
+	/// Storage: `MessageQueue::Pages` (r:1 w:1)
+	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(32818), added: 35293, mode: `MaxEncodedLen`)
 	fn service_page_base_no_completion() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `115`
 		//  Estimated: `36283`
-		// Minimum execution time: 6_918_000 picoseconds.
-		Weight::from_parts(7_083_000, 0)
+		// Minimum execution time: 5_870_000 picoseconds.
+		Weight::from_parts(6_028_000, 0)
 			.saturating_add(Weight::from_parts(0, 36283))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
+	/// Storage: `MessageQueue::BookStateFor` (r:0 w:1)
+	/// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::Pages` (r:0 w:1)
+	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(32818), added: 35293, mode: `MaxEncodedLen`)
 	fn service_page_item() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 28_445_000 picoseconds.
-		Weight::from_parts(28_659_000, 0)
+		// Minimum execution time: 80_681_000 picoseconds.
+		Weight::from_parts(81_818_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
+			.saturating_add(T::DbWeight::get().writes(2))
 	}
-	/// Storage: MessageQueue ServiceHead (r:1 w:1)
-	/// Proof: MessageQueue ServiceHead (max_values: Some(1), max_size: Some(6), added: 501, mode: MaxEncodedLen)
-	/// Storage: MessageQueue BookStateFor (r:1 w:0)
-	/// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen)
+	/// Storage: `MessageQueue::ServiceHead` (r:1 w:1)
+	/// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(6), added: 501, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::BookStateFor` (r:1 w:0)
+	/// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`)
 	fn bump_service_head() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `149`
+		//  Measured:  `220`
 		//  Estimated: `3520`
-		// Minimum execution time: 7_224_000 picoseconds.
-		Weight::from_parts(7_441_000, 0)
+		// Minimum execution time: 8_641_000 picoseconds.
+		Weight::from_parts(8_995_000, 0)
 			.saturating_add(Weight::from_parts(0, 3520))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: MessageQueue BookStateFor (r:1 w:1)
-	/// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen)
-	/// Storage: MessageQueue Pages (r:1 w:1)
-	/// Proof: MessageQueue Pages (max_values: None, max_size: Some(32818), added: 35293, mode: MaxEncodedLen)
-	/// Storage: Configuration ActiveConfig (r:1 w:0)
-	/// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1)
-	/// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1)
-	/// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1)
-	/// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1)
+	/// Storage: `MessageQueue::BookStateFor` (r:1 w:1)
+	/// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::Pages` (r:1 w:1)
+	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(32818), added: 35293, mode: `MaxEncodedLen`)
+	/// Storage: UNKNOWN KEY `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1)
+	/// Proof: UNKNOWN KEY `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1)
+	/// Storage: UNKNOWN KEY `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1)
+	/// Proof: UNKNOWN KEY `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1)
 	fn reap_page() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `33232`
+		//  Measured:  `32945`
 		//  Estimated: `36283`
-		// Minimum execution time: 45_211_000 picoseconds.
-		Weight::from_parts(45_505_000, 0)
+		// Minimum execution time: 38_473_000 picoseconds.
+		Weight::from_parts(39_831_000, 0)
 			.saturating_add(Weight::from_parts(0, 36283))
-			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(4))
 	}
-	/// Storage: MessageQueue BookStateFor (r:1 w:1)
-	/// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen)
-	/// Storage: MessageQueue Pages (r:1 w:1)
-	/// Proof: MessageQueue Pages (max_values: None, max_size: Some(32818), added: 35293, mode: MaxEncodedLen)
-	/// Storage: Configuration ActiveConfig (r:1 w:0)
-	/// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1)
-	/// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1)
-	/// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1)
-	/// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1)
+	/// Storage: `MessageQueue::BookStateFor` (r:1 w:1)
+	/// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::Pages` (r:1 w:1)
+	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(32818), added: 35293, mode: `MaxEncodedLen`)
+	/// Storage: UNKNOWN KEY `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1)
+	/// Proof: UNKNOWN KEY `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1)
+	/// Storage: UNKNOWN KEY `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1)
+	/// Proof: UNKNOWN KEY `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1)
 	fn execute_overweight_page_removed() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `33232`
+		//  Measured:  `32945`
 		//  Estimated: `36283`
-		// Minimum execution time: 52_346_000 picoseconds.
-		Weight::from_parts(52_745_000, 0)
+		// Minimum execution time: 48_717_000 picoseconds.
+		Weight::from_parts(49_724_000, 0)
 			.saturating_add(Weight::from_parts(0, 36283))
-			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(4))
 	}
-	/// Storage: MessageQueue BookStateFor (r:1 w:1)
-	/// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen)
-	/// Storage: MessageQueue Pages (r:1 w:1)
-	/// Proof: MessageQueue Pages (max_values: None, max_size: Some(32818), added: 35293, mode: MaxEncodedLen)
-	/// Storage: Configuration ActiveConfig (r:1 w:0)
-	/// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1)
-	/// Proof Skipped: unknown `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1)
-	/// Storage: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1)
-	/// Proof Skipped: unknown `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1)
+	/// Storage: `MessageQueue::BookStateFor` (r:1 w:1)
+	/// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`)
+	/// Storage: `MessageQueue::Pages` (r:1 w:1)
+	/// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(32818), added: 35293, mode: `MaxEncodedLen`)
+	/// Storage: UNKNOWN KEY `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1)
+	/// Proof: UNKNOWN KEY `0x3a72656c61795f64697370617463685f71756575655f72656d61696e696e675f` (r:0 w:1)
+	/// Storage: UNKNOWN KEY `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1)
+	/// Proof: UNKNOWN KEY `0xf5207f03cfdce586301014700e2c2593fad157e461d71fd4c1f936839a5f1f3e` (r:0 w:1)
 	fn execute_overweight_page_updated() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `33232`
+		//  Measured:  `32945`
 		//  Estimated: `36283`
-		// Minimum execution time: 72_567_000 picoseconds.
-		Weight::from_parts(73_300_000, 0)
+		// Minimum execution time: 72_718_000 picoseconds.
+		Weight::from_parts(74_081_000, 0)
 			.saturating_add(Weight::from_parts(0, 36283))
-			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(4))
 	}
 }
diff --git a/polkadot/runtime/rococo/src/weights/pallet_multisig.rs b/polkadot/runtime/rococo/src/weights/pallet_multisig.rs
index a4f33fe198c..f1b81759ece 100644
--- a/polkadot/runtime/rococo/src/weights/pallet_multisig.rs
+++ b/polkadot/runtime/rococo/src/weights/pallet_multisig.rs
@@ -16,11 +16,11 @@
 
 //! Autogenerated weights for `pallet_multisig`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
-//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
 // ./target/production/polkadot
@@ -29,12 +29,15 @@
 // --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
 // --pallet=pallet_multisig
 // --extrinsic=*
 // --execution=wasm
 // --wasm-execution=compiled
-// --header=./file_header.txt
-// --output=./runtime/rococo/src/weights/
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -52,110 +55,110 @@ impl<T: frame_system::Config> pallet_multisig::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 11_475_000 picoseconds.
-		Weight::from_parts(11_904_745, 0)
+		// Minimum execution time: 12_023_000 picoseconds.
+		Weight::from_parts(12_643_116, 0)
 			.saturating_add(Weight::from_parts(0, 0))
-			// Standard Error: 1
-			.saturating_add(Weight::from_parts(492, 0).saturating_mul(z.into()))
+			// Standard Error: 3
+			.saturating_add(Weight::from_parts(582, 0).saturating_mul(z.into()))
 	}
-	/// Storage: Multisig Multisigs (r:1 w:1)
-	/// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen)
+	/// Storage: `Multisig::Multisigs` (r:1 w:1)
+	/// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`)
 	/// The range of component `s` is `[2, 100]`.
 	/// The range of component `z` is `[0, 10000]`.
 	fn as_multi_create(s: u32, z: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `193 + s * (2 ±0)`
+		//  Measured:  `229 + s * (2 ±0)`
 		//  Estimated: `6811`
-		// Minimum execution time: 38_857_000 picoseconds.
-		Weight::from_parts(33_611_791, 0)
+		// Minimum execution time: 39_339_000 picoseconds.
+		Weight::from_parts(27_243_033, 0)
 			.saturating_add(Weight::from_parts(0, 6811))
-			// Standard Error: 400
-			.saturating_add(Weight::from_parts(59_263, 0).saturating_mul(s.into()))
-			// Standard Error: 3
-			.saturating_add(Weight::from_parts(1_211, 0).saturating_mul(z.into()))
+			// Standard Error: 1_319
+			.saturating_add(Weight::from_parts(142_212, 0).saturating_mul(s.into()))
+			// Standard Error: 12
+			.saturating_add(Weight::from_parts(1_592, 0).saturating_mul(z.into()))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Multisig Multisigs (r:1 w:1)
-	/// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen)
+	/// Storage: `Multisig::Multisigs` (r:1 w:1)
+	/// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`)
 	/// The range of component `s` is `[3, 100]`.
 	/// The range of component `z` is `[0, 10000]`.
 	fn as_multi_approve(s: u32, z: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `211`
+		//  Measured:  `248`
 		//  Estimated: `6811`
-		// Minimum execution time: 25_715_000 picoseconds.
-		Weight::from_parts(20_607_294, 0)
+		// Minimum execution time: 27_647_000 picoseconds.
+		Weight::from_parts(15_828_725, 0)
 			.saturating_add(Weight::from_parts(0, 6811))
-			// Standard Error: 285
-			.saturating_add(Weight::from_parts(58_225, 0).saturating_mul(s.into()))
-			// Standard Error: 2
-			.saturating_add(Weight::from_parts(1_160, 0).saturating_mul(z.into()))
+			// Standard Error: 908
+			.saturating_add(Weight::from_parts(130_880, 0).saturating_mul(s.into()))
+			// Standard Error: 8
+			.saturating_add(Weight::from_parts(1_532, 0).saturating_mul(z.into()))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Multisig Multisigs (r:1 w:1)
-	/// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen)
-	/// Storage: System Account (r:1 w:1)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
+	/// Storage: `Multisig::Multisigs` (r:1 w:1)
+	/// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
 	/// The range of component `s` is `[2, 100]`.
 	/// The range of component `z` is `[0, 10000]`.
 	fn as_multi_complete(s: u32, z: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `317 + s * (33 ±0)`
+		//  Measured:  `354 + s * (33 ±0)`
 		//  Estimated: `6811`
-		// Minimum execution time: 43_751_000 picoseconds.
-		Weight::from_parts(37_398_513, 0)
+		// Minimum execution time: 46_971_000 picoseconds.
+		Weight::from_parts(32_150_393, 0)
 			.saturating_add(Weight::from_parts(0, 6811))
-			// Standard Error: 426
-			.saturating_add(Weight::from_parts(70_904, 0).saturating_mul(s.into()))
-			// Standard Error: 4
-			.saturating_add(Weight::from_parts(1_235, 0).saturating_mul(z.into()))
+			// Standard Error: 1_129
+			.saturating_add(Weight::from_parts(154_796, 0).saturating_mul(s.into()))
+			// Standard Error: 11
+			.saturating_add(Weight::from_parts(1_603, 0).saturating_mul(z.into()))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
-	/// Storage: Multisig Multisigs (r:1 w:1)
-	/// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen)
+	/// Storage: `Multisig::Multisigs` (r:1 w:1)
+	/// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`)
 	/// The range of component `s` is `[2, 100]`.
 	fn approve_as_multi_create(s: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `193 + s * (2 ±0)`
+		//  Measured:  `229 + s * (2 ±0)`
 		//  Estimated: `6811`
-		// Minimum execution time: 31_278_000 picoseconds.
-		Weight::from_parts(32_075_573, 0)
+		// Minimum execution time: 24_947_000 picoseconds.
+		Weight::from_parts(26_497_183, 0)
 			.saturating_add(Weight::from_parts(0, 6811))
-			// Standard Error: 452
-			.saturating_add(Weight::from_parts(62_018, 0).saturating_mul(s.into()))
+			// Standard Error: 1_615
+			.saturating_add(Weight::from_parts(147_071, 0).saturating_mul(s.into()))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Multisig Multisigs (r:1 w:1)
-	/// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen)
+	/// Storage: `Multisig::Multisigs` (r:1 w:1)
+	/// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`)
 	/// The range of component `s` is `[2, 100]`.
 	fn approve_as_multi_approve(s: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `211`
+		//  Measured:  `248`
 		//  Estimated: `6811`
-		// Minimum execution time: 18_178_000 picoseconds.
-		Weight::from_parts(18_649_867, 0)
+		// Minimum execution time: 13_897_000 picoseconds.
+		Weight::from_parts(14_828_339, 0)
 			.saturating_add(Weight::from_parts(0, 6811))
-			// Standard Error: 293
-			.saturating_add(Weight::from_parts(56_475, 0).saturating_mul(s.into()))
+			// Standard Error: 1_136
+			.saturating_add(Weight::from_parts(133_925, 0).saturating_mul(s.into()))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Multisig Multisigs (r:1 w:1)
-	/// Proof: Multisig Multisigs (max_values: None, max_size: Some(3346), added: 5821, mode: MaxEncodedLen)
+	/// Storage: `Multisig::Multisigs` (r:1 w:1)
+	/// Proof: `Multisig::Multisigs` (`max_values`: None, `max_size`: Some(3346), added: 5821, mode: `MaxEncodedLen`)
 	/// The range of component `s` is `[2, 100]`.
 	fn cancel_as_multi(s: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `383 + s * (1 ±0)`
+		//  Measured:  `420 + s * (1 ±0)`
 		//  Estimated: `6811`
-		// Minimum execution time: 32_265_000 picoseconds.
-		Weight::from_parts(32_984_014, 0)
+		// Minimum execution time: 28_984_000 picoseconds.
+		Weight::from_parts(29_853_232, 0)
 			.saturating_add(Weight::from_parts(0, 6811))
-			// Standard Error: 452
-			.saturating_add(Weight::from_parts(59_934, 0).saturating_mul(s.into()))
+			// Standard Error: 650
+			.saturating_add(Weight::from_parts(113_440, 0).saturating_mul(s.into()))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
diff --git a/polkadot/runtime/rococo/src/weights/pallet_nis.rs b/polkadot/runtime/rococo/src/weights/pallet_nis.rs
index 35dad482129..38b41f3a8e2 100644
--- a/polkadot/runtime/rococo/src/weights/pallet_nis.rs
+++ b/polkadot/runtime/rococo/src/weights/pallet_nis.rs
@@ -16,11 +16,11 @@
 
 //! Autogenerated weights for `pallet_nis`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
-//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
 // ./target/production/polkadot
@@ -29,12 +29,15 @@
 // --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
 // --pallet=pallet_nis
 // --extrinsic=*
 // --execution=wasm
 // --wasm-execution=compiled
-// --header=./file_header.txt
-// --output=./runtime/rococo/src/weights/
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -47,202 +50,186 @@ use core::marker::PhantomData;
 /// Weight functions for `pallet_nis`.
 pub struct WeightInfo<T>(PhantomData<T>);
 impl<T: frame_system::Config> pallet_nis::WeightInfo for WeightInfo<T> {
-	/// Storage: Nis Queues (r:1 w:1)
-	/// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen)
-	/// Storage: Balances Holds (r:1 w:1)
-	/// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen)
-	/// Storage: Nis QueueTotals (r:1 w:1)
-	/// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen)
+	/// Storage: `Nis::Queues` (r:1 w:1)
+	/// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Holds` (r:1 w:1)
+	/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`)
+	/// Storage: `Nis::QueueTotals` (r:1 w:1)
+	/// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`)
 	/// The range of component `l` is `[0, 999]`.
 	fn place_bid(l: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `6209 + l * (48 ±0)`
 		//  Estimated: `51487`
-		// Minimum execution time: 44_704_000 picoseconds.
-		Weight::from_parts(44_933_886, 0)
+		// Minimum execution time: 39_592_000 picoseconds.
+		Weight::from_parts(38_234_037, 0)
 			.saturating_add(Weight::from_parts(0, 51487))
-			// Standard Error: 712
-			.saturating_add(Weight::from_parts(71_570, 0).saturating_mul(l.into()))
+			// Standard Error: 1_237
+			.saturating_add(Weight::from_parts(88_816, 0).saturating_mul(l.into()))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(3))
 	}
-	/// Storage: Nis Queues (r:1 w:1)
-	/// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen)
-	/// Storage: Balances Holds (r:1 w:1)
-	/// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen)
-	/// Storage: Nis QueueTotals (r:1 w:1)
-	/// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen)
+	/// Storage: `Nis::Queues` (r:1 w:1)
+	/// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Holds` (r:1 w:1)
+	/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`)
+	/// Storage: `Nis::QueueTotals` (r:1 w:1)
+	/// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`)
 	fn place_bid_max() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `54211`
 		//  Estimated: `51487`
-		// Minimum execution time: 126_544_000 picoseconds.
-		Weight::from_parts(128_271_000, 0)
+		// Minimum execution time: 134_847_000 picoseconds.
+		Weight::from_parts(139_510_000, 0)
 			.saturating_add(Weight::from_parts(0, 51487))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(3))
 	}
-	/// Storage: Nis Queues (r:1 w:1)
-	/// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen)
-	/// Storage: Balances Holds (r:1 w:1)
-	/// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen)
-	/// Storage: Nis QueueTotals (r:1 w:1)
-	/// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen)
+	/// Storage: `Nis::Queues` (r:1 w:1)
+	/// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Holds` (r:1 w:1)
+	/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`)
+	/// Storage: `Nis::QueueTotals` (r:1 w:1)
+	/// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`)
 	/// The range of component `l` is `[1, 1000]`.
 	fn retract_bid(l: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `6209 + l * (48 ±0)`
 		//  Estimated: `51487`
-		// Minimum execution time: 47_640_000 picoseconds.
-		Weight::from_parts(42_214_261, 0)
+		// Minimum execution time: 43_330_000 picoseconds.
+		Weight::from_parts(35_097_881, 0)
 			.saturating_add(Weight::from_parts(0, 51487))
-			// Standard Error: 732
-			.saturating_add(Weight::from_parts(87_277, 0).saturating_mul(l.into()))
+			// Standard Error: 1_119
+			.saturating_add(Weight::from_parts(73_640, 0).saturating_mul(l.into()))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(3))
 	}
-	/// Storage: Nis Summary (r:1 w:0)
-	/// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen)
-	/// Storage: Balances InactiveIssuance (r:1 w:0)
-	/// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen)
-	/// Storage: System Account (r:1 w:1)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
+	/// Storage: `Nis::Summary` (r:1 w:0)
+	/// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
 	fn fund_deficit() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `225`
 		//  Estimated: `3593`
-		// Minimum execution time: 38_031_000 picoseconds.
-		Weight::from_parts(38_441_000, 0)
+		// Minimum execution time: 29_989_000 picoseconds.
+		Weight::from_parts(30_865_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
-			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Nis Receipts (r:1 w:1)
-	/// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen)
-	/// Storage: Balances Holds (r:1 w:1)
-	/// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen)
-	/// Storage: System Account (r:1 w:1)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
-	/// Storage: Nis Summary (r:1 w:1)
-	/// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen)
-	/// Storage: NisCounterpartBalances TotalIssuance (r:1 w:1)
-	/// Proof: NisCounterpartBalances TotalIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen)
-	/// Storage: NisCounterpartBalances Account (r:1 w:1)
-	/// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen)
+	/// Storage: `Nis::Receipts` (r:1 w:1)
+	/// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Holds` (r:1 w:1)
+	/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `Nis::Summary` (r:1 w:1)
+	/// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`)
+	/// Storage: `NisCounterpartBalances::Account` (r:1 w:1)
+	/// Proof: `NisCounterpartBalances::Account` (`max_values`: None, `max_size`: Some(112), added: 2587, mode: `MaxEncodedLen`)
 	fn communify() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `469`
+		//  Measured:  `387`
 		//  Estimated: `3593`
-		// Minimum execution time: 69_269_000 picoseconds.
-		Weight::from_parts(70_000_000, 0)
+		// Minimum execution time: 58_114_000 picoseconds.
+		Weight::from_parts(59_540_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
-			.saturating_add(T::DbWeight::get().reads(6))
-			.saturating_add(T::DbWeight::get().writes(6))
+			.saturating_add(T::DbWeight::get().reads(5))
+			.saturating_add(T::DbWeight::get().writes(5))
 	}
-	/// Storage: Nis Receipts (r:1 w:1)
-	/// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen)
-	/// Storage: Nis Summary (r:1 w:1)
-	/// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen)
-	/// Storage: Balances InactiveIssuance (r:1 w:0)
-	/// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen)
-	/// Storage: System Account (r:1 w:1)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
-	/// Storage: NisCounterpartBalances Account (r:1 w:1)
-	/// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen)
-	/// Storage: NisCounterpartBalances TotalIssuance (r:1 w:1)
-	/// Proof: NisCounterpartBalances TotalIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen)
-	/// Storage: Balances Holds (r:1 w:1)
-	/// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen)
+	/// Storage: `Nis::Receipts` (r:1 w:1)
+	/// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`)
+	/// Storage: `Nis::Summary` (r:1 w:1)
+	/// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `NisCounterpartBalances::Account` (r:1 w:1)
+	/// Proof: `NisCounterpartBalances::Account` (`max_values`: None, `max_size`: Some(112), added: 2587, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Holds` (r:1 w:1)
+	/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`)
 	fn privatize() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `659`
+		//  Measured:  `543`
 		//  Estimated: `3593`
-		// Minimum execution time: 85_763_000 picoseconds.
-		Weight::from_parts(86_707_000, 0)
+		// Minimum execution time: 75_780_000 picoseconds.
+		Weight::from_parts(77_097_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
-			.saturating_add(T::DbWeight::get().reads(7))
-			.saturating_add(T::DbWeight::get().writes(6))
+			.saturating_add(T::DbWeight::get().reads(5))
+			.saturating_add(T::DbWeight::get().writes(5))
 	}
-	/// Storage: Nis Receipts (r:1 w:1)
-	/// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen)
-	/// Storage: Nis Summary (r:1 w:1)
-	/// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen)
-	/// Storage: Balances InactiveIssuance (r:1 w:0)
-	/// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen)
-	/// Storage: System Account (r:1 w:0)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
-	/// Storage: Balances Holds (r:1 w:1)
-	/// Proof: Balances Holds (max_values: None, max_size: Some(67), added: 2542, mode: MaxEncodedLen)
+	/// Storage: `Nis::Receipts` (r:1 w:1)
+	/// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`)
+	/// Storage: `Nis::Summary` (r:1 w:1)
+	/// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:0)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Holds` (r:1 w:1)
+	/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`)
 	fn thaw_private() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `387`
 		//  Estimated: `3593`
-		// Minimum execution time: 47_336_000 picoseconds.
-		Weight::from_parts(47_623_000, 0)
+		// Minimum execution time: 46_133_000 picoseconds.
+		Weight::from_parts(47_250_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
-			.saturating_add(T::DbWeight::get().reads(5))
+			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(3))
 	}
-	/// Storage: Nis Receipts (r:1 w:1)
-	/// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen)
-	/// Storage: Nis Summary (r:1 w:1)
-	/// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen)
-	/// Storage: NisCounterpartBalances Account (r:1 w:1)
-	/// Proof: NisCounterpartBalances Account (max_values: None, max_size: Some(112), added: 2587, mode: MaxEncodedLen)
-	/// Storage: NisCounterpartBalances TotalIssuance (r:1 w:1)
-	/// Proof: NisCounterpartBalances TotalIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen)
-	/// Storage: Balances InactiveIssuance (r:1 w:0)
-	/// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen)
-	/// Storage: System Account (r:1 w:1)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
+	/// Storage: `Nis::Receipts` (r:1 w:1)
+	/// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`)
+	/// Storage: `Nis::Summary` (r:1 w:1)
+	/// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`)
+	/// Storage: `NisCounterpartBalances::Account` (r:1 w:1)
+	/// Proof: `NisCounterpartBalances::Account` (`max_values`: None, `max_size`: Some(112), added: 2587, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
 	fn thaw_communal() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `604`
+		//  Measured:  `488`
 		//  Estimated: `3593`
-		// Minimum execution time: 90_972_000 picoseconds.
-		Weight::from_parts(92_074_000, 0)
+		// Minimum execution time: 77_916_000 picoseconds.
+		Weight::from_parts(79_427_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
-			.saturating_add(T::DbWeight::get().reads(6))
-			.saturating_add(T::DbWeight::get().writes(5))
+			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().writes(4))
 	}
-	/// Storage: Nis Summary (r:1 w:1)
-	/// Proof: Nis Summary (max_values: Some(1), max_size: Some(40), added: 535, mode: MaxEncodedLen)
-	/// Storage: Balances InactiveIssuance (r:1 w:0)
-	/// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen)
-	/// Storage: System Account (r:1 w:0)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
-	/// Storage: Nis QueueTotals (r:1 w:1)
-	/// Proof: Nis QueueTotals (max_values: Some(1), max_size: Some(6002), added: 6497, mode: MaxEncodedLen)
+	/// Storage: `Nis::Summary` (r:1 w:1)
+	/// Proof: `Nis::Summary` (`max_values`: Some(1), `max_size`: Some(40), added: 535, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:0)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `Nis::QueueTotals` (r:1 w:1)
+	/// Proof: `Nis::QueueTotals` (`max_values`: Some(1), `max_size`: Some(6002), added: 6497, mode: `MaxEncodedLen`)
 	fn process_queues() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `6658`
 		//  Estimated: `7487`
-		// Minimum execution time: 21_469_000 picoseconds.
-		Weight::from_parts(21_983_000, 0)
+		// Minimum execution time: 22_992_000 picoseconds.
+		Weight::from_parts(24_112_000, 0)
 			.saturating_add(Weight::from_parts(0, 7487))
-			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
-	/// Storage: Nis Queues (r:1 w:1)
-	/// Proof: Nis Queues (max_values: None, max_size: Some(48022), added: 50497, mode: MaxEncodedLen)
+	/// Storage: `Nis::Queues` (r:1 w:1)
+	/// Proof: `Nis::Queues` (`max_values`: None, `max_size`: Some(48022), added: 50497, mode: `MaxEncodedLen`)
 	fn process_queue() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `76`
 		//  Estimated: `51487`
-		// Minimum execution time: 4_912_000 picoseconds.
-		Weight::from_parts(5_013_000, 0)
+		// Minimum execution time: 3_856_000 picoseconds.
+		Weight::from_parts(4_125_000, 0)
 			.saturating_add(Weight::from_parts(0, 51487))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Nis Receipts (r:0 w:1)
-	/// Proof: Nis Receipts (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen)
+	/// Storage: `Nis::Receipts` (r:0 w:1)
+	/// Proof: `Nis::Receipts` (`max_values`: None, `max_size`: Some(81), added: 2556, mode: `MaxEncodedLen`)
 	fn process_bid() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 7_048_000 picoseconds.
-		Weight::from_parts(7_278_000, 0)
+		// Minimum execution time: 4_344_000 picoseconds.
+		Weight::from_parts(4_545_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
diff --git a/polkadot/runtime/rococo/src/weights/pallet_preimage.rs b/polkadot/runtime/rococo/src/weights/pallet_preimage.rs
index e051ebd5bba..7a2b77b84d8 100644
--- a/polkadot/runtime/rococo/src/weights/pallet_preimage.rs
+++ b/polkadot/runtime/rococo/src/weights/pallet_preimage.rs
@@ -16,11 +16,11 @@
 
 //! Autogenerated weights for `pallet_preimage`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
-//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
 // ./target/production/polkadot
@@ -29,12 +29,15 @@
 // --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
 // --pallet=pallet_preimage
 // --extrinsic=*
 // --execution=wasm
 // --wasm-execution=compiled
-// --header=./file_header.txt
-// --output=./runtime/rococo/src/weights/
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -47,184 +50,219 @@ use core::marker::PhantomData;
 /// Weight functions for `pallet_preimage`.
 pub struct WeightInfo<T>(PhantomData<T>);
 impl<T: frame_system::Config> pallet_preimage::WeightInfo for WeightInfo<T> {
-	fn ensure_updated(n: u32, ) -> Weight {
-		// Proof Size summary in bytes:
-		//  Measured:  `193 + n * (91 ±0)`
-		//  Estimated: `3593 + n * (2566 ±0)`
-		// Minimum execution time: 2_000_000 picoseconds.
-		Weight::from_parts(2_000_000, 3593)
-			// Standard Error: 13_720
-			.saturating_add(Weight::from_parts(17_309_199, 0).saturating_mul(n.into()))
-			.saturating_add(T::DbWeight::get().reads(1_u64))
-			.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into())))
-			.saturating_add(T::DbWeight::get().writes(1_u64))
-			.saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(n.into())))
-			.saturating_add(Weight::from_parts(0, 2566).saturating_mul(n.into()))
-	}
-
-	/// Storage: Preimage StatusFor (r:1 w:1)
-	/// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen)
-	/// Storage: Preimage PreimageFor (r:0 w:1)
-	/// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen)
+	/// Storage: `Preimage::StatusFor` (r:1 w:0)
+	/// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
+	/// Storage: `Preimage::RequestStatusFor` (r:1 w:1)
+	/// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Holds` (r:1 w:1)
+	/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`)
+	/// Storage: `Preimage::PreimageFor` (r:0 w:1)
+	/// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`)
 	/// The range of component `s` is `[0, 4194304]`.
 	fn note_preimage(s: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `215`
-		//  Estimated: `3556`
-		// Minimum execution time: 31_040_000 picoseconds.
-		Weight::from_parts(31_236_000, 0)
-			.saturating_add(Weight::from_parts(0, 3556))
-			// Standard Error: 1
-			.saturating_add(Weight::from_parts(1_974, 0).saturating_mul(s.into()))
-			.saturating_add(T::DbWeight::get().reads(1))
-			.saturating_add(T::DbWeight::get().writes(2))
+		//  Measured:  `114`
+		//  Estimated: `3568`
+		// Minimum execution time: 40_363_000 picoseconds.
+		Weight::from_parts(41_052_000, 0)
+			.saturating_add(Weight::from_parts(0, 3568))
+			// Standard Error: 6
+			.saturating_add(Weight::from_parts(2_298, 0).saturating_mul(s.into()))
+			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().writes(3))
 	}
-	/// Storage: Preimage StatusFor (r:1 w:1)
-	/// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen)
-	/// Storage: Preimage PreimageFor (r:0 w:1)
-	/// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen)
+	/// Storage: `Preimage::StatusFor` (r:1 w:0)
+	/// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
+	/// Storage: `Preimage::RequestStatusFor` (r:1 w:1)
+	/// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
+	/// Storage: `Preimage::PreimageFor` (r:0 w:1)
+	/// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`)
 	/// The range of component `s` is `[0, 4194304]`.
 	fn note_requested_preimage(s: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `178`
 		//  Estimated: `3556`
-		// Minimum execution time: 18_025_000 picoseconds.
-		Weight::from_parts(18_264_000, 0)
+		// Minimum execution time: 14_570_000 picoseconds.
+		Weight::from_parts(14_890_000, 0)
 			.saturating_add(Weight::from_parts(0, 3556))
-			// Standard Error: 1
-			.saturating_add(Weight::from_parts(1_974, 0).saturating_mul(s.into()))
-			.saturating_add(T::DbWeight::get().reads(1))
+			// Standard Error: 2
+			.saturating_add(Weight::from_parts(2_364, 0).saturating_mul(s.into()))
+			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
-	/// Storage: Preimage StatusFor (r:1 w:1)
-	/// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen)
-	/// Storage: Preimage PreimageFor (r:0 w:1)
-	/// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen)
+	/// Storage: `Preimage::StatusFor` (r:1 w:0)
+	/// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
+	/// Storage: `Preimage::RequestStatusFor` (r:1 w:1)
+	/// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
+	/// Storage: `Preimage::PreimageFor` (r:0 w:1)
+	/// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`)
 	/// The range of component `s` is `[0, 4194304]`.
 	fn note_no_deposit_preimage(s: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `178`
 		//  Estimated: `3556`
-		// Minimum execution time: 17_122_000 picoseconds.
-		Weight::from_parts(17_332_000, 0)
+		// Minimum execution time: 13_933_000 picoseconds.
+		Weight::from_parts(14_290_000, 0)
 			.saturating_add(Weight::from_parts(0, 3556))
-			// Standard Error: 1
-			.saturating_add(Weight::from_parts(1_968, 0).saturating_mul(s.into()))
-			.saturating_add(T::DbWeight::get().reads(1))
+			// Standard Error: 2
+			.saturating_add(Weight::from_parts(2_349, 0).saturating_mul(s.into()))
+			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
-	/// Storage: Preimage StatusFor (r:1 w:1)
-	/// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen)
-	/// Storage: Preimage PreimageFor (r:0 w:1)
-	/// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen)
+	/// Storage: `Preimage::StatusFor` (r:1 w:0)
+	/// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
+	/// Storage: `Preimage::RequestStatusFor` (r:1 w:1)
+	/// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Holds` (r:1 w:1)
+	/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`)
+	/// Storage: `Preimage::PreimageFor` (r:0 w:1)
+	/// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`)
 	fn unnote_preimage() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `361`
-		//  Estimated: `3556`
-		// Minimum execution time: 38_218_000 picoseconds.
-		Weight::from_parts(39_841_000, 0)
-			.saturating_add(Weight::from_parts(0, 3556))
-			.saturating_add(T::DbWeight::get().reads(1))
-			.saturating_add(T::DbWeight::get().writes(2))
+		//  Measured:  `315`
+		//  Estimated: `3568`
+		// Minimum execution time: 54_373_000 picoseconds.
+		Weight::from_parts(58_205_000, 0)
+			.saturating_add(Weight::from_parts(0, 3568))
+			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().writes(3))
 	}
-	/// Storage: Preimage StatusFor (r:1 w:1)
-	/// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen)
-	/// Storage: Preimage PreimageFor (r:0 w:1)
-	/// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen)
+	/// Storage: `Preimage::StatusFor` (r:1 w:0)
+	/// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
+	/// Storage: `Preimage::RequestStatusFor` (r:1 w:1)
+	/// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
+	/// Storage: `Preimage::PreimageFor` (r:0 w:1)
+	/// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`)
 	fn unnote_no_deposit_preimage() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `216`
 		//  Estimated: `3556`
-		// Minimum execution time: 23_217_000 picoseconds.
-		Weight::from_parts(24_246_000, 0)
+		// Minimum execution time: 24_267_000 picoseconds.
+		Weight::from_parts(27_063_000, 0)
 			.saturating_add(Weight::from_parts(0, 3556))
-			.saturating_add(T::DbWeight::get().reads(1))
+			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
-	/// Storage: Preimage StatusFor (r:1 w:1)
-	/// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen)
+	/// Storage: `Preimage::StatusFor` (r:1 w:0)
+	/// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
+	/// Storage: `Preimage::RequestStatusFor` (r:1 w:1)
+	/// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
 	fn request_preimage() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `260`
 		//  Estimated: `3556`
-		// Minimum execution time: 21_032_000 picoseconds.
-		Weight::from_parts(21_844_000, 0)
+		// Minimum execution time: 25_569_000 picoseconds.
+		Weight::from_parts(27_895_000, 0)
 			.saturating_add(Weight::from_parts(0, 3556))
-			.saturating_add(T::DbWeight::get().reads(1))
+			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Preimage StatusFor (r:1 w:1)
-	/// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen)
+	/// Storage: `Preimage::StatusFor` (r:1 w:0)
+	/// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
+	/// Storage: `Preimage::RequestStatusFor` (r:1 w:1)
+	/// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
 	fn request_no_deposit_preimage() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `216`
 		//  Estimated: `3556`
-		// Minimum execution time: 13_954_000 picoseconds.
-		Weight::from_parts(14_501_000, 0)
+		// Minimum execution time: 14_182_000 picoseconds.
+		Weight::from_parts(16_098_000, 0)
 			.saturating_add(Weight::from_parts(0, 3556))
-			.saturating_add(T::DbWeight::get().reads(1))
+			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Preimage StatusFor (r:1 w:1)
-	/// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen)
+	/// Storage: `Preimage::StatusFor` (r:1 w:0)
+	/// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
+	/// Storage: `Preimage::RequestStatusFor` (r:1 w:1)
+	/// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
 	fn request_unnoted_preimage() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `114`
 		//  Estimated: `3556`
-		// Minimum execution time: 14_874_000 picoseconds.
-		Weight::from_parts(15_380_000, 0)
+		// Minimum execution time: 14_681_000 picoseconds.
+		Weight::from_parts(15_549_000, 0)
 			.saturating_add(Weight::from_parts(0, 3556))
-			.saturating_add(T::DbWeight::get().reads(1))
+			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Preimage StatusFor (r:1 w:1)
-	/// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen)
+	/// Storage: `Preimage::StatusFor` (r:1 w:0)
+	/// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
+	/// Storage: `Preimage::RequestStatusFor` (r:1 w:1)
+	/// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
 	fn request_requested_preimage() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `178`
 		//  Estimated: `3556`
-		// Minimum execution time: 10_199_000 picoseconds.
-		Weight::from_parts(10_493_000, 0)
+		// Minimum execution time: 9_577_000 picoseconds.
+		Weight::from_parts(10_146_000, 0)
 			.saturating_add(Weight::from_parts(0, 3556))
-			.saturating_add(T::DbWeight::get().reads(1))
+			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Preimage StatusFor (r:1 w:1)
-	/// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen)
-	/// Storage: Preimage PreimageFor (r:0 w:1)
-	/// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: MaxEncodedLen)
+	/// Storage: `Preimage::StatusFor` (r:1 w:0)
+	/// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
+	/// Storage: `Preimage::RequestStatusFor` (r:1 w:1)
+	/// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
+	/// Storage: `Preimage::PreimageFor` (r:0 w:1)
+	/// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `MaxEncodedLen`)
 	fn unrequest_preimage() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `216`
 		//  Estimated: `3556`
-		// Minimum execution time: 21_772_000 picoseconds.
-		Weight::from_parts(22_554_000, 0)
+		// Minimum execution time: 21_003_000 picoseconds.
+		Weight::from_parts(23_549_000, 0)
 			.saturating_add(Weight::from_parts(0, 3556))
-			.saturating_add(T::DbWeight::get().reads(1))
+			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
-	/// Storage: Preimage StatusFor (r:1 w:1)
-	/// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen)
+	/// Storage: `Preimage::StatusFor` (r:1 w:0)
+	/// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
+	/// Storage: `Preimage::RequestStatusFor` (r:1 w:1)
+	/// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
 	fn unrequest_unnoted_preimage() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `178`
 		//  Estimated: `3556`
-		// Minimum execution time: 10_115_000 picoseconds.
-		Weight::from_parts(10_452_000, 0)
+		// Minimum execution time: 9_507_000 picoseconds.
+		Weight::from_parts(10_013_000, 0)
 			.saturating_add(Weight::from_parts(0, 3556))
-			.saturating_add(T::DbWeight::get().reads(1))
+			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Preimage StatusFor (r:1 w:1)
-	/// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen)
+	/// Storage: `Preimage::StatusFor` (r:1 w:0)
+	/// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
+	/// Storage: `Preimage::RequestStatusFor` (r:1 w:1)
+	/// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
 	fn unrequest_multi_referenced_preimage() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `178`
 		//  Estimated: `3556`
-		// Minimum execution time: 10_031_000 picoseconds.
-		Weight::from_parts(10_310_000, 0)
+		// Minimum execution time: 9_293_000 picoseconds.
+		Weight::from_parts(10_055_000, 0)
 			.saturating_add(Weight::from_parts(0, 3556))
-			.saturating_add(T::DbWeight::get().reads(1))
+			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
+	/// Storage: `Preimage::StatusFor` (r:1023 w:1023)
+	/// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1023 w:1023)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Holds` (r:1023 w:1023)
+	/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`)
+	/// Storage: `Preimage::RequestStatusFor` (r:0 w:1023)
+	/// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
+	/// The range of component `n` is `[1, 1024]`.
+	fn ensure_updated(n: u32, ) -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0 + n * (227 ±0)`
+		//  Estimated: `990 + n * (2603 ±0)`
+		// Minimum execution time: 48_846_000 picoseconds.
+		Weight::from_parts(49_378_000, 0)
+			.saturating_add(Weight::from_parts(0, 990))
+			// Standard Error: 38_493
+			.saturating_add(Weight::from_parts(47_418_285, 0).saturating_mul(n.into()))
+			.saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(n.into())))
+			.saturating_add(T::DbWeight::get().writes((4_u64).saturating_mul(n.into())))
+			.saturating_add(Weight::from_parts(0, 2603).saturating_mul(n.into()))
+	}
 }
diff --git a/polkadot/runtime/rococo/src/weights/pallet_proxy.rs b/polkadot/runtime/rococo/src/weights/pallet_proxy.rs
index d9737a85c05..c9202593095 100644
--- a/polkadot/runtime/rococo/src/weights/pallet_proxy.rs
+++ b/polkadot/runtime/rococo/src/weights/pallet_proxy.rs
@@ -16,11 +16,11 @@
 
 //! Autogenerated weights for `pallet_proxy`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
-//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
 // ./target/production/polkadot
@@ -29,12 +29,15 @@
 // --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
 // --pallet=pallet_proxy
 // --extrinsic=*
 // --execution=wasm
 // --wasm-execution=compiled
-// --header=./file_header.txt
-// --output=./runtime/rococo/src/weights/
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -47,172 +50,176 @@ use core::marker::PhantomData;
 /// Weight functions for `pallet_proxy`.
 pub struct WeightInfo<T>(PhantomData<T>);
 impl<T: frame_system::Config> pallet_proxy::WeightInfo for WeightInfo<T> {
-	/// Storage: Proxy Proxies (r:1 w:0)
-	/// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen)
+	/// Storage: `Proxy::Proxies` (r:1 w:0)
+	/// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`)
 	/// The range of component `p` is `[1, 31]`.
 	fn proxy(p: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `227 + p * (37 ±0)`
+		//  Measured:  `89 + p * (37 ±0)`
 		//  Estimated: `4706`
-		// Minimum execution time: 15_956_000 picoseconds.
-		Weight::from_parts(16_300_358, 0)
+		// Minimum execution time: 11_267_000 picoseconds.
+		Weight::from_parts(11_798_007, 0)
 			.saturating_add(Weight::from_parts(0, 4706))
-			// Standard Error: 652
-			.saturating_add(Weight::from_parts(30_807, 0).saturating_mul(p.into()))
+			// Standard Error: 858
+			.saturating_add(Weight::from_parts(43_735, 0).saturating_mul(p.into()))
 			.saturating_add(T::DbWeight::get().reads(1))
 	}
-	/// Storage: Proxy Proxies (r:1 w:0)
-	/// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen)
-	/// Storage: Proxy Announcements (r:1 w:1)
-	/// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen)
-	/// Storage: System Account (r:1 w:1)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
+	/// Storage: `Proxy::Proxies` (r:1 w:0)
+	/// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`)
+	/// Storage: `Proxy::Announcements` (r:1 w:1)
+	/// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
 	/// The range of component `a` is `[0, 31]`.
 	/// The range of component `p` is `[1, 31]`.
 	fn proxy_announced(a: u32, p: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `554 + a * (68 ±0) + p * (37 ±0)`
+		//  Measured:  `416 + a * (68 ±0) + p * (37 ±0)`
 		//  Estimated: `5698`
-		// Minimum execution time: 37_584_000 picoseconds.
-		Weight::from_parts(37_858_207, 0)
+		// Minimum execution time: 32_791_000 picoseconds.
+		Weight::from_parts(32_776_904, 0)
 			.saturating_add(Weight::from_parts(0, 5698))
-			// Standard Error: 1_868
-			.saturating_add(Weight::from_parts(148_967, 0).saturating_mul(a.into()))
-			// Standard Error: 1_930
-			.saturating_add(Weight::from_parts(13_017, 0).saturating_mul(p.into()))
+			// Standard Error: 2_382
+			.saturating_add(Weight::from_parts(143_857, 0).saturating_mul(a.into()))
+			// Standard Error: 2_461
+			.saturating_add(Weight::from_parts(40_024, 0).saturating_mul(p.into()))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
-	/// Storage: Proxy Announcements (r:1 w:1)
-	/// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen)
-	/// Storage: System Account (r:1 w:1)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
+	/// Storage: `Proxy::Announcements` (r:1 w:1)
+	/// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
 	/// The range of component `a` is `[0, 31]`.
 	/// The range of component `p` is `[1, 31]`.
-	fn remove_announcement(a: u32, _p: u32, ) -> Weight {
+	fn remove_announcement(a: u32, p: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `469 + a * (68 ±0)`
+		//  Measured:  `331 + a * (68 ±0)`
 		//  Estimated: `5698`
-		// Minimum execution time: 24_642_000 picoseconds.
-		Weight::from_parts(25_526_588, 0)
+		// Minimum execution time: 21_831_000 picoseconds.
+		Weight::from_parts(22_479_938, 0)
 			.saturating_add(Weight::from_parts(0, 5698))
-			// Standard Error: 1_138
-			.saturating_add(Weight::from_parts(131_157, 0).saturating_mul(a.into()))
+			// Standard Error: 1_738
+			.saturating_add(Weight::from_parts(146_532, 0).saturating_mul(a.into()))
+			// Standard Error: 1_796
+			.saturating_add(Weight::from_parts(7_499, 0).saturating_mul(p.into()))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
-	/// Storage: Proxy Announcements (r:1 w:1)
-	/// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen)
-	/// Storage: System Account (r:1 w:1)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
+	/// Storage: `Proxy::Announcements` (r:1 w:1)
+	/// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
 	/// The range of component `a` is `[0, 31]`.
 	/// The range of component `p` is `[1, 31]`.
-	fn reject_announcement(a: u32, _p: u32, ) -> Weight {
+	fn reject_announcement(a: u32, p: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `469 + a * (68 ±0)`
+		//  Measured:  `331 + a * (68 ±0)`
 		//  Estimated: `5698`
-		// Minimum execution time: 24_377_000 picoseconds.
-		Weight::from_parts(25_464_033, 0)
+		// Minimum execution time: 21_776_000 picoseconds.
+		Weight::from_parts(22_762_843, 0)
 			.saturating_add(Weight::from_parts(0, 5698))
-			// Standard Error: 1_116
-			.saturating_add(Weight::from_parts(130_722, 0).saturating_mul(a.into()))
+			// Standard Error: 1_402
+			.saturating_add(Weight::from_parts(137_512, 0).saturating_mul(a.into()))
+			// Standard Error: 1_449
+			.saturating_add(Weight::from_parts(3_645, 0).saturating_mul(p.into()))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
-	/// Storage: Proxy Proxies (r:1 w:0)
-	/// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen)
-	/// Storage: Proxy Announcements (r:1 w:1)
-	/// Proof: Proxy Announcements (max_values: None, max_size: Some(2233), added: 4708, mode: MaxEncodedLen)
-	/// Storage: System Account (r:1 w:1)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
+	/// Storage: `Proxy::Proxies` (r:1 w:0)
+	/// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`)
+	/// Storage: `Proxy::Announcements` (r:1 w:1)
+	/// Proof: `Proxy::Announcements` (`max_values`: None, `max_size`: Some(2233), added: 4708, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
 	/// The range of component `a` is `[0, 31]`.
 	/// The range of component `p` is `[1, 31]`.
 	fn announce(a: u32, p: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `486 + a * (68 ±0) + p * (37 ±0)`
+		//  Measured:  `348 + a * (68 ±0) + p * (37 ±0)`
 		//  Estimated: `5698`
-		// Minimum execution time: 34_202_000 picoseconds.
-		Weight::from_parts(34_610_079, 0)
+		// Minimum execution time: 29_108_000 picoseconds.
+		Weight::from_parts(29_508_910, 0)
 			.saturating_add(Weight::from_parts(0, 5698))
-			// Standard Error: 1_234
-			.saturating_add(Weight::from_parts(134_197, 0).saturating_mul(a.into()))
-			// Standard Error: 1_275
-			.saturating_add(Weight::from_parts(15_970, 0).saturating_mul(p.into()))
+			// Standard Error: 2_268
+			.saturating_add(Weight::from_parts(144_770, 0).saturating_mul(a.into()))
+			// Standard Error: 2_343
+			.saturating_add(Weight::from_parts(25_851, 0).saturating_mul(p.into()))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
-	/// Storage: Proxy Proxies (r:1 w:1)
-	/// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen)
+	/// Storage: `Proxy::Proxies` (r:1 w:1)
+	/// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`)
 	/// The range of component `p` is `[1, 31]`.
 	fn add_proxy(p: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `227 + p * (37 ±0)`
+		//  Measured:  `89 + p * (37 ±0)`
 		//  Estimated: `4706`
-		// Minimum execution time: 25_492_000 picoseconds.
-		Weight::from_parts(25_984_867, 0)
+		// Minimum execution time: 18_942_000 picoseconds.
+		Weight::from_parts(19_518_812, 0)
 			.saturating_add(Weight::from_parts(0, 4706))
-			// Standard Error: 893
-			.saturating_add(Weight::from_parts(51_868, 0).saturating_mul(p.into()))
+			// Standard Error: 1_078
+			.saturating_add(Weight::from_parts(46_147, 0).saturating_mul(p.into()))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Proxy Proxies (r:1 w:1)
-	/// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen)
+	/// Storage: `Proxy::Proxies` (r:1 w:1)
+	/// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`)
 	/// The range of component `p` is `[1, 31]`.
 	fn remove_proxy(p: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `227 + p * (37 ±0)`
+		//  Measured:  `89 + p * (37 ±0)`
 		//  Estimated: `4706`
-		// Minimum execution time: 25_492_000 picoseconds.
-		Weight::from_parts(26_283_445, 0)
+		// Minimum execution time: 18_993_000 picoseconds.
+		Weight::from_parts(19_871_741, 0)
 			.saturating_add(Weight::from_parts(0, 4706))
-			// Standard Error: 1_442
-			.saturating_add(Weight::from_parts(53_504, 0).saturating_mul(p.into()))
+			// Standard Error: 1_883
+			.saturating_add(Weight::from_parts(46_033, 0).saturating_mul(p.into()))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Proxy Proxies (r:1 w:1)
-	/// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen)
+	/// Storage: `Proxy::Proxies` (r:1 w:1)
+	/// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`)
 	/// The range of component `p` is `[1, 31]`.
 	fn remove_proxies(p: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `227 + p * (37 ±0)`
+		//  Measured:  `89 + p * (37 ±0)`
 		//  Estimated: `4706`
-		// Minimum execution time: 22_083_000 picoseconds.
-		Weight::from_parts(22_688_835, 0)
+		// Minimum execution time: 17_849_000 picoseconds.
+		Weight::from_parts(18_776_170, 0)
 			.saturating_add(Weight::from_parts(0, 4706))
-			// Standard Error: 994
-			.saturating_add(Weight::from_parts(32_994, 0).saturating_mul(p.into()))
+			// Standard Error: 1_239
+			.saturating_add(Weight::from_parts(27_960, 0).saturating_mul(p.into()))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Proxy Proxies (r:1 w:1)
-	/// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen)
+	/// Storage: `Proxy::Proxies` (r:1 w:1)
+	/// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`)
 	/// The range of component `p` is `[1, 31]`.
 	fn create_pure(p: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `239`
+		//  Measured:  `101`
 		//  Estimated: `4706`
-		// Minimum execution time: 27_042_000 picoseconds.
-		Weight::from_parts(27_624_587, 0)
+		// Minimum execution time: 20_049_000 picoseconds.
+		Weight::from_parts(20_881_515, 0)
 			.saturating_add(Weight::from_parts(0, 4706))
-			// Standard Error: 671
-			.saturating_add(Weight::from_parts(5_888, 0).saturating_mul(p.into()))
+			// Standard Error: 952
+			.saturating_add(Weight::from_parts(5_970, 0).saturating_mul(p.into()))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Proxy Proxies (r:1 w:1)
-	/// Proof: Proxy Proxies (max_values: None, max_size: Some(1241), added: 3716, mode: MaxEncodedLen)
+	/// Storage: `Proxy::Proxies` (r:1 w:1)
+	/// Proof: `Proxy::Proxies` (`max_values`: None, `max_size`: Some(1241), added: 3716, mode: `MaxEncodedLen`)
 	/// The range of component `p` is `[0, 30]`.
 	fn kill_pure(p: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `264 + p * (37 ±0)`
+		//  Measured:  `126 + p * (37 ±0)`
 		//  Estimated: `4706`
-		// Minimum execution time: 23_396_000 picoseconds.
-		Weight::from_parts(24_003_080, 0)
+		// Minimum execution time: 18_528_000 picoseconds.
+		Weight::from_parts(19_384_189, 0)
 			.saturating_add(Weight::from_parts(0, 4706))
-			// Standard Error: 684
-			.saturating_add(Weight::from_parts(29_878, 0).saturating_mul(p.into()))
+			// Standard Error: 1_106
+			.saturating_add(Weight::from_parts(35_698, 0).saturating_mul(p.into()))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
diff --git a/polkadot/runtime/rococo/src/weights/pallet_ranked_collective.rs b/polkadot/runtime/rococo/src/weights/pallet_ranked_collective.rs
index ce9d5fcc0c7..fa2decb1671 100644
--- a/polkadot/runtime/rococo/src/weights/pallet_ranked_collective.rs
+++ b/polkadot/runtime/rococo/src/weights/pallet_ranked_collective.rs
@@ -16,24 +16,26 @@
 
 //! Autogenerated weights for `pallet_ranked_collective`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2024-01-24, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `runner-grjcggob-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
-// target/production/polkadot
+// ./target/production/polkadot
 // benchmark
 // pallet
+// --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --pallet=pallet_ranked_collective
 // --extrinsic=*
+// --execution=wasm
 // --wasm-execution=compiled
-// --heap-pages=4096
-// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json
-// --pallet=pallet_ranked_collective
-// --chain=rococo-dev
 // --header=./polkadot/file_header.txt
 // --output=./polkadot/runtime/rococo/src/weights/
 
@@ -60,8 +62,8 @@ impl<T: frame_system::Config> pallet_ranked_collective::WeightInfo for WeightInf
 		// Proof Size summary in bytes:
 		//  Measured:  `42`
 		//  Estimated: `3507`
-		// Minimum execution time: 13_480_000 picoseconds.
-		Weight::from_parts(13_786_000, 0)
+		// Minimum execution time: 13_428_000 picoseconds.
+		Weight::from_parts(14_019_000, 0)
 			.saturating_add(Weight::from_parts(0, 3507))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(4))
@@ -79,11 +81,11 @@ impl<T: frame_system::Config> pallet_ranked_collective::WeightInfo for WeightInf
 		// Proof Size summary in bytes:
 		//  Measured:  `516 + r * (281 ±0)`
 		//  Estimated: `3519 + r * (2529 ±0)`
-		// Minimum execution time: 28_771_000 picoseconds.
-		Weight::from_parts(29_256_825, 0)
+		// Minimum execution time: 28_566_000 picoseconds.
+		Weight::from_parts(29_346_952, 0)
 			.saturating_add(Weight::from_parts(0, 3519))
-			// Standard Error: 21_594
-			.saturating_add(Weight::from_parts(14_649_527, 0).saturating_mul(r.into()))
+			// Standard Error: 21_068
+			.saturating_add(Weight::from_parts(14_471_237, 0).saturating_mul(r.into()))
 			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(r.into())))
 			.saturating_add(T::DbWeight::get().writes(6))
@@ -103,11 +105,11 @@ impl<T: frame_system::Config> pallet_ranked_collective::WeightInfo for WeightInf
 		// Proof Size summary in bytes:
 		//  Measured:  `214 + r * (17 ±0)`
 		//  Estimated: `3507`
-		// Minimum execution time: 16_117_000 picoseconds.
-		Weight::from_parts(16_978_453, 0)
+		// Minimum execution time: 16_161_000 picoseconds.
+		Weight::from_parts(16_981_334, 0)
 			.saturating_add(Weight::from_parts(0, 3507))
-			// Standard Error: 4_511
-			.saturating_add(Weight::from_parts(324_261, 0).saturating_mul(r.into()))
+			// Standard Error: 4_596
+			.saturating_add(Weight::from_parts(313_386, 0).saturating_mul(r.into()))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(4))
 	}
@@ -124,11 +126,11 @@ impl<T: frame_system::Config> pallet_ranked_collective::WeightInfo for WeightInf
 		// Proof Size summary in bytes:
 		//  Measured:  `532 + r * (72 ±0)`
 		//  Estimated: `3519`
-		// Minimum execution time: 28_995_000 picoseconds.
-		Weight::from_parts(31_343_215, 0)
+		// Minimum execution time: 28_406_000 picoseconds.
+		Weight::from_parts(31_178_557, 0)
 			.saturating_add(Weight::from_parts(0, 3519))
-			// Standard Error: 16_438
-			.saturating_add(Weight::from_parts(637_462, 0).saturating_mul(r.into()))
+			// Standard Error: 17_737
+			.saturating_add(Weight::from_parts(627_757, 0).saturating_mul(r.into()))
 			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(6))
 	}
@@ -140,15 +142,17 @@ impl<T: frame_system::Config> pallet_ranked_collective::WeightInfo for WeightInf
 	/// Proof: `FellowshipCollective::Voting` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Agenda` (r:2 w:2)
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
+	/// Storage: `Scheduler::Retries` (r:0 w:1)
+	/// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
 	fn vote() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `603`
 		//  Estimated: `83866`
-		// Minimum execution time: 38_820_000 picoseconds.
-		Weight::from_parts(40_240_000, 0)
+		// Minimum execution time: 41_164_000 picoseconds.
+		Weight::from_parts(42_163_000, 0)
 			.saturating_add(Weight::from_parts(0, 83866))
 			.saturating_add(T::DbWeight::get().reads(5))
-			.saturating_add(T::DbWeight::get().writes(4))
+			.saturating_add(T::DbWeight::get().writes(5))
 	}
 	/// Storage: `FellowshipReferenda::ReferendumInfoFor` (r:1 w:0)
 	/// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`)
@@ -161,11 +165,11 @@ impl<T: frame_system::Config> pallet_ranked_collective::WeightInfo for WeightInf
 		// Proof Size summary in bytes:
 		//  Measured:  `400 + n * (50 ±0)`
 		//  Estimated: `4365 + n * (2540 ±0)`
-		// Minimum execution time: 12_972_000 picoseconds.
-		Weight::from_parts(15_829_333, 0)
+		// Minimum execution time: 13_183_000 picoseconds.
+		Weight::from_parts(15_604_064, 0)
 			.saturating_add(Weight::from_parts(0, 4365))
-			// Standard Error: 1_754
-			.saturating_add(Weight::from_parts(1_116_520, 0).saturating_mul(n.into()))
+			// Standard Error: 2_018
+			.saturating_add(Weight::from_parts(1_101_088, 0).saturating_mul(n.into()))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into())))
 			.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into())))
@@ -183,8 +187,8 @@ impl<T: frame_system::Config> pallet_ranked_collective::WeightInfo for WeightInf
 		// Proof Size summary in bytes:
 		//  Measured:  `337`
 		//  Estimated: `6048`
-		// Minimum execution time: 44_601_000 picoseconds.
-		Weight::from_parts(45_714_000, 0)
+		// Minimum execution time: 43_603_000 picoseconds.
+		Weight::from_parts(44_809_000, 0)
 			.saturating_add(Weight::from_parts(0, 6048))
 			.saturating_add(T::DbWeight::get().reads(6))
 			.saturating_add(T::DbWeight::get().writes(10))
diff --git a/polkadot/runtime/rococo/src/weights/pallet_recovery.rs b/polkadot/runtime/rococo/src/weights/pallet_recovery.rs
new file mode 100644
index 00000000000..ed79aa2b1f1
--- /dev/null
+++ b/polkadot/runtime/rococo/src/weights/pallet_recovery.rs
@@ -0,0 +1,186 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Polkadot.
+
+// Polkadot is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Polkadot is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `pallet_recovery`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/production/polkadot
+// benchmark
+// pallet
+// --chain=rococo-dev
+// --steps=50
+// --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --pallet=pallet_recovery
+// --extrinsic=*
+// --execution=wasm
+// --wasm-execution=compiled
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `pallet_recovery`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> pallet_recovery::WeightInfo for WeightInfo<T> {
+	/// Storage: `Recovery::Proxy` (r:1 w:0)
+	/// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`)
+	fn as_recovered() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `215`
+		//  Estimated: `3545`
+		// Minimum execution time: 7_899_000 picoseconds.
+		Weight::from_parts(8_205_000, 0)
+			.saturating_add(Weight::from_parts(0, 3545))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	/// Storage: `Recovery::Proxy` (r:0 w:1)
+	/// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`)
+	fn set_recovered() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 6_258_000 picoseconds.
+		Weight::from_parts(6_494_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+	/// Storage: `Recovery::Recoverable` (r:1 w:1)
+	/// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`)
+	/// The range of component `n` is `[1, 9]`.
+	fn create_recovery(n: u32, ) -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `109`
+		//  Estimated: `3816`
+		// Minimum execution time: 19_369_000 picoseconds.
+		Weight::from_parts(20_185_132, 0)
+			.saturating_add(Weight::from_parts(0, 3816))
+			// Standard Error: 4_275
+			.saturating_add(Weight::from_parts(78_024, 0).saturating_mul(n.into()))
+			.saturating_add(T::DbWeight::get().reads(1))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+	/// Storage: `Recovery::Recoverable` (r:1 w:0)
+	/// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`)
+	/// Storage: `Recovery::ActiveRecoveries` (r:1 w:1)
+	/// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`)
+	fn initiate_recovery() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `206`
+		//  Estimated: `3854`
+		// Minimum execution time: 22_425_000 picoseconds.
+		Weight::from_parts(23_171_000, 0)
+			.saturating_add(Weight::from_parts(0, 3854))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+	/// Storage: `Recovery::Recoverable` (r:1 w:0)
+	/// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`)
+	/// Storage: `Recovery::ActiveRecoveries` (r:1 w:1)
+	/// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`)
+	/// The range of component `n` is `[1, 9]`.
+	fn vouch_recovery(n: u32, ) -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `294 + n * (64 ±0)`
+		//  Estimated: `3854`
+		// Minimum execution time: 17_308_000 picoseconds.
+		Weight::from_parts(18_118_782, 0)
+			.saturating_add(Weight::from_parts(0, 3854))
+			// Standard Error: 4_309
+			.saturating_add(Weight::from_parts(126_278, 0).saturating_mul(n.into()))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+	/// Storage: `Recovery::Recoverable` (r:1 w:0)
+	/// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`)
+	/// Storage: `Recovery::ActiveRecoveries` (r:1 w:0)
+	/// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`)
+	/// Storage: `Recovery::Proxy` (r:1 w:1)
+	/// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`)
+	/// The range of component `n` is `[1, 9]`.
+	fn claim_recovery(n: u32, ) -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `326 + n * (64 ±0)`
+		//  Estimated: `3854`
+		// Minimum execution time: 20_755_000 picoseconds.
+		Weight::from_parts(21_821_713, 0)
+			.saturating_add(Weight::from_parts(0, 3854))
+			// Standard Error: 4_550
+			.saturating_add(Weight::from_parts(101_916, 0).saturating_mul(n.into()))
+			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+	/// Storage: `Recovery::ActiveRecoveries` (r:1 w:1)
+	/// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// The range of component `n` is `[1, 9]`.
+	fn close_recovery(n: u32, ) -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `447 + n * (32 ±0)`
+		//  Estimated: `3854`
+		// Minimum execution time: 29_957_000 picoseconds.
+		Weight::from_parts(31_010_309, 0)
+			.saturating_add(Weight::from_parts(0, 3854))
+			// Standard Error: 5_913
+			.saturating_add(Weight::from_parts(110_070, 0).saturating_mul(n.into()))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+	/// Storage: `Recovery::ActiveRecoveries` (r:1 w:0)
+	/// Proof: `Recovery::ActiveRecoveries` (`max_values`: None, `max_size`: Some(389), added: 2864, mode: `MaxEncodedLen`)
+	/// Storage: `Recovery::Recoverable` (r:1 w:1)
+	/// Proof: `Recovery::Recoverable` (`max_values`: None, `max_size`: Some(351), added: 2826, mode: `MaxEncodedLen`)
+	/// The range of component `n` is `[1, 9]`.
+	fn remove_recovery(n: u32, ) -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `204 + n * (32 ±0)`
+		//  Estimated: `3854`
+		// Minimum execution time: 24_430_000 picoseconds.
+		Weight::from_parts(24_462_856, 0)
+			.saturating_add(Weight::from_parts(0, 3854))
+			// Standard Error: 13_646
+			.saturating_add(Weight::from_parts(507_715, 0).saturating_mul(n.into()))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+	/// Storage: `Recovery::Proxy` (r:1 w:1)
+	/// Proof: `Recovery::Proxy` (`max_values`: None, `max_size`: Some(80), added: 2555, mode: `MaxEncodedLen`)
+	fn cancel_recovered() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `215`
+		//  Estimated: `3545`
+		// Minimum execution time: 9_686_000 picoseconds.
+		Weight::from_parts(10_071_000, 0)
+			.saturating_add(Weight::from_parts(0, 3545))
+			.saturating_add(T::DbWeight::get().reads(1))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+}
diff --git a/polkadot/runtime/rococo/src/weights/pallet_referenda_fellowship_referenda.rs b/polkadot/runtime/rococo/src/weights/pallet_referenda_fellowship_referenda.rs
index 96f172230e1..6dfcea2b832 100644
--- a/polkadot/runtime/rococo/src/weights/pallet_referenda_fellowship_referenda.rs
+++ b/polkadot/runtime/rococo/src/weights/pallet_referenda_fellowship_referenda.rs
@@ -16,27 +16,28 @@
 
 //! Autogenerated weights for `pallet_referenda`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-07-11, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `runner-xerhrdyb-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
-//! EXECUTION: `Some(Wasm)`, WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
-// target/production/polkadot
+// ./target/production/polkadot
 // benchmark
 // pallet
+// --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --pallet=pallet_referenda
 // --extrinsic=*
 // --execution=wasm
 // --wasm-execution=compiled
-// --heap-pages=4096
-// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json
-// --pallet=pallet_referenda
-// --chain=rococo-dev
-// --header=./file_header.txt
-// --output=./runtime/rococo/src/weights/
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -59,10 +60,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`)
 	fn submit() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `327`
+		//  Measured:  `292`
 		//  Estimated: `42428`
-		// Minimum execution time: 29_909_000 picoseconds.
-		Weight::from_parts(30_645_000, 0)
+		// Minimum execution time: 24_053_000 picoseconds.
+		Weight::from_parts(25_121_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(3))
@@ -71,15 +72,17 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Agenda` (r:2 w:2)
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
+	/// Storage: `Scheduler::Retries` (r:0 w:1)
+	/// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
 	fn place_decision_deposit_preparing() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `438`
+		//  Measured:  `403`
 		//  Estimated: `83866`
-		// Minimum execution time: 54_405_000 picoseconds.
-		Weight::from_parts(55_583_000, 0)
+		// Minimum execution time: 45_064_000 picoseconds.
+		Weight::from_parts(46_112_000, 0)
 			.saturating_add(Weight::from_parts(0, 83866))
 			.saturating_add(T::DbWeight::get().reads(3))
-			.saturating_add(T::DbWeight::get().writes(3))
+			.saturating_add(T::DbWeight::get().writes(4))
 	}
 	/// Storage: `FellowshipReferenda::ReferendumInfoFor` (r:1 w:1)
 	/// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`)
@@ -89,15 +92,17 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `FellowshipReferenda::TrackQueue` (`max_values`: None, `max_size`: Some(812), added: 3287, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Agenda` (r:1 w:1)
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
+	/// Storage: `Scheduler::Retries` (r:0 w:1)
+	/// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
 	fn place_decision_deposit_queued() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `2076`
+		//  Measured:  `2041`
 		//  Estimated: `42428`
-		// Minimum execution time: 110_477_000 picoseconds.
-		Weight::from_parts(119_187_000, 0)
+		// Minimum execution time: 94_146_000 picoseconds.
+		Weight::from_parts(98_587_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
 			.saturating_add(T::DbWeight::get().reads(4))
-			.saturating_add(T::DbWeight::get().writes(3))
+			.saturating_add(T::DbWeight::get().writes(4))
 	}
 	/// Storage: `FellowshipReferenda::ReferendumInfoFor` (r:1 w:1)
 	/// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`)
@@ -107,15 +112,17 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `FellowshipReferenda::TrackQueue` (`max_values`: None, `max_size`: Some(812), added: 3287, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Agenda` (r:1 w:1)
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
+	/// Storage: `Scheduler::Retries` (r:0 w:1)
+	/// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
 	fn place_decision_deposit_not_queued() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `2117`
+		//  Measured:  `2082`
 		//  Estimated: `42428`
-		// Minimum execution time: 111_467_000 picoseconds.
-		Weight::from_parts(117_758_000, 0)
+		// Minimum execution time: 93_002_000 picoseconds.
+		Weight::from_parts(96_924_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
 			.saturating_add(T::DbWeight::get().reads(4))
-			.saturating_add(T::DbWeight::get().writes(3))
+			.saturating_add(T::DbWeight::get().writes(4))
 	}
 	/// Storage: `FellowshipReferenda::ReferendumInfoFor` (r:1 w:1)
 	/// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`)
@@ -125,15 +132,17 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `FellowshipCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Agenda` (r:2 w:2)
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
+	/// Storage: `Scheduler::Retries` (r:0 w:1)
+	/// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
 	fn place_decision_deposit_passing() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `774`
+		//  Measured:  `739`
 		//  Estimated: `83866`
-		// Minimum execution time: 191_135_000 picoseconds.
-		Weight::from_parts(210_535_000, 0)
+		// Minimum execution time: 160_918_000 picoseconds.
+		Weight::from_parts(175_603_000, 0)
 			.saturating_add(Weight::from_parts(0, 83866))
 			.saturating_add(T::DbWeight::get().reads(5))
-			.saturating_add(T::DbWeight::get().writes(4))
+			.saturating_add(T::DbWeight::get().writes(5))
 	}
 	/// Storage: `FellowshipReferenda::ReferendumInfoFor` (r:1 w:1)
 	/// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`)
@@ -143,24 +152,26 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `FellowshipCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Agenda` (r:2 w:2)
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
+	/// Storage: `Scheduler::Retries` (r:0 w:1)
+	/// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
 	fn place_decision_deposit_failing() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `639`
+		//  Measured:  `604`
 		//  Estimated: `83866`
-		// Minimum execution time: 67_168_000 picoseconds.
-		Weight::from_parts(68_895_000, 0)
+		// Minimum execution time: 55_253_000 picoseconds.
+		Weight::from_parts(56_488_000, 0)
 			.saturating_add(Weight::from_parts(0, 83866))
 			.saturating_add(T::DbWeight::get().reads(5))
-			.saturating_add(T::DbWeight::get().writes(4))
+			.saturating_add(T::DbWeight::get().writes(5))
 	}
 	/// Storage: `FellowshipReferenda::ReferendumInfoFor` (r:1 w:1)
 	/// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`)
 	fn refund_decision_deposit() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `351`
+		//  Measured:  `317`
 		//  Estimated: `4365`
-		// Minimum execution time: 31_298_000 picoseconds.
-		Weight::from_parts(32_570_000, 0)
+		// Minimum execution time: 24_497_000 picoseconds.
+		Weight::from_parts(25_280_000, 0)
 			.saturating_add(Weight::from_parts(0, 4365))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -169,10 +180,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`)
 	fn refund_submission_deposit() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `201`
+		//  Measured:  `167`
 		//  Estimated: `4365`
-		// Minimum execution time: 15_674_000 picoseconds.
-		Weight::from_parts(16_190_000, 0)
+		// Minimum execution time: 11_374_000 picoseconds.
+		Weight::from_parts(11_817_000, 0)
 			.saturating_add(Weight::from_parts(0, 4365))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -181,15 +192,17 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Agenda` (r:2 w:2)
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
+	/// Storage: `Scheduler::Retries` (r:0 w:1)
+	/// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
 	fn cancel() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `383`
+		//  Measured:  `348`
 		//  Estimated: `83866`
-		// Minimum execution time: 38_927_000 picoseconds.
-		Weight::from_parts(40_545_000, 0)
+		// Minimum execution time: 31_805_000 picoseconds.
+		Weight::from_parts(32_622_000, 0)
 			.saturating_add(Weight::from_parts(0, 83866))
 			.saturating_add(T::DbWeight::get().reads(3))
-			.saturating_add(T::DbWeight::get().writes(3))
+			.saturating_add(T::DbWeight::get().writes(4))
 	}
 	/// Storage: `FellowshipReferenda::ReferendumInfoFor` (r:1 w:1)
 	/// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`)
@@ -197,15 +210,17 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	/// Storage: `FellowshipReferenda::MetadataOf` (r:1 w:0)
 	/// Proof: `FellowshipReferenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
+	/// Storage: `Scheduler::Retries` (r:0 w:1)
+	/// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
 	fn kill() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `484`
+		//  Measured:  `449`
 		//  Estimated: `83866`
-		// Minimum execution time: 80_209_000 picoseconds.
-		Weight::from_parts(82_084_000, 0)
+		// Minimum execution time: 62_364_000 picoseconds.
+		Weight::from_parts(63_798_000, 0)
 			.saturating_add(Weight::from_parts(0, 83866))
 			.saturating_add(T::DbWeight::get().reads(4))
-			.saturating_add(T::DbWeight::get().writes(3))
+			.saturating_add(T::DbWeight::get().writes(4))
 	}
 	/// Storage: `FellowshipReferenda::TrackQueue` (r:1 w:0)
 	/// Proof: `FellowshipReferenda::TrackQueue` (`max_values`: None, `max_size`: Some(812), added: 3287, mode: `MaxEncodedLen`)
@@ -213,10 +228,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `FellowshipReferenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`)
 	fn one_fewer_deciding_queue_empty() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `174`
+		//  Measured:  `140`
 		//  Estimated: `4277`
-		// Minimum execution time: 9_520_000 picoseconds.
-		Weight::from_parts(10_088_000, 0)
+		// Minimum execution time: 8_811_000 picoseconds.
+		Weight::from_parts(9_224_000, 0)
 			.saturating_add(Weight::from_parts(0, 4277))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -231,10 +246,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	fn one_fewer_deciding_failing() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `2376`
+		//  Measured:  `2341`
 		//  Estimated: `42428`
-		// Minimum execution time: 93_893_000 picoseconds.
-		Weight::from_parts(101_065_000, 0)
+		// Minimum execution time: 83_292_000 picoseconds.
+		Weight::from_parts(89_114_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
 			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(3))
@@ -249,10 +264,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	fn one_fewer_deciding_passing() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `2362`
+		//  Measured:  `2327`
 		//  Estimated: `42428`
-		// Minimum execution time: 98_811_000 picoseconds.
-		Weight::from_parts(103_590_000, 0)
+		// Minimum execution time: 84_648_000 picoseconds.
+		Weight::from_parts(89_332_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
 			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(3))
@@ -263,10 +278,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `FellowshipReferenda::TrackQueue` (`max_values`: None, `max_size`: Some(812), added: 3287, mode: `MaxEncodedLen`)
 	fn nudge_referendum_requeued_insertion() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `1841`
+		//  Measured:  `1807`
 		//  Estimated: `4365`
-		// Minimum execution time: 43_230_000 picoseconds.
-		Weight::from_parts(46_120_000, 0)
+		// Minimum execution time: 40_529_000 picoseconds.
+		Weight::from_parts(45_217_000, 0)
 			.saturating_add(Weight::from_parts(0, 4365))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -277,10 +292,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `FellowshipReferenda::TrackQueue` (`max_values`: None, `max_size`: Some(812), added: 3287, mode: `MaxEncodedLen`)
 	fn nudge_referendum_requeued_slide() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `1808`
+		//  Measured:  `1774`
 		//  Estimated: `4365`
-		// Minimum execution time: 43_092_000 picoseconds.
-		Weight::from_parts(46_018_000, 0)
+		// Minimum execution time: 40_894_000 picoseconds.
+		Weight::from_parts(45_726_000, 0)
 			.saturating_add(Weight::from_parts(0, 4365))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -293,10 +308,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `FellowshipReferenda::TrackQueue` (`max_values`: None, `max_size`: Some(812), added: 3287, mode: `MaxEncodedLen`)
 	fn nudge_referendum_queued() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `1824`
+		//  Measured:  `1790`
 		//  Estimated: `4365`
-		// Minimum execution time: 49_697_000 picoseconds.
-		Weight::from_parts(53_795_000, 0)
+		// Minimum execution time: 48_187_000 picoseconds.
+		Weight::from_parts(52_655_000, 0)
 			.saturating_add(Weight::from_parts(0, 4365))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(2))
@@ -309,10 +324,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `FellowshipReferenda::TrackQueue` (`max_values`: None, `max_size`: Some(812), added: 3287, mode: `MaxEncodedLen`)
 	fn nudge_referendum_not_queued() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `1865`
+		//  Measured:  `1831`
 		//  Estimated: `4365`
-		// Minimum execution time: 50_417_000 picoseconds.
-		Weight::from_parts(53_214_000, 0)
+		// Minimum execution time: 47_548_000 picoseconds.
+		Weight::from_parts(51_547_000, 0)
 			.saturating_add(Weight::from_parts(0, 4365))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(2))
@@ -323,10 +338,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	fn nudge_referendum_no_deposit() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `335`
+		//  Measured:  `300`
 		//  Estimated: `42428`
-		// Minimum execution time: 25_688_000 picoseconds.
-		Weight::from_parts(26_575_000, 0)
+		// Minimum execution time: 20_959_000 picoseconds.
+		Weight::from_parts(21_837_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
@@ -337,10 +352,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	fn nudge_referendum_preparing() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `383`
+		//  Measured:  `348`
 		//  Estimated: `42428`
-		// Minimum execution time: 26_230_000 picoseconds.
-		Weight::from_parts(27_235_000, 0)
+		// Minimum execution time: 21_628_000 picoseconds.
+		Weight::from_parts(22_192_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
@@ -349,10 +364,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`)
 	fn nudge_referendum_timed_out() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `242`
+		//  Measured:  `208`
 		//  Estimated: `4365`
-		// Minimum execution time: 17_585_000 picoseconds.
-		Weight::from_parts(18_225_000, 0)
+		// Minimum execution time: 12_309_000 picoseconds.
+		Weight::from_parts(12_644_000, 0)
 			.saturating_add(Weight::from_parts(0, 4365))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -367,10 +382,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	fn nudge_referendum_begin_deciding_failing() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `584`
+		//  Measured:  `549`
 		//  Estimated: `42428`
-		// Minimum execution time: 38_243_000 picoseconds.
-		Weight::from_parts(39_959_000, 0)
+		// Minimum execution time: 31_871_000 picoseconds.
+		Weight::from_parts(33_123_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
 			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(3))
@@ -385,10 +400,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	fn nudge_referendum_begin_deciding_passing() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `719`
+		//  Measured:  `684`
 		//  Estimated: `42428`
-		// Minimum execution time: 88_424_000 picoseconds.
-		Weight::from_parts(92_969_000, 0)
+		// Minimum execution time: 73_715_000 picoseconds.
+		Weight::from_parts(79_980_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
 			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(3))
@@ -401,10 +416,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	fn nudge_referendum_begin_confirming() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `770`
+		//  Measured:  `735`
 		//  Estimated: `42428`
-		// Minimum execution time: 138_207_000 picoseconds.
-		Weight::from_parts(151_726_000, 0)
+		// Minimum execution time: 128_564_000 picoseconds.
+		Weight::from_parts(138_536_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(2))
@@ -417,10 +432,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	fn nudge_referendum_end_confirming() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `755`
+		//  Measured:  `720`
 		//  Estimated: `42428`
-		// Minimum execution time: 131_001_000 picoseconds.
-		Weight::from_parts(148_651_000, 0)
+		// Minimum execution time: 129_775_000 picoseconds.
+		Weight::from_parts(139_001_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(2))
@@ -433,10 +448,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	fn nudge_referendum_continue_not_confirming() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `770`
+		//  Measured:  `735`
 		//  Estimated: `42428`
-		// Minimum execution time: 109_612_000 picoseconds.
-		Weight::from_parts(143_626_000, 0)
+		// Minimum execution time: 128_233_000 picoseconds.
+		Weight::from_parts(135_796_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(2))
@@ -449,10 +464,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	fn nudge_referendum_continue_confirming() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `776`
+		//  Measured:  `741`
 		//  Estimated: `42428`
-		// Minimum execution time: 71_754_000 picoseconds.
-		Weight::from_parts(77_329_000, 0)
+		// Minimum execution time: 66_995_000 picoseconds.
+		Weight::from_parts(72_678_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(2))
@@ -467,10 +482,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`)
 	fn nudge_referendum_approved() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `776`
+		//  Measured:  `741`
 		//  Estimated: `83866`
-		// Minimum execution time: 153_244_000 picoseconds.
-		Weight::from_parts(169_961_000, 0)
+		// Minimum execution time: 137_764_000 picoseconds.
+		Weight::from_parts(152_260_000, 0)
 			.saturating_add(Weight::from_parts(0, 83866))
 			.saturating_add(T::DbWeight::get().reads(5))
 			.saturating_add(T::DbWeight::get().writes(4))
@@ -483,10 +498,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	fn nudge_referendum_rejected() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `772`
+		//  Measured:  `737`
 		//  Estimated: `42428`
-		// Minimum execution time: 137_997_000 picoseconds.
-		Weight::from_parts(157_862_000, 0)
+		// Minimum execution time: 119_992_000 picoseconds.
+		Weight::from_parts(134_805_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(2))
@@ -495,16 +510,18 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `FellowshipReferenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(900), added: 3375, mode: `MaxEncodedLen`)
 	/// Storage: `Preimage::StatusFor` (r:1 w:0)
 	/// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
+	/// Storage: `Preimage::RequestStatusFor` (r:1 w:0)
+	/// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
 	/// Storage: `FellowshipReferenda::MetadataOf` (r:0 w:1)
 	/// Proof: `FellowshipReferenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
 	fn set_some_metadata() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `458`
+		//  Measured:  `424`
 		//  Estimated: `4365`
-		// Minimum execution time: 21_794_000 picoseconds.
-		Weight::from_parts(22_341_000, 0)
+		// Minimum execution time: 20_927_000 picoseconds.
+		Weight::from_parts(21_802_000, 0)
 			.saturating_add(Weight::from_parts(0, 4365))
-			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
 	/// Storage: `FellowshipReferenda::ReferendumInfoFor` (r:1 w:0)
@@ -513,10 +530,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `FellowshipReferenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
 	fn clear_metadata() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `319`
+		//  Measured:  `285`
 		//  Estimated: `4365`
-		// Minimum execution time: 18_458_000 picoseconds.
-		Weight::from_parts(19_097_000, 0)
+		// Minimum execution time: 14_253_000 picoseconds.
+		Weight::from_parts(15_031_000, 0)
 			.saturating_add(Weight::from_parts(0, 4365))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
diff --git a/polkadot/runtime/rococo/src/weights/pallet_referenda_referenda.rs b/polkadot/runtime/rococo/src/weights/pallet_referenda_referenda.rs
index b7cc5df28b9..c35925198f9 100644
--- a/polkadot/runtime/rococo/src/weights/pallet_referenda_referenda.rs
+++ b/polkadot/runtime/rococo/src/weights/pallet_referenda_referenda.rs
@@ -16,27 +16,28 @@
 
 //! Autogenerated weights for `pallet_referenda`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-07-11, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `runner-xerhrdyb-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
-//! EXECUTION: `Some(Wasm)`, WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
-// target/production/polkadot
+// ./target/production/polkadot
 // benchmark
 // pallet
+// --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --pallet=pallet_referenda
 // --extrinsic=*
 // --execution=wasm
 // --wasm-execution=compiled
-// --heap-pages=4096
-// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json
-// --pallet=pallet_referenda
-// --chain=rococo-dev
-// --header=./file_header.txt
-// --output=./runtime/rococo/src/weights/
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -57,10 +58,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
 	fn submit() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `324`
+		//  Measured:  `185`
 		//  Estimated: `42428`
-		// Minimum execution time: 39_852_000 picoseconds.
-		Weight::from_parts(41_610_000, 0)
+		// Minimum execution time: 28_612_000 picoseconds.
+		Weight::from_parts(30_060_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(3))
@@ -69,15 +70,17 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Agenda` (r:2 w:2)
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
+	/// Storage: `Scheduler::Retries` (r:0 w:1)
+	/// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
 	fn place_decision_deposit_preparing() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `577`
+		//  Measured:  `438`
 		//  Estimated: `83866`
-		// Minimum execution time: 52_588_000 picoseconds.
-		Weight::from_parts(54_154_000, 0)
+		// Minimum execution time: 42_827_000 picoseconds.
+		Weight::from_parts(44_072_000, 0)
 			.saturating_add(Weight::from_parts(0, 83866))
 			.saturating_add(T::DbWeight::get().reads(3))
-			.saturating_add(T::DbWeight::get().writes(3))
+			.saturating_add(T::DbWeight::get().writes(4))
 	}
 	/// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1)
 	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
@@ -87,15 +90,17 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Agenda` (r:1 w:1)
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
+	/// Storage: `Scheduler::Retries` (r:0 w:1)
+	/// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
 	fn place_decision_deposit_queued() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `3334`
+		//  Measured:  `3225`
 		//  Estimated: `42428`
-		// Minimum execution time: 70_483_000 picoseconds.
-		Weight::from_parts(72_731_000, 0)
+		// Minimum execution time: 56_475_000 picoseconds.
+		Weight::from_parts(58_888_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
 			.saturating_add(T::DbWeight::get().reads(4))
-			.saturating_add(T::DbWeight::get().writes(3))
+			.saturating_add(T::DbWeight::get().writes(4))
 	}
 	/// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1)
 	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
@@ -105,60 +110,62 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Agenda` (r:1 w:1)
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
+	/// Storage: `Scheduler::Retries` (r:0 w:1)
+	/// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
 	fn place_decision_deposit_not_queued() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `3354`
+		//  Measured:  `3245`
 		//  Estimated: `42428`
-		// Minimum execution time: 68_099_000 picoseconds.
-		Weight::from_parts(71_560_000, 0)
+		// Minimum execution time: 56_542_000 picoseconds.
+		Weight::from_parts(58_616_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
 			.saturating_add(T::DbWeight::get().reads(4))
-			.saturating_add(T::DbWeight::get().writes(3))
+			.saturating_add(T::DbWeight::get().writes(4))
 	}
 	/// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1)
 	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
 	/// Storage: `Referenda::DecidingCount` (r:1 w:1)
 	/// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`)
-	/// Storage: `Balances::InactiveIssuance` (r:1 w:0)
-	/// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Agenda` (r:2 w:2)
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
+	/// Storage: `Scheduler::Retries` (r:0 w:1)
+	/// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
 	fn place_decision_deposit_passing() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `577`
+		//  Measured:  `438`
 		//  Estimated: `83866`
-		// Minimum execution time: 64_357_000 picoseconds.
-		Weight::from_parts(66_081_000, 0)
+		// Minimum execution time: 51_218_000 picoseconds.
+		Weight::from_parts(53_148_000, 0)
 			.saturating_add(Weight::from_parts(0, 83866))
-			.saturating_add(T::DbWeight::get().reads(5))
-			.saturating_add(T::DbWeight::get().writes(4))
+			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().writes(5))
 	}
 	/// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1)
 	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
 	/// Storage: `Referenda::DecidingCount` (r:1 w:1)
 	/// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`)
-	/// Storage: `Balances::InactiveIssuance` (r:1 w:0)
-	/// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Agenda` (r:2 w:2)
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
+	/// Storage: `Scheduler::Retries` (r:0 w:1)
+	/// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
 	fn place_decision_deposit_failing() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `577`
+		//  Measured:  `438`
 		//  Estimated: `83866`
-		// Minimum execution time: 62_709_000 picoseconds.
-		Weight::from_parts(64_534_000, 0)
+		// Minimum execution time: 49_097_000 picoseconds.
+		Weight::from_parts(50_796_000, 0)
 			.saturating_add(Weight::from_parts(0, 83866))
-			.saturating_add(T::DbWeight::get().reads(5))
-			.saturating_add(T::DbWeight::get().writes(4))
+			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().writes(5))
 	}
 	/// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1)
 	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
 	fn refund_decision_deposit() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `417`
+		//  Measured:  `279`
 		//  Estimated: `4401`
-		// Minimum execution time: 31_296_000 picoseconds.
-		Weight::from_parts(32_221_000, 0)
+		// Minimum execution time: 23_720_000 picoseconds.
+		Weight::from_parts(24_327_000, 0)
 			.saturating_add(Weight::from_parts(0, 4401))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -167,10 +174,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
 	fn refund_submission_deposit() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `407`
+		//  Measured:  `269`
 		//  Estimated: `4401`
-		// Minimum execution time: 31_209_000 picoseconds.
-		Weight::from_parts(32_168_000, 0)
+		// Minimum execution time: 24_089_000 picoseconds.
+		Weight::from_parts(24_556_000, 0)
 			.saturating_add(Weight::from_parts(0, 4401))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -179,15 +186,17 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Agenda` (r:2 w:2)
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
+	/// Storage: `Scheduler::Retries` (r:0 w:1)
+	/// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
 	fn cancel() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `485`
+		//  Measured:  `346`
 		//  Estimated: `83866`
-		// Minimum execution time: 38_887_000 picoseconds.
-		Weight::from_parts(40_193_000, 0)
+		// Minimum execution time: 29_022_000 picoseconds.
+		Weight::from_parts(29_590_000, 0)
 			.saturating_add(Weight::from_parts(0, 83866))
 			.saturating_add(T::DbWeight::get().reads(3))
-			.saturating_add(T::DbWeight::get().writes(3))
+			.saturating_add(T::DbWeight::get().writes(4))
 	}
 	/// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1)
 	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
@@ -195,15 +204,17 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	/// Storage: `Referenda::MetadataOf` (r:1 w:0)
 	/// Proof: `Referenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
+	/// Storage: `Scheduler::Retries` (r:0 w:1)
+	/// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
 	fn kill() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `726`
+		//  Measured:  `587`
 		//  Estimated: `83866`
-		// Minimum execution time: 106_054_000 picoseconds.
-		Weight::from_parts(108_318_000, 0)
+		// Minimum execution time: 81_920_000 picoseconds.
+		Weight::from_parts(84_492_000, 0)
 			.saturating_add(Weight::from_parts(0, 83866))
 			.saturating_add(T::DbWeight::get().reads(4))
-			.saturating_add(T::DbWeight::get().writes(3))
+			.saturating_add(T::DbWeight::get().writes(4))
 	}
 	/// Storage: `Referenda::TrackQueue` (r:1 w:0)
 	/// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`)
@@ -211,10 +222,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`)
 	fn one_fewer_deciding_queue_empty() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `240`
+		//  Measured:  `102`
 		//  Estimated: `5477`
-		// Minimum execution time: 9_263_000 picoseconds.
-		Weight::from_parts(9_763_000, 0)
+		// Minimum execution time: 8_134_000 picoseconds.
+		Weight::from_parts(8_574_000, 0)
 			.saturating_add(Weight::from_parts(0, 5477))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -223,36 +234,32 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`)
 	/// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1)
 	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
-	/// Storage: `Balances::InactiveIssuance` (r:1 w:0)
-	/// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Agenda` (r:1 w:1)
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	fn one_fewer_deciding_failing() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `3254`
+		//  Measured:  `3115`
 		//  Estimated: `42428`
-		// Minimum execution time: 50_080_000 picoseconds.
-		Weight::from_parts(51_858_000, 0)
+		// Minimum execution time: 39_932_000 picoseconds.
+		Weight::from_parts(42_086_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
-			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(3))
 	}
 	/// Storage: `Referenda::TrackQueue` (r:1 w:1)
 	/// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`)
 	/// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1)
 	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
-	/// Storage: `Balances::InactiveIssuance` (r:1 w:0)
-	/// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Agenda` (r:1 w:1)
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	fn one_fewer_deciding_passing() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `3254`
+		//  Measured:  `3115`
 		//  Estimated: `42428`
-		// Minimum execution time: 53_889_000 picoseconds.
-		Weight::from_parts(55_959_000, 0)
+		// Minimum execution time: 42_727_000 picoseconds.
+		Weight::from_parts(44_280_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
-			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(3))
 	}
 	/// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0)
@@ -261,10 +268,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`)
 	fn nudge_referendum_requeued_insertion() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `3077`
+		//  Measured:  `2939`
 		//  Estimated: `5477`
-		// Minimum execution time: 23_266_000 picoseconds.
-		Weight::from_parts(24_624_000, 0)
+		// Minimum execution time: 20_918_000 picoseconds.
+		Weight::from_parts(22_180_000, 0)
 			.saturating_add(Weight::from_parts(0, 5477))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -275,10 +282,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`)
 	fn nudge_referendum_requeued_slide() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `3077`
+		//  Measured:  `2939`
 		//  Estimated: `5477`
-		// Minimum execution time: 22_846_000 picoseconds.
-		Weight::from_parts(24_793_000, 0)
+		// Minimum execution time: 20_943_000 picoseconds.
+		Weight::from_parts(21_932_000, 0)
 			.saturating_add(Weight::from_parts(0, 5477))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -291,10 +298,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`)
 	fn nudge_referendum_queued() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `3081`
+		//  Measured:  `2943`
 		//  Estimated: `5477`
-		// Minimum execution time: 28_284_000 picoseconds.
-		Weight::from_parts(29_940_000, 0)
+		// Minimum execution time: 25_197_000 picoseconds.
+		Weight::from_parts(26_083_000, 0)
 			.saturating_add(Weight::from_parts(0, 5477))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(2))
@@ -307,10 +314,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Referenda::TrackQueue` (`max_values`: None, `max_size`: Some(2012), added: 4487, mode: `MaxEncodedLen`)
 	fn nudge_referendum_not_queued() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `3101`
+		//  Measured:  `2963`
 		//  Estimated: `5477`
-		// Minimum execution time: 28_133_000 picoseconds.
-		Weight::from_parts(29_638_000, 0)
+		// Minimum execution time: 24_969_000 picoseconds.
+		Weight::from_parts(26_096_000, 0)
 			.saturating_add(Weight::from_parts(0, 5477))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(2))
@@ -321,10 +328,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	fn nudge_referendum_no_deposit() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `437`
+		//  Measured:  `298`
 		//  Estimated: `42428`
-		// Minimum execution time: 25_710_000 picoseconds.
-		Weight::from_parts(26_500_000, 0)
+		// Minimum execution time: 18_050_000 picoseconds.
+		Weight::from_parts(18_790_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
@@ -335,10 +342,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	fn nudge_referendum_preparing() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `485`
+		//  Measured:  `346`
 		//  Estimated: `42428`
-		// Minimum execution time: 25_935_000 picoseconds.
-		Weight::from_parts(26_803_000, 0)
+		// Minimum execution time: 18_357_000 picoseconds.
+		Weight::from_parts(18_957_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
@@ -347,10 +354,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
 	fn nudge_referendum_timed_out() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `344`
+		//  Measured:  `206`
 		//  Estimated: `4401`
-		// Minimum execution time: 17_390_000 picoseconds.
-		Weight::from_parts(18_042_000, 0)
+		// Minimum execution time: 11_479_000 picoseconds.
+		Weight::from_parts(11_968_000, 0)
 			.saturating_add(Weight::from_parts(0, 4401))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -359,150 +366,136 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
 	/// Storage: `Referenda::DecidingCount` (r:1 w:1)
 	/// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`)
-	/// Storage: `Balances::InactiveIssuance` (r:1 w:0)
-	/// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Agenda` (r:1 w:1)
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	fn nudge_referendum_begin_deciding_failing() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `485`
+		//  Measured:  `346`
 		//  Estimated: `42428`
-		// Minimum execution time: 35_141_000 picoseconds.
-		Weight::from_parts(36_318_000, 0)
+		// Minimum execution time: 24_471_000 picoseconds.
+		Weight::from_parts(25_440_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
-			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(3))
 	}
 	/// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1)
 	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
 	/// Storage: `Referenda::DecidingCount` (r:1 w:1)
 	/// Proof: `Referenda::DecidingCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`)
-	/// Storage: `Balances::InactiveIssuance` (r:1 w:0)
-	/// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Agenda` (r:1 w:1)
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	fn nudge_referendum_begin_deciding_passing() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `485`
+		//  Measured:  `346`
 		//  Estimated: `42428`
-		// Minimum execution time: 37_815_000 picoseconds.
-		Weight::from_parts(39_243_000, 0)
+		// Minimum execution time: 26_580_000 picoseconds.
+		Weight::from_parts(27_570_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
-			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(3))
 	}
 	/// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1)
 	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
-	/// Storage: `Balances::InactiveIssuance` (r:1 w:0)
-	/// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Agenda` (r:1 w:1)
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	fn nudge_referendum_begin_confirming() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `538`
+		//  Measured:  `399`
 		//  Estimated: `42428`
-		// Minimum execution time: 30_779_000 picoseconds.
-		Weight::from_parts(31_845_000, 0)
+		// Minimum execution time: 24_331_000 picoseconds.
+		Weight::from_parts(25_291_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
-			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
 	/// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1)
 	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
-	/// Storage: `Balances::InactiveIssuance` (r:1 w:0)
-	/// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Agenda` (r:1 w:1)
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	fn nudge_referendum_end_confirming() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `521`
+		//  Measured:  `382`
 		//  Estimated: `42428`
-		// Minimum execution time: 31_908_000 picoseconds.
-		Weight::from_parts(33_253_000, 0)
+		// Minimum execution time: 24_768_000 picoseconds.
+		Weight::from_parts(25_746_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
-			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
 	/// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1)
 	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
-	/// Storage: `Balances::InactiveIssuance` (r:1 w:0)
-	/// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Agenda` (r:1 w:1)
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	fn nudge_referendum_continue_not_confirming() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `538`
+		//  Measured:  `399`
 		//  Estimated: `42428`
-		// Minimum execution time: 28_951_000 picoseconds.
-		Weight::from_parts(30_004_000, 0)
+		// Minimum execution time: 23_171_000 picoseconds.
+		Weight::from_parts(24_161_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
-			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
 	/// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1)
 	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
-	/// Storage: `Balances::InactiveIssuance` (r:1 w:0)
-	/// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Agenda` (r:1 w:1)
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	fn nudge_referendum_continue_confirming() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `542`
+		//  Measured:  `403`
 		//  Estimated: `42428`
-		// Minimum execution time: 27_750_000 picoseconds.
-		Weight::from_parts(28_588_000, 0)
+		// Minimum execution time: 22_263_000 picoseconds.
+		Weight::from_parts(23_062_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
-			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
 	/// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1)
 	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
-	/// Storage: `Balances::InactiveIssuance` (r:1 w:0)
-	/// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Agenda` (r:2 w:2)
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Lookup` (r:1 w:1)
 	/// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`)
 	fn nudge_referendum_approved() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `542`
+		//  Measured:  `403`
 		//  Estimated: `83866`
-		// Minimum execution time: 43_950_000 picoseconds.
-		Weight::from_parts(46_164_000, 0)
+		// Minimum execution time: 33_710_000 picoseconds.
+		Weight::from_parts(34_871_000, 0)
 			.saturating_add(Weight::from_parts(0, 83866))
-			.saturating_add(T::DbWeight::get().reads(5))
+			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(4))
 	}
 	/// Storage: `Referenda::ReferendumInfoFor` (r:1 w:1)
 	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
-	/// Storage: `Balances::InactiveIssuance` (r:1 w:0)
-	/// Proof: `Balances::InactiveIssuance` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Agenda` (r:1 w:1)
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	fn nudge_referendum_rejected() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `538`
+		//  Measured:  `399`
 		//  Estimated: `42428`
-		// Minimum execution time: 31_050_000 picoseconds.
-		Weight::from_parts(32_169_000, 0)
+		// Minimum execution time: 24_260_000 picoseconds.
+		Weight::from_parts(25_104_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
-			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
 	/// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0)
 	/// Proof: `Referenda::ReferendumInfoFor` (`max_values`: None, `max_size`: Some(936), added: 3411, mode: `MaxEncodedLen`)
 	/// Storage: `Preimage::StatusFor` (r:1 w:0)
 	/// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
+	/// Storage: `Preimage::RequestStatusFor` (r:1 w:0)
+	/// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
 	/// Storage: `Referenda::MetadataOf` (r:0 w:1)
 	/// Proof: `Referenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
 	fn set_some_metadata() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `560`
+		//  Measured:  `422`
 		//  Estimated: `4401`
-		// Minimum execution time: 21_193_000 picoseconds.
-		Weight::from_parts(22_116_000, 0)
+		// Minimum execution time: 19_821_000 picoseconds.
+		Weight::from_parts(20_641_000, 0)
 			.saturating_add(Weight::from_parts(0, 4401))
-			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
 	/// Storage: `Referenda::ReferendumInfoFor` (r:1 w:0)
@@ -511,10 +504,10 @@ impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
 	/// Proof: `Referenda::MetadataOf` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`)
 	fn clear_metadata() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `421`
+		//  Measured:  `283`
 		//  Estimated: `4401`
-		// Minimum execution time: 18_065_000 picoseconds.
-		Weight::from_parts(18_781_000, 0)
+		// Minimum execution time: 13_411_000 picoseconds.
+		Weight::from_parts(14_070_000, 0)
 			.saturating_add(Weight::from_parts(0, 4401))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
diff --git a/polkadot/runtime/rococo/src/weights/pallet_scheduler.rs b/polkadot/runtime/rococo/src/weights/pallet_scheduler.rs
index 0f36dbd384d..5f6b41d2b54 100644
--- a/polkadot/runtime/rococo/src/weights/pallet_scheduler.rs
+++ b/polkadot/runtime/rococo/src/weights/pallet_scheduler.rs
@@ -16,24 +16,26 @@
 
 //! Autogenerated weights for `pallet_scheduler`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2024-01-25, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `runner-grjcggob-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
-// target/production/polkadot
+// ./target/production/polkadot
 // benchmark
 // pallet
+// --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --pallet=pallet_scheduler
 // --extrinsic=*
+// --execution=wasm
 // --wasm-execution=compiled
-// --heap-pages=4096
-// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json
-// --pallet=pallet_scheduler
-// --chain=rococo-dev
 // --header=./polkadot/file_header.txt
 // --output=./polkadot/runtime/rococo/src/weights/
 
@@ -54,8 +56,8 @@ impl<T: frame_system::Config> pallet_scheduler::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `68`
 		//  Estimated: `1489`
-		// Minimum execution time: 2_869_000 picoseconds.
-		Weight::from_parts(3_109_000, 0)
+		// Minimum execution time: 3_114_000 picoseconds.
+		Weight::from_parts(3_245_000, 0)
 			.saturating_add(Weight::from_parts(0, 1489))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -67,11 +69,11 @@ impl<T: frame_system::Config> pallet_scheduler::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `115 + s * (177 ±0)`
 		//  Estimated: `42428`
-		// Minimum execution time: 3_326_000 picoseconds.
-		Weight::from_parts(5_818_563, 0)
+		// Minimum execution time: 3_430_000 picoseconds.
+		Weight::from_parts(6_250_920, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
-			// Standard Error: 1_261
-			.saturating_add(Weight::from_parts(336_446, 0).saturating_mul(s.into()))
+			// Standard Error: 1_350
+			.saturating_add(Weight::from_parts(333_245, 0).saturating_mul(s.into()))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
@@ -79,8 +81,8 @@ impl<T: frame_system::Config> pallet_scheduler::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 3_007_000 picoseconds.
-		Weight::from_parts(3_197_000, 0)
+		// Minimum execution time: 3_166_000 picoseconds.
+		Weight::from_parts(3_295_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 	}
 	/// Storage: `Preimage::PreimageFor` (r:1 w:1)
@@ -94,11 +96,11 @@ impl<T: frame_system::Config> pallet_scheduler::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `251 + s * (1 ±0)`
 		//  Estimated: `3716 + s * (1 ±0)`
-		// Minimum execution time: 16_590_000 picoseconds.
-		Weight::from_parts(16_869_000, 0)
+		// Minimum execution time: 17_072_000 picoseconds.
+		Weight::from_parts(17_393_000, 0)
 			.saturating_add(Weight::from_parts(0, 3716))
-			// Standard Error: 9
-			.saturating_add(Weight::from_parts(1_308, 0).saturating_mul(s.into()))
+			// Standard Error: 1
+			.saturating_add(Weight::from_parts(1_204, 0).saturating_mul(s.into()))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(2))
 			.saturating_add(Weight::from_parts(0, 1).saturating_mul(s.into()))
@@ -109,8 +111,8 @@ impl<T: frame_system::Config> pallet_scheduler::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 4_320_000 picoseconds.
-		Weight::from_parts(4_594_000, 0)
+		// Minimum execution time: 4_566_000 picoseconds.
+		Weight::from_parts(4_775_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
@@ -118,24 +120,24 @@ impl<T: frame_system::Config> pallet_scheduler::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 2_956_000 picoseconds.
-		Weight::from_parts(3_216_000, 0)
+		// Minimum execution time: 3_180_000 picoseconds.
+		Weight::from_parts(3_339_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 	}
 	fn execute_dispatch_signed() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 1_824_000 picoseconds.
-		Weight::from_parts(1_929_000, 0)
+		// Minimum execution time: 1_656_000 picoseconds.
+		Weight::from_parts(1_829_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 	}
 	fn execute_dispatch_unsigned() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 1_749_000 picoseconds.
-		Weight::from_parts(1_916_000, 0)
+		// Minimum execution time: 1_628_000 picoseconds.
+		Weight::from_parts(1_840_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 	}
 	/// Storage: `Scheduler::Agenda` (r:1 w:1)
@@ -145,16 +147,18 @@ impl<T: frame_system::Config> pallet_scheduler::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `115 + s * (177 ±0)`
 		//  Estimated: `42428`
-		// Minimum execution time: 9_086_000 picoseconds.
-		Weight::from_parts(11_733_696, 0)
+		// Minimum execution time: 9_523_000 picoseconds.
+		Weight::from_parts(12_482_434, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
-			// Standard Error: 1_362
-			.saturating_add(Weight::from_parts(375_266, 0).saturating_mul(s.into()))
+			// Standard Error: 1_663
+			.saturating_add(Weight::from_parts(370_122, 0).saturating_mul(s.into()))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
 	/// Storage: `Scheduler::Agenda` (r:1 w:1)
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
+	/// Storage: `Scheduler::Retries` (r:0 w:1)
+	/// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Lookup` (r:0 w:1)
 	/// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`)
 	/// The range of component `s` is `[1, 50]`.
@@ -162,13 +166,13 @@ impl<T: frame_system::Config> pallet_scheduler::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `115 + s * (177 ±0)`
 		//  Estimated: `42428`
-		// Minimum execution time: 12_716_000 picoseconds.
-		Weight::from_parts(12_529_180, 0)
+		// Minimum execution time: 14_649_000 picoseconds.
+		Weight::from_parts(14_705_132, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
-			// Standard Error: 867
-			.saturating_add(Weight::from_parts(548_188, 0).saturating_mul(s.into()))
+			// Standard Error: 1_126
+			.saturating_add(Weight::from_parts(547_438, 0).saturating_mul(s.into()))
 			.saturating_add(T::DbWeight::get().reads(1))
-			.saturating_add(T::DbWeight::get().writes(2))
+			.saturating_add(T::DbWeight::get().writes(3))
 	}
 	/// Storage: `Scheduler::Lookup` (r:1 w:1)
 	/// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`)
@@ -179,11 +183,11 @@ impl<T: frame_system::Config> pallet_scheduler::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `292 + s * (185 ±0)`
 		//  Estimated: `42428`
-		// Minimum execution time: 12_053_000 picoseconds.
-		Weight::from_parts(15_358_056, 0)
+		// Minimum execution time: 12_335_000 picoseconds.
+		Weight::from_parts(16_144_217, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
-			// Standard Error: 3_176
-			.saturating_add(Weight::from_parts(421_589, 0).saturating_mul(s.into()))
+			// Standard Error: 3_533
+			.saturating_add(Weight::from_parts(413_823, 0).saturating_mul(s.into()))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
@@ -191,49 +195,48 @@ impl<T: frame_system::Config> pallet_scheduler::WeightInfo for WeightInfo<T> {
 	/// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Agenda` (r:1 w:1)
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
+	/// Storage: `Scheduler::Retries` (r:0 w:1)
+	/// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
 	/// The range of component `s` is `[1, 50]`.
 	fn cancel_named(s: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `318 + s * (185 ±0)`
 		//  Estimated: `42428`
-		// Minimum execution time: 14_803_000 picoseconds.
-		Weight::from_parts(15_805_714, 0)
+		// Minimum execution time: 16_906_000 picoseconds.
+		Weight::from_parts(17_846_662, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
-			// Standard Error: 2_597
-			.saturating_add(Weight::from_parts(611_053, 0).saturating_mul(s.into()))
+			// Standard Error: 2_687
+			.saturating_add(Weight::from_parts(613_356, 0).saturating_mul(s.into()))
 			.saturating_add(T::DbWeight::get().reads(2))
-			.saturating_add(T::DbWeight::get().writes(2))
+			.saturating_add(T::DbWeight::get().writes(3))
 	}
-	/// Storage: `Scheduler::Retries` (r:1 w:2)
-	/// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Agenda` (r:1 w:1)
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
-	/// Storage: `Scheduler::Lookup` (r:0 w:1)
-	/// Proof: `Scheduler::Lookup` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`)
+	/// Storage: `Scheduler::Retries` (r:0 w:1)
+	/// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
 	/// The range of component `s` is `[1, 50]`.
 	fn schedule_retry(s: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `196`
+		//  Measured:  `155`
 		//  Estimated: `42428`
-		// Minimum execution time: 13_156_000 picoseconds.
-		Weight::from_parts(13_801_287, 0)
+		// Minimum execution time: 8_988_000 picoseconds.
+		Weight::from_parts(9_527_838, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
-			// Standard Error: 568
-			.saturating_add(Weight::from_parts(35_441, 0).saturating_mul(s.into()))
-			.saturating_add(T::DbWeight::get().reads(2))
-			.saturating_add(T::DbWeight::get().writes(4))
+			// Standard Error: 523
+			.saturating_add(Weight::from_parts(25_453, 0).saturating_mul(s.into()))
+			.saturating_add(T::DbWeight::get().reads(1))
+			.saturating_add(T::DbWeight::get().writes(2))
 	}
 	/// Storage: `Scheduler::Agenda` (r:1 w:0)
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Retries` (r:0 w:1)
 	/// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
-	/// The range of component `s` is `[1, 50]`.
 	fn set_retry() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `115 + s * (177 ±0)`
+		//  Measured:  `8965`
 		//  Estimated: `42428`
-		// Minimum execution time: 7_912_000 picoseconds.
-		Weight::from_parts(8_081_460, 0)
+		// Minimum execution time: 23_337_000 picoseconds.
+		Weight::from_parts(24_255_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -244,13 +247,12 @@ impl<T: frame_system::Config> pallet_scheduler::WeightInfo for WeightInfo<T> {
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Retries` (r:0 w:1)
 	/// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
-	/// The range of component `s` is `[1, 50]`.
 	fn set_retry_named() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `324 + s * (185 ±0)`
+		//  Measured:  `9643`
 		//  Estimated: `42428`
-		// Minimum execution time: 10_673_000 picoseconds.
-		Weight::from_parts(12_212_185, 0)
+		// Minimum execution time: 30_704_000 picoseconds.
+		Weight::from_parts(31_646_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -259,13 +261,12 @@ impl<T: frame_system::Config> pallet_scheduler::WeightInfo for WeightInfo<T> {
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Retries` (r:0 w:1)
 	/// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
-	/// The range of component `s` is `[1, 50]`.
 	fn cancel_retry() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `115 + s * (177 ±0)`
+		//  Measured:  `8977`
 		//  Estimated: `42428`
-		// Minimum execution time: 7_912_000 picoseconds.
-		Weight::from_parts(8_081_460, 0)
+		// Minimum execution time: 22_279_000 picoseconds.
+		Weight::from_parts(23_106_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -276,13 +277,12 @@ impl<T: frame_system::Config> pallet_scheduler::WeightInfo for WeightInfo<T> {
 	/// Proof: `Scheduler::Agenda` (`max_values`: None, `max_size`: Some(38963), added: 41438, mode: `MaxEncodedLen`)
 	/// Storage: `Scheduler::Retries` (r:0 w:1)
 	/// Proof: `Scheduler::Retries` (`max_values`: None, `max_size`: Some(30), added: 2505, mode: `MaxEncodedLen`)
-	/// The range of component `s` is `[1, 50]`.
 	fn cancel_retry_named() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `324 + s * (185 ±0)`
+		//  Measured:  `9655`
 		//  Estimated: `42428`
-		// Minimum execution time: 10_673_000 picoseconds.
-		Weight::from_parts(12_212_185, 0)
+		// Minimum execution time: 29_649_000 picoseconds.
+		Weight::from_parts(30_472_000, 0)
 			.saturating_add(Weight::from_parts(0, 42428))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
diff --git a/polkadot/runtime/rococo/src/weights/pallet_sudo.rs b/polkadot/runtime/rococo/src/weights/pallet_sudo.rs
index 694174954fc..ecc31dc3fa9 100644
--- a/polkadot/runtime/rococo/src/weights/pallet_sudo.rs
+++ b/polkadot/runtime/rococo/src/weights/pallet_sudo.rs
@@ -16,24 +16,26 @@
 
 //! Autogenerated weights for `pallet_sudo`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-11-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `runner-yprdrvc7-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
-// target/production/polkadot
+// ./target/production/polkadot
 // benchmark
 // pallet
+// --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --pallet=pallet_sudo
 // --extrinsic=*
+// --execution=wasm
 // --wasm-execution=compiled
-// --heap-pages=4096
-// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json
-// --pallet=pallet_sudo
-// --chain=rococo-dev
 // --header=./polkadot/file_header.txt
 // --output=./polkadot/runtime/rococo/src/weights/
 
@@ -54,8 +56,8 @@ impl<T: frame_system::Config> pallet_sudo::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `132`
 		//  Estimated: `1517`
-		// Minimum execution time: 8_432_000 picoseconds.
-		Weight::from_parts(8_757_000, 0)
+		// Minimum execution time: 8_336_000 picoseconds.
+		Weight::from_parts(8_569_000, 0)
 			.saturating_add(Weight::from_parts(0, 1517))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -66,8 +68,8 @@ impl<T: frame_system::Config> pallet_sudo::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `132`
 		//  Estimated: `1517`
-		// Minimum execution time: 9_167_000 picoseconds.
-		Weight::from_parts(9_397_000, 0)
+		// Minimum execution time: 8_858_000 picoseconds.
+		Weight::from_parts(9_238_000, 0)
 			.saturating_add(Weight::from_parts(0, 1517))
 			.saturating_add(T::DbWeight::get().reads(1))
 	}
@@ -77,8 +79,8 @@ impl<T: frame_system::Config> pallet_sudo::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `132`
 		//  Estimated: `1517`
-		// Minimum execution time: 9_133_000 picoseconds.
-		Weight::from_parts(9_573_000, 0)
+		// Minimum execution time: 8_921_000 picoseconds.
+		Weight::from_parts(9_324_000, 0)
 			.saturating_add(Weight::from_parts(0, 1517))
 			.saturating_add(T::DbWeight::get().reads(1))
 	}
@@ -88,10 +90,21 @@ impl<T: frame_system::Config> pallet_sudo::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `132`
 		//  Estimated: `1517`
-		// Minimum execution time: 7_374_000 picoseconds.
-		Weight::from_parts(7_702_000, 0)
+		// Minimum execution time: 7_398_000 picoseconds.
+		Weight::from_parts(7_869_000, 0)
 			.saturating_add(Weight::from_parts(0, 1517))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
+	/// Storage: `Sudo::Key` (r:1 w:0)
+	/// Proof: `Sudo::Key` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
+	fn check_only_sudo_account() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `132`
+		//  Estimated: `1517`
+		// Minimum execution time: 3_146_000 picoseconds.
+		Weight::from_parts(3_314_000, 0)
+			.saturating_add(Weight::from_parts(0, 1517))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
 }
diff --git a/polkadot/runtime/rococo/src/weights/pallet_timestamp.rs b/polkadot/runtime/rococo/src/weights/pallet_timestamp.rs
index 1bb2e227ab7..7d79621b9e6 100644
--- a/polkadot/runtime/rococo/src/weights/pallet_timestamp.rs
+++ b/polkadot/runtime/rococo/src/weights/pallet_timestamp.rs
@@ -16,11 +16,11 @@
 
 //! Autogenerated weights for `pallet_timestamp`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
-//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
 // ./target/production/polkadot
@@ -29,12 +29,15 @@
 // --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
 // --pallet=pallet_timestamp
 // --extrinsic=*
 // --execution=wasm
 // --wasm-execution=compiled
-// --header=./file_header.txt
-// --output=./runtime/rococo/src/weights/
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -47,26 +50,26 @@ use core::marker::PhantomData;
 /// Weight functions for `pallet_timestamp`.
 pub struct WeightInfo<T>(PhantomData<T>);
 impl<T: frame_system::Config> pallet_timestamp::WeightInfo for WeightInfo<T> {
-	/// Storage: Timestamp Now (r:1 w:1)
-	/// Proof: Timestamp Now (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen)
-	/// Storage: Babe CurrentSlot (r:1 w:0)
-	/// Proof: Babe CurrentSlot (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen)
+	/// Storage: `Timestamp::Now` (r:1 w:1)
+	/// Proof: `Timestamp::Now` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`)
+	/// Storage: `Babe::CurrentSlot` (r:1 w:0)
+	/// Proof: `Babe::CurrentSlot` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`)
 	fn set() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `311`
+		//  Measured:  `137`
 		//  Estimated: `1493`
-		// Minimum execution time: 10_103_000 picoseconds.
-		Weight::from_parts(10_597_000, 0)
+		// Minimum execution time: 5_596_000 picoseconds.
+		Weight::from_parts(5_823_000, 0)
 			.saturating_add(Weight::from_parts(0, 1493))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
 	fn on_finalize() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `94`
+		//  Measured:  `57`
 		//  Estimated: `0`
-		// Minimum execution time: 4_718_000 picoseconds.
-		Weight::from_parts(4_839_000, 0)
+		// Minimum execution time: 2_777_000 picoseconds.
+		Weight::from_parts(2_900_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 	}
 }
diff --git a/polkadot/runtime/rococo/src/weights/pallet_transaction_payment.rs b/polkadot/runtime/rococo/src/weights/pallet_transaction_payment.rs
new file mode 100644
index 00000000000..44dfab289fb
--- /dev/null
+++ b/polkadot/runtime/rococo/src/weights/pallet_transaction_payment.rs
@@ -0,0 +1,68 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Polkadot.
+
+// Polkadot is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Polkadot is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `pallet_transaction_payment`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/production/polkadot
+// benchmark
+// pallet
+// --chain=rococo-dev
+// --steps=50
+// --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --pallet=pallet_transaction_payment
+// --extrinsic=*
+// --execution=wasm
+// --wasm-execution=compiled
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `pallet_transaction_payment`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> pallet_transaction_payment::WeightInfo for WeightInfo<T> {
+	/// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0)
+	/// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
+	/// Storage: `Authorship::Author` (r:1 w:0)
+	/// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
+	/// Storage: `System::Digest` (r:1 w:0)
+	/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	fn charge_transaction_payment() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `252`
+		//  Estimated: `1737`
+		// Minimum execution time: 33_070_000 picoseconds.
+		Weight::from_parts(33_730_000, 0)
+			.saturating_add(Weight::from_parts(0, 1737))
+			.saturating_add(T::DbWeight::get().reads(3))
+	}
+}
diff --git a/polkadot/runtime/rococo/src/weights/pallet_treasury.rs b/polkadot/runtime/rococo/src/weights/pallet_treasury.rs
index 06246ada72f..42d7b260764 100644
--- a/polkadot/runtime/rococo/src/weights/pallet_treasury.rs
+++ b/polkadot/runtime/rococo/src/weights/pallet_treasury.rs
@@ -16,25 +16,28 @@
 
 //! Autogenerated weights for `pallet_treasury`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-07-07, STEPS: `50`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `cob`, CPU: `<UNKNOWN>`
-//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
-// ./target/debug/polkadot
+// ./target/production/polkadot
 // benchmark
 // pallet
 // --chain=rococo-dev
 // --steps=50
-// --repeat=2
+// --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
 // --pallet=pallet_treasury
 // --extrinsic=*
+// --execution=wasm
 // --wasm-execution=compiled
-// --heap-pages=4096
-// --output=./runtime/rococo/src/weights/
-// --header=./file_header.txt
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -47,18 +50,18 @@ use core::marker::PhantomData;
 /// Weight functions for `pallet_treasury`.
 pub struct WeightInfo<T>(PhantomData<T>);
 impl<T: frame_system::Config> pallet_treasury::WeightInfo for WeightInfo<T> {
-	/// Storage: Treasury ProposalCount (r:1 w:1)
-	/// Proof: Treasury ProposalCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
-	/// Storage: Treasury Approvals (r:1 w:1)
-	/// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen)
-	/// Storage: Treasury Proposals (r:0 w:1)
-	/// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen)
+	/// Storage: `Treasury::ProposalCount` (r:1 w:1)
+	/// Proof: `Treasury::ProposalCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
+	/// Storage: `Treasury::Approvals` (r:1 w:1)
+	/// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`)
+	/// Storage: `Treasury::Proposals` (r:0 w:1)
+	/// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`)
 	fn spend_local() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `42`
+		//  Measured:  `142`
 		//  Estimated: `1887`
-		// Minimum execution time: 177_000_000 picoseconds.
-		Weight::from_parts(191_000_000, 0)
+		// Minimum execution time: 9_928_000 picoseconds.
+		Weight::from_parts(10_560_000, 0)
 			.saturating_add(Weight::from_parts(0, 1887))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(3))
@@ -67,111 +70,103 @@ impl<T: frame_system::Config> pallet_treasury::WeightInfo for WeightInfo<T> {
 	/// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen)
 	fn remove_approval() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `127`
+		//  Measured:  `227`
 		//  Estimated: `1887`
-		// Minimum execution time: 80_000_000 picoseconds.
-		Weight::from_parts(82_000_000, 0)
+		// Minimum execution time: 5_386_000 picoseconds.
+		Weight::from_parts(5_585_000, 0)
 			.saturating_add(Weight::from_parts(0, 1887))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Treasury Deactivated (r:1 w:1)
-	/// Proof: Treasury Deactivated (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen)
-	/// Storage: Balances InactiveIssuance (r:1 w:1)
-	/// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen)
-	/// Storage: Treasury Approvals (r:1 w:1)
-	/// Proof: Treasury Approvals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen)
-	/// Storage: Treasury Proposals (r:99 w:99)
-	/// Proof: Treasury Proposals (max_values: None, max_size: Some(108), added: 2583, mode: MaxEncodedLen)
-	/// Storage: System Account (r:199 w:199)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
-	/// Storage: Bounties BountyApprovals (r:1 w:1)
-	/// Proof: Bounties BountyApprovals (max_values: Some(1), max_size: Some(402), added: 897, mode: MaxEncodedLen)
+	/// Storage: `Treasury::Deactivated` (r:1 w:1)
+	/// Proof: `Treasury::Deactivated` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
+	/// Storage: `Treasury::Approvals` (r:1 w:1)
+	/// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`)
+	/// Storage: `Treasury::Proposals` (r:99 w:99)
+	/// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:199 w:199)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `Bounties::BountyApprovals` (r:1 w:1)
+	/// Proof: `Bounties::BountyApprovals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`)
 	/// The range of component `p` is `[0, 99]`.
 	fn on_initialize_proposals(p: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `331 + p * (251 ±0)`
+		//  Measured:  `431 + p * (251 ±0)`
 		//  Estimated: `3593 + p * (5206 ±0)`
-		// Minimum execution time: 887_000_000 picoseconds.
-		Weight::from_parts(828_616_021, 0)
+		// Minimum execution time: 43_737_000 picoseconds.
+		Weight::from_parts(39_883_021, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
-			// Standard Error: 695_351
-			.saturating_add(Weight::from_parts(566_114_524, 0).saturating_mul(p.into()))
-			.saturating_add(T::DbWeight::get().reads(5))
+			// Standard Error: 12_917
+			.saturating_add(Weight::from_parts(31_796_205, 0).saturating_mul(p.into()))
+			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(p.into())))
-			.saturating_add(T::DbWeight::get().writes(5))
+			.saturating_add(T::DbWeight::get().writes(4))
 			.saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(p.into())))
 			.saturating_add(Weight::from_parts(0, 5206).saturating_mul(p.into()))
 	}
-	/// Storage: AssetRate ConversionRateToNative (r:1 w:0)
-	/// Proof: AssetRate ConversionRateToNative (max_values: None, max_size: Some(1237), added: 3712, mode: MaxEncodedLen)
-	/// Storage: Treasury SpendCount (r:1 w:1)
-	/// Proof: Treasury SpendCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
-	/// Storage: Treasury Spends (r:0 w:1)
-	/// Proof: Treasury Spends (max_values: None, max_size: Some(1848), added: 4323, mode: MaxEncodedLen)
+	/// Storage: `AssetRate::ConversionRateToNative` (r:1 w:0)
+	/// Proof: `AssetRate::ConversionRateToNative` (`max_values`: None, `max_size`: Some(1238), added: 3713, mode: `MaxEncodedLen`)
+	/// Storage: `Treasury::SpendCount` (r:1 w:1)
+	/// Proof: `Treasury::SpendCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
+	/// Storage: `Treasury::Spends` (r:0 w:1)
+	/// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(1853), added: 4328, mode: `MaxEncodedLen`)
 	fn spend() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `114`
-		//  Estimated: `4702`
-		// Minimum execution time: 208_000_000 picoseconds.
-		Weight::from_parts(222_000_000, 0)
-			.saturating_add(Weight::from_parts(0, 4702))
+		//  Measured:  `215`
+		//  Estimated: `4703`
+		// Minimum execution time: 16_829_000 picoseconds.
+		Weight::from_parts(17_251_000, 0)
+			.saturating_add(Weight::from_parts(0, 4703))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
-	/// Storage: Treasury Spends (r:1 w:1)
-	/// Proof: Treasury Spends (max_values: None, max_size: Some(1848), added: 4323, mode: MaxEncodedLen)
-	/// Storage: XcmPallet QueryCounter (r:1 w:1)
-	/// Proof Skipped: XcmPallet QueryCounter (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Configuration ActiveConfig (r:1 w:0)
-	/// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Dmp DeliveryFeeFactor (r:1 w:0)
-	/// Proof Skipped: Dmp DeliveryFeeFactor (max_values: None, max_size: None, mode: Measured)
-	/// Storage: XcmPallet SupportedVersion (r:1 w:0)
-	/// Proof Skipped: XcmPallet SupportedVersion (max_values: None, max_size: None, mode: Measured)
-	/// Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1)
-	/// Proof Skipped: XcmPallet VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: XcmPallet SafeXcmVersion (r:1 w:0)
-	/// Proof Skipped: XcmPallet SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Dmp DownwardMessageQueues (r:1 w:1)
-	/// Proof Skipped: Dmp DownwardMessageQueues (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Dmp DownwardMessageQueueHeads (r:1 w:1)
-	/// Proof Skipped: Dmp DownwardMessageQueueHeads (max_values: None, max_size: None, mode: Measured)
-	/// Storage: XcmPallet Queries (r:0 w:1)
-	/// Proof Skipped: XcmPallet Queries (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `Treasury::Spends` (r:1 w:1)
+	/// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(1853), added: 4328, mode: `MaxEncodedLen`)
+	/// Storage: `XcmPallet::QueryCounter` (r:1 w:1)
+	/// Proof: `XcmPallet::QueryCounter` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0)
+	/// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `XcmPallet::SupportedVersion` (r:1 w:0)
+	/// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1)
+	/// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1)
+	/// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `XcmPallet::Queries` (r:0 w:1)
+	/// Proof: `XcmPallet::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	fn payout() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `737`
-		//  Estimated: `5313`
-		// Minimum execution time: 551_000_000 picoseconds.
-		Weight::from_parts(569_000_000, 0)
-			.saturating_add(Weight::from_parts(0, 5313))
-			.saturating_add(T::DbWeight::get().reads(9))
-			.saturating_add(T::DbWeight::get().writes(6))
+		//  Measured:  `458`
+		//  Estimated: `5318`
+		// Minimum execution time: 41_554_000 picoseconds.
+		Weight::from_parts(42_451_000, 0)
+			.saturating_add(Weight::from_parts(0, 5318))
+			.saturating_add(T::DbWeight::get().reads(6))
+			.saturating_add(T::DbWeight::get().writes(5))
 	}
-	/// Storage: Treasury Spends (r:1 w:1)
-	/// Proof: Treasury Spends (max_values: None, max_size: Some(1848), added: 4323, mode: MaxEncodedLen)
-	/// Storage: XcmPallet Queries (r:1 w:1)
-	/// Proof Skipped: XcmPallet Queries (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `Treasury::Spends` (r:1 w:1)
+	/// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(1853), added: 4328, mode: `MaxEncodedLen`)
+	/// Storage: `XcmPallet::Queries` (r:1 w:1)
+	/// Proof: `XcmPallet::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	fn check_status() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `442`
-		//  Estimated: `5313`
-		// Minimum execution time: 245_000_000 picoseconds.
-		Weight::from_parts(281_000_000, 0)
-			.saturating_add(Weight::from_parts(0, 5313))
+		//  Measured:  `306`
+		//  Estimated: `5318`
+		// Minimum execution time: 22_546_000 picoseconds.
+		Weight::from_parts(23_151_000, 0)
+			.saturating_add(Weight::from_parts(0, 5318))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
-	/// Storage: Treasury Spends (r:1 w:1)
-	/// Proof: Treasury Spends (max_values: None, max_size: Some(1848), added: 4323, mode: MaxEncodedLen)
+	/// Storage: `Treasury::Spends` (r:1 w:1)
+	/// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(1853), added: 4328, mode: `MaxEncodedLen`)
 	fn void_spend() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `172`
-		//  Estimated: `5313`
-		// Minimum execution time: 147_000_000 picoseconds.
-		Weight::from_parts(160_000_000, 0)
-			.saturating_add(Weight::from_parts(0, 5313))
+		//  Measured:  `278`
+		//  Estimated: `5318`
+		// Minimum execution time: 12_169_000 picoseconds.
+		Weight::from_parts(12_484_000, 0)
+			.saturating_add(Weight::from_parts(0, 5318))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
diff --git a/polkadot/runtime/rococo/src/weights/pallet_utility.rs b/polkadot/runtime/rococo/src/weights/pallet_utility.rs
index f50f60eaad7..6f2a374247f 100644
--- a/polkadot/runtime/rococo/src/weights/pallet_utility.rs
+++ b/polkadot/runtime/rococo/src/weights/pallet_utility.rs
@@ -16,11 +16,11 @@
 
 //! Autogenerated weights for `pallet_utility`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
-//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
 // ./target/production/polkadot
@@ -29,12 +29,15 @@
 // --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
 // --pallet=pallet_utility
 // --extrinsic=*
 // --execution=wasm
 // --wasm-execution=compiled
-// --header=./file_header.txt
-// --output=./runtime/rococo/src/weights/
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -52,18 +55,18 @@ impl<T: frame_system::Config> pallet_utility::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 6_738_000 picoseconds.
-		Weight::from_parts(2_704_821, 0)
+		// Minimum execution time: 4_041_000 picoseconds.
+		Weight::from_parts(5_685_496, 0)
 			.saturating_add(Weight::from_parts(0, 0))
-			// Standard Error: 2_999
-			.saturating_add(Weight::from_parts(4_627_278, 0).saturating_mul(c.into()))
+			// Standard Error: 810
+			.saturating_add(Weight::from_parts(3_177_197, 0).saturating_mul(c.into()))
 	}
 	fn as_derivative() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 5_294_000 picoseconds.
-		Weight::from_parts(5_467_000, 0)
+		// Minimum execution time: 3_667_000 picoseconds.
+		Weight::from_parts(3_871_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 	}
 	/// The range of component `c` is `[0, 1000]`.
@@ -71,18 +74,18 @@ impl<T: frame_system::Config> pallet_utility::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 6_828_000 picoseconds.
-		Weight::from_parts(4_650_678, 0)
+		// Minimum execution time: 4_116_000 picoseconds.
+		Weight::from_parts(6_453_932, 0)
 			.saturating_add(Weight::from_parts(0, 0))
-			// Standard Error: 2_789
-			.saturating_add(Weight::from_parts(4_885_004, 0).saturating_mul(c.into()))
+			// Standard Error: 825
+			.saturating_add(Weight::from_parts(3_366_112, 0).saturating_mul(c.into()))
 	}
 	fn dispatch_as() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 9_020_000 picoseconds.
-		Weight::from_parts(9_205_000, 0)
+		// Minimum execution time: 5_630_000 picoseconds.
+		Weight::from_parts(5_956_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 	}
 	/// The range of component `c` is `[0, 1000]`.
@@ -90,10 +93,10 @@ impl<T: frame_system::Config> pallet_utility::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 6_852_000 picoseconds.
-		Weight::from_parts(20_703_134, 0)
+		// Minimum execution time: 4_165_000 picoseconds.
+		Weight::from_parts(5_442_561, 0)
 			.saturating_add(Weight::from_parts(0, 0))
-			// Standard Error: 3_924
-			.saturating_add(Weight::from_parts(4_604_529, 0).saturating_mul(c.into()))
+			// Standard Error: 460
+			.saturating_add(Weight::from_parts(3_173_577, 0).saturating_mul(c.into()))
 	}
 }
diff --git a/polkadot/runtime/rococo/src/weights/pallet_vesting.rs b/polkadot/runtime/rococo/src/weights/pallet_vesting.rs
index 2596207d583..c21ab087774 100644
--- a/polkadot/runtime/rococo/src/weights/pallet_vesting.rs
+++ b/polkadot/runtime/rococo/src/weights/pallet_vesting.rs
@@ -16,11 +16,11 @@
 
 //! Autogenerated weights for `pallet_vesting`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
-//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
 // ./target/production/polkadot
@@ -29,12 +29,15 @@
 // --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
 // --pallet=pallet_vesting
 // --extrinsic=*
 // --execution=wasm
 // --wasm-execution=compiled
-// --header=./file_header.txt
-// --output=./runtime/rococo/src/weights/
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -47,143 +50,143 @@ use core::marker::PhantomData;
 /// Weight functions for `pallet_vesting`.
 pub struct WeightInfo<T>(PhantomData<T>);
 impl<T: frame_system::Config> pallet_vesting::WeightInfo for WeightInfo<T> {
-	/// Storage: Vesting Vesting (r:1 w:1)
-	/// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen)
-	/// Storage: Balances Locks (r:1 w:1)
-	/// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen)
-	/// Storage: Balances Freezes (r:1 w:0)
-	/// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen)
+	/// Storage: `Vesting::Vesting` (r:1 w:1)
+	/// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Locks` (r:1 w:1)
+	/// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Freezes` (r:1 w:0)
+	/// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`)
 	/// The range of component `l` is `[0, 49]`.
 	/// The range of component `s` is `[1, 28]`.
 	fn vest_locked(l: u32, s: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `277 + l * (25 ±0) + s * (36 ±0)`
 		//  Estimated: `4764`
-		// Minimum execution time: 32_820_000 picoseconds.
-		Weight::from_parts(31_640_992, 0)
+		// Minimum execution time: 29_288_000 picoseconds.
+		Weight::from_parts(29_095_507, 0)
 			.saturating_add(Weight::from_parts(0, 4764))
-			// Standard Error: 449
-			.saturating_add(Weight::from_parts(45_254, 0).saturating_mul(l.into()))
-			// Standard Error: 800
-			.saturating_add(Weight::from_parts(72_178, 0).saturating_mul(s.into()))
+			// Standard Error: 1_679
+			.saturating_add(Weight::from_parts(33_164, 0).saturating_mul(l.into()))
+			// Standard Error: 2_988
+			.saturating_add(Weight::from_parts(67_092, 0).saturating_mul(s.into()))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
-	/// Storage: Vesting Vesting (r:1 w:1)
-	/// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen)
-	/// Storage: Balances Locks (r:1 w:1)
-	/// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen)
-	/// Storage: Balances Freezes (r:1 w:0)
-	/// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen)
+	/// Storage: `Vesting::Vesting` (r:1 w:1)
+	/// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Locks` (r:1 w:1)
+	/// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Freezes` (r:1 w:0)
+	/// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`)
 	/// The range of component `l` is `[0, 49]`.
 	/// The range of component `s` is `[1, 28]`.
 	fn vest_unlocked(l: u32, s: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `277 + l * (25 ±0) + s * (36 ±0)`
 		//  Estimated: `4764`
-		// Minimum execution time: 36_054_000 picoseconds.
-		Weight::from_parts(35_825_428, 0)
+		// Minimum execution time: 31_003_000 picoseconds.
+		Weight::from_parts(30_528_438, 0)
 			.saturating_add(Weight::from_parts(0, 4764))
-			// Standard Error: 749
-			.saturating_add(Weight::from_parts(31_738, 0).saturating_mul(l.into()))
-			// Standard Error: 1_333
-			.saturating_add(Weight::from_parts(40_580, 0).saturating_mul(s.into()))
+			// Standard Error: 1_586
+			.saturating_add(Weight::from_parts(35_429, 0).saturating_mul(l.into()))
+			// Standard Error: 2_823
+			.saturating_add(Weight::from_parts(76_505, 0).saturating_mul(s.into()))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
-	/// Storage: Vesting Vesting (r:1 w:1)
-	/// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen)
-	/// Storage: Balances Locks (r:1 w:1)
-	/// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen)
-	/// Storage: Balances Freezes (r:1 w:0)
-	/// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen)
-	/// Storage: System Account (r:1 w:1)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
+	/// Storage: `Vesting::Vesting` (r:1 w:1)
+	/// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Locks` (r:1 w:1)
+	/// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Freezes` (r:1 w:0)
+	/// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
 	/// The range of component `l` is `[0, 49]`.
 	/// The range of component `s` is `[1, 28]`.
 	fn vest_other_locked(l: u32, s: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `380 + l * (25 ±0) + s * (36 ±0)`
 		//  Estimated: `4764`
-		// Minimum execution time: 35_440_000 picoseconds.
-		Weight::from_parts(34_652_647, 0)
+		// Minimum execution time: 31_269_000 picoseconds.
+		Weight::from_parts(30_661_898, 0)
 			.saturating_add(Weight::from_parts(0, 4764))
-			// Standard Error: 517
-			.saturating_add(Weight::from_parts(41_942, 0).saturating_mul(l.into()))
-			// Standard Error: 920
-			.saturating_add(Weight::from_parts(66_074, 0).saturating_mul(s.into()))
+			// Standard Error: 1_394
+			.saturating_add(Weight::from_parts(39_300, 0).saturating_mul(l.into()))
+			// Standard Error: 2_480
+			.saturating_add(Weight::from_parts(78_849, 0).saturating_mul(s.into()))
 			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(3))
 	}
-	/// Storage: Vesting Vesting (r:1 w:1)
-	/// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen)
-	/// Storage: Balances Locks (r:1 w:1)
-	/// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen)
-	/// Storage: Balances Freezes (r:1 w:0)
-	/// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen)
-	/// Storage: System Account (r:1 w:1)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
+	/// Storage: `Vesting::Vesting` (r:1 w:1)
+	/// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Locks` (r:1 w:1)
+	/// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Freezes` (r:1 w:0)
+	/// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
 	/// The range of component `l` is `[0, 49]`.
 	/// The range of component `s` is `[1, 28]`.
 	fn vest_other_unlocked(l: u32, s: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `380 + l * (25 ±0) + s * (36 ±0)`
 		//  Estimated: `4764`
-		// Minimum execution time: 38_880_000 picoseconds.
-		Weight::from_parts(39_625_819, 0)
+		// Minimum execution time: 33_040_000 picoseconds.
+		Weight::from_parts(32_469_674, 0)
 			.saturating_add(Weight::from_parts(0, 4764))
-			// Standard Error: 1_032
-			.saturating_add(Weight::from_parts(29_856, 0).saturating_mul(l.into()))
-			// Standard Error: 1_837
-			.saturating_add(Weight::from_parts(6_210, 0).saturating_mul(s.into()))
+			// Standard Error: 1_418
+			.saturating_add(Weight::from_parts(44_206, 0).saturating_mul(l.into()))
+			// Standard Error: 2_523
+			.saturating_add(Weight::from_parts(74_224, 0).saturating_mul(s.into()))
 			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(3))
 	}
-	/// Storage: Vesting Vesting (r:1 w:1)
-	/// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen)
-	/// Storage: System Account (r:1 w:1)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
-	/// Storage: Balances Locks (r:1 w:1)
-	/// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen)
-	/// Storage: Balances Freezes (r:1 w:0)
-	/// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen)
+	/// Storage: `Vesting::Vesting` (r:1 w:1)
+	/// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Locks` (r:1 w:1)
+	/// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Freezes` (r:1 w:0)
+	/// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`)
 	/// The range of component `l` is `[0, 49]`.
 	/// The range of component `s` is `[0, 27]`.
 	fn vested_transfer(l: u32, s: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `451 + l * (25 ±0) + s * (36 ±0)`
 		//  Estimated: `4764`
-		// Minimum execution time: 68_294_000 picoseconds.
-		Weight::from_parts(68_313_394, 0)
+		// Minimum execution time: 62_032_000 picoseconds.
+		Weight::from_parts(63_305_621, 0)
 			.saturating_add(Weight::from_parts(0, 4764))
-			// Standard Error: 983
-			.saturating_add(Weight::from_parts(48_156, 0).saturating_mul(l.into()))
-			// Standard Error: 1_750
-			.saturating_add(Weight::from_parts(87_719, 0).saturating_mul(s.into()))
+			// Standard Error: 2_277
+			.saturating_add(Weight::from_parts(42_767, 0).saturating_mul(l.into()))
+			// Standard Error: 4_051
+			.saturating_add(Weight::from_parts(65_487, 0).saturating_mul(s.into()))
 			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(3))
 	}
-	/// Storage: Vesting Vesting (r:1 w:1)
-	/// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen)
-	/// Storage: System Account (r:2 w:2)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
-	/// Storage: Balances Locks (r:1 w:1)
-	/// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen)
-	/// Storage: Balances Freezes (r:1 w:0)
-	/// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen)
+	/// Storage: `Vesting::Vesting` (r:1 w:1)
+	/// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:2 w:2)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Locks` (r:1 w:1)
+	/// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Freezes` (r:1 w:0)
+	/// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`)
 	/// The range of component `l` is `[0, 49]`.
 	/// The range of component `s` is `[0, 27]`.
 	fn force_vested_transfer(l: u32, s: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `554 + l * (25 ±0) + s * (36 ±0)`
 		//  Estimated: `6196`
-		// Minimum execution time: 70_529_000 picoseconds.
-		Weight::from_parts(70_619_962, 0)
+		// Minimum execution time: 63_303_000 picoseconds.
+		Weight::from_parts(65_180_847, 0)
 			.saturating_add(Weight::from_parts(0, 6196))
-			// Standard Error: 1_259
-			.saturating_add(Weight::from_parts(50_685, 0).saturating_mul(l.into()))
-			// Standard Error: 2_241
-			.saturating_add(Weight::from_parts(91_444, 0).saturating_mul(s.into()))
+			// Standard Error: 2_220
+			.saturating_add(Weight::from_parts(28_829, 0).saturating_mul(l.into()))
+			// Standard Error: 3_951
+			.saturating_add(Weight::from_parts(84_970, 0).saturating_mul(s.into()))
 			.saturating_add(T::DbWeight::get().reads(5))
 			.saturating_add(T::DbWeight::get().writes(4))
 	}
@@ -192,59 +195,70 @@ impl<T: frame_system::Config> pallet_vesting::WeightInfo for WeightInfo<T> {
 	/// Storage: `Balances::Locks` (r:1 w:1)
 	/// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
 	/// Storage: `Balances::Freezes` (r:1 w:0)
-	/// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`)
+	/// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`)
 	/// Storage: `System::Account` (r:1 w:1)
 	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
 	/// The range of component `l` is `[0, 49]`.
 	/// The range of component `s` is `[2, 28]`.
-	fn force_remove_vesting_schedule(l: u32, s: u32, ) -> Weight {
-		// Proof Size summary in bytes:
-		//  Measured:  `555 + l * (25 ±0) + s * (36 ±0)`
-		//  Estimated: `4764`
-		// Minimum execution time: 41_497_000 picoseconds.
-		Weight::from_parts(38_763_834, 4764)
-			// Standard Error: 2_030
-			.saturating_add(Weight::from_parts(99_580, 0).saturating_mul(l.into()))
-			// Standard Error: 3_750
-			.saturating_add(Weight::from_parts(132_188, 0).saturating_mul(s.into()))
-			.saturating_add(T::DbWeight::get().reads(4_u64))
-			.saturating_add(T::DbWeight::get().writes(3_u64))
-	}
 	fn not_unlocking_merge_schedules(l: u32, s: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `378 + l * (25 ±0) + s * (36 ±0)`
 		//  Estimated: `4764`
-		// Minimum execution time: 36_428_000 picoseconds.
-		Weight::from_parts(35_604_430, 0)
+		// Minimum execution time: 31_440_000 picoseconds.
+		Weight::from_parts(30_773_053, 0)
 			.saturating_add(Weight::from_parts(0, 4764))
-			// Standard Error: 504
-			.saturating_add(Weight::from_parts(43_191, 0).saturating_mul(l.into()))
-			// Standard Error: 931
-			.saturating_add(Weight::from_parts(66_795, 0).saturating_mul(s.into()))
+			// Standard Error: 1_474
+			.saturating_add(Weight::from_parts(43_019, 0).saturating_mul(l.into()))
+			// Standard Error: 2_723
+			.saturating_add(Weight::from_parts(73_360, 0).saturating_mul(s.into()))
 			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(3))
 	}
-	/// Storage: Vesting Vesting (r:1 w:1)
-	/// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen)
-	/// Storage: Balances Locks (r:1 w:1)
-	/// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen)
-	/// Storage: Balances Freezes (r:1 w:0)
-	/// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen)
-	/// Storage: System Account (r:1 w:1)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
+	/// Storage: `Vesting::Vesting` (r:1 w:1)
+	/// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Locks` (r:1 w:1)
+	/// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Freezes` (r:1 w:0)
+	/// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
 	/// The range of component `l` is `[0, 49]`.
 	/// The range of component `s` is `[2, 28]`.
 	fn unlocking_merge_schedules(l: u32, s: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `378 + l * (25 ±0) + s * (36 ±0)`
 		//  Estimated: `4764`
-		// Minimum execution time: 40_696_000 picoseconds.
-		Weight::from_parts(39_741_284, 0)
+		// Minimum execution time: 34_221_000 picoseconds.
+		Weight::from_parts(33_201_125, 0)
+			.saturating_add(Weight::from_parts(0, 4764))
+			// Standard Error: 1_751
+			.saturating_add(Weight::from_parts(44_088, 0).saturating_mul(l.into()))
+			// Standard Error: 3_234
+			.saturating_add(Weight::from_parts(86_228, 0).saturating_mul(s.into()))
+			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().writes(3))
+	}
+	/// Storage: `Vesting::Vesting` (r:1 w:1)
+	/// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Locks` (r:1 w:1)
+	/// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Freezes` (r:1 w:0)
+	/// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// The range of component `l` is `[0, 49]`.
+	/// The range of component `s` is `[2, 28]`.
+	fn force_remove_vesting_schedule(l: u32, s: u32, ) -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `451 + l * (25 ±0) + s * (36 ±0)`
+		//  Estimated: `4764`
+		// Minimum execution time: 35_553_000 picoseconds.
+		Weight::from_parts(34_974_083, 0)
 			.saturating_add(Weight::from_parts(0, 4764))
-			// Standard Error: 478
-			.saturating_add(Weight::from_parts(43_792, 0).saturating_mul(l.into()))
-			// Standard Error: 883
-			.saturating_add(Weight::from_parts(66_540, 0).saturating_mul(s.into()))
+			// Standard Error: 1_560
+			.saturating_add(Weight::from_parts(34_615, 0).saturating_mul(l.into()))
+			// Standard Error: 2_882
+			.saturating_add(Weight::from_parts(83_419, 0).saturating_mul(s.into()))
 			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(3))
 	}
diff --git a/polkadot/runtime/rococo/src/weights/pallet_whitelist.rs b/polkadot/runtime/rococo/src/weights/pallet_whitelist.rs
index 7c307deec4c..ec67268d144 100644
--- a/polkadot/runtime/rococo/src/weights/pallet_whitelist.rs
+++ b/polkadot/runtime/rococo/src/weights/pallet_whitelist.rs
@@ -16,26 +16,28 @@
 
 //! Autogenerated weights for `pallet_whitelist`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-08-25, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `runner-aahe6cbd-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
-// target/production/polkadot
+// ./target/production/polkadot
 // benchmark
 // pallet
+// --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --pallet=pallet_whitelist
 // --extrinsic=*
+// --execution=wasm
 // --wasm-execution=compiled
-// --heap-pages=4096
-// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json
-// --pallet=pallet_whitelist
-// --chain=rococo-dev
-// --header=./file_header.txt
-// --output=./runtime/rococo/src/weights/
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -50,67 +52,75 @@ pub struct WeightInfo<T>(PhantomData<T>);
 impl<T: frame_system::Config> pallet_whitelist::WeightInfo for WeightInfo<T> {
 	/// Storage: `Whitelist::WhitelistedCall` (r:1 w:1)
 	/// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`)
-	/// Storage: `Preimage::StatusFor` (r:1 w:1)
+	/// Storage: `Preimage::StatusFor` (r:1 w:0)
 	/// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
+	/// Storage: `Preimage::RequestStatusFor` (r:1 w:1)
+	/// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
 	fn whitelist_call() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `223`
 		//  Estimated: `3556`
-		// Minimum execution time: 20_035_000 picoseconds.
-		Weight::from_parts(20_452_000, 0)
+		// Minimum execution time: 16_686_000 picoseconds.
+		Weight::from_parts(17_042_000, 0)
 			.saturating_add(Weight::from_parts(0, 3556))
-			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
 	/// Storage: `Whitelist::WhitelistedCall` (r:1 w:1)
 	/// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`)
-	/// Storage: `Preimage::StatusFor` (r:1 w:1)
+	/// Storage: `Preimage::StatusFor` (r:1 w:0)
 	/// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
+	/// Storage: `Preimage::RequestStatusFor` (r:1 w:1)
+	/// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
 	fn remove_whitelisted_call() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `352`
 		//  Estimated: `3556`
-		// Minimum execution time: 20_247_000 picoseconds.
-		Weight::from_parts(20_808_000, 0)
+		// Minimum execution time: 18_250_000 picoseconds.
+		Weight::from_parts(19_026_000, 0)
 			.saturating_add(Weight::from_parts(0, 3556))
-			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
 	/// Storage: `Whitelist::WhitelistedCall` (r:1 w:1)
 	/// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`)
 	/// Storage: `Preimage::PreimageFor` (r:1 w:1)
 	/// Proof: `Preimage::PreimageFor` (`max_values`: None, `max_size`: Some(4194344), added: 4196819, mode: `Measured`)
-	/// Storage: `Preimage::StatusFor` (r:1 w:1)
+	/// Storage: `Preimage::StatusFor` (r:1 w:0)
 	/// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
+	/// Storage: `Preimage::RequestStatusFor` (r:1 w:1)
+	/// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
 	/// The range of component `n` is `[1, 4194294]`.
 	fn dispatch_whitelisted_call(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `428 + n * (1 ±0)`
 		//  Estimated: `3892 + n * (1 ±0)`
-		// Minimum execution time: 32_633_000 picoseconds.
-		Weight::from_parts(32_855_000, 0)
+		// Minimum execution time: 28_741_000 picoseconds.
+		Weight::from_parts(29_024_000, 0)
 			.saturating_add(Weight::from_parts(0, 3892))
-			// Standard Error: 1
-			.saturating_add(Weight::from_parts(1_223, 0).saturating_mul(n.into()))
-			.saturating_add(T::DbWeight::get().reads(3))
+			// Standard Error: 7
+			.saturating_add(Weight::from_parts(1_305, 0).saturating_mul(n.into()))
+			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(3))
 			.saturating_add(Weight::from_parts(0, 1).saturating_mul(n.into()))
 	}
 	/// Storage: `Whitelist::WhitelistedCall` (r:1 w:1)
 	/// Proof: `Whitelist::WhitelistedCall` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`)
-	/// Storage: `Preimage::StatusFor` (r:1 w:1)
+	/// Storage: `Preimage::StatusFor` (r:1 w:0)
 	/// Proof: `Preimage::StatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
+	/// Storage: `Preimage::RequestStatusFor` (r:1 w:1)
+	/// Proof: `Preimage::RequestStatusFor` (`max_values`: None, `max_size`: Some(91), added: 2566, mode: `MaxEncodedLen`)
 	/// The range of component `n` is `[1, 10000]`.
 	fn dispatch_whitelisted_call_with_preimage(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `352`
 		//  Estimated: `3556`
-		// Minimum execution time: 23_833_000 picoseconds.
-		Weight::from_parts(24_698_994, 0)
+		// Minimum execution time: 21_670_000 picoseconds.
+		Weight::from_parts(22_561_364, 0)
 			.saturating_add(Weight::from_parts(0, 3556))
 			// Standard Error: 4
-			.saturating_add(Weight::from_parts(1_454, 0).saturating_mul(n.into()))
-			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(Weight::from_parts(1_468, 0).saturating_mul(n.into()))
+			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
 }
diff --git a/polkadot/runtime/rococo/src/weights/pallet_xcm.rs b/polkadot/runtime/rococo/src/weights/pallet_xcm.rs
index 5544ca44658..d5cf33515e6 100644
--- a/polkadot/runtime/rococo/src/weights/pallet_xcm.rs
+++ b/polkadot/runtime/rococo/src/weights/pallet_xcm.rs
@@ -17,23 +17,25 @@
 //! Autogenerated weights for `pallet_xcm`
 //!
 //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
-//! DATE: 2024-02-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
 //! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
-// target/production/polkadot
+// ./target/production/polkadot
 // benchmark
 // pallet
+// --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --pallet=pallet_xcm
 // --extrinsic=*
+// --execution=wasm
 // --wasm-execution=compiled
-// --heap-pages=4096
-// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json
-// --pallet=pallet_xcm
-// --chain=rococo-dev
 // --header=./polkadot/file_header.txt
 // --output=./polkadot/runtime/rococo/src/weights/
 
@@ -60,8 +62,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `180`
 		//  Estimated: `3645`
-		// Minimum execution time: 25_043_000 picoseconds.
-		Weight::from_parts(25_682_000, 0)
+		// Minimum execution time: 25_521_000 picoseconds.
+		Weight::from_parts(25_922_000, 0)
 			.saturating_add(Weight::from_parts(0, 3645))
 			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(2))
@@ -80,8 +82,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `180`
 		//  Estimated: `3645`
-		// Minimum execution time: 107_570_000 picoseconds.
-		Weight::from_parts(109_878_000, 0)
+		// Minimum execution time: 112_185_000 picoseconds.
+		Weight::from_parts(115_991_000, 0)
 			.saturating_add(Weight::from_parts(0, 3645))
 			.saturating_add(T::DbWeight::get().reads(5))
 			.saturating_add(T::DbWeight::get().writes(3))
@@ -100,8 +102,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `232`
 		//  Estimated: `3697`
-		// Minimum execution time: 106_341_000 picoseconds.
-		Weight::from_parts(109_135_000, 0)
+		// Minimum execution time: 108_693_000 picoseconds.
+		Weight::from_parts(111_853_000, 0)
 			.saturating_add(Weight::from_parts(0, 3697))
 			.saturating_add(T::DbWeight::get().reads(5))
 			.saturating_add(T::DbWeight::get().writes(3))
@@ -120,8 +122,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `180`
 		//  Estimated: `3645`
-		// Minimum execution time: 108_372_000 picoseconds.
-		Weight::from_parts(112_890_000, 0)
+		// Minimum execution time: 113_040_000 picoseconds.
+		Weight::from_parts(115_635_000, 0)
 			.saturating_add(Weight::from_parts(0, 3645))
 			.saturating_add(T::DbWeight::get().reads(5))
 			.saturating_add(T::DbWeight::get().writes(3))
@@ -130,8 +132,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 6_957_000 picoseconds.
-		Weight::from_parts(7_417_000, 0)
+		// Minimum execution time: 6_979_000 picoseconds.
+		Weight::from_parts(7_342_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 	}
 	/// Storage: `XcmPallet::SupportedVersion` (r:0 w:1)
@@ -140,8 +142,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 7_053_000 picoseconds.
-		Weight::from_parts(7_462_000, 0)
+		// Minimum execution time: 7_144_000 picoseconds.
+		Weight::from_parts(7_297_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
@@ -149,8 +151,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 1_918_000 picoseconds.
-		Weight::from_parts(2_037_000, 0)
+		// Minimum execution time: 1_886_000 picoseconds.
+		Weight::from_parts(1_995_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 	}
 	/// Storage: `XcmPallet::VersionNotifiers` (r:1 w:1)
@@ -171,8 +173,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `180`
 		//  Estimated: `3645`
-		// Minimum execution time: 30_417_000 picoseconds.
-		Weight::from_parts(31_191_000, 0)
+		// Minimum execution time: 31_238_000 picoseconds.
+		Weight::from_parts(31_955_000, 0)
 			.saturating_add(Weight::from_parts(0, 3645))
 			.saturating_add(T::DbWeight::get().reads(6))
 			.saturating_add(T::DbWeight::get().writes(5))
@@ -193,8 +195,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `360`
 		//  Estimated: `3825`
-		// Minimum execution time: 36_666_000 picoseconds.
-		Weight::from_parts(37_779_000, 0)
+		// Minimum execution time: 37_237_000 picoseconds.
+		Weight::from_parts(38_569_000, 0)
 			.saturating_add(Weight::from_parts(0, 3825))
 			.saturating_add(T::DbWeight::get().reads(5))
 			.saturating_add(T::DbWeight::get().writes(4))
@@ -205,8 +207,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 1_869_000 picoseconds.
-		Weight::from_parts(2_003_000, 0)
+		// Minimum execution time: 1_884_000 picoseconds.
+		Weight::from_parts(2_028_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
@@ -216,8 +218,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `22`
 		//  Estimated: `13387`
-		// Minimum execution time: 16_188_000 picoseconds.
-		Weight::from_parts(16_435_000, 0)
+		// Minimum execution time: 16_048_000 picoseconds.
+		Weight::from_parts(16_617_000, 0)
 			.saturating_add(Weight::from_parts(0, 13387))
 			.saturating_add(T::DbWeight::get().reads(5))
 			.saturating_add(T::DbWeight::get().writes(2))
@@ -228,8 +230,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `26`
 		//  Estimated: `13391`
-		// Minimum execution time: 16_431_000 picoseconds.
-		Weight::from_parts(16_935_000, 0)
+		// Minimum execution time: 16_073_000 picoseconds.
+		Weight::from_parts(16_672_000, 0)
 			.saturating_add(Weight::from_parts(0, 13391))
 			.saturating_add(T::DbWeight::get().reads(5))
 			.saturating_add(T::DbWeight::get().writes(2))
@@ -240,8 +242,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `40`
 		//  Estimated: `15880`
-		// Minimum execution time: 18_460_000 picoseconds.
-		Weight::from_parts(18_885_000, 0)
+		// Minimum execution time: 18_422_000 picoseconds.
+		Weight::from_parts(18_900_000, 0)
 			.saturating_add(Weight::from_parts(0, 15880))
 			.saturating_add(T::DbWeight::get().reads(6))
 	}
@@ -259,8 +261,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `216`
 		//  Estimated: `6156`
-		// Minimum execution time: 29_623_000 picoseconds.
-		Weight::from_parts(30_661_000, 0)
+		// Minimum execution time: 30_373_000 picoseconds.
+		Weight::from_parts(30_972_000, 0)
 			.saturating_add(Weight::from_parts(0, 6156))
 			.saturating_add(T::DbWeight::get().reads(6))
 			.saturating_add(T::DbWeight::get().writes(3))
@@ -271,8 +273,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `69`
 		//  Estimated: `10959`
-		// Minimum execution time: 12_043_000 picoseconds.
-		Weight::from_parts(12_360_000, 0)
+		// Minimum execution time: 11_863_000 picoseconds.
+		Weight::from_parts(12_270_000, 0)
 			.saturating_add(Weight::from_parts(0, 10959))
 			.saturating_add(T::DbWeight::get().reads(4))
 	}
@@ -282,8 +284,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `33`
 		//  Estimated: `13398`
-		// Minimum execution time: 16_511_000 picoseconds.
-		Weight::from_parts(17_011_000, 0)
+		// Minimum execution time: 16_733_000 picoseconds.
+		Weight::from_parts(17_094_000, 0)
 			.saturating_add(Weight::from_parts(0, 13398))
 			.saturating_add(T::DbWeight::get().reads(5))
 			.saturating_add(T::DbWeight::get().writes(2))
@@ -302,8 +304,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `216`
 		//  Estimated: `13581`
-		// Minimum execution time: 39_041_000 picoseconds.
-		Weight::from_parts(39_883_000, 0)
+		// Minimum execution time: 39_236_000 picoseconds.
+		Weight::from_parts(40_587_000, 0)
 			.saturating_add(Weight::from_parts(0, 13581))
 			.saturating_add(T::DbWeight::get().reads(9))
 			.saturating_add(T::DbWeight::get().writes(4))
@@ -316,8 +318,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `1485`
-		// Minimum execution time: 2_030_000 picoseconds.
-		Weight::from_parts(2_150_000, 0)
+		// Minimum execution time: 2_145_000 picoseconds.
+		Weight::from_parts(2_255_000, 0)
 			.saturating_add(Weight::from_parts(0, 1485))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(2))
@@ -328,8 +330,8 @@ impl<T: frame_system::Config> pallet_xcm::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `7576`
 		//  Estimated: `11041`
-		// Minimum execution time: 22_615_000 picoseconds.
-		Weight::from_parts(23_008_000, 0)
+		// Minimum execution time: 22_518_000 picoseconds.
+		Weight::from_parts(22_926_000, 0)
 			.saturating_add(Weight::from_parts(0, 11041))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
diff --git a/polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_fungible.rs b/polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_fungible.rs
new file mode 100644
index 00000000000..dc5e5d8ca4b
--- /dev/null
+++ b/polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_fungible.rs
@@ -0,0 +1,191 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Polkadot.
+
+// Polkadot is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Polkadot is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `pallet_xcm_benchmarks::fungible`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/production/polkadot
+// benchmark
+// pallet
+// --chain=rococo-dev
+// --steps=50
+// --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --pallet=pallet_xcm_benchmarks::fungible
+// --extrinsic=*
+// --execution=wasm
+// --wasm-execution=compiled
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_fungible.rs
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `pallet_xcm_benchmarks::fungible`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> pallet_xcm_benchmarks::fungible::WeightInfo for WeightInfo<T> {
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	fn withdraw_asset() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `101`
+		//  Estimated: `3593`
+		// Minimum execution time: 27_223_000 picoseconds.
+		Weight::from_parts(27_947_000, 0)
+			.saturating_add(Weight::from_parts(0, 3593))
+			.saturating_add(T::DbWeight::get().reads(1))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+	/// Storage: `System::Account` (r:2 w:2)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	fn transfer_asset() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `101`
+		//  Estimated: `6196`
+		// Minimum execution time: 36_502_000 picoseconds.
+		Weight::from_parts(37_023_000, 0)
+			.saturating_add(Weight::from_parts(0, 6196))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+	/// Storage: `System::Account` (r:2 w:2)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0)
+	/// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `XcmPallet::SupportedVersion` (r:1 w:0)
+	/// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1)
+	/// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1)
+	/// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	fn transfer_reserve_asset() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `281`
+		//  Estimated: `6196`
+		// Minimum execution time: 85_152_000 picoseconds.
+		Weight::from_parts(86_442_000, 0)
+			.saturating_add(Weight::from_parts(0, 6196))
+			.saturating_add(T::DbWeight::get().reads(6))
+			.saturating_add(T::DbWeight::get().writes(4))
+	}
+	/// Storage: `Benchmark::Override` (r:0 w:0)
+	/// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	fn reserve_asset_deposited() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 18_446_744_073_709_551_000 picoseconds.
+		Weight::from_parts(18_446_744_073_709_551_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	/// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0)
+	/// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `XcmPallet::SupportedVersion` (r:1 w:0)
+	/// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1)
+	/// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1)
+	/// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	fn initiate_reserve_withdraw() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `281`
+		//  Estimated: `3746`
+		// Minimum execution time: 56_571_000 picoseconds.
+		Weight::from_parts(58_163_000, 0)
+			.saturating_add(Weight::from_parts(0, 3746))
+			.saturating_add(T::DbWeight::get().reads(5))
+			.saturating_add(T::DbWeight::get().writes(3))
+	}
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	fn receive_teleported_asset() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `103`
+		//  Estimated: `3593`
+		// Minimum execution time: 27_411_000 picoseconds.
+		Weight::from_parts(27_953_000, 0)
+			.saturating_add(Weight::from_parts(0, 3593))
+			.saturating_add(T::DbWeight::get().reads(1))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	fn deposit_asset() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `3593`
+		// Minimum execution time: 20_776_000 picoseconds.
+		Weight::from_parts(21_145_000, 0)
+			.saturating_add(Weight::from_parts(0, 3593))
+			.saturating_add(T::DbWeight::get().reads(1))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+	/// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0)
+	/// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `XcmPallet::SupportedVersion` (r:1 w:0)
+	/// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1)
+	/// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1)
+	/// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	fn deposit_reserve_asset() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `180`
+		//  Estimated: `3645`
+		// Minimum execution time: 51_738_000 picoseconds.
+		Weight::from_parts(53_251_000, 0)
+			.saturating_add(Weight::from_parts(0, 3645))
+			.saturating_add(T::DbWeight::get().reads(5))
+			.saturating_add(T::DbWeight::get().writes(3))
+	}
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0)
+	/// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `XcmPallet::SupportedVersion` (r:1 w:0)
+	/// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1)
+	/// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1)
+	/// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	fn initiate_teleport() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `180`
+		//  Estimated: `3645`
+		// Minimum execution time: 39_333_000 picoseconds.
+		Weight::from_parts(40_515_000, 0)
+			.saturating_add(Weight::from_parts(0, 3645))
+			.saturating_add(T::DbWeight::get().reads(5))
+			.saturating_add(T::DbWeight::get().writes(3))
+	}
+}
diff --git a/polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_generic.rs b/polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_generic.rs
new file mode 100644
index 00000000000..b62f36172ba
--- /dev/null
+++ b/polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_generic.rs
@@ -0,0 +1,347 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Polkadot.
+
+// Polkadot is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Polkadot is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `pallet_xcm_benchmarks::generic`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/production/polkadot
+// benchmark
+// pallet
+// --chain=rococo-dev
+// --steps=50
+// --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --pallet=pallet_xcm_benchmarks::generic
+// --extrinsic=*
+// --execution=wasm
+// --wasm-execution=compiled
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/pallet_xcm_benchmarks_generic.rs
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `pallet_xcm_benchmarks::generic`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> pallet_xcm_benchmarks::generic::WeightInfo for WeightInfo<T> {
+	/// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0)
+	/// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `XcmPallet::SupportedVersion` (r:1 w:0)
+	/// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1)
+	/// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1)
+	/// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	fn report_holding() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `281`
+		//  Estimated: `3746`
+		// Minimum execution time: 55_210_000 picoseconds.
+		Weight::from_parts(56_613_000, 0)
+			.saturating_add(Weight::from_parts(0, 3746))
+			.saturating_add(T::DbWeight::get().reads(5))
+			.saturating_add(T::DbWeight::get().writes(3))
+	}
+	fn buy_execution() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 1_246_000 picoseconds.
+		Weight::from_parts(1_339_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	/// Storage: `XcmPallet::Queries` (r:1 w:0)
+	/// Proof: `XcmPallet::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	fn query_response() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `3465`
+		// Minimum execution time: 5_377_000 picoseconds.
+		Weight::from_parts(5_549_000, 0)
+			.saturating_add(Weight::from_parts(0, 3465))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	fn transact() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 7_008_000 picoseconds.
+		Weight::from_parts(7_361_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn refund_surplus() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 1_700_000 picoseconds.
+		Weight::from_parts(1_848_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn set_error_handler() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 1_198_000 picoseconds.
+		Weight::from_parts(1_265_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn set_appendix() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 1_197_000 picoseconds.
+		Weight::from_parts(1_267_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn clear_error() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 1_193_000 picoseconds.
+		Weight::from_parts(1_258_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn descend_origin() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 1_268_000 picoseconds.
+		Weight::from_parts(1_342_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn clear_origin() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 1_173_000 picoseconds.
+		Weight::from_parts(1_248_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	/// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0)
+	/// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `XcmPallet::SupportedVersion` (r:1 w:0)
+	/// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1)
+	/// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1)
+	/// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	fn report_error() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `281`
+		//  Estimated: `3746`
+		// Minimum execution time: 53_715_000 picoseconds.
+		Weight::from_parts(54_860_000, 0)
+			.saturating_add(Weight::from_parts(0, 3746))
+			.saturating_add(T::DbWeight::get().reads(5))
+			.saturating_add(T::DbWeight::get().writes(3))
+	}
+	/// Storage: `XcmPallet::AssetTraps` (r:1 w:1)
+	/// Proof: `XcmPallet::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	fn claim_asset() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `23`
+		//  Estimated: `3488`
+		// Minimum execution time: 8_621_000 picoseconds.
+		Weight::from_parts(8_903_000, 0)
+			.saturating_add(Weight::from_parts(0, 3488))
+			.saturating_add(T::DbWeight::get().reads(1))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+	fn trap() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 1_211_000 picoseconds.
+		Weight::from_parts(1_281_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	/// Storage: `XcmPallet::VersionNotifyTargets` (r:1 w:1)
+	/// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0)
+	/// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `XcmPallet::SupportedVersion` (r:1 w:0)
+	/// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1)
+	/// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1)
+	/// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	fn subscribe_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `180`
+		//  Estimated: `3645`
+		// Minimum execution time: 26_448_000 picoseconds.
+		Weight::from_parts(27_057_000, 0)
+			.saturating_add(Weight::from_parts(0, 3645))
+			.saturating_add(T::DbWeight::get().reads(5))
+			.saturating_add(T::DbWeight::get().writes(3))
+	}
+	/// Storage: `XcmPallet::VersionNotifyTargets` (r:0 w:1)
+	/// Proof: `XcmPallet::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	fn unsubscribe_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 3_498_000 picoseconds.
+		Weight::from_parts(3_614_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+	fn burn_asset() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 1_575_000 picoseconds.
+		Weight::from_parts(1_698_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn expect_asset() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 1_334_000 picoseconds.
+		Weight::from_parts(1_435_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn expect_origin() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 1_244_000 picoseconds.
+		Weight::from_parts(1_337_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn expect_error() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 1_244_000 picoseconds.
+		Weight::from_parts(1_331_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn expect_transact_status() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 1_407_000 picoseconds.
+		Weight::from_parts(1_522_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	/// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0)
+	/// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `XcmPallet::SupportedVersion` (r:1 w:0)
+	/// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1)
+	/// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1)
+	/// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	fn query_pallet() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `281`
+		//  Estimated: `3746`
+		// Minimum execution time: 62_963_000 picoseconds.
+		Weight::from_parts(64_556_000, 0)
+			.saturating_add(Weight::from_parts(0, 3746))
+			.saturating_add(T::DbWeight::get().reads(5))
+			.saturating_add(T::DbWeight::get().writes(3))
+	}
+	fn expect_pallet() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 8_458_000 picoseconds.
+		Weight::from_parts(8_741_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	/// Storage: `Dmp::DeliveryFeeFactor` (r:1 w:0)
+	/// Proof: `Dmp::DeliveryFeeFactor` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `XcmPallet::SupportedVersion` (r:1 w:0)
+	/// Proof: `XcmPallet::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Dmp::DownwardMessageQueues` (r:1 w:1)
+	/// Proof: `Dmp::DownwardMessageQueues` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `Dmp::DownwardMessageQueueHeads` (r:1 w:1)
+	/// Proof: `Dmp::DownwardMessageQueueHeads` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	fn report_transact_status() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `281`
+		//  Estimated: `3746`
+		// Minimum execution time: 54_068_000 picoseconds.
+		Weight::from_parts(55_665_000, 0)
+			.saturating_add(Weight::from_parts(0, 3746))
+			.saturating_add(T::DbWeight::get().reads(5))
+			.saturating_add(T::DbWeight::get().writes(3))
+	}
+	fn clear_transact_status() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 1_290_000 picoseconds.
+		Weight::from_parts(1_348_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn set_topic() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 1_189_000 picoseconds.
+		Weight::from_parts(1_268_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn clear_topic() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 1_197_000 picoseconds.
+		Weight::from_parts(1_276_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn set_fees_mode() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 1_197_000 picoseconds.
+		Weight::from_parts(1_253_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn unpaid_execution() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 1_250_000 picoseconds.
+		Weight::from_parts(1_354_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+}
diff --git a/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_assigned_slots.rs b/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_assigned_slots.rs
index 2aaf282c59d..fd13c2ac946 100644
--- a/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_assigned_slots.rs
+++ b/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_assigned_slots.rs
@@ -16,26 +16,28 @@
 
 //! Autogenerated weights for `runtime_common::assigned_slots`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-08-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `runner-ynta1nyy-project-163-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
-//! EXECUTION: ``, WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
-// target/production/polkadot
+// ./target/production/polkadot
 // benchmark
 // pallet
+// --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --pallet=runtime_common::assigned_slots
 // --extrinsic=*
+// --execution=wasm
 // --wasm-execution=compiled
-// --heap-pages=4096
-// --json-file=/builds/parity/mirrors/polkadot/.git/.artifacts/bench.json
-// --pallet=runtime_common::assigned_slots
-// --chain=rococo-dev
-// --header=./file_header.txt
-// --output=./runtime/rococo/src/weights/
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/runtime_common_assigned_slots.rs
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -68,15 +70,15 @@ impl<T: frame_system::Config> polkadot_runtime_common::assigned_slots::WeightInf
 	/// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	fn assign_perm_parachain_slot() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `673`
-		//  Estimated: `4138`
-		// Minimum execution time: 84_646_000 picoseconds.
-		Weight::from_parts(91_791_000, 0)
-			.saturating_add(Weight::from_parts(0, 4138))
+		//  Measured:  `730`
+		//  Estimated: `4195`
+		// Minimum execution time: 71_337_000 picoseconds.
+		Weight::from_parts(80_807_000, 0)
+			.saturating_add(Weight::from_parts(0, 4195))
 			.saturating_add(T::DbWeight::get().reads(9))
-			.saturating_add(T::DbWeight::get().writes(6))
+			.saturating_add(T::DbWeight::get().writes(5))
 	}
-	/// Storage: `Registrar::Paras` (r:1 w:1)
+	/// Storage: `Registrar::Paras` (r:1 w:0)
 	/// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	/// Storage: `Paras::ParaLifecycles` (r:1 w:1)
 	/// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`)
@@ -98,13 +100,13 @@ impl<T: frame_system::Config> polkadot_runtime_common::assigned_slots::WeightInf
 	/// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	fn assign_temp_parachain_slot() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `673`
-		//  Estimated: `4138`
-		// Minimum execution time: 68_091_000 picoseconds.
-		Weight::from_parts(77_310_000, 0)
-			.saturating_add(Weight::from_parts(0, 4138))
+		//  Measured:  `730`
+		//  Estimated: `4195`
+		// Minimum execution time: 60_188_000 picoseconds.
+		Weight::from_parts(63_932_000, 0)
+			.saturating_add(Weight::from_parts(0, 4195))
 			.saturating_add(T::DbWeight::get().reads(10))
-			.saturating_add(T::DbWeight::get().writes(7))
+			.saturating_add(T::DbWeight::get().writes(6))
 	}
 	/// Storage: `AssignedSlots::PermanentSlots` (r:1 w:0)
 	/// Proof: `AssignedSlots::PermanentSlots` (`max_values`: None, `max_size`: Some(20), added: 2495, mode: `MaxEncodedLen`)
@@ -118,11 +120,11 @@ impl<T: frame_system::Config> polkadot_runtime_common::assigned_slots::WeightInf
 	/// Proof: `AssignedSlots::TemporarySlotCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
 	fn unassign_parachain_slot() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `823`
-		//  Estimated: `4288`
-		// Minimum execution time: 38_081_000 picoseconds.
-		Weight::from_parts(40_987_000, 0)
-			.saturating_add(Weight::from_parts(0, 4288))
+		//  Measured:  `856`
+		//  Estimated: `4321`
+		// Minimum execution time: 35_764_000 picoseconds.
+		Weight::from_parts(38_355_000, 0)
+			.saturating_add(Weight::from_parts(0, 4321))
 			.saturating_add(T::DbWeight::get().reads(5))
 			.saturating_add(T::DbWeight::get().writes(3))
 	}
@@ -132,8 +134,8 @@ impl<T: frame_system::Config> polkadot_runtime_common::assigned_slots::WeightInf
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 7_182_000 picoseconds.
-		Weight::from_parts(7_437_000, 0)
+		// Minimum execution time: 4_634_000 picoseconds.
+		Weight::from_parts(4_852_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
@@ -143,8 +145,8 @@ impl<T: frame_system::Config> polkadot_runtime_common::assigned_slots::WeightInf
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 7_153_000 picoseconds.
-		Weight::from_parts(7_456_000, 0)
+		// Minimum execution time: 4_563_000 picoseconds.
+		Weight::from_parts(4_829_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
diff --git a/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_auctions.rs b/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_auctions.rs
index 897dc1c1752..acf2da8cab9 100644
--- a/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_auctions.rs
+++ b/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_auctions.rs
@@ -16,11 +16,11 @@
 
 //! Autogenerated weights for `runtime_common::auctions`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
-//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
 // ./target/production/polkadot
@@ -29,12 +29,15 @@
 // --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
 // --pallet=runtime_common::auctions
 // --extrinsic=*
 // --execution=wasm
 // --wasm-execution=compiled
-// --header=./file_header.txt
-// --output=./runtime/rococo/src/weights/runtime_common_auctions.rs
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/runtime_common_auctions.rs
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -55,84 +58,82 @@ impl<T: frame_system::Config> polkadot_runtime_common::auctions::WeightInfo for
 		// Proof Size summary in bytes:
 		//  Measured:  `4`
 		//  Estimated: `1493`
-		// Minimum execution time: 12_805_000 picoseconds.
-		Weight::from_parts(13_153_000, 0)
+		// Minimum execution time: 7_307_000 picoseconds.
+		Weight::from_parts(7_680_000, 0)
 			.saturating_add(Weight::from_parts(0, 1493))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
-	/// Storage: Paras ParaLifecycles (r:1 w:0)
-	/// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Auctions AuctionCounter (r:1 w:0)
-	/// Proof: Auctions AuctionCounter (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
-	/// Storage: Auctions AuctionInfo (r:1 w:0)
-	/// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen)
-	/// Storage: Slots Leases (r:1 w:0)
-	/// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Auctions Winning (r:1 w:1)
-	/// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen)
-	/// Storage: Auctions ReservedAmounts (r:2 w:2)
-	/// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen)
-	/// Storage: System Account (r:1 w:1)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
+	/// Storage: `Paras::ParaLifecycles` (r:1 w:0)
+	/// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Auctions::AuctionCounter` (r:1 w:0)
+	/// Proof: `Auctions::AuctionCounter` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
+	/// Storage: `Auctions::AuctionInfo` (r:1 w:0)
+	/// Proof: `Auctions::AuctionInfo` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`)
+	/// Storage: `Slots::Leases` (r:1 w:0)
+	/// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Auctions::Winning` (r:1 w:1)
+	/// Proof: `Auctions::Winning` (`max_values`: None, `max_size`: Some(1920), added: 4395, mode: `MaxEncodedLen`)
+	/// Storage: `Auctions::ReservedAmounts` (r:2 w:2)
+	/// Proof: `Auctions::ReservedAmounts` (`max_values`: None, `max_size`: Some(60), added: 2535, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
 	fn bid() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `728`
+		//  Measured:  `761`
 		//  Estimated: `6060`
-		// Minimum execution time: 77_380_000 picoseconds.
-		Weight::from_parts(80_503_000, 0)
+		// Minimum execution time: 75_448_000 picoseconds.
+		Weight::from_parts(78_716_000, 0)
 			.saturating_add(Weight::from_parts(0, 6060))
 			.saturating_add(T::DbWeight::get().reads(8))
 			.saturating_add(T::DbWeight::get().writes(4))
 	}
-	/// Storage: Auctions AuctionInfo (r:1 w:1)
-	/// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen)
-	/// Storage: Babe NextRandomness (r:1 w:0)
-	/// Proof: Babe NextRandomness (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen)
-	/// Storage: Babe EpochStart (r:1 w:0)
-	/// Proof: Babe EpochStart (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen)
-	/// Storage: Auctions AuctionCounter (r:1 w:0)
-	/// Proof: Auctions AuctionCounter (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
-	/// Storage: Auctions Winning (r:3600 w:3600)
-	/// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen)
-	/// Storage: Auctions ReservedAmounts (r:37 w:36)
-	/// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen)
-	/// Storage: System Account (r:36 w:36)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
-	/// Storage: Slots Leases (r:2 w:2)
-	/// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Paras ParaLifecycles (r:1 w:1)
-	/// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured)
-	/// Storage: ParasShared CurrentSessionIndex (r:1 w:0)
-	/// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras ActionsQueue (r:1 w:1)
-	/// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Registrar Paras (r:1 w:1)
-	/// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `Auctions::AuctionInfo` (r:1 w:1)
+	/// Proof: `Auctions::AuctionInfo` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`)
+	/// Storage: `Babe::NextRandomness` (r:1 w:0)
+	/// Proof: `Babe::NextRandomness` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
+	/// Storage: `Babe::EpochStart` (r:1 w:0)
+	/// Proof: `Babe::EpochStart` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`)
+	/// Storage: `Auctions::AuctionCounter` (r:1 w:0)
+	/// Proof: `Auctions::AuctionCounter` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
+	/// Storage: `Auctions::Winning` (r:3600 w:3600)
+	/// Proof: `Auctions::Winning` (`max_values`: None, `max_size`: Some(1920), added: 4395, mode: `MaxEncodedLen`)
+	/// Storage: `Auctions::ReservedAmounts` (r:37 w:36)
+	/// Proof: `Auctions::ReservedAmounts` (`max_values`: None, `max_size`: Some(60), added: 2535, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:36 w:36)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `Slots::Leases` (r:2 w:2)
+	/// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::ParaLifecycles` (r:1 w:1)
+	/// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0)
+	/// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::ActionsQueue` (r:1 w:1)
+	/// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	fn on_initialize() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `6947789`
+		//  Measured:  `6947017`
 		//  Estimated: `15822990`
-		// Minimum execution time: 6_311_055_000 picoseconds.
-		Weight::from_parts(6_409_142_000, 0)
+		// Minimum execution time: 7_120_207_000 picoseconds.
+		Weight::from_parts(7_273_496_000, 0)
 			.saturating_add(Weight::from_parts(0, 15822990))
-			.saturating_add(T::DbWeight::get().reads(3683))
-			.saturating_add(T::DbWeight::get().writes(3678))
+			.saturating_add(T::DbWeight::get().reads(3682))
+			.saturating_add(T::DbWeight::get().writes(3677))
 	}
-	/// Storage: Auctions ReservedAmounts (r:37 w:36)
-	/// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen)
-	/// Storage: System Account (r:36 w:36)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
-	/// Storage: Auctions Winning (r:3600 w:3600)
-	/// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen)
-	/// Storage: Auctions AuctionInfo (r:0 w:1)
-	/// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen)
+	/// Storage: `Auctions::ReservedAmounts` (r:37 w:36)
+	/// Proof: `Auctions::ReservedAmounts` (`max_values`: None, `max_size`: Some(60), added: 2535, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:36 w:36)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `Auctions::Winning` (r:3600 w:3600)
+	/// Proof: `Auctions::Winning` (`max_values`: None, `max_size`: Some(1920), added: 4395, mode: `MaxEncodedLen`)
+	/// Storage: `Auctions::AuctionInfo` (r:0 w:1)
+	/// Proof: `Auctions::AuctionInfo` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`)
 	fn cancel_auction() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `177732`
 		//  Estimated: `15822990`
-		// Minimum execution time: 4_849_561_000 picoseconds.
-		Weight::from_parts(4_955_226_000, 0)
+		// Minimum execution time: 5_536_281_000 picoseconds.
+		Weight::from_parts(5_675_163_000, 0)
 			.saturating_add(Weight::from_parts(0, 15822990))
 			.saturating_add(T::DbWeight::get().reads(3673))
 			.saturating_add(T::DbWeight::get().writes(3673))
diff --git a/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_claims.rs b/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_claims.rs
index 8fbc798dbd4..3871310678e 100644
--- a/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_claims.rs
+++ b/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_claims.rs
@@ -16,11 +16,11 @@
 
 //! Autogenerated weights for `runtime_common::claims`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
-//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
 // ./target/production/polkadot
@@ -29,12 +29,15 @@
 // --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
 // --pallet=runtime_common::claims
 // --extrinsic=*
 // --execution=wasm
 // --wasm-execution=compiled
-// --header=./file_header.txt
-// --output=./runtime/rococo/src/weights/runtime_common_claims.rs
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/runtime_common_claims.rs
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -67,100 +70,113 @@ impl<T: frame_system::Config> polkadot_runtime_common::claims::WeightInfo for We
 		// Proof Size summary in bytes:
 		//  Measured:  `558`
 		//  Estimated: `4764`
-		// Minimum execution time: 144_931_000 picoseconds.
-		Weight::from_parts(156_550_000, 0)
+		// Minimum execution time: 181_028_000 picoseconds.
+		Weight::from_parts(194_590_000, 0)
 			.saturating_add(Weight::from_parts(0, 4764))
 			.saturating_add(T::DbWeight::get().reads(8))
 			.saturating_add(T::DbWeight::get().writes(6))
 	}
-	/// Storage: Claims Total (r:1 w:1)
-	/// Proof Skipped: Claims Total (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Claims Vesting (r:0 w:1)
-	/// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Claims Claims (r:0 w:1)
-	/// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Claims Signing (r:0 w:1)
-	/// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `Claims::Total` (r:1 w:1)
+	/// Proof: `Claims::Total` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Claims::Vesting` (r:0 w:1)
+	/// Proof: `Claims::Vesting` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Claims::Claims` (r:0 w:1)
+	/// Proof: `Claims::Claims` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Claims::Signing` (r:0 w:1)
+	/// Proof: `Claims::Signing` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	fn mint_claim() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `216`
 		//  Estimated: `1701`
-		// Minimum execution time: 11_300_000 picoseconds.
-		Weight::from_parts(11_642_000, 0)
+		// Minimum execution time: 11_224_000 picoseconds.
+		Weight::from_parts(13_342_000, 0)
 			.saturating_add(Weight::from_parts(0, 1701))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(4))
 	}
-	/// Storage: Claims Claims (r:1 w:1)
-	/// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Claims Signing (r:1 w:1)
-	/// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Claims Total (r:1 w:1)
-	/// Proof Skipped: Claims Total (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Claims Vesting (r:1 w:1)
-	/// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Vesting Vesting (r:1 w:1)
-	/// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen)
-	/// Storage: System Account (r:1 w:0)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
-	/// Storage: Balances Locks (r:1 w:1)
-	/// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen)
-	/// Storage: Balances Freezes (r:1 w:0)
-	/// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen)
+	/// Storage: `Claims::Claims` (r:1 w:1)
+	/// Proof: `Claims::Claims` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Claims::Signing` (r:1 w:1)
+	/// Proof: `Claims::Signing` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Claims::Total` (r:1 w:1)
+	/// Proof: `Claims::Total` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Claims::Vesting` (r:1 w:1)
+	/// Proof: `Claims::Vesting` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Vesting::Vesting` (r:1 w:1)
+	/// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:0)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Locks` (r:1 w:1)
+	/// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Freezes` (r:1 w:0)
+	/// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`)
 	fn claim_attest() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `558`
 		//  Estimated: `4764`
-		// Minimum execution time: 149_112_000 picoseconds.
-		Weight::from_parts(153_872_000, 0)
+		// Minimum execution time: 187_964_000 picoseconds.
+		Weight::from_parts(202_553_000, 0)
 			.saturating_add(Weight::from_parts(0, 4764))
 			.saturating_add(T::DbWeight::get().reads(8))
 			.saturating_add(T::DbWeight::get().writes(6))
 	}
-	/// Storage: Claims Preclaims (r:1 w:1)
-	/// Proof Skipped: Claims Preclaims (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Claims Signing (r:1 w:1)
-	/// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Claims Claims (r:1 w:1)
-	/// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Claims Total (r:1 w:1)
-	/// Proof Skipped: Claims Total (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Claims Vesting (r:1 w:1)
-	/// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Vesting Vesting (r:1 w:1)
-	/// Proof: Vesting Vesting (max_values: None, max_size: Some(1057), added: 3532, mode: MaxEncodedLen)
-	/// Storage: System Account (r:1 w:0)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
-	/// Storage: Balances Locks (r:1 w:1)
-	/// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen)
-	/// Storage: Balances Freezes (r:1 w:0)
-	/// Proof: Balances Freezes (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen)
+	/// Storage: `Claims::Preclaims` (r:1 w:1)
+	/// Proof: `Claims::Preclaims` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Claims::Signing` (r:1 w:1)
+	/// Proof: `Claims::Signing` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Claims::Claims` (r:1 w:1)
+	/// Proof: `Claims::Claims` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Claims::Total` (r:1 w:1)
+	/// Proof: `Claims::Total` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Claims::Vesting` (r:1 w:1)
+	/// Proof: `Claims::Vesting` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Vesting::Vesting` (r:1 w:1)
+	/// Proof: `Vesting::Vesting` (`max_values`: None, `max_size`: Some(1057), added: 3532, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:0)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Locks` (r:1 w:1)
+	/// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`)
+	/// Storage: `Balances::Freezes` (r:1 w:0)
+	/// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`)
 	fn attest() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `632`
 		//  Estimated: `4764`
-		// Minimum execution time: 69_619_000 picoseconds.
-		Weight::from_parts(79_242_000, 0)
+		// Minimum execution time: 78_210_000 picoseconds.
+		Weight::from_parts(84_581_000, 0)
 			.saturating_add(Weight::from_parts(0, 4764))
 			.saturating_add(T::DbWeight::get().reads(9))
 			.saturating_add(T::DbWeight::get().writes(7))
 	}
-	/// Storage: Claims Claims (r:1 w:2)
-	/// Proof Skipped: Claims Claims (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Claims Vesting (r:1 w:2)
-	/// Proof Skipped: Claims Vesting (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Claims Signing (r:1 w:2)
-	/// Proof Skipped: Claims Signing (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Claims Preclaims (r:1 w:1)
-	/// Proof Skipped: Claims Preclaims (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `Claims::Claims` (r:1 w:2)
+	/// Proof: `Claims::Claims` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Claims::Vesting` (r:1 w:2)
+	/// Proof: `Claims::Vesting` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Claims::Signing` (r:1 w:2)
+	/// Proof: `Claims::Signing` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Claims::Preclaims` (r:1 w:1)
+	/// Proof: `Claims::Preclaims` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	fn move_claim() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `440`
 		//  Estimated: `3905`
-		// Minimum execution time: 22_066_000 picoseconds.
-		Weight::from_parts(22_483_000, 0)
+		// Minimum execution time: 33_940_000 picoseconds.
+		Weight::from_parts(48_438_000, 0)
 			.saturating_add(Weight::from_parts(0, 3905))
 			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(7))
 	}
+	/// Storage: `Claims::Preclaims` (r:1 w:0)
+	/// Proof: `Claims::Preclaims` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Claims::Signing` (r:1 w:0)
+	/// Proof: `Claims::Signing` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	fn prevalidate_attests() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `296`
+		//  Estimated: `3761`
+		// Minimum execution time: 9_025_000 picoseconds.
+		Weight::from_parts(10_563_000, 0)
+			.saturating_add(Weight::from_parts(0, 3761))
+			.saturating_add(T::DbWeight::get().reads(2))
+	}
 }
diff --git a/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_crowdloan.rs b/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_crowdloan.rs
index b75ff8d42e7..2a01de67acc 100644
--- a/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_crowdloan.rs
+++ b/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_crowdloan.rs
@@ -16,11 +16,11 @@
 
 //! Autogenerated weights for `runtime_common::crowdloan`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
-//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
 // ./target/production/polkadot
@@ -29,12 +29,15 @@
 // --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
 // --pallet=runtime_common::crowdloan
 // --extrinsic=*
 // --execution=wasm
 // --wasm-execution=compiled
-// --header=./file_header.txt
-// --output=./runtime/rococo/src/weights/runtime_common_crowdloan.rs
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/runtime_common_crowdloan.rs
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -61,158 +64,154 @@ impl<T: frame_system::Config> polkadot_runtime_common::crowdloan::WeightInfo for
 		// Proof Size summary in bytes:
 		//  Measured:  `438`
 		//  Estimated: `3903`
-		// Minimum execution time: 50_399_000 picoseconds.
-		Weight::from_parts(51_641_000, 0)
+		// Minimum execution time: 46_095_000 picoseconds.
+		Weight::from_parts(48_111_000, 0)
 			.saturating_add(Weight::from_parts(0, 3903))
 			.saturating_add(T::DbWeight::get().reads(5))
-			.saturating_add(T::DbWeight::get().writes(4))
+			.saturating_add(T::DbWeight::get().writes(3))
 	}
-	/// Storage: Crowdloan Funds (r:1 w:1)
-	/// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Slots Leases (r:1 w:0)
-	/// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Auctions AuctionInfo (r:1 w:0)
-	/// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen)
-	/// Storage: System Account (r:1 w:1)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
-	/// Storage: Balances InactiveIssuance (r:1 w:1)
-	/// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen)
-	/// Storage: Crowdloan EndingsCount (r:1 w:0)
-	/// Proof Skipped: Crowdloan EndingsCount (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Crowdloan NewRaise (r:1 w:1)
-	/// Proof Skipped: Crowdloan NewRaise (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1)
-	/// Proof Skipped: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1)
+	/// Storage: `Crowdloan::Funds` (r:1 w:1)
+	/// Proof: `Crowdloan::Funds` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Slots::Leases` (r:1 w:0)
+	/// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Auctions::AuctionInfo` (r:1 w:0)
+	/// Proof: `Auctions::AuctionInfo` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `Crowdloan::EndingsCount` (r:1 w:0)
+	/// Proof: `Crowdloan::EndingsCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Crowdloan::NewRaise` (r:1 w:1)
+	/// Proof: `Crowdloan::NewRaise` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: UNKNOWN KEY `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1)
+	/// Proof: UNKNOWN KEY `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1)
 	fn contribute() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `530`
-		//  Estimated: `3995`
-		// Minimum execution time: 128_898_000 picoseconds.
-		Weight::from_parts(130_277_000, 0)
-			.saturating_add(Weight::from_parts(0, 3995))
-			.saturating_add(T::DbWeight::get().reads(8))
-			.saturating_add(T::DbWeight::get().writes(5))
+		//  Measured:  `563`
+		//  Estimated: `4028`
+		// Minimum execution time: 133_059_000 picoseconds.
+		Weight::from_parts(136_515_000, 0)
+			.saturating_add(Weight::from_parts(0, 4028))
+			.saturating_add(T::DbWeight::get().reads(7))
+			.saturating_add(T::DbWeight::get().writes(4))
 	}
-	/// Storage: Crowdloan Funds (r:1 w:1)
-	/// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured)
-	/// Storage: System Account (r:2 w:2)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
-	/// Storage: Balances InactiveIssuance (r:1 w:1)
-	/// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen)
-	/// Storage: unknown `0xc85982571aa615c788ef9b2c16f54f25773fd439e8ee1ed2aa3ae43d48e880f0` (r:1 w:1)
-	/// Proof Skipped: unknown `0xc85982571aa615c788ef9b2c16f54f25773fd439e8ee1ed2aa3ae43d48e880f0` (r:1 w:1)
+	/// Storage: `Crowdloan::Funds` (r:1 w:1)
+	/// Proof: `Crowdloan::Funds` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `System::Account` (r:2 w:2)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: UNKNOWN KEY `0xc85982571aa615c788ef9b2c16f54f25773fd439e8ee1ed2aa3ae43d48e880f0` (r:1 w:1)
+	/// Proof: UNKNOWN KEY `0xc85982571aa615c788ef9b2c16f54f25773fd439e8ee1ed2aa3ae43d48e880f0` (r:1 w:1)
 	fn withdraw() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `689`
+		//  Measured:  `687`
 		//  Estimated: `6196`
-		// Minimum execution time: 69_543_000 picoseconds.
-		Weight::from_parts(71_522_000, 0)
+		// Minimum execution time: 71_733_000 picoseconds.
+		Weight::from_parts(74_034_000, 0)
 			.saturating_add(Weight::from_parts(0, 6196))
-			.saturating_add(T::DbWeight::get().reads(5))
-			.saturating_add(T::DbWeight::get().writes(5))
+			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().writes(4))
 	}
-	/// Storage: Skipped Metadata (r:0 w:0)
-	/// Proof Skipped: Skipped Metadata (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `Skipped::Metadata` (r:0 w:0)
+	/// Proof: `Skipped::Metadata` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	/// The range of component `k` is `[0, 1000]`.
 	fn refund(k: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `127 + k * (189 ±0)`
-		//  Estimated: `140 + k * (189 ±0)`
-		// Minimum execution time: 50_735_000 picoseconds.
-		Weight::from_parts(52_282_000, 0)
-			.saturating_add(Weight::from_parts(0, 140))
-			// Standard Error: 21_607
-			.saturating_add(Weight::from_parts(38_955_985, 0).saturating_mul(k.into()))
-			.saturating_add(T::DbWeight::get().reads(4))
+		//  Measured:  `125 + k * (189 ±0)`
+		//  Estimated: `138 + k * (189 ±0)`
+		// Minimum execution time: 46_016_000 picoseconds.
+		Weight::from_parts(48_260_000, 0)
+			.saturating_add(Weight::from_parts(0, 138))
+			// Standard Error: 21_140
+			.saturating_add(Weight::from_parts(39_141_925, 0).saturating_mul(k.into()))
+			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(k.into())))
-			.saturating_add(T::DbWeight::get().writes(3))
+			.saturating_add(T::DbWeight::get().writes(2))
 			.saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(k.into())))
 			.saturating_add(Weight::from_parts(0, 189).saturating_mul(k.into()))
 	}
-	/// Storage: Crowdloan Funds (r:1 w:1)
-	/// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured)
-	/// Storage: System Account (r:2 w:2)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
+	/// Storage: `Crowdloan::Funds` (r:1 w:1)
+	/// Proof: `Crowdloan::Funds` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `System::Account` (r:2 w:2)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
 	fn dissolve() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `515`
+		//  Measured:  `514`
 		//  Estimated: `6196`
-		// Minimum execution time: 43_100_000 picoseconds.
-		Weight::from_parts(44_272_000, 0)
+		// Minimum execution time: 44_724_000 picoseconds.
+		Weight::from_parts(47_931_000, 0)
 			.saturating_add(Weight::from_parts(0, 6196))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(3))
 	}
-	/// Storage: Crowdloan Funds (r:1 w:1)
-	/// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `Crowdloan::Funds` (r:1 w:1)
+	/// Proof: `Crowdloan::Funds` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	fn edit() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `235`
-		//  Estimated: `3700`
-		// Minimum execution time: 18_702_000 picoseconds.
-		Weight::from_parts(19_408_000, 0)
-			.saturating_add(Weight::from_parts(0, 3700))
+		//  Measured:  `234`
+		//  Estimated: `3699`
+		// Minimum execution time: 19_512_000 picoseconds.
+		Weight::from_parts(21_129_000, 0)
+			.saturating_add(Weight::from_parts(0, 3699))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Crowdloan Funds (r:1 w:0)
-	/// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured)
-	/// Storage: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1)
-	/// Proof Skipped: unknown `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1)
+	/// Storage: `Crowdloan::Funds` (r:1 w:0)
+	/// Proof: `Crowdloan::Funds` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: UNKNOWN KEY `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1)
+	/// Proof: UNKNOWN KEY `0xd861ea1ebf4800d4b89f4ff787ad79ee96d9a708c85b57da7eb8f9ddeda61291` (r:1 w:1)
 	fn add_memo() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `412`
 		//  Estimated: `3877`
-		// Minimum execution time: 25_568_000 picoseconds.
-		Weight::from_parts(26_203_000, 0)
+		// Minimum execution time: 33_529_000 picoseconds.
+		Weight::from_parts(37_082_000, 0)
 			.saturating_add(Weight::from_parts(0, 3877))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Crowdloan Funds (r:1 w:0)
-	/// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Crowdloan NewRaise (r:1 w:1)
-	/// Proof Skipped: Crowdloan NewRaise (max_values: Some(1), max_size: None, mode: Measured)
+	/// Storage: `Crowdloan::Funds` (r:1 w:0)
+	/// Proof: `Crowdloan::Funds` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Crowdloan::NewRaise` (r:1 w:1)
+	/// Proof: `Crowdloan::NewRaise` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
 	fn poke() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `239`
-		//  Estimated: `3704`
-		// Minimum execution time: 17_832_000 picoseconds.
-		Weight::from_parts(18_769_000, 0)
-			.saturating_add(Weight::from_parts(0, 3704))
+		//  Measured:  `238`
+		//  Estimated: `3703`
+		// Minimum execution time: 23_153_000 picoseconds.
+		Weight::from_parts(24_181_000, 0)
+			.saturating_add(Weight::from_parts(0, 3703))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Auctions AuctionInfo (r:1 w:0)
-	/// Proof: Auctions AuctionInfo (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen)
-	/// Storage: Crowdloan EndingsCount (r:1 w:1)
-	/// Proof Skipped: Crowdloan EndingsCount (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Crowdloan NewRaise (r:1 w:1)
-	/// Proof Skipped: Crowdloan NewRaise (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Crowdloan Funds (r:100 w:0)
-	/// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Auctions AuctionCounter (r:1 w:0)
-	/// Proof: Auctions AuctionCounter (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
-	/// Storage: Paras ParaLifecycles (r:100 w:0)
-	/// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Slots Leases (r:100 w:0)
-	/// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Auctions Winning (r:1 w:1)
-	/// Proof: Auctions Winning (max_values: None, max_size: Some(1920), added: 4395, mode: MaxEncodedLen)
-	/// Storage: Auctions ReservedAmounts (r:100 w:100)
-	/// Proof: Auctions ReservedAmounts (max_values: None, max_size: Some(60), added: 2535, mode: MaxEncodedLen)
-	/// Storage: System Account (r:100 w:100)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
+	/// Storage: `Auctions::AuctionInfo` (r:1 w:0)
+	/// Proof: `Auctions::AuctionInfo` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`)
+	/// Storage: `Crowdloan::EndingsCount` (r:1 w:1)
+	/// Proof: `Crowdloan::EndingsCount` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Crowdloan::NewRaise` (r:1 w:1)
+	/// Proof: `Crowdloan::NewRaise` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Crowdloan::Funds` (r:100 w:0)
+	/// Proof: `Crowdloan::Funds` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Auctions::AuctionCounter` (r:1 w:0)
+	/// Proof: `Auctions::AuctionCounter` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
+	/// Storage: `Paras::ParaLifecycles` (r:100 w:0)
+	/// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Slots::Leases` (r:100 w:0)
+	/// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Auctions::Winning` (r:1 w:1)
+	/// Proof: `Auctions::Winning` (`max_values`: None, `max_size`: Some(1920), added: 4395, mode: `MaxEncodedLen`)
+	/// Storage: `Auctions::ReservedAmounts` (r:100 w:100)
+	/// Proof: `Auctions::ReservedAmounts` (`max_values`: None, `max_size`: Some(60), added: 2535, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:100 w:100)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
 	/// The range of component `n` is `[2, 100]`.
 	fn on_initialize(n: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `197 + n * (356 ±0)`
+		//  Measured:  `229 + n * (356 ±0)`
 		//  Estimated: `5385 + n * (2832 ±0)`
-		// Minimum execution time: 128_319_000 picoseconds.
-		Weight::from_parts(130_877_000, 0)
+		// Minimum execution time: 120_164_000 picoseconds.
+		Weight::from_parts(3_390_119, 0)
 			.saturating_add(Weight::from_parts(0, 5385))
-			// Standard Error: 61_381
-			.saturating_add(Weight::from_parts(60_209_202, 0).saturating_mul(n.into()))
+			// Standard Error: 41_727
+			.saturating_add(Weight::from_parts(54_453_016, 0).saturating_mul(n.into()))
 			.saturating_add(T::DbWeight::get().reads(5))
 			.saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(n.into())))
 			.saturating_add(T::DbWeight::get().writes(3))
diff --git a/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_identity_migrator.rs b/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_identity_migrator.rs
index 4ea6f679680..3df3c6c8dd9 100644
--- a/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_identity_migrator.rs
+++ b/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_identity_migrator.rs
@@ -1,36 +1,43 @@
 // Copyright (C) Parity Technologies (UK) Ltd.
-// SPDX-License-Identifier: Apache-2.0
+// This file is part of Polkadot.
 
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// 	http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+// Polkadot is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Polkadot is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
 
 //! Autogenerated weights for `runtime_common::identity_migrator`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-11-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `sbtb`, CPU: `13th Gen Intel(R) Core(TM) i7-1365U`
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
-// ./target/release/polkadot
+// ./target/production/polkadot
 // benchmark
 // pallet
 // --chain=rococo-dev
-// --steps=2
-// --repeat=1
+// --steps=50
+// --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
 // --pallet=runtime_common::identity_migrator
 // --extrinsic=*
-// --output=./migrator-release.rs
+// --execution=wasm
+// --wasm-execution=compiled
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/runtime_common_identity_migrator.rs
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -44,7 +51,7 @@ use core::marker::PhantomData;
 pub struct WeightInfo<T>(PhantomData<T>);
 impl<T: frame_system::Config> polkadot_runtime_common::identity_migrator::WeightInfo for WeightInfo<T> {
 	/// Storage: `Identity::IdentityOf` (r:1 w:1)
-	/// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`)
+	/// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`)
 	/// Storage: `Identity::SubsOf` (r:1 w:1)
 	/// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`)
 	/// Storage: `System::Account` (r:2 w:2)
@@ -63,34 +70,34 @@ impl<T: frame_system::Config> polkadot_runtime_common::identity_migrator::Weight
 	/// The range of component `s` is `[0, 100]`.
 	fn reap_identity(r: u32, s: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `7292 + r * (8 ±0) + s * (32 ±0)`
-		//  Estimated: `11003 + r * (8 ±0) + s * (33 ±0)`
-		// Minimum execution time: 163_756_000 picoseconds.
-		Weight::from_parts(158_982_500, 0)
-			.saturating_add(Weight::from_parts(0, 11003))
-			// Standard Error: 1_143_629
-			.saturating_add(Weight::from_parts(238_675, 0).saturating_mul(r.into()))
-			// Standard Error: 228_725
-			.saturating_add(Weight::from_parts(1_529_645, 0).saturating_mul(s.into()))
+		//  Measured:  `7457 + r * (5 ±0) + s * (32 ±0)`
+		//  Estimated: `11037 + r * (7 ±0) + s * (32 ±0)`
+		// Minimum execution time: 157_343_000 picoseconds.
+		Weight::from_parts(159_289_236, 0)
+			.saturating_add(Weight::from_parts(0, 11037))
+			// Standard Error: 16_439
+			.saturating_add(Weight::from_parts(224_293, 0).saturating_mul(r.into()))
+			// Standard Error: 3_367
+			.saturating_add(Weight::from_parts(1_383_637, 0).saturating_mul(s.into()))
 			.saturating_add(T::DbWeight::get().reads(8))
-			.saturating_add(T::DbWeight::get().writes(5))
+			.saturating_add(T::DbWeight::get().writes(6))
 			.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into())))
-			.saturating_add(Weight::from_parts(0, 8).saturating_mul(r.into()))
-			.saturating_add(Weight::from_parts(0, 33).saturating_mul(s.into()))
+			.saturating_add(Weight::from_parts(0, 7).saturating_mul(r.into()))
+			.saturating_add(Weight::from_parts(0, 32).saturating_mul(s.into()))
 	}
 	/// Storage: `Identity::IdentityOf` (r:1 w:1)
-	/// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7538), added: 10013, mode: `MaxEncodedLen`)
+	/// Proof: `Identity::IdentityOf` (`max_values`: None, `max_size`: Some(7572), added: 10047, mode: `MaxEncodedLen`)
 	/// Storage: `System::Account` (r:1 w:1)
 	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
 	/// Storage: `Identity::SubsOf` (r:1 w:1)
 	/// Proof: `Identity::SubsOf` (`max_values`: None, `max_size`: Some(3258), added: 5733, mode: `MaxEncodedLen`)
 	fn poke_deposit() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `7229`
-		//  Estimated: `11003`
-		// Minimum execution time: 137_570_000 picoseconds.
-		Weight::from_parts(137_570_000, 0)
-			.saturating_add(Weight::from_parts(0, 11003))
+		//  Measured:  `7242`
+		//  Estimated: `11037`
+		// Minimum execution time: 114_384_000 picoseconds.
+		Weight::from_parts(115_741_000, 0)
+			.saturating_add(Weight::from_parts(0, 11037))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(3))
 	}
diff --git a/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_paras_registrar.rs b/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_paras_registrar.rs
index 0ce09d1be2a..ad261a7f774 100644
--- a/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_paras_registrar.rs
+++ b/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_paras_registrar.rs
@@ -16,11 +16,11 @@
 
 //! Autogenerated weights for `runtime_common::paras_registrar`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
-//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
 // ./target/production/polkadot
@@ -29,12 +29,15 @@
 // --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
 // --pallet=runtime_common::paras_registrar
 // --extrinsic=*
 // --execution=wasm
 // --wasm-execution=compiled
-// --header=./file_header.txt
-// --output=./runtime/rococo/src/weights/runtime_common_paras_registrar.rs
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/runtime_common_paras_registrar.rs
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -55,167 +58,161 @@ impl<T: frame_system::Config> polkadot_runtime_common::paras_registrar::WeightIn
 	/// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured)
 	fn reserve() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `97`
-		//  Estimated: `3562`
-		// Minimum execution time: 29_948_000 picoseconds.
-		Weight::from_parts(30_433_000, 0)
-			.saturating_add(Weight::from_parts(0, 3562))
+		//  Measured:  `96`
+		//  Estimated: `3561`
+		// Minimum execution time: 24_109_000 picoseconds.
+		Weight::from_parts(24_922_000, 0)
+			.saturating_add(Weight::from_parts(0, 3561))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
-	/// Storage: Registrar Paras (r:1 w:1)
-	/// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Paras ParaLifecycles (r:1 w:1)
-	/// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Configuration ActiveConfig (r:1 w:0)
-	/// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras PvfActiveVoteMap (r:1 w:1)
-	/// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Paras CodeByHash (r:1 w:1)
-	/// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured)
-	/// Storage: ParasShared ActiveValidatorKeys (r:1 w:0)
-	/// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras PvfActiveVoteList (r:1 w:1)
-	/// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras CodeByHashRefs (r:1 w:1)
-	/// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Paras CurrentCodeHash (r:0 w:1)
-	/// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Paras UpcomingParasGenesis (r:0 w:1)
-	/// Proof Skipped: Paras UpcomingParasGenesis (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `Registrar::Paras` (r:1 w:1)
+	/// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::ParaLifecycles` (r:1 w:1)
+	/// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1)
+	/// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::CodeByHash` (r:1 w:1)
+	/// Proof: `Paras::CodeByHash` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0)
+	/// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::PvfActiveVoteList` (r:1 w:1)
+	/// Proof: `Paras::PvfActiveVoteList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::CodeByHashRefs` (r:1 w:1)
+	/// Proof: `Paras::CodeByHashRefs` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::CurrentCodeHash` (r:0 w:1)
+	/// Proof: `Paras::CurrentCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::UpcomingParasGenesis` (r:0 w:1)
+	/// Proof: `Paras::UpcomingParasGenesis` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	fn register() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `616`
-		//  Estimated: `4081`
-		// Minimum execution time: 6_332_113_000 picoseconds.
-		Weight::from_parts(6_407_158_000, 0)
-			.saturating_add(Weight::from_parts(0, 4081))
-			.saturating_add(T::DbWeight::get().reads(8))
+		//  Measured:  `352`
+		//  Estimated: `3817`
+		// Minimum execution time: 7_207_580_000 picoseconds.
+		Weight::from_parts(7_298_567_000, 0)
+			.saturating_add(Weight::from_parts(0, 3817))
+			.saturating_add(T::DbWeight::get().reads(7))
 			.saturating_add(T::DbWeight::get().writes(8))
 	}
-	/// Storage: Registrar Paras (r:1 w:1)
-	/// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Paras ParaLifecycles (r:1 w:1)
-	/// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Configuration ActiveConfig (r:1 w:0)
-	/// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras PvfActiveVoteMap (r:1 w:1)
-	/// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Paras CodeByHash (r:1 w:1)
-	/// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured)
-	/// Storage: ParasShared ActiveValidatorKeys (r:1 w:0)
-	/// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras PvfActiveVoteList (r:1 w:1)
-	/// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras CodeByHashRefs (r:1 w:1)
-	/// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Paras CurrentCodeHash (r:0 w:1)
-	/// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Paras UpcomingParasGenesis (r:0 w:1)
-	/// Proof Skipped: Paras UpcomingParasGenesis (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `Registrar::Paras` (r:1 w:1)
+	/// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::ParaLifecycles` (r:1 w:1)
+	/// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1)
+	/// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::CodeByHash` (r:1 w:1)
+	/// Proof: `Paras::CodeByHash` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0)
+	/// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::PvfActiveVoteList` (r:1 w:1)
+	/// Proof: `Paras::PvfActiveVoteList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::CodeByHashRefs` (r:1 w:1)
+	/// Proof: `Paras::CodeByHashRefs` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::CurrentCodeHash` (r:0 w:1)
+	/// Proof: `Paras::CurrentCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::UpcomingParasGenesis` (r:0 w:1)
+	/// Proof: `Paras::UpcomingParasGenesis` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	fn force_register() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `533`
-		//  Estimated: `3998`
-		// Minimum execution time: 6_245_403_000 picoseconds.
-		Weight::from_parts(6_289_575_000, 0)
-			.saturating_add(Weight::from_parts(0, 3998))
-			.saturating_add(T::DbWeight::get().reads(8))
+		//  Measured:  `269`
+		//  Estimated: `3734`
+		// Minimum execution time: 7_196_460_000 picoseconds.
+		Weight::from_parts(7_385_729_000, 0)
+			.saturating_add(Weight::from_parts(0, 3734))
+			.saturating_add(T::DbWeight::get().reads(7))
 			.saturating_add(T::DbWeight::get().writes(8))
 	}
-	/// Storage: Registrar Paras (r:1 w:1)
-	/// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Paras ParaLifecycles (r:1 w:1)
-	/// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Paras FutureCodeHash (r:1 w:0)
-	/// Proof Skipped: Paras FutureCodeHash (max_values: None, max_size: None, mode: Measured)
-	/// Storage: ParasShared CurrentSessionIndex (r:1 w:0)
-	/// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras ActionsQueue (r:1 w:1)
-	/// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured)
-	/// Storage: MessageQueue BookStateFor (r:1 w:0)
-	/// Proof: MessageQueue BookStateFor (max_values: None, max_size: Some(55), added: 2530, mode: MaxEncodedLen)
-	/// Storage: Registrar PendingSwap (r:0 w:1)
-	/// Proof Skipped: Registrar PendingSwap (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `Registrar::Paras` (r:1 w:1)
+	/// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::ParaLifecycles` (r:1 w:1)
+	/// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::FutureCodeHash` (r:1 w:0)
+	/// Proof: `Paras::FutureCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0)
+	/// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::ActionsQueue` (r:1 w:1)
+	/// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `MessageQueue::BookStateFor` (r:1 w:0)
+	/// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(55), added: 2530, mode: `MaxEncodedLen`)
+	/// Storage: `Registrar::PendingSwap` (r:0 w:1)
+	/// Proof: `Registrar::PendingSwap` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	fn deregister() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `476`
-		//  Estimated: `3941`
-		// Minimum execution time: 49_822_000 picoseconds.
-		Weight::from_parts(50_604_000, 0)
-			.saturating_add(Weight::from_parts(0, 3941))
+		//  Measured:  `499`
+		//  Estimated: `3964`
+		// Minimum execution time: 54_761_000 picoseconds.
+		Weight::from_parts(57_931_000, 0)
+			.saturating_add(Weight::from_parts(0, 3964))
 			.saturating_add(T::DbWeight::get().reads(6))
 			.saturating_add(T::DbWeight::get().writes(4))
 	}
-	/// Storage: Registrar Paras (r:1 w:0)
-	/// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Paras ParaLifecycles (r:2 w:2)
-	/// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Registrar PendingSwap (r:1 w:1)
-	/// Proof Skipped: Registrar PendingSwap (max_values: None, max_size: None, mode: Measured)
-	/// Storage: ParasShared CurrentSessionIndex (r:1 w:0)
-	/// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras ActionsQueue (r:1 w:1)
-	/// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Crowdloan Funds (r:2 w:2)
-	/// Proof Skipped: Crowdloan Funds (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Slots Leases (r:2 w:2)
-	/// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `Registrar::Paras` (r:1 w:0)
+	/// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::ParaLifecycles` (r:2 w:2)
+	/// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Registrar::PendingSwap` (r:1 w:1)
+	/// Proof: `Registrar::PendingSwap` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0)
+	/// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::ActionsQueue` (r:1 w:1)
+	/// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Crowdloan::Funds` (r:2 w:2)
+	/// Proof: `Crowdloan::Funds` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Slots::Leases` (r:2 w:2)
+	/// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	fn swap() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `780`
-		//  Estimated: `6720`
-		// Minimum execution time: 55_166_000 picoseconds.
-		Weight::from_parts(56_913_000, 0)
-			.saturating_add(Weight::from_parts(0, 6720))
+		//  Measured:  `837`
+		//  Estimated: `6777`
+		// Minimum execution time: 59_564_000 picoseconds.
+		Weight::from_parts(62_910_000, 0)
+			.saturating_add(Weight::from_parts(0, 6777))
 			.saturating_add(T::DbWeight::get().reads(10))
 			.saturating_add(T::DbWeight::get().writes(8))
 	}
-	/// Storage: Paras FutureCodeHash (r:1 w:1)
-	/// Proof Skipped: Paras FutureCodeHash (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Paras UpgradeRestrictionSignal (r:1 w:1)
-	/// Proof Skipped: Paras UpgradeRestrictionSignal (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Configuration ActiveConfig (r:1 w:0)
-	/// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras CurrentCodeHash (r:1 w:0)
-	/// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Paras UpgradeCooldowns (r:1 w:1)
-	/// Proof Skipped: Paras UpgradeCooldowns (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras PvfActiveVoteMap (r:1 w:1)
-	/// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Paras CodeByHash (r:1 w:1)
-	/// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured)
-	/// Storage: ParasShared ActiveValidatorKeys (r:1 w:0)
-	/// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras PvfActiveVoteList (r:1 w:1)
-	/// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras CodeByHashRefs (r:1 w:1)
-	/// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured)
-	/// The range of component `b` is `[1, 3145728]`.
+	/// Storage: `Paras::FutureCodeHash` (r:1 w:1)
+	/// Proof: `Paras::FutureCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::UpgradeRestrictionSignal` (r:1 w:1)
+	/// Proof: `Paras::UpgradeRestrictionSignal` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::CurrentCodeHash` (r:1 w:0)
+	/// Proof: `Paras::CurrentCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::UpgradeCooldowns` (r:1 w:1)
+	/// Proof: `Paras::UpgradeCooldowns` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1)
+	/// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::CodeByHash` (r:1 w:1)
+	/// Proof: `Paras::CodeByHash` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0)
+	/// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::PvfActiveVoteList` (r:1 w:1)
+	/// Proof: `Paras::PvfActiveVoteList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::CodeByHashRefs` (r:1 w:1)
+	/// Proof: `Paras::CodeByHashRefs` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// The range of component `b` is `[9, 3145728]`.
 	fn schedule_code_upgrade(b: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `464`
-		//  Estimated: `3929`
-		// Minimum execution time: 43_650_000 picoseconds.
-		Weight::from_parts(43_918_000, 0)
-			.saturating_add(Weight::from_parts(0, 3929))
-			// Standard Error: 6
-			.saturating_add(Weight::from_parts(2_041, 0).saturating_mul(b.into()))
-			.saturating_add(T::DbWeight::get().reads(10))
+		//  Measured:  `201`
+		//  Estimated: `3666`
+		// Minimum execution time: 33_106_000 picoseconds.
+		Weight::from_parts(33_526_000, 0)
+			.saturating_add(Weight::from_parts(0, 3666))
+			// Standard Error: 2
+			.saturating_add(Weight::from_parts(2_334, 0).saturating_mul(b.into()))
+			.saturating_add(T::DbWeight::get().reads(9))
 			.saturating_add(T::DbWeight::get().writes(7))
 	}
-	/// Storage: Paras Heads (r:0 w:1)
-	/// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `Paras::Heads` (r:0 w:1)
+	/// Proof: `Paras::Heads` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	/// The range of component `b` is `[1, 1048576]`.
 	fn set_current_head(b: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 8_666_000 picoseconds.
-		Weight::from_parts(8_893_000, 0)
+		// Minimum execution time: 5_992_000 picoseconds.
+		Weight::from_parts(12_059_689, 0)
 			.saturating_add(Weight::from_parts(0, 0))
-			// Standard Error: 2
-			.saturating_add(Weight::from_parts(855, 0).saturating_mul(b.into()))
+			// Standard Error: 0
+			.saturating_add(Weight::from_parts(959, 0).saturating_mul(b.into()))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
 }
diff --git a/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_slots.rs b/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_slots.rs
index 8c601aa8486..b99ee1f9a0d 100644
--- a/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_slots.rs
+++ b/polkadot/runtime/rococo/src/weights/polkadot_runtime_common_slots.rs
@@ -16,11 +16,11 @@
 
 //! Autogenerated weights for `runtime_common::slots`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
-//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
 // ./target/production/polkadot
@@ -29,12 +29,15 @@
 // --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
 // --pallet=runtime_common::slots
 // --extrinsic=*
 // --execution=wasm
 // --wasm-execution=compiled
-// --header=./file_header.txt
-// --output=./runtime/rococo/src/weights/runtime_common_slots.rs
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/runtime_common_slots.rs
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -53,80 +56,76 @@ impl<T: frame_system::Config> polkadot_runtime_common::slots::WeightInfo for Wei
 	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
 	fn force_lease() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `287`
-		//  Estimated: `3752`
-		// Minimum execution time: 29_932_000 picoseconds.
-		Weight::from_parts(30_334_000, 0)
-			.saturating_add(Weight::from_parts(0, 3752))
+		//  Measured:  `320`
+		//  Estimated: `3785`
+		// Minimum execution time: 26_570_000 picoseconds.
+		Weight::from_parts(27_619_000, 0)
+			.saturating_add(Weight::from_parts(0, 3785))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
 	}
-	/// Storage: Paras Parachains (r:1 w:0)
-	/// Proof Skipped: Paras Parachains (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Slots Leases (r:101 w:100)
-	/// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Paras ParaLifecycles (r:200 w:200)
-	/// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured)
-	/// Storage: ParasShared CurrentSessionIndex (r:1 w:0)
-	/// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras ActionsQueue (r:1 w:1)
-	/// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Registrar Paras (r:100 w:100)
-	/// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `Paras::Parachains` (r:1 w:0)
+	/// Proof: `Paras::Parachains` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Slots::Leases` (r:101 w:100)
+	/// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::ParaLifecycles` (r:200 w:200)
+	/// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0)
+	/// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::ActionsQueue` (r:1 w:1)
+	/// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	/// The range of component `c` is `[0, 100]`.
 	/// The range of component `t` is `[0, 100]`.
 	fn manage_lease_period_start(c: u32, t: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `26 + c * (47 ±0) + t * (308 ±0)`
-		//  Estimated: `2800 + c * (2526 ±0) + t * (2789 ±0)`
-		// Minimum execution time: 634_547_000 picoseconds.
-		Weight::from_parts(643_045_000, 0)
-			.saturating_add(Weight::from_parts(0, 2800))
-			// Standard Error: 81_521
-			.saturating_add(Weight::from_parts(2_705_219, 0).saturating_mul(c.into()))
-			// Standard Error: 81_521
-			.saturating_add(Weight::from_parts(11_464_132, 0).saturating_mul(t.into()))
+		//  Measured:  `594 + c * (20 ±0) + t * (234 ±0)`
+		//  Estimated: `4065 + c * (2496 ±0) + t * (2709 ±0)`
+		// Minimum execution time: 729_793_000 picoseconds.
+		Weight::from_parts(740_820_000, 0)
+			.saturating_add(Weight::from_parts(0, 4065))
+			// Standard Error: 88_206
+			.saturating_add(Weight::from_parts(2_793_142, 0).saturating_mul(c.into()))
+			// Standard Error: 88_206
+			.saturating_add(Weight::from_parts(8_933_065, 0).saturating_mul(t.into()))
 			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c.into())))
-			.saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(t.into())))
+			.saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(t.into())))
 			.saturating_add(T::DbWeight::get().writes(1))
 			.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(c.into())))
-			.saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(t.into())))
-			.saturating_add(Weight::from_parts(0, 2526).saturating_mul(c.into()))
-			.saturating_add(Weight::from_parts(0, 2789).saturating_mul(t.into()))
+			.saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(t.into())))
+			.saturating_add(Weight::from_parts(0, 2496).saturating_mul(c.into()))
+			.saturating_add(Weight::from_parts(0, 2709).saturating_mul(t.into()))
 	}
-	/// Storage: Slots Leases (r:1 w:1)
-	/// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured)
-	/// Storage: System Account (r:8 w:8)
-	/// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen)
+	/// Storage: `Slots::Leases` (r:1 w:1)
+	/// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `System::Account` (r:8 w:8)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
 	fn clear_all_leases() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `2759`
+		//  Measured:  `2792`
 		//  Estimated: `21814`
-		// Minimum execution time: 129_756_000 picoseconds.
-		Weight::from_parts(131_810_000, 0)
+		// Minimum execution time: 123_888_000 picoseconds.
+		Weight::from_parts(131_245_000, 0)
 			.saturating_add(Weight::from_parts(0, 21814))
 			.saturating_add(T::DbWeight::get().reads(9))
 			.saturating_add(T::DbWeight::get().writes(9))
 	}
-	/// Storage: Slots Leases (r:1 w:0)
-	/// Proof Skipped: Slots Leases (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Paras ParaLifecycles (r:1 w:1)
-	/// Proof Skipped: Paras ParaLifecycles (max_values: None, max_size: None, mode: Measured)
-	/// Storage: ParasShared CurrentSessionIndex (r:1 w:0)
-	/// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras ActionsQueue (r:1 w:1)
-	/// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Registrar Paras (r:1 w:1)
-	/// Proof Skipped: Registrar Paras (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `Slots::Leases` (r:1 w:0)
+	/// Proof: `Slots::Leases` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::ParaLifecycles` (r:1 w:1)
+	/// Proof: `Paras::ParaLifecycles` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0)
+	/// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::ActionsQueue` (r:1 w:1)
+	/// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	fn trigger_onboard() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `707`
-		//  Estimated: `4172`
-		// Minimum execution time: 29_527_000 picoseconds.
-		Weight::from_parts(30_055_000, 0)
-			.saturating_add(Weight::from_parts(0, 4172))
-			.saturating_add(T::DbWeight::get().reads(5))
-			.saturating_add(T::DbWeight::get().writes(3))
+		//  Measured:  `612`
+		//  Estimated: `4077`
+		// Minimum execution time: 27_341_000 picoseconds.
+		Weight::from_parts(28_697_000, 0)
+			.saturating_add(Weight::from_parts(0, 4077))
+			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().writes(2))
 	}
 }
diff --git a/polkadot/runtime/rococo/src/weights/polkadot_runtime_parachains_configuration.rs b/polkadot/runtime/rococo/src/weights/polkadot_runtime_parachains_configuration.rs
index 5592a85c90f..3ca49aaa165 100644
--- a/polkadot/runtime/rococo/src/weights/polkadot_runtime_parachains_configuration.rs
+++ b/polkadot/runtime/rococo/src/weights/polkadot_runtime_parachains_configuration.rs
@@ -17,25 +17,27 @@
 //! Autogenerated weights for `runtime_parachains::configuration`
 //!
 //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
-//! DATE: 2024-02-08, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
 //! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
-// target/production/polkadot
+// ./target/production/polkadot
 // benchmark
 // pallet
+// --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --pallet=runtime_parachains::configuration
 // --extrinsic=*
+// --execution=wasm
 // --wasm-execution=compiled
-// --heap-pages=4096
-// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json
-// --pallet=runtime_parachains::configuration
-// --chain=rococo-dev
 // --header=./polkadot/file_header.txt
-// --output=./polkadot/runtime/rococo/src/weights/
+// --output=./polkadot/runtime/rococo/src/weights/runtime_parachains_configuration.rs
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -58,8 +60,8 @@ impl<T: frame_system::Config> polkadot_runtime_parachains::configuration::Weight
 		// Proof Size summary in bytes:
 		//  Measured:  `151`
 		//  Estimated: `1636`
-		// Minimum execution time: 7_789_000 picoseconds.
-		Weight::from_parts(8_269_000, 0)
+		// Minimum execution time: 7_689_000 picoseconds.
+		Weight::from_parts(8_089_000, 0)
 			.saturating_add(Weight::from_parts(0, 1636))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -74,8 +76,8 @@ impl<T: frame_system::Config> polkadot_runtime_parachains::configuration::Weight
 		// Proof Size summary in bytes:
 		//  Measured:  `151`
 		//  Estimated: `1636`
-		// Minimum execution time: 7_851_000 picoseconds.
-		Weight::from_parts(8_152_000, 0)
+		// Minimum execution time: 7_735_000 picoseconds.
+		Weight::from_parts(8_150_000, 0)
 			.saturating_add(Weight::from_parts(0, 1636))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -90,8 +92,8 @@ impl<T: frame_system::Config> polkadot_runtime_parachains::configuration::Weight
 		// Proof Size summary in bytes:
 		//  Measured:  `151`
 		//  Estimated: `1636`
-		// Minimum execution time: 7_960_000 picoseconds.
-		Weight::from_parts(8_276_000, 0)
+		// Minimum execution time: 7_902_000 picoseconds.
+		Weight::from_parts(8_196_000, 0)
 			.saturating_add(Weight::from_parts(0, 1636))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -116,8 +118,8 @@ impl<T: frame_system::Config> polkadot_runtime_parachains::configuration::Weight
 		// Proof Size summary in bytes:
 		//  Measured:  `151`
 		//  Estimated: `1636`
-		// Minimum execution time: 7_912_000 picoseconds.
-		Weight::from_parts(8_164_000, 0)
+		// Minimum execution time: 7_634_000 picoseconds.
+		Weight::from_parts(7_983_000, 0)
 			.saturating_add(Weight::from_parts(0, 1636))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -132,8 +134,8 @@ impl<T: frame_system::Config> polkadot_runtime_parachains::configuration::Weight
 		// Proof Size summary in bytes:
 		//  Measured:  `151`
 		//  Estimated: `1636`
-		// Minimum execution time: 9_782_000 picoseconds.
-		Weight::from_parts(10_373_000, 0)
+		// Minimum execution time: 9_580_000 picoseconds.
+		Weight::from_parts(9_989_000, 0)
 			.saturating_add(Weight::from_parts(0, 1636))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -148,8 +150,8 @@ impl<T: frame_system::Config> polkadot_runtime_parachains::configuration::Weight
 		// Proof Size summary in bytes:
 		//  Measured:  `151`
 		//  Estimated: `1636`
-		// Minimum execution time: 7_870_000 picoseconds.
-		Weight::from_parts(8_274_000, 0)
+		// Minimum execution time: 7_787_000 picoseconds.
+		Weight::from_parts(8_008_000, 0)
 			.saturating_add(Weight::from_parts(0, 1636))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -164,8 +166,8 @@ impl<T: frame_system::Config> polkadot_runtime_parachains::configuration::Weight
 		// Proof Size summary in bytes:
 		//  Measured:  `151`
 		//  Estimated: `1636`
-		// Minimum execution time: 9_960_000 picoseconds.
-		Weight::from_parts(10_514_000, 0)
+		// Minimum execution time: 9_557_000 picoseconds.
+		Weight::from_parts(9_994_000, 0)
 			.saturating_add(Weight::from_parts(0, 1636))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -180,8 +182,8 @@ impl<T: frame_system::Config> polkadot_runtime_parachains::configuration::Weight
 		// Proof Size summary in bytes:
 		//  Measured:  `151`
 		//  Estimated: `1636`
-		// Minimum execution time: 7_913_000 picoseconds.
-		Weight::from_parts(8_338_000, 0)
+		// Minimum execution time: 7_775_000 picoseconds.
+		Weight::from_parts(7_989_000, 0)
 			.saturating_add(Weight::from_parts(0, 1636))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(1))
diff --git a/polkadot/runtime/rococo/src/weights/polkadot_runtime_parachains_disputes.rs b/polkadot/runtime/rococo/src/weights/polkadot_runtime_parachains_disputes.rs
index a20515502b1..6f86d6a1259 100644
--- a/polkadot/runtime/rococo/src/weights/polkadot_runtime_parachains_disputes.rs
+++ b/polkadot/runtime/rococo/src/weights/polkadot_runtime_parachains_disputes.rs
@@ -16,11 +16,11 @@
 
 //! Autogenerated weights for `runtime_parachains::disputes`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
-//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
 // ./target/production/polkadot
@@ -29,12 +29,15 @@
 // --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
 // --pallet=runtime_parachains::disputes
 // --extrinsic=*
 // --execution=wasm
 // --wasm-execution=compiled
-// --header=./file_header.txt
-// --output=./runtime/rococo/src/weights/runtime_parachains_disputes.rs
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/runtime_parachains_disputes.rs
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -53,8 +56,8 @@ impl<T: frame_system::Config> polkadot_runtime_parachains::disputes::WeightInfo
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 2_937_000 picoseconds.
-		Weight::from_parts(3_082_000, 0)
+		// Minimum execution time: 1_855_000 picoseconds.
+		Weight::from_parts(2_015_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
diff --git a/polkadot/runtime/rococo/src/weights/polkadot_runtime_parachains_initializer.rs b/polkadot/runtime/rococo/src/weights/polkadot_runtime_parachains_initializer.rs
index 6065c32b174..b915c4ec0f3 100644
--- a/polkadot/runtime/rococo/src/weights/polkadot_runtime_parachains_initializer.rs
+++ b/polkadot/runtime/rococo/src/weights/polkadot_runtime_parachains_initializer.rs
@@ -16,11 +16,11 @@
 
 //! Autogenerated weights for `runtime_parachains::initializer`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
-//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
 // ./target/production/polkadot
@@ -29,12 +29,15 @@
 // --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
 // --pallet=runtime_parachains::initializer
 // --extrinsic=*
 // --execution=wasm
 // --wasm-execution=compiled
-// --header=./file_header.txt
-// --output=./runtime/rococo/src/weights/runtime_parachains_initializer.rs
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/runtime_parachains_initializer.rs
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -54,11 +57,11 @@ impl<T: frame_system::Config> polkadot_runtime_parachains::initializer::WeightIn
 		// Proof Size summary in bytes:
 		//  Measured:  `0 + d * (11 ±0)`
 		//  Estimated: `1480 + d * (11 ±0)`
-		// Minimum execution time: 3_771_000 picoseconds.
-		Weight::from_parts(6_491_437, 0)
+		// Minimum execution time: 2_634_000 picoseconds.
+		Weight::from_parts(2_728_000, 0)
 			.saturating_add(Weight::from_parts(0, 1480))
-			// Standard Error: 9
-			.saturating_add(Weight::from_parts(1_356, 0).saturating_mul(d.into()))
+			// Standard Error: 19
+			.saturating_add(Weight::from_parts(2_499, 0).saturating_mul(d.into()))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 			.saturating_add(Weight::from_parts(0, 11).saturating_mul(d.into()))
diff --git a/polkadot/runtime/rococo/src/weights/polkadot_runtime_parachains_on_demand.rs b/polkadot/runtime/rococo/src/weights/polkadot_runtime_parachains_on_demand.rs
index 0c36eeaf7d4..1dd62d129f9 100644
--- a/polkadot/runtime/rococo/src/weights/polkadot_runtime_parachains_on_demand.rs
+++ b/polkadot/runtime/rococo/src/weights/polkadot_runtime_parachains_on_demand.rs
@@ -23,12 +23,18 @@
 //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
-// target/production/polkadot
+// ./target/production/polkadot
 // benchmark
 // pallet
+// --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --pallet=runtime_parachains::assigner_on_demand
 // --extrinsic=*
+// --execution=wasm
 // --wasm-execution=compiled
 // --heap-pages=4096
 // --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json
diff --git a/polkadot/runtime/rococo/src/weights/polkadot_runtime_parachains_paras.rs b/polkadot/runtime/rococo/src/weights/polkadot_runtime_parachains_paras.rs
index 2dcabb7c36b..c463552b6ad 100644
--- a/polkadot/runtime/rococo/src/weights/polkadot_runtime_parachains_paras.rs
+++ b/polkadot/runtime/rococo/src/weights/polkadot_runtime_parachains_paras.rs
@@ -16,11 +16,11 @@
 
 //! Autogenerated weights for `runtime_parachains::paras`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-05-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
-//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("rococo-dev"), DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
 // ./target/production/polkadot
@@ -29,12 +29,15 @@
 // --chain=rococo-dev
 // --steps=50
 // --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
 // --pallet=runtime_parachains::paras
 // --extrinsic=*
 // --execution=wasm
 // --wasm-execution=compiled
-// --header=./file_header.txt
-// --output=./runtime/rococo/src/weights/runtime_parachains_paras.rs
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/runtime_parachains_paras.rs
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -64,230 +67,231 @@ impl<T: frame_system::Config> polkadot_runtime_parachains::paras::WeightInfo for
 		// Proof Size summary in bytes:
 		//  Measured:  `8309`
 		//  Estimated: `11774`
-		// Minimum execution time: 31_941_000 picoseconds.
-		Weight::from_parts(32_139_000, 0)
+		// Minimum execution time: 27_488_000 picoseconds.
+		Weight::from_parts(27_810_000, 0)
 			.saturating_add(Weight::from_parts(0, 11774))
-			// Standard Error: 5
-			.saturating_add(Weight::from_parts(2_011, 0).saturating_mul(c.into()))
+			// Standard Error: 8
+			.saturating_add(Weight::from_parts(2_189, 0).saturating_mul(c.into()))
 			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(6))
 	}
-	/// Storage: Paras Heads (r:0 w:1)
-	/// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `Paras::Heads` (r:0 w:1)
+	/// Proof: `Paras::Heads` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	/// The range of component `s` is `[1, 1048576]`.
 	fn force_set_current_head(s: u32, ) -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 8_275_000 picoseconds.
-		Weight::from_parts(8_321_000, 0)
+		// Minimum execution time: 5_793_000 picoseconds.
+		Weight::from_parts(7_987_606, 0)
 			.saturating_add(Weight::from_parts(0, 0))
-			// Standard Error: 2
-			.saturating_add(Weight::from_parts(858, 0).saturating_mul(s.into()))
+			// Standard Error: 1
+			.saturating_add(Weight::from_parts(971, 0).saturating_mul(s.into()))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	// Storage: Paras Heads (r:0 w:1)
+	/// Storage: `Paras::MostRecentContext` (r:0 w:1)
+	/// Proof: `Paras::MostRecentContext` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	fn force_set_most_recent_context() -> Weight {
-		Weight::from_parts(10_155_000, 0)
-			// Standard Error: 0
-			.saturating_add(T::DbWeight::get().writes(1 as u64))
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 2_733_000 picoseconds.
+		Weight::from_parts(2_954_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Configuration ActiveConfig (r:1 w:0)
-	/// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras FutureCodeHash (r:1 w:1)
-	/// Proof Skipped: Paras FutureCodeHash (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Paras CurrentCodeHash (r:1 w:0)
-	/// Proof Skipped: Paras CurrentCodeHash (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Paras UpgradeCooldowns (r:1 w:1)
-	/// Proof Skipped: Paras UpgradeCooldowns (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras PvfActiveVoteMap (r:1 w:1)
-	/// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Paras CodeByHash (r:1 w:1)
-	/// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured)
-	/// Storage: ParasShared ActiveValidatorKeys (r:1 w:0)
-	/// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras PvfActiveVoteList (r:1 w:1)
-	/// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras CodeByHashRefs (r:1 w:1)
-	/// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Paras UpgradeRestrictionSignal (r:0 w:1)
-	/// Proof Skipped: Paras UpgradeRestrictionSignal (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `Paras::FutureCodeHash` (r:1 w:1)
+	/// Proof: `Paras::FutureCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::CurrentCodeHash` (r:1 w:0)
+	/// Proof: `Paras::CurrentCodeHash` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::UpgradeCooldowns` (r:1 w:1)
+	/// Proof: `Paras::UpgradeCooldowns` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1)
+	/// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::CodeByHash` (r:1 w:1)
+	/// Proof: `Paras::CodeByHash` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0)
+	/// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::PvfActiveVoteList` (r:1 w:1)
+	/// Proof: `Paras::PvfActiveVoteList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::CodeByHashRefs` (r:1 w:1)
+	/// Proof: `Paras::CodeByHashRefs` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::UpgradeRestrictionSignal` (r:0 w:1)
+	/// Proof: `Paras::UpgradeRestrictionSignal` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	/// The range of component `c` is `[1, 3145728]`.
 	fn force_schedule_code_upgrade(c: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `8715`
-		//  Estimated: `12180`
-		// Minimum execution time: 49_923_000 picoseconds.
-		Weight::from_parts(50_688_000, 0)
-			.saturating_add(Weight::from_parts(0, 12180))
-			// Standard Error: 1
-			.saturating_add(Weight::from_parts(1_976, 0).saturating_mul(c.into()))
-			.saturating_add(T::DbWeight::get().reads(9))
-			.saturating_add(T::DbWeight::get().writes(7))
+		//  Measured:  `8452`
+		//  Estimated: `11917`
+		// Minimum execution time: 6_072_000 picoseconds.
+		Weight::from_parts(6_128_000, 0)
+			.saturating_add(Weight::from_parts(0, 11917))
+			// Standard Error: 2
+			.saturating_add(Weight::from_parts(2_334, 0).saturating_mul(c.into()))
+			.saturating_add(T::DbWeight::get().reads(7))
+			.saturating_add(T::DbWeight::get().writes(6))
 	}
-	/// Storage: Paras FutureCodeUpgrades (r:1 w:0)
-	/// Proof Skipped: Paras FutureCodeUpgrades (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Paras Heads (r:0 w:1)
-	/// Proof Skipped: Paras Heads (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Paras UpgradeGoAheadSignal (r:0 w:1)
-	/// Proof Skipped: Paras UpgradeGoAheadSignal (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `Paras::FutureCodeUpgrades` (r:1 w:0)
+	/// Proof: `Paras::FutureCodeUpgrades` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Registrar::Paras` (r:1 w:0)
+	/// Proof: `Registrar::Paras` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::Heads` (r:0 w:1)
+	/// Proof: `Paras::Heads` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::UpgradeGoAheadSignal` (r:0 w:1)
+	/// Proof: `Paras::UpgradeGoAheadSignal` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::MostRecentContext` (r:0 w:1)
+	/// Proof: `Paras::MostRecentContext` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	/// The range of component `s` is `[1, 1048576]`.
 	fn force_note_new_head(s: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `95`
-		//  Estimated: `3560`
-		// Minimum execution time: 14_408_000 picoseconds.
-		Weight::from_parts(14_647_000, 0)
-			.saturating_add(Weight::from_parts(0, 3560))
-			// Standard Error: 2
-			.saturating_add(Weight::from_parts(858, 0).saturating_mul(s.into()))
-			.saturating_add(T::DbWeight::get().reads(1))
-			.saturating_add(T::DbWeight::get().writes(2))
+		//  Measured:  `163`
+		//  Estimated: `3628`
+		// Minimum execution time: 15_166_000 picoseconds.
+		Weight::from_parts(21_398_053, 0)
+			.saturating_add(Weight::from_parts(0, 3628))
+			// Standard Error: 1
+			.saturating_add(Weight::from_parts(976, 0).saturating_mul(s.into()))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(3))
 	}
-	/// Storage: ParasShared CurrentSessionIndex (r:1 w:0)
-	/// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras ActionsQueue (r:1 w:1)
-	/// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0)
+	/// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::ActionsQueue` (r:1 w:1)
+	/// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	fn force_queue_action() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `4288`
-		//  Estimated: `7753`
-		// Minimum execution time: 20_009_000 picoseconds.
-		Weight::from_parts(20_518_000, 0)
-			.saturating_add(Weight::from_parts(0, 7753))
+		//  Measured:  `4312`
+		//  Estimated: `7777`
+		// Minimum execution time: 16_345_000 picoseconds.
+		Weight::from_parts(16_712_000, 0)
+			.saturating_add(Weight::from_parts(0, 7777))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Paras PvfActiveVoteMap (r:1 w:1)
-	/// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Paras PvfActiveVoteList (r:1 w:1)
-	/// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Configuration ActiveConfig (r:1 w:0)
-	/// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: ParasShared CurrentSessionIndex (r:1 w:0)
-	/// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras ActionsQueue (r:1 w:1)
-	/// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1)
+	/// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::PvfActiveVoteList` (r:1 w:1)
+	/// Proof: `Paras::PvfActiveVoteList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0)
+	/// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::ActionsQueue` (r:1 w:1)
+	/// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	/// The range of component `c` is `[1, 3145728]`.
 	fn add_trusted_validation_code(c: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `946`
-		//  Estimated: `4411`
-		// Minimum execution time: 80_626_000 picoseconds.
-		Weight::from_parts(52_721_755, 0)
-			.saturating_add(Weight::from_parts(0, 4411))
-			// Standard Error: 1
-			.saturating_add(Weight::from_parts(1_443, 0).saturating_mul(c.into()))
-			.saturating_add(T::DbWeight::get().reads(5))
+		//  Measured:  `683`
+		//  Estimated: `4148`
+		// Minimum execution time: 78_076_000 picoseconds.
+		Weight::from_parts(123_193_814, 0)
+			.saturating_add(Weight::from_parts(0, 4148))
+			// Standard Error: 5
+			.saturating_add(Weight::from_parts(1_770, 0).saturating_mul(c.into()))
+			.saturating_add(T::DbWeight::get().reads(4))
 			.saturating_add(T::DbWeight::get().writes(3))
 	}
-	/// Storage: Paras CodeByHashRefs (r:1 w:0)
-	/// Proof Skipped: Paras CodeByHashRefs (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Paras CodeByHash (r:0 w:1)
-	/// Proof Skipped: Paras CodeByHash (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `Paras::CodeByHashRefs` (r:1 w:0)
+	/// Proof: `Paras::CodeByHashRefs` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::CodeByHash` (r:0 w:1)
+	/// Proof: `Paras::CodeByHash` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	fn poke_unused_validation_code() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `28`
 		//  Estimated: `3493`
-		// Minimum execution time: 6_692_000 picoseconds.
-		Weight::from_parts(7_009_000, 0)
+		// Minimum execution time: 5_184_000 picoseconds.
+		Weight::from_parts(5_430_000, 0)
 			.saturating_add(Weight::from_parts(0, 3493))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: ParasShared ActiveValidatorKeys (r:1 w:0)
-	/// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: ParasShared CurrentSessionIndex (r:1 w:0)
-	/// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras PvfActiveVoteMap (r:1 w:1)
-	/// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0)
+	/// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0)
+	/// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1)
+	/// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	fn include_pvf_check_statement() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `26682`
-		//  Estimated: `30147`
-		// Minimum execution time: 87_994_000 picoseconds.
-		Weight::from_parts(89_933_000, 0)
-			.saturating_add(Weight::from_parts(0, 30147))
+		//  Measured:  `26706`
+		//  Estimated: `30171`
+		// Minimum execution time: 102_995_000 picoseconds.
+		Weight::from_parts(108_977_000, 0)
+			.saturating_add(Weight::from_parts(0, 30171))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: ParasShared ActiveValidatorKeys (r:1 w:0)
-	/// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: ParasShared CurrentSessionIndex (r:1 w:0)
-	/// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras PvfActiveVoteMap (r:1 w:1)
-	/// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Paras PvfActiveVoteList (r:1 w:1)
-	/// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Configuration ActiveConfig (r:1 w:0)
-	/// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras UpcomingUpgrades (r:1 w:1)
-	/// Proof Skipped: Paras UpcomingUpgrades (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: System Digest (r:1 w:1)
-	/// Proof Skipped: System Digest (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras FutureCodeUpgrades (r:0 w:100)
-	/// Proof Skipped: Paras FutureCodeUpgrades (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0)
+	/// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0)
+	/// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1)
+	/// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::PvfActiveVoteList` (r:1 w:1)
+	/// Proof: `Paras::PvfActiveVoteList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::UpcomingUpgrades` (r:1 w:1)
+	/// Proof: `Paras::UpcomingUpgrades` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `System::Digest` (r:1 w:1)
+	/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::FutureCodeUpgrades` (r:0 w:100)
+	/// Proof: `Paras::FutureCodeUpgrades` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	fn include_pvf_check_statement_finalize_upgrade_accept() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `27523`
-		//  Estimated: `30988`
-		// Minimum execution time: 783_222_000 picoseconds.
-		Weight::from_parts(794_959_000, 0)
-			.saturating_add(Weight::from_parts(0, 30988))
-			.saturating_add(T::DbWeight::get().reads(7))
+		//  Measured:  `27360`
+		//  Estimated: `30825`
+		// Minimum execution time: 709_433_000 picoseconds.
+		Weight::from_parts(725_074_000, 0)
+			.saturating_add(Weight::from_parts(0, 30825))
+			.saturating_add(T::DbWeight::get().reads(6))
 			.saturating_add(T::DbWeight::get().writes(104))
 	}
-	/// Storage: ParasShared ActiveValidatorKeys (r:1 w:0)
-	/// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: ParasShared CurrentSessionIndex (r:1 w:0)
-	/// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras PvfActiveVoteMap (r:1 w:1)
-	/// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0)
+	/// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0)
+	/// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1)
+	/// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	fn include_pvf_check_statement_finalize_upgrade_reject() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `27214`
-		//  Estimated: `30679`
-		// Minimum execution time: 87_424_000 picoseconds.
-		Weight::from_parts(88_737_000, 0)
-			.saturating_add(Weight::from_parts(0, 30679))
+		//  Measured:  `27338`
+		//  Estimated: `30803`
+		// Minimum execution time: 98_973_000 picoseconds.
+		Weight::from_parts(104_715_000, 0)
+			.saturating_add(Weight::from_parts(0, 30803))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: ParasShared ActiveValidatorKeys (r:1 w:0)
-	/// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: ParasShared CurrentSessionIndex (r:1 w:0)
-	/// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras PvfActiveVoteMap (r:1 w:1)
-	/// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Paras PvfActiveVoteList (r:1 w:1)
-	/// Proof Skipped: Paras PvfActiveVoteList (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Configuration ActiveConfig (r:1 w:0)
-	/// Proof Skipped: Configuration ActiveConfig (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras ActionsQueue (r:1 w:1)
-	/// Proof Skipped: Paras ActionsQueue (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0)
+	/// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0)
+	/// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1)
+	/// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::PvfActiveVoteList` (r:1 w:1)
+	/// Proof: `Paras::PvfActiveVoteList` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::ActionsQueue` (r:1 w:1)
+	/// Proof: `Paras::ActionsQueue` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	fn include_pvf_check_statement_finalize_onboarding_accept() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `26991`
-		//  Estimated: `30456`
-		// Minimum execution time: 612_485_000 picoseconds.
-		Weight::from_parts(621_670_000, 0)
-			.saturating_add(Weight::from_parts(0, 30456))
-			.saturating_add(T::DbWeight::get().reads(6))
+		//  Measured:  `26728`
+		//  Estimated: `30193`
+		// Minimum execution time: 550_958_000 picoseconds.
+		Weight::from_parts(564_497_000, 0)
+			.saturating_add(Weight::from_parts(0, 30193))
+			.saturating_add(T::DbWeight::get().reads(5))
 			.saturating_add(T::DbWeight::get().writes(3))
 	}
-	/// Storage: ParasShared ActiveValidatorKeys (r:1 w:0)
-	/// Proof Skipped: ParasShared ActiveValidatorKeys (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: ParasShared CurrentSessionIndex (r:1 w:0)
-	/// Proof Skipped: ParasShared CurrentSessionIndex (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Paras PvfActiveVoteMap (r:1 w:1)
-	/// Proof Skipped: Paras PvfActiveVoteMap (max_values: None, max_size: None, mode: Measured)
+	/// Storage: `ParasShared::ActiveValidatorKeys` (r:1 w:0)
+	/// Proof: `ParasShared::ActiveValidatorKeys` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0)
+	/// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Paras::PvfActiveVoteMap` (r:1 w:1)
+	/// Proof: `Paras::PvfActiveVoteMap` (`max_values`: None, `max_size`: None, mode: `Measured`)
 	fn include_pvf_check_statement_finalize_onboarding_reject() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `26682`
-		//  Estimated: `30147`
-		// Minimum execution time: 86_673_000 picoseconds.
-		Weight::from_parts(87_424_000, 0)
-			.saturating_add(Weight::from_parts(0, 30147))
+		//  Measured:  `26706`
+		//  Estimated: `30171`
+		// Minimum execution time: 97_088_000 picoseconds.
+		Weight::from_parts(103_617_000, 0)
+			.saturating_add(Weight::from_parts(0, 30171))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
diff --git a/polkadot/runtime/rococo/src/weights/runtime_common_coretime.rs b/polkadot/runtime/rococo/src/weights/runtime_common_coretime.rs
new file mode 100644
index 00000000000..d068f07e759
--- /dev/null
+++ b/polkadot/runtime/rococo/src/weights/runtime_common_coretime.rs
@@ -0,0 +1,86 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Polkadot.
+
+// Polkadot is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Polkadot is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `runtime_common::coretime`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-02-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("rococo-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/production/polkadot
+// benchmark
+// pallet
+// --chain=rococo-dev
+// --steps=50
+// --repeat=20
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --pallet=runtime_common::coretime
+// --extrinsic=*
+// --execution=wasm
+// --wasm-execution=compiled
+// --header=./polkadot/file_header.txt
+// --output=./polkadot/runtime/rococo/src/weights/runtime_common_coretime.rs
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `runtime_common::coretime`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> runtime_common::coretime::WeightInfo for WeightInfo<T> {
+	/// Storage: `Configuration::PendingConfigs` (r:1 w:1)
+	/// Proof: `Configuration::PendingConfigs` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `Configuration::BypassConsistencyCheck` (r:1 w:0)
+	/// Proof: `Configuration::BypassConsistencyCheck` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	/// Storage: `ParasShared::CurrentSessionIndex` (r:1 w:0)
+	/// Proof: `ParasShared::CurrentSessionIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	fn request_core_count() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `151`
+		//  Estimated: `1636`
+		// Minimum execution time: 7_543_000 picoseconds.
+		Weight::from_parts(7_745_000, 0)
+			.saturating_add(Weight::from_parts(0, 1636))
+			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+	/// Storage: `CoretimeAssignmentProvider::CoreDescriptors` (r:1 w:1)
+	/// Proof: `CoretimeAssignmentProvider::CoreDescriptors` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `CoretimeAssignmentProvider::CoreSchedules` (r:0 w:1)
+	/// Proof: `CoretimeAssignmentProvider::CoreSchedules` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// The range of component `s` is `[1, 100]`.
+	fn assign_core(s: u32, ) -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `180`
+		//  Estimated: `3645`
+		// Minimum execution time: 9_367_000 picoseconds.
+		Weight::from_parts(9_932_305, 0)
+			.saturating_add(Weight::from_parts(0, 3645))
+			// Standard Error: 231
+			.saturating_add(Weight::from_parts(12_947, 0).saturating_mul(s.into()))
+			.saturating_add(T::DbWeight::get().reads(1))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+}
diff --git a/polkadot/runtime/test-runtime/Cargo.toml b/polkadot/runtime/test-runtime/Cargo.toml
index ac379b69e3f..90a0285cd17 100644
--- a/polkadot/runtime/test-runtime/Cargo.toml
+++ b/polkadot/runtime/test-runtime/Cargo.toml
@@ -144,6 +144,7 @@ runtime-benchmarks = [
 	"pallet-staking/runtime-benchmarks",
 	"pallet-sudo/runtime-benchmarks",
 	"pallet-timestamp/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"pallet-vesting/runtime-benchmarks",
 	"pallet-xcm/runtime-benchmarks",
 	"polkadot-primitives/runtime-benchmarks",
diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs
index 6ba8e6ad318..96104ace7d7 100644
--- a/polkadot/runtime/test-runtime/src/lib.rs
+++ b/polkadot/runtime/test-runtime/src/lib.rs
@@ -82,8 +82,8 @@ use sp_runtime::{
 	curve::PiecewiseLinear,
 	generic, impl_opaque_keys,
 	traits::{
-		BlakeTwo256, Block as BlockT, ConvertInto, Extrinsic as ExtrinsicT, OpaqueKeys,
-		SaturatedConversion, StaticLookup, Verify,
+		BlakeTwo256, Block as BlockT, ConvertInto, OpaqueKeys, SaturatedConversion, StaticLookup,
+		Verify,
 	},
 	transaction_validity::{TransactionPriority, TransactionSource, TransactionValidity},
 	ApplyExtrinsicResult, FixedU128, KeyTypeId, Perbill, Percent,
@@ -167,14 +167,34 @@ impl frame_system::Config for Runtime {
 	type MaxConsumers = frame_support::traits::ConstU32<16>;
 }
 
-impl<C> frame_system::offchain::SendTransactionTypes<C> for Runtime
+impl<C> frame_system::offchain::CreateTransactionBase<C> for Runtime
 where
 	RuntimeCall: From<C>,
 {
-	type OverarchingCall = RuntimeCall;
+	type RuntimeCall = RuntimeCall;
 	type Extrinsic = UncheckedExtrinsic;
 }
 
+impl<C> frame_system::offchain::CreateInherent<C> for Runtime
+where
+	RuntimeCall: From<C>,
+{
+	fn create_inherent(call: Self::RuntimeCall) -> Self::Extrinsic {
+		UncheckedExtrinsic::new_bare(call)
+	}
+}
+
+impl<C> frame_system::offchain::CreateTransaction<C> for Runtime
+where
+	RuntimeCall: From<C>,
+{
+	type Extension = TxExtension;
+
+	fn create_transaction(call: Self::RuntimeCall, extension: Self::Extension) -> Self::Extrinsic {
+		UncheckedExtrinsic::new_transaction(call, extension)
+	}
+}
+
 parameter_types! {
 	pub storage EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS as u64;
 	pub storage ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
@@ -251,6 +271,7 @@ impl pallet_transaction_payment::Config for Runtime {
 	type WeightToFee = WeightToFee;
 	type LengthToFee = frame_support::weights::ConstantMultiplier<Balance, TransactionByteFee>;
 	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
+	type WeightInfo = ();
 }
 
 parameter_types! {
@@ -395,18 +416,20 @@ impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for R
 where
 	RuntimeCall: From<LocalCall>,
 {
-	fn create_transaction<C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>>(
+	fn create_signed_transaction<
+		C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>,
+	>(
 		call: RuntimeCall,
 		public: <Signature as Verify>::Signer,
 		account: AccountId,
 		nonce: <Runtime as frame_system::Config>::Nonce,
-	) -> Option<(RuntimeCall, <UncheckedExtrinsic as ExtrinsicT>::SignaturePayload)> {
+	) -> Option<UncheckedExtrinsic> {
 		let period =
 			BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2) as u64;
 
 		let current_block = System::block_number().saturated_into::<u64>().saturating_sub(1);
 		let tip = 0;
-		let extra: SignedExtra = (
+		let tx_ext: TxExtension = (
 			frame_system::CheckNonZeroSender::<Runtime>::new(),
 			frame_system::CheckSpecVersion::<Runtime>::new(),
 			frame_system::CheckTxVersion::<Runtime>::new(),
@@ -418,16 +441,18 @@ where
 			frame_system::CheckNonce::<Runtime>::from(nonce),
 			frame_system::CheckWeight::<Runtime>::new(),
 			pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),
-		);
-		let raw_payload = SignedPayload::new(call, extra)
+		)
+			.into();
+		let raw_payload = SignedPayload::new(call, tx_ext)
 			.map_err(|e| {
 				log::warn!("Unable to create signed payload: {:?}", e);
 			})
 			.ok()?;
 		let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?;
-		let (call, extra, _) = raw_payload.deconstruct();
+		let (call, tx_ext, _) = raw_payload.deconstruct();
 		let address = Indices::unlookup(account);
-		Some((call, (address, signature, extra)))
+		let transaction = UncheckedExtrinsic::new_signed(call, address, signature, tx_ext);
+		Some(transaction)
 	}
 }
 
@@ -746,8 +771,8 @@ pub type Block = generic::Block<Header, UncheckedExtrinsic>;
 pub type SignedBlock = generic::SignedBlock<Block>;
 /// `BlockId` type as expected by this runtime.
 pub type BlockId = generic::BlockId<Block>;
-/// The `SignedExtension` to the basic transaction logic.
-pub type SignedExtra = (
+/// The extension to the basic transaction logic.
+pub type TxExtension = (
 	frame_system::CheckNonZeroSender<Runtime>,
 	frame_system::CheckSpecVersion<Runtime>,
 	frame_system::CheckTxVersion<Runtime>,
@@ -759,7 +784,10 @@ pub type SignedExtra = (
 );
 /// Unchecked extrinsic type as expected by this runtime.
 pub type UncheckedExtrinsic =
-	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
+/// Unchecked signature payload type as expected by this runtime.
+pub type UncheckedSignaturePayload =
+	generic::UncheckedSignaturePayload<Address, Signature, TxExtension>;
 
 /// Executive: handles dispatch to the various modules.
 pub type Executive = frame_executive::Executive<
@@ -770,7 +798,7 @@ pub type Executive = frame_executive::Executive<
 	AllPalletsWithSystem,
 >;
 /// The payload being signed in transactions.
-pub type SignedPayload = generic::SignedPayload<RuntimeCall, SignedExtra>;
+pub type SignedPayload = generic::SignedPayload<RuntimeCall, TxExtension>;
 
 pub type Hash = <Block as BlockT>::Hash;
 pub type Extrinsic = <Block as BlockT>::Extrinsic;
diff --git a/polkadot/runtime/westend/Cargo.toml b/polkadot/runtime/westend/Cargo.toml
index 31c04c26ece..fcb5719de89 100644
--- a/polkadot/runtime/westend/Cargo.toml
+++ b/polkadot/runtime/westend/Cargo.toml
@@ -277,6 +277,7 @@ runtime-benchmarks = [
 	"pallet-state-trie-migration/runtime-benchmarks",
 	"pallet-sudo/runtime-benchmarks",
 	"pallet-timestamp/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"pallet-treasury/runtime-benchmarks",
 	"pallet-utility/runtime-benchmarks",
 	"pallet-vesting/runtime-benchmarks",
diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs
index 0216ccaf491..b7dae533224 100644
--- a/polkadot/runtime/westend/src/lib.rs
+++ b/polkadot/runtime/westend/src/lib.rs
@@ -97,8 +97,8 @@ use sp_core::{ConstU8, OpaqueMetadata, RuntimeDebug, H256};
 use sp_runtime::{
 	create_runtime_str, generic, impl_opaque_keys,
 	traits::{
-		AccountIdConversion, BlakeTwo256, Block as BlockT, ConvertInto, Extrinsic as ExtrinsicT,
-		IdentityLookup, Keccak256, OpaqueKeys, SaturatedConversion, Verify,
+		AccountIdConversion, BlakeTwo256, Block as BlockT, ConvertInto, IdentityLookup, Keccak256,
+		OpaqueKeys, SaturatedConversion, Verify,
 	},
 	transaction_validity::{TransactionPriority, TransactionSource, TransactionValidity},
 	ApplyExtrinsicResult, FixedU128, KeyTypeId, Percent, Permill,
@@ -218,6 +218,7 @@ impl frame_system::Config for Runtime {
 	type Version = Version;
 	type AccountData = pallet_balances::AccountData<Balance>;
 	type SystemWeightInfo = weights::frame_system::WeightInfo<Runtime>;
+	type ExtensionsWeightInfo = weights::frame_system_extensions::WeightInfo<Runtime>;
 	type SS58Prefix = SS58Prefix;
 	type MaxConsumers = frame_support::traits::ConstU32<16>;
 }
@@ -480,6 +481,7 @@ impl pallet_transaction_payment::Config for Runtime {
 	type WeightToFee = WeightToFee;
 	type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
 	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
+	type WeightInfo = weights::pallet_transaction_payment::WeightInfo<Runtime>;
 }
 
 parameter_types! {
@@ -853,18 +855,44 @@ impl pallet_grandpa::Config for Runtime {
 		pallet_grandpa::EquivocationReportSystem<Self, Offences, Historical, ReportLongevity>;
 }
 
+impl frame_system::offchain::SigningTypes for Runtime {
+	type Public = <Signature as Verify>::Signer;
+	type Signature = Signature;
+}
+
+impl<C> frame_system::offchain::CreateTransactionBase<C> for Runtime
+where
+	RuntimeCall: From<C>,
+{
+	type RuntimeCall = RuntimeCall;
+	type Extrinsic = UncheckedExtrinsic;
+}
+
+impl<LocalCall> frame_system::offchain::CreateTransaction<LocalCall> for Runtime
+where
+	RuntimeCall: From<LocalCall>,
+{
+	type Extension = TxExtension;
+
+	fn create_transaction(call: RuntimeCall, extension: TxExtension) -> UncheckedExtrinsic {
+		UncheckedExtrinsic::new_transaction(call, extension)
+	}
+}
+
 /// Submits a transaction with the node's public and signature type. Adheres to the signed extension
 /// format of the chain.
 impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Runtime
 where
 	RuntimeCall: From<LocalCall>,
 {
-	fn create_transaction<C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>>(
+	fn create_signed_transaction<
+		C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>,
+	>(
 		call: RuntimeCall,
 		public: <Signature as Verify>::Signer,
 		account: AccountId,
 		nonce: <Runtime as frame_system::Config>::Nonce,
-	) -> Option<(RuntimeCall, <UncheckedExtrinsic as ExtrinsicT>::SignaturePayload)> {
+	) -> Option<UncheckedExtrinsic> {
 		use sp_runtime::traits::StaticLookup;
 		// take the biggest period possible.
 		let period =
@@ -876,7 +904,7 @@ where
 			// so the actual block number is `n`.
 			.saturating_sub(1);
 		let tip = 0;
-		let extra: SignedExtra = (
+		let tx_ext: TxExtension = (
 			frame_system::CheckNonZeroSender::<Runtime>::new(),
 			frame_system::CheckSpecVersion::<Runtime>::new(),
 			frame_system::CheckTxVersion::<Runtime>::new(),
@@ -889,30 +917,28 @@ where
 			frame_system::CheckWeight::<Runtime>::new(),
 			pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),
 			frame_metadata_hash_extension::CheckMetadataHash::<Runtime>::new(true),
-		);
-		let raw_payload = SignedPayload::new(call, extra)
+		)
+			.into();
+		let raw_payload = SignedPayload::new(call, tx_ext)
 			.map_err(|e| {
 				log::warn!("Unable to create signed payload: {:?}", e);
 			})
 			.ok()?;
 		let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?;
-		let (call, extra, _) = raw_payload.deconstruct();
+		let (call, tx_ext, _) = raw_payload.deconstruct();
 		let address = <Runtime as frame_system::Config>::Lookup::unlookup(account);
-		Some((call, (address, signature, extra)))
+		let transaction = UncheckedExtrinsic::new_signed(call, address, signature, tx_ext);
+		Some(transaction)
 	}
 }
 
-impl frame_system::offchain::SigningTypes for Runtime {
-	type Public = <Signature as Verify>::Signer;
-	type Signature = Signature;
-}
-
-impl<C> frame_system::offchain::SendTransactionTypes<C> for Runtime
+impl<LocalCall> frame_system::offchain::CreateInherent<LocalCall> for Runtime
 where
-	RuntimeCall: From<C>,
+	RuntimeCall: From<LocalCall>,
 {
-	type OverarchingCall = RuntimeCall;
-	type Extrinsic = UncheckedExtrinsic;
+	fn create_inherent(call: RuntimeCall) -> UncheckedExtrinsic {
+		UncheckedExtrinsic::new_bare(call)
+	}
 }
 
 parameter_types! {
@@ -1742,8 +1768,8 @@ pub type Block = generic::Block<Header, UncheckedExtrinsic>;
 pub type SignedBlock = generic::SignedBlock<Block>;
 /// `BlockId` type as expected by this runtime.
 pub type BlockId = generic::BlockId<Block>;
-/// The `SignedExtension` to the basic transaction logic.
-pub type SignedExtra = (
+/// The extension to the basic transaction logic.
+pub type TxExtension = (
 	frame_system::CheckNonZeroSender<Runtime>,
 	frame_system::CheckSpecVersion<Runtime>,
 	frame_system::CheckTxVersion<Runtime>,
@@ -1784,7 +1810,11 @@ pub mod migrations {
 
 /// Unchecked extrinsic type as expected by this runtime.
 pub type UncheckedExtrinsic =
-	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
+/// Unchecked signature payload type as expected by this runtime.
+pub type UncheckedSignaturePayload =
+	generic::UncheckedSignaturePayload<Address, Signature, TxExtension>;
+
 /// Executive: handles dispatch to the various modules.
 pub type Executive = frame_executive::Executive<
 	Runtime,
@@ -1795,7 +1825,7 @@ pub type Executive = frame_executive::Executive<
 	Migrations,
 >;
 /// The payload being signed in transactions.
-pub type SignedPayload = generic::SignedPayload<RuntimeCall, SignedExtra>;
+pub type SignedPayload = generic::SignedPayload<RuntimeCall, TxExtension>;
 
 #[cfg(feature = "runtime-benchmarks")]
 mod benches {
@@ -1844,7 +1874,9 @@ mod benches {
 		[pallet_staking, Staking]
 		[pallet_sudo, Sudo]
 		[frame_system, SystemBench::<Runtime>]
+		[frame_system_extensions, SystemExtensionsBench::<Runtime>]
 		[pallet_timestamp, Timestamp]
+		[pallet_transaction_payment, TransactionPayment]
 		[pallet_treasury, Treasury]
 		[pallet_utility, Utility]
 		[pallet_vesting, Vesting]
@@ -2508,6 +2540,7 @@ sp_api::impl_runtime_apis! {
 			use pallet_election_provider_support_benchmarking::Pallet as ElectionProviderBench;
 			use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
 			use frame_system_benchmarking::Pallet as SystemBench;
+			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
 			use pallet_nomination_pools_benchmarking::Pallet as NominationPoolsBench;
 
 			type XcmBalances = pallet_xcm_benchmarks::fungible::Pallet::<Runtime>;
@@ -2536,6 +2569,7 @@ sp_api::impl_runtime_apis! {
 			use pallet_election_provider_support_benchmarking::Pallet as ElectionProviderBench;
 			use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
 			use frame_system_benchmarking::Pallet as SystemBench;
+			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
 			use pallet_nomination_pools_benchmarking::Pallet as NominationPoolsBench;
 
 			impl pallet_session_benchmarking::Config for Runtime {}
diff --git a/polkadot/runtime/westend/src/tests.rs b/polkadot/runtime/westend/src/tests.rs
index c1b396a4cd2..02fd6b61496 100644
--- a/polkadot/runtime/westend/src/tests.rs
+++ b/polkadot/runtime/westend/src/tests.rs
@@ -68,7 +68,7 @@ fn sanity_check_teleport_assets_weight() {
 		weight_limit: Unlimited,
 	}
 	.get_dispatch_info()
-	.weight;
+	.call_weight;
 
 	assert!((weight * 50).all_lt(BlockWeights::get().max_block));
 }
diff --git a/polkadot/runtime/westend/src/weights/frame_system_extensions.rs b/polkadot/runtime/westend/src/weights/frame_system_extensions.rs
new file mode 100644
index 00000000000..048f23fbcb9
--- /dev/null
+++ b/polkadot/runtime/westend/src/weights/frame_system_extensions.rs
@@ -0,0 +1,131 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Polkadot.
+
+// Polkadot is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Polkadot is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `frame_system_extensions`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-09-12, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("westend-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/debug/polkadot
+// benchmark
+// pallet
+// --steps=2
+// --repeat=2
+// --extrinsic=*
+// --wasm-execution=compiled
+// --heap-pages=4096
+// --pallet=frame-system-extensions
+// --chain=westend-dev
+// --output=./polkadot/runtime/westend/src/weights/
+// --header=./polkadot/file_header.txt
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `frame_system_extensions`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> frame_system::ExtensionsWeightInfo for WeightInfo<T> {
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_genesis() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `54`
+		//  Estimated: `3509`
+		// Minimum execution time: 75_764_000 picoseconds.
+		Weight::from_parts(85_402_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_mortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 118_233_000 picoseconds.
+		Weight::from_parts(126_539_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_immortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 118_233_000 picoseconds.
+		Weight::from_parts(126_539_000, 0)
+			.saturating_add(Weight::from_parts(0, 3509))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	fn check_non_zero_sender() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 7_885_000 picoseconds.
+		Weight::from_parts(12_784_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	fn check_nonce() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `101`
+		//  Estimated: `3593`
+		// Minimum execution time: 104_237_000 picoseconds.
+		Weight::from_parts(110_910_000, 0)
+			.saturating_add(Weight::from_parts(0, 3593))
+			.saturating_add(T::DbWeight::get().reads(1))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+	fn check_spec_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 6_141_000 picoseconds.
+		Weight::from_parts(11_502_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	fn check_tx_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 6_192_000 picoseconds.
+		Weight::from_parts(11_481_000, 0)
+			.saturating_add(Weight::from_parts(0, 0))
+	}
+	/// Storage: `System::AllExtrinsicsLen` (r:1 w:1)
+	/// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
+	fn check_weight() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `24`
+		//  Estimated: `1489`
+		// Minimum execution time: 87_616_000 picoseconds.
+		Weight::from_parts(93_607_000, 0)
+			.saturating_add(Weight::from_parts(0, 1489))
+			.saturating_add(T::DbWeight::get().reads(1))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+}
diff --git a/polkadot/runtime/westend/src/weights/mod.rs b/polkadot/runtime/westend/src/weights/mod.rs
index ae11f6ccba4..8c12c1adb9c 100644
--- a/polkadot/runtime/westend/src/weights/mod.rs
+++ b/polkadot/runtime/westend/src/weights/mod.rs
@@ -17,6 +17,7 @@
 
 pub mod frame_election_provider_support;
 pub mod frame_system;
+pub mod frame_system_extensions;
 pub mod pallet_asset_rate;
 pub mod pallet_bags_list;
 pub mod pallet_balances;
@@ -39,6 +40,7 @@ pub mod pallet_session;
 pub mod pallet_staking;
 pub mod pallet_sudo;
 pub mod pallet_timestamp;
+pub mod pallet_transaction_payment;
 pub mod pallet_treasury;
 pub mod pallet_utility;
 pub mod pallet_vesting;
diff --git a/polkadot/runtime/westend/src/weights/pallet_sudo.rs b/polkadot/runtime/westend/src/weights/pallet_sudo.rs
index e9ab3ad37a4..649c43e031d 100644
--- a/polkadot/runtime/westend/src/weights/pallet_sudo.rs
+++ b/polkadot/runtime/westend/src/weights/pallet_sudo.rs
@@ -94,4 +94,15 @@ impl<T: frame_system::Config> pallet_sudo::WeightInfo for WeightInfo<T> {
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
+	/// Storage: `Sudo::Key` (r:1 w:0)
+	/// Proof: `Sudo::Key` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
+	fn check_only_sudo_account() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `132`
+		//  Estimated: `1517`
+		// Minimum execution time: 2_875_000 picoseconds.
+		Weight::from_parts(6_803_000, 0)
+			.saturating_add(Weight::from_parts(0, 1517))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
 }
diff --git a/polkadot/runtime/westend/src/weights/pallet_transaction_payment.rs b/polkadot/runtime/westend/src/weights/pallet_transaction_payment.rs
new file mode 100644
index 00000000000..71a01b6a0c2
--- /dev/null
+++ b/polkadot/runtime/westend/src/weights/pallet_transaction_payment.rs
@@ -0,0 +1,68 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Polkadot.
+
+// Polkadot is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Polkadot is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Autogenerated weights for `pallet_transaction_payment`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-09-12, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("westend-dev")`, DB CACHE: 1024
+
+// Executed Command:
+// ./target/debug/polkadot
+// benchmark
+// pallet
+// --steps=2
+// --repeat=2
+// --extrinsic=*
+// --wasm-execution=compiled
+// --heap-pages=4096
+// --pallet=pallet-transaction-payment
+// --chain=westend-dev
+// --output=./polkadot/runtime/westend/src/weights/
+// --header=./polkadot/file_header.txt
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::Weight};
+use core::marker::PhantomData;
+
+/// Weight functions for `pallet_transaction_payment`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> pallet_transaction_payment::WeightInfo for WeightInfo<T> {
+	/// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0)
+	/// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `Authorship::Author` (r:1 w:0)
+	/// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
+	/// Storage: `System::Digest` (r:1 w:0)
+	/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	fn charge_transaction_payment() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `320`
+		//  Estimated: `3593`
+		// Minimum execution time: 569_518_000 picoseconds.
+		Weight::from_parts(590_438_000, 0)
+			.saturating_add(Weight::from_parts(0, 3593))
+			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+}
diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs
index 40a7da58a68..f1ec3f604d7 100644
--- a/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs
+++ b/polkadot/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs
@@ -121,7 +121,7 @@ benchmarks! {
 
 		let instruction = Instruction::Transact {
 			origin_kind: OriginKind::SovereignAccount,
-			require_weight_at_most: noop_call.get_dispatch_info().weight,
+			require_weight_at_most: noop_call.get_dispatch_info().call_weight,
 			call: double_encoded_noop_call,
 		};
 		let xcm = Xcm(vec![instruction]);
diff --git a/polkadot/xcm/pallet-xcm-benchmarks/src/lib.rs b/polkadot/xcm/pallet-xcm-benchmarks/src/lib.rs
index 210b8f65637..5f8482bdcb8 100644
--- a/polkadot/xcm/pallet-xcm-benchmarks/src/lib.rs
+++ b/polkadot/xcm/pallet-xcm-benchmarks/src/lib.rs
@@ -62,7 +62,7 @@ const SEED: u32 = 0;
 /// The XCM executor to use for doing stuff.
 pub type ExecutorOf<T> = xcm_executor::XcmExecutor<<T as Config>::XcmConfig>;
 /// The overarching call type.
-pub type OverArchingCallOf<T> = <T as frame_system::Config>::RuntimeCall;
+pub type RuntimeCallOf<T> = <T as frame_system::Config>::RuntimeCall;
 /// The asset transactor of our executor
 pub type AssetTransactorOf<T> = <<T as Config>::XcmConfig as XcmConfig>::AssetTransactor;
 /// The call type of executor's config. Should eventually resolve to the same overarching call type.
diff --git a/polkadot/xcm/pallet-xcm/src/lib.rs b/polkadot/xcm/pallet-xcm/src/lib.rs
index 951fb8553d5..254bc2c7b83 100644
--- a/polkadot/xcm/pallet-xcm/src/lib.rs
+++ b/polkadot/xcm/pallet-xcm/src/lib.rs
@@ -2744,7 +2744,7 @@ impl<T: Config> Pallet<T> {
 			.invert_target(&responder)
 			.map_err(|()| XcmError::LocationNotInvertible)?;
 		let notify: <T as Config>::RuntimeCall = notify.into();
-		let max_weight = notify.get_dispatch_info().weight;
+		let max_weight = notify.get_dispatch_info().call_weight;
 		let query_id = Self::new_notify_query(responder, notify, timeout, Here);
 		let response_info = QueryResponseInfo { destination, query_id, max_weight };
 		let report_error = Xcm(vec![ReportError(response_info)]);
@@ -3278,7 +3278,7 @@ impl<T: Config> OnResponse for Pallet<T> {
 							<T as Config>::RuntimeCall::decode(&mut bytes)
 						}) {
 							Queries::<T>::remove(query_id);
-							let weight = call.get_dispatch_info().weight;
+							let weight = call.get_dispatch_info().call_weight;
 							if weight.any_gt(max_weight) {
 								let e = Event::NotifyOverweight {
 									query_id,
diff --git a/polkadot/xcm/xcm-builder/Cargo.toml b/polkadot/xcm/xcm-builder/Cargo.toml
index 671f0181277..eaa115740f3 100644
--- a/polkadot/xcm/xcm-builder/Cargo.toml
+++ b/polkadot/xcm/xcm-builder/Cargo.toml
@@ -49,6 +49,7 @@ runtime-benchmarks = [
 	"pallet-assets/runtime-benchmarks",
 	"pallet-balances/runtime-benchmarks",
 	"pallet-salary/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"pallet-xcm/runtime-benchmarks",
 	"polkadot-parachain-primitives/runtime-benchmarks",
 	"polkadot-primitives/runtime-benchmarks",
diff --git a/polkadot/xcm/xcm-builder/src/tests/mock.rs b/polkadot/xcm/xcm-builder/src/tests/mock.rs
index 9f42aee87c9..bec7b253977 100644
--- a/polkadot/xcm/xcm-builder/src/tests/mock.rs
+++ b/polkadot/xcm/xcm-builder/src/tests/mock.rs
@@ -100,13 +100,13 @@ impl Dispatchable for TestCall {
 
 impl GetDispatchInfo for TestCall {
 	fn get_dispatch_info(&self) -> DispatchInfo {
-		let weight = *match self {
+		let call_weight = *match self {
 			TestCall::OnlyRoot(estimate, ..) |
 			TestCall::OnlyParachain(estimate, ..) |
 			TestCall::OnlySigned(estimate, ..) |
 			TestCall::Any(estimate, ..) => estimate,
 		};
-		DispatchInfo { weight, ..Default::default() }
+		DispatchInfo { call_weight, ..Default::default() }
 	}
 }
 
diff --git a/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs b/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs
index 9f2146fa30e..d76ff21b859 100644
--- a/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs
+++ b/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs
@@ -26,13 +26,21 @@ use frame_support::{
 };
 use frame_system::{EnsureRoot, EnsureSigned};
 use polkadot_primitives::{AccountIndex, BlakeTwo256, Signature};
-use polkadot_test_runtime::SignedExtra;
 use sp_runtime::{generic, traits::MaybeEquivalence, AccountId32, BuildStorage};
 use xcm_executor::{traits::ConvertLocation, XcmExecutor};
 
+pub type TxExtension = (
+	frame_system::CheckNonZeroSender<Test>,
+	frame_system::CheckSpecVersion<Test>,
+	frame_system::CheckTxVersion<Test>,
+	frame_system::CheckGenesis<Test>,
+	frame_system::CheckMortality<Test>,
+	frame_system::CheckNonce<Test>,
+	frame_system::CheckWeight<Test>,
+);
 pub type Address = sp_runtime::MultiAddress<AccountId, AccountIndex>;
 pub type UncheckedExtrinsic =
-	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
 pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
 pub type Block = generic::Block<Header, UncheckedExtrinsic>;
 
diff --git a/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs b/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs
index 020a4a54285..e95473c5407 100644
--- a/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs
+++ b/polkadot/xcm/xcm-executor/integration-tests/src/lib.rs
@@ -81,7 +81,7 @@ fn transact_recursion_limit_works() {
 			BuyExecution { fees: (Here, 1).into(), weight_limit: Unlimited },
 			Transact {
 				origin_kind: OriginKind::Native,
-				require_weight_at_most: call.get_dispatch_info().weight,
+				require_weight_at_most: call.get_dispatch_info().call_weight,
 				call: call.encode().into(),
 			},
 		])
diff --git a/polkadot/xcm/xcm-executor/src/lib.rs b/polkadot/xcm/xcm-executor/src/lib.rs
index 71985360b7d..e3addfa3e79 100644
--- a/polkadot/xcm/xcm-executor/src/lib.rs
+++ b/polkadot/xcm/xcm-executor/src/lib.rs
@@ -861,7 +861,7 @@ impl<Config: config::Config> XcmExecutor<Config> {
 					"Dispatching with origin",
 				);
 
-				let weight = message_call.get_dispatch_info().weight;
+				let weight = message_call.get_dispatch_info().call_weight;
 
 				if !weight.all_lte(require_weight_at_most) {
 					tracing::trace!(
diff --git a/polkadot/xcm/xcm-runtime-apis/tests/mock.rs b/polkadot/xcm/xcm-runtime-apis/tests/mock.rs
index 3e284c915bf..b3afa23503e 100644
--- a/polkadot/xcm/xcm-runtime-apis/tests/mock.rs
+++ b/polkadot/xcm/xcm-runtime-apis/tests/mock.rs
@@ -60,9 +60,16 @@ construct_runtime! {
 	}
 }
 
-pub type SignedExtra = (frame_system::CheckWeight<TestRuntime>,);
-pub type TestXt = sp_runtime::testing::TestXt<RuntimeCall, SignedExtra>;
-type Block = sp_runtime::testing::Block<TestXt>;
+pub type TxExtension = (frame_system::CheckWeight<TestRuntime>,);
+
+// we only use the hash type from this, so using the mock should be fine.
+pub(crate) type Extrinsic = sp_runtime::generic::UncheckedExtrinsic<
+	u64,
+	RuntimeCall,
+	sp_runtime::testing::UintAuthorityId,
+	TxExtension,
+>;
+type Block = sp_runtime::testing::Block<Extrinsic>;
 type Balance = u128;
 type AssetIdForAssetsPallet = u32;
 type AccountId = u64;
diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs
index 616329a2f06..fc650ae55a7 100644
--- a/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs
+++ b/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs
@@ -44,13 +44,13 @@ use xcm_builder::{
 };
 use xcm_executor::{Config, XcmExecutor};
 
-pub type SignedExtra = (frame_system::CheckNonZeroSender<Runtime>,);
+pub type TxExtension = (frame_system::CheckNonZeroSender<Runtime>,);
 
 pub type BlockNumber = u64;
 pub type Address = MultiAddress<AccountId, ()>;
 pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
 pub type UncheckedExtrinsic =
-	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
 pub type Block = generic::Block<Header, UncheckedExtrinsic>;
 
 pub type Signature = MultiSignature;
diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs
index 459d2640b6d..58687b47852 100644
--- a/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs
+++ b/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs
@@ -45,13 +45,13 @@ use xcm_builder::{
 };
 use xcm_executor::{Config, XcmExecutor};
 
-pub type SignedExtra = (frame_system::CheckNonZeroSender<Runtime>,);
+pub type TxExtension = (frame_system::CheckNonZeroSender<Runtime>,);
 
 pub type BlockNumber = u64;
 pub type Address = MultiAddress<AccountId, ()>;
 pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
 pub type UncheckedExtrinsic =
-	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
 pub type Block = generic::Block<Header, UncheckedExtrinsic>;
 
 pub type Signature = MultiSignature;
diff --git a/prdoc/pr_3685.prdoc b/prdoc/pr_3685.prdoc
new file mode 100644
index 00000000000..bd414c93a6f
--- /dev/null
+++ b/prdoc/pr_3685.prdoc
@@ -0,0 +1,300 @@
+# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0
+# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json
+
+title: FRAME Reintroduce `TransactionExtension` as a replacement for `SignedExtension`
+
+doc:
+  - audience: [Runtime Dev, Runtime User, Node Operator, Node Dev]
+    description: |
+      Introduces a new trait `TransactionExtension` to replace `SignedExtension`. Introduce the
+      idea of transactions which obey the runtime's extensions and have according Extension data
+      (né Extra data) yet do not have hard-coded signatures.
+
+      Deprecate the terminology of "Unsigned" when used for transactions/extrinsics owing to there
+      now being "proper" unsigned transactions which obey the extension framework and "old-style"
+      unsigned which do not. Instead we have `General` for the former and `Bare` for the latter.
+      Unsigned will be phased out as a type of transaction, and `Bare` will only be used for
+      Inherents.
+
+      Types of extrinsic are now therefore
+        - Bare (no hardcoded signature, no Extra data; used to be known as "Unsigned")
+            - Bare transactions (deprecated) - Gossiped, validated with `ValidateUnsigned`
+              (deprecated) and the `_bare_compat` bits of `TransactionExtension` (deprecated).
+            - Inherents - Not gossiped, validated with `ProvideInherent`.
+        - Extended (Extra data) - Gossiped, validated via `TransactionExtension`.
+            - Signed transactions (with a hardcoded signature).
+            - General transactions (without a hardcoded signature).
+
+      Notable information on `TransactionExtension` and the differences from `SignedExtension`
+        - `AdditionalSigned`/`additional_signed` is renamed to `Implicit`/`implicit`. It is encoded
+          for the entire transaction and passed in to each extension as a new argument to validate.
+        - `pre_dispatch` is renamed to `prepare`.
+        - `validate` runs transaction validation logic both off-chain and on-chain, and is
+          non-mutating.
+        - `prepare` runs on-chain pre-execution logic using information extracted during validation
+          and is mutating.
+        - `validate` and `prepare` are now passed an `Origin` rather than an `AccountId`. If the
+          extension logic presumes an `AccountId`, consider using the trait function
+          `AsSystemOriginSigner::as_system_origin_signer`.
+        - A signature on the underlying transaction may validly not be present.
+        - The origin may be altered during validation.
+        - Validation functionality present in `validate` should not be repeated in `prepare`.
+          Useful information obtained during `validate` should now be passed in to `prepare` using
+          the new user-specifiable type `Val`.
+        - Unsigned logic should be temporarily migrated from the old `*_unsigned` functions into the
+          regular versions of the new functions where the `Origin` is `None`, until the deprecation
+          of `ValidateUnsigned` in phase 2 of Extrinsic Horizon.
+        - The `Call` type defining the runtime call is now a type parameter.
+        - Extensions now track the weight they consume during validation, preparation and
+          post-dispatch through the `TransactionExtensionBase::weight` function.
+        - `TestXt` was removed and its usage in tests was replaced with `UncheckedExtrinsic`
+          instances.
+
+      To fix the build issues introduced by this change, use the `AsTransactionExtension` adapter
+      to wrap existing `SignedExtension`s by converting them using the `From<SignedExtension>`
+      generic implementation for `AsTransactionExtension`. More details on migrating existing
+      `SignedExtension` implementations to `TransactionExtension` in the PR description.
+
+crates:
+  - name: bridge-runtime-common
+    bump: major
+  - name: bp-bridge-hub-cumulus
+    bump: major
+  - name: bp-bridge-hub-rococo
+    bump: major
+  - name: bp-bridge-hub-westend
+    bump: major
+  - name: bp-kusama
+    bump: major
+  - name: bp-polkadot-bulletin
+    bump: major
+  - name: bp-polkadot
+    bump: major
+  - name: bp-rococo
+    bump: major
+  - name: bp-westend
+    bump: major
+  - name: pallet-bridge-relayers
+    bump: major
+  - name: bp-polkadot-core
+    bump: major
+  - name: bp-relayers
+    bump: major
+  - name: bp-runtime
+    bump: major
+  - name: substrate-relay-helper
+    bump: major
+  - name: snowbridge-pallet-ethereum-client
+    bump: major
+  - name: snowbridge-pallet-inbound-queue
+    bump: major
+  - name: snowbridge-pallet-outbound-queue
+    bump: major
+  - name: snowbridge-pallet-system
+    bump: major
+  - name: snowbridge-runtime-test-common
+    bump: major
+  - name: parachain-template-runtime
+    bump: major
+  - name: cumulus-pallet-parachain-system
+    bump: major
+  - name: asset-hub-rococo-runtime
+    bump: major
+  - name: asset-hub-westend-runtime
+    bump: major
+  - name: bridge-hub-rococo-runtime
+    bump: major
+  - name: bridge-hub-westend-runtime
+    bump: major
+  - name: collectives-westend-runtime
+    bump: major
+  - name: contracts-rococo-runtime
+    bump: major
+  - name: coretime-rococo-runtime
+    bump: major
+  - name: coretime-westend-runtime
+    bump: major
+  - name: glutton-westend-runtime
+    bump: major
+  - name: people-rococo-runtime
+    bump: major
+  - name: people-westend-runtime
+    bump: major
+  - name: parachains-runtimes-test-utils
+    bump: major
+  - name: penpal-runtime
+    bump: major
+  - name: rococo-parachain-runtime
+    bump: major
+  - name: polkadot-omni-node
+    bump: major
+  - name: polkadot-parachain-bin
+    bump: major
+  - name: cumulus-primitives-storage-weight-reclaim
+    bump: major
+  - name: cumulus-test-client
+    bump: major
+  - name: cumulus-test-runtime
+    bump: major
+  - name: cumulus-test-service
+    bump: major
+  - name: polkadot-sdk-docs
+    bump: major
+  - name: polkadot-service
+    bump: major
+  - name: polkadot-test-service
+    bump: major
+  - name: polkadot-runtime-common
+    bump: major
+  - name: polkadot-runtime-parachains
+    bump: major
+  - name: rococo-runtime
+    bump: major
+  - name: polkadot-test-runtime
+    bump: major
+  - name: westend-runtime
+    bump: major
+  - name: pallet-xcm-benchmarks
+    bump: major
+  - name: pallet-xcm
+    bump: major
+  - name: staging-xcm-builder
+    bump: major
+  - name: staging-xcm-executor
+    bump: major
+  - name: xcm-runtime-apis
+    bump: major
+  - name: xcm-simulator
+    bump: major
+  - name: minimal-template-runtime
+    bump: major
+  - name: minimal-template-node
+    bump: major
+  - name: solochain-template-runtime
+    bump: major
+  - name: staging-node-cli
+    bump: major
+  - name: kitchensink-runtime
+    bump: major
+  - name: node-testing
+    bump: major
+  - name: sc-client-api
+    bump: major
+  - name: sc-client-db
+    bump: major
+  - name: sc-network-gossip
+    bump: major
+  - name: sc-network-sync
+    bump: major
+  - name: sc-transaction-pool
+    bump: major
+  - name: polkadot-sdk-frame
+    bump: major
+  - name: pallet-alliance
+    bump: major
+  - name: pallet-assets
+    bump: major
+  - name: pallet-asset-conversion
+    bump: major
+  - name: pallet-babe
+    bump: major
+  - name: pallet-balances
+    bump: major
+  - name: pallet-beefy
+    bump: major
+  - name: pallet-collective
+    bump: major
+  - name: pallet-contracts
+    bump: major
+  - name: pallet-election-provider-multi-phase
+    bump: major
+  - name: pallet-elections-phragmen
+    bump: major
+  - name: pallet-example-basic
+    bump: major
+  - name: pallet-example-tasks
+    bump: major
+  - name: pallet-example-offchain-worker
+    bump: major
+  - name: pallet-examples
+    bump: major
+  - name: frame-executive
+    bump: major
+  - name: pallet-grandpa
+    bump: major
+  - name: pallet-im-online
+    bump: major
+  - name: pallet-lottery
+    bump: major
+  - name: frame-metadata-hash-extension
+    bump: major
+  - name: pallet-mixnet
+    bump: major
+  - name: pallet-multisig
+    bump: major
+  - name: pallet-offences
+    bump: major
+  - name: pallet-proxy
+    bump: major
+  - name: pallet-recovery
+    bump: major
+  - name: pallet-revive
+    bump: major
+  - name: pallet-sassafras
+    bump: major
+  - name: pallet-scheduler
+    bump: major
+  - name: pallet-state-trie-migration
+    bump: major
+  - name: pallet-sudo
+    bump: major
+  - name: frame-support-procedural
+    bump: major
+  - name: frame-support
+    bump: major
+  - name: frame-support-test
+    bump: major
+  - name: frame-system
+    bump: major
+  - name: frame-system-benchmarking
+    bump: major
+  - name: pallet-transaction-payment
+    bump: major
+  - name: pallet-asset-conversion-tx-payment
+    bump: major
+  - name: pallet-asset-tx-payment
+    bump: major
+  - name: pallet-skip-feeless-payment
+    bump: major
+  - name: pallet-utility
+    bump: major
+  - name: pallet-whitelist
+    bump: major
+  - name: sp-inherents
+    bump: major
+  - name: sp-metadata-ir
+    bump: major
+  - name: sp-runtime
+    bump: major
+  - name: sp-storage
+    bump: major
+  - name: sp-test-primitives
+    bump: major
+  - name: substrate-test-runtime
+    bump: major
+  - name: substrate-test-utils
+    bump: major
+  - name: frame-benchmarking-cli
+    bump: major
+  - name: frame-remote-externalities
+    bump: major
+  - name: substrate-rpc-client
+    bump: major
+  - name: minimal-template-runtime
+    bump: major
+  - name: parachain-template-runtime
+    bump: major
+  - name: solochain-template-node
+    bump: major
+  - name: polkadot-sdk
+    bump: major
diff --git a/substrate/.maintain/frame-weight-template.hbs b/substrate/.maintain/frame-weight-template.hbs
index ecd384a5145..ec9eee205ce 100644
--- a/substrate/.maintain/frame-weight-template.hbs
+++ b/substrate/.maintain/frame-weight-template.hbs
@@ -33,7 +33,7 @@ pub trait WeightInfo {
 
 /// Weights for `{{pallet}}` using the Substrate node and recommended hardware.
 pub struct SubstrateWeight<T>(PhantomData<T>);
-{{#if (eq pallet "frame_system")}}
+{{#if (or (eq pallet "frame_system") (eq pallet "frame_system_extensions"))}}
 impl<T: crate::Config> WeightInfo for SubstrateWeight<T> {
 {{else}}
 impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
diff --git a/substrate/bin/node/cli/benches/block_production.rs b/substrate/bin/node/cli/benches/block_production.rs
index de883d1051f..d8041ed400c 100644
--- a/substrate/bin/node/cli/benches/block_production.rs
+++ b/substrate/bin/node/cli/benches/block_production.rs
@@ -120,10 +120,9 @@ fn new_node(tokio_handle: Handle) -> node_cli::service::NewFullBase {
 }
 
 fn extrinsic_set_time(now: u64) -> OpaqueExtrinsic {
-	kitchensink_runtime::UncheckedExtrinsic {
-		signature: None,
-		function: kitchensink_runtime::RuntimeCall::Timestamp(pallet_timestamp::Call::set { now }),
-	}
+	kitchensink_runtime::UncheckedExtrinsic::new_bare(kitchensink_runtime::RuntimeCall::Timestamp(
+		pallet_timestamp::Call::set { now },
+	))
 	.into()
 }
 
diff --git a/substrate/bin/node/cli/benches/executor.rs b/substrate/bin/node/cli/benches/executor.rs
index fa4da5c13d4..412b7f0ba0f 100644
--- a/substrate/bin/node/cli/benches/executor.rs
+++ b/substrate/bin/node/cli/benches/executor.rs
@@ -31,7 +31,7 @@ use sp_core::{
 	storage::well_known_keys,
 	traits::{CallContext, CodeExecutor, RuntimeCode},
 };
-use sp_runtime::traits::BlakeTwo256;
+use sp_runtime::{generic::ExtrinsicFormat, traits::BlakeTwo256};
 use sp_state_machine::TestExternalities as CoreTestExternalities;
 use staging_node_cli::service::RuntimeExecutor;
 
@@ -146,11 +146,11 @@ fn test_blocks(
 ) -> Vec<(Vec<u8>, Hash)> {
 	let mut test_ext = new_test_ext(genesis_config);
 	let mut block1_extrinsics = vec![CheckedExtrinsic {
-		signed: None,
+		format: ExtrinsicFormat::Bare,
 		function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: 0 }),
 	}];
 	block1_extrinsics.extend((0..20).map(|i| CheckedExtrinsic {
-		signed: Some((alice(), signed_extra(i, 0))),
+		format: ExtrinsicFormat::Signed(alice(), tx_ext(i, 0)),
 		function: RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death {
 			dest: bob().into(),
 			value: 1 * DOLLARS,
diff --git a/substrate/bin/node/cli/src/service.rs b/substrate/bin/node/cli/src/service.rs
index 4eb1db185e9..00658b361df 100644
--- a/substrate/bin/node/cli/src/service.rs
+++ b/substrate/bin/node/cli/src/service.rs
@@ -121,7 +121,7 @@ pub fn create_extrinsic(
 		.map(|c| c / 2)
 		.unwrap_or(2) as u64;
 	let tip = 0;
-	let extra: kitchensink_runtime::SignedExtra =
+	let tx_ext: kitchensink_runtime::TxExtension =
 		(
 			frame_system::CheckNonZeroSender::<kitchensink_runtime::Runtime>::new(),
 			frame_system::CheckSpecVersion::<kitchensink_runtime::Runtime>::new(),
@@ -143,7 +143,7 @@ pub fn create_extrinsic(
 
 	let raw_payload = kitchensink_runtime::SignedPayload::from_raw(
 		function.clone(),
-		extra.clone(),
+		tx_ext.clone(),
 		(
 			(),
 			kitchensink_runtime::VERSION.spec_version,
@@ -162,7 +162,7 @@ pub fn create_extrinsic(
 		function,
 		sp_runtime::AccountId32::from(sender.public()).into(),
 		kitchensink_runtime::Signature::Sr25519(signature),
-		extra,
+		tx_ext,
 	)
 }
 
@@ -866,7 +866,7 @@ mod tests {
 	use codec::Encode;
 	use kitchensink_runtime::{
 		constants::{currency::CENTS, time::SLOT_DURATION},
-		Address, BalancesCall, RuntimeCall, UncheckedExtrinsic,
+		Address, BalancesCall, RuntimeCall, TxExtension, UncheckedExtrinsic,
 	};
 	use node_primitives::{Block, DigestItem, Signature};
 	use polkadot_sdk::{sc_transaction_pool_api::MaintainedTransactionPool, *};
@@ -1070,7 +1070,7 @@ mod tests {
 					pallet_asset_conversion_tx_payment::ChargeAssetTxPayment::from(0, None),
 				);
 				let metadata_hash = frame_metadata_hash_extension::CheckMetadataHash::new(false);
-				let extra = (
+				let tx_ext: TxExtension = (
 					check_non_zero_sender,
 					check_spec_version,
 					check_tx_version,
@@ -1083,7 +1083,7 @@ mod tests {
 				);
 				let raw_payload = SignedPayload::from_raw(
 					function,
-					extra,
+					tx_ext,
 					(
 						(),
 						spec_version,
@@ -1097,9 +1097,9 @@ mod tests {
 					),
 				);
 				let signature = raw_payload.using_encoded(|payload| signer.sign(payload));
-				let (function, extra, _) = raw_payload.deconstruct();
+				let (function, tx_ext, _) = raw_payload.deconstruct();
 				index += 1;
-				UncheckedExtrinsic::new_signed(function, from.into(), signature.into(), extra)
+				UncheckedExtrinsic::new_signed(function, from.into(), signature.into(), tx_ext)
 					.into()
 			},
 		);
diff --git a/substrate/bin/node/cli/tests/basic.rs b/substrate/bin/node/cli/tests/basic.rs
index 037ddbb1e47..616d813f78e 100644
--- a/substrate/bin/node/cli/tests/basic.rs
+++ b/substrate/bin/node/cli/tests/basic.rs
@@ -17,11 +17,11 @@
 
 use codec::{Decode, Encode, Joiner};
 use frame_support::{
-	dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo},
+	dispatch::{DispatchClass, GetDispatchInfo},
 	traits::Currency,
 	weights::Weight,
 };
-use frame_system::{self, AccountInfo, EventRecord, Phase};
+use frame_system::{self, AccountInfo, DispatchEventInfo, EventRecord, Phase};
 use polkadot_sdk::*;
 use sp_core::{storage::well_known_keys, traits::Externalities};
 use sp_runtime::{
@@ -59,17 +59,23 @@ pub fn bloaty_code_unwrap() -> &'static [u8] {
 /// Note that reads the multiplier from storage directly, hence to get the fee of `extrinsic`
 /// at block `n`, it must be called prior to executing block `n` to do the calculation with the
 /// correct multiplier.
-fn transfer_fee<E: Encode>(extrinsic: &E) -> Balance {
-	TransactionPayment::compute_fee(
-		extrinsic.encode().len() as u32,
-		&default_transfer_call().get_dispatch_info(),
-		0,
-	)
+fn transfer_fee(extrinsic: &UncheckedExtrinsic) -> Balance {
+	let mut info = default_transfer_call().get_dispatch_info();
+	info.extension_weight = extrinsic.extension_weight();
+	TransactionPayment::compute_fee(extrinsic.encode().len() as u32, &info, 0)
+}
+
+/// Default transfer fee, same as `transfer_fee`, but with a weight refund factored in.
+fn transfer_fee_with_refund(extrinsic: &UncheckedExtrinsic, weight_refund: Weight) -> Balance {
+	let mut info = default_transfer_call().get_dispatch_info();
+	info.extension_weight = extrinsic.extension_weight();
+	let post_info = (Some(info.total_weight().saturating_sub(weight_refund)), info.pays_fee).into();
+	TransactionPayment::compute_actual_fee(extrinsic.encode().len() as u32, &info, &post_info, 0)
 }
 
 fn xt() -> UncheckedExtrinsic {
 	sign(CheckedExtrinsic {
-		signed: Some((alice(), signed_extra(0, 0))),
+		format: sp_runtime::generic::ExtrinsicFormat::Signed(alice(), tx_ext(0, 0)),
 		function: RuntimeCall::Balances(default_transfer_call()),
 	})
 }
@@ -86,11 +92,11 @@ fn changes_trie_block() -> (Vec<u8>, Hash) {
 		GENESIS_HASH.into(),
 		vec![
 			CheckedExtrinsic {
-				signed: None,
+				format: sp_runtime::generic::ExtrinsicFormat::Bare,
 				function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: time }),
 			},
 			CheckedExtrinsic {
-				signed: Some((alice(), signed_extra(0, 0))),
+				format: sp_runtime::generic::ExtrinsicFormat::Signed(alice(), tx_ext(0, 0)),
 				function: RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death {
 					dest: bob().into(),
 					value: 69 * DOLLARS,
@@ -113,11 +119,11 @@ fn blocks() -> ((Vec<u8>, Hash), (Vec<u8>, Hash)) {
 		GENESIS_HASH.into(),
 		vec![
 			CheckedExtrinsic {
-				signed: None,
+				format: sp_runtime::generic::ExtrinsicFormat::Bare,
 				function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: time1 }),
 			},
 			CheckedExtrinsic {
-				signed: Some((alice(), signed_extra(0, 0))),
+				format: sp_runtime::generic::ExtrinsicFormat::Signed(alice(), tx_ext(0, 0)),
 				function: RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death {
 					dest: bob().into(),
 					value: 69 * DOLLARS,
@@ -133,18 +139,18 @@ fn blocks() -> ((Vec<u8>, Hash), (Vec<u8>, Hash)) {
 		block1.1,
 		vec![
 			CheckedExtrinsic {
-				signed: None,
+				format: sp_runtime::generic::ExtrinsicFormat::Bare,
 				function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: time2 }),
 			},
 			CheckedExtrinsic {
-				signed: Some((bob(), signed_extra(0, 0))),
+				format: sp_runtime::generic::ExtrinsicFormat::Signed(bob(), tx_ext(0, 0)),
 				function: RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death {
 					dest: alice().into(),
 					value: 5 * DOLLARS,
 				}),
 			},
 			CheckedExtrinsic {
-				signed: Some((alice(), signed_extra(1, 0))),
+				format: sp_runtime::generic::ExtrinsicFormat::Signed(alice(), tx_ext(1, 0)),
 				function: RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death {
 					dest: bob().into(),
 					value: 15 * DOLLARS,
@@ -168,11 +174,11 @@ fn block_with_size(time: u64, nonce: u32, size: usize) -> (Vec<u8>, Hash) {
 		GENESIS_HASH.into(),
 		vec![
 			CheckedExtrinsic {
-				signed: None,
+				format: sp_runtime::generic::ExtrinsicFormat::Bare,
 				function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: time * 1000 }),
 			},
 			CheckedExtrinsic {
-				signed: Some((alice(), signed_extra(nonce, 0))),
+				format: sp_runtime::generic::ExtrinsicFormat::Signed(alice(), tx_ext(nonce, 0)),
 				function: RuntimeCall::System(frame_system::Call::remark { remark: vec![0; size] }),
 			},
 		],
@@ -257,13 +263,14 @@ fn successful_execution_with_native_equivalent_code_gives_ok() {
 	let r = executor_call(&mut t, "Core_initialize_block", &vec![].and(&from_block_number(1u32))).0;
 	assert!(r.is_ok());
 
-	let fees = t.execute_with(|| transfer_fee(&xt()));
+	let weight_refund = Weight::zero();
+	let fees_after_refund = t.execute_with(|| transfer_fee_with_refund(&xt(), weight_refund));
 
 	let r = executor_call(&mut t, "BlockBuilder_apply_extrinsic", &vec![].and(&xt())).0;
 	assert!(r.is_ok());
 
 	t.execute_with(|| {
-		assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - fees);
+		assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - fees_after_refund);
 		assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS);
 	});
 }
@@ -297,13 +304,14 @@ fn successful_execution_with_foreign_code_gives_ok() {
 	let r = executor_call(&mut t, "Core_initialize_block", &vec![].and(&from_block_number(1u32))).0;
 	assert!(r.is_ok());
 
-	let fees = t.execute_with(|| transfer_fee(&xt()));
+	let weight_refund = Weight::zero();
+	let fees_after_refund = t.execute_with(|| transfer_fee_with_refund(&xt(), weight_refund));
 
 	let r = executor_call(&mut t, "BlockBuilder_apply_extrinsic", &vec![].and(&xt())).0;
 	assert!(r.is_ok());
 
 	t.execute_with(|| {
-		assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - fees);
+		assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - fees_after_refund);
 		assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS);
 	});
 }
@@ -316,15 +324,18 @@ fn full_native_block_import_works() {
 
 	let mut alice_last_known_balance: Balance = Default::default();
 	let mut fees = t.execute_with(|| transfer_fee(&xt()));
+	let extension_weight = xt().extension_weight();
+	let weight_refund = Weight::zero();
+	let fees_after_refund = t.execute_with(|| transfer_fee_with_refund(&xt(), weight_refund));
 
-	let transfer_weight = default_transfer_call().get_dispatch_info().weight.saturating_add(
+	let transfer_weight = default_transfer_call().get_dispatch_info().call_weight.saturating_add(
 		<Runtime as frame_system::Config>::BlockWeights::get()
 			.get(DispatchClass::Normal)
 			.base_extrinsic,
 	);
 	let timestamp_weight = pallet_timestamp::Call::set::<Runtime> { now: Default::default() }
 		.get_dispatch_info()
-		.weight
+		.call_weight
 		.saturating_add(
 			<Runtime as frame_system::Config>::BlockWeights::get()
 				.get(DispatchClass::Mandatory)
@@ -334,17 +345,17 @@ fn full_native_block_import_works() {
 	executor_call(&mut t, "Core_execute_block", &block1.0).0.unwrap();
 
 	t.execute_with(|| {
-		assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - fees);
+		assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - fees_after_refund);
 		assert_eq!(Balances::total_balance(&bob()), 169 * DOLLARS);
 		alice_last_known_balance = Balances::total_balance(&alice());
 		let events = vec![
 			EventRecord {
 				phase: Phase::ApplyExtrinsic(0),
 				event: RuntimeEvent::System(frame_system::Event::ExtrinsicSuccess {
-					dispatch_info: DispatchInfo {
+					dispatch_info: DispatchEventInfo {
 						weight: timestamp_weight,
 						class: DispatchClass::Mandatory,
-						..Default::default()
+						pays_fee: Default::default(),
 					},
 				}),
 				topics: vec![],
@@ -370,21 +381,21 @@ fn full_native_block_import_works() {
 				phase: Phase::ApplyExtrinsic(1),
 				event: RuntimeEvent::Balances(pallet_balances::Event::Deposit {
 					who: pallet_treasury::Pallet::<Runtime>::account_id(),
-					amount: fees * 8 / 10,
+					amount: fees_after_refund * 8 / 10,
 				}),
 				topics: vec![],
 			},
 			EventRecord {
 				phase: Phase::ApplyExtrinsic(1),
 				event: RuntimeEvent::Treasury(pallet_treasury::Event::Deposit {
-					value: fees * 8 / 10,
+					value: fees_after_refund * 8 / 10,
 				}),
 				topics: vec![],
 			},
 			EventRecord {
 				phase: Phase::ApplyExtrinsic(1),
 				event: RuntimeEvent::Balances(pallet_balances::Event::Rescinded {
-					amount: fees * 2 / 10,
+					amount: fees_after_refund * 2 / 10,
 				}),
 				topics: vec![],
 			},
@@ -393,7 +404,7 @@ fn full_native_block_import_works() {
 				event: RuntimeEvent::TransactionPayment(
 					pallet_transaction_payment::Event::TransactionFeePaid {
 						who: alice().into(),
-						actual_fee: fees,
+						actual_fee: fees_after_refund,
 						tip: 0,
 					},
 				),
@@ -402,7 +413,11 @@ fn full_native_block_import_works() {
 			EventRecord {
 				phase: Phase::ApplyExtrinsic(1),
 				event: RuntimeEvent::System(frame_system::Event::ExtrinsicSuccess {
-					dispatch_info: DispatchInfo { weight: transfer_weight, ..Default::default() },
+					dispatch_info: DispatchEventInfo {
+						weight: transfer_weight
+							.saturating_add(extension_weight.saturating_sub(weight_refund)),
+						..Default::default()
+					},
 				}),
 				topics: vec![],
 			},
@@ -412,15 +427,18 @@ fn full_native_block_import_works() {
 
 	fees = t.execute_with(|| transfer_fee(&xt()));
 	let pot = t.execute_with(|| Treasury::pot());
+	let extension_weight = xt().extension_weight();
+	let weight_refund = Weight::zero();
+	let fees_after_refund = t.execute_with(|| transfer_fee_with_refund(&xt(), weight_refund));
 
 	executor_call(&mut t, "Core_execute_block", &block2.0).0.unwrap();
 
 	t.execute_with(|| {
 		assert_eq!(
 			Balances::total_balance(&alice()),
-			alice_last_known_balance - 10 * DOLLARS - fees,
+			alice_last_known_balance - 10 * DOLLARS - fees_after_refund,
 		);
-		assert_eq!(Balances::total_balance(&bob()), 179 * DOLLARS - fees);
+		assert_eq!(Balances::total_balance(&bob()), 179 * DOLLARS - fees_after_refund);
 		let events = vec![
 			EventRecord {
 				phase: Phase::Initialization,
@@ -433,10 +451,10 @@ fn full_native_block_import_works() {
 			EventRecord {
 				phase: Phase::ApplyExtrinsic(0),
 				event: RuntimeEvent::System(frame_system::Event::ExtrinsicSuccess {
-					dispatch_info: DispatchInfo {
+					dispatch_info: DispatchEventInfo {
 						weight: timestamp_weight,
 						class: DispatchClass::Mandatory,
-						..Default::default()
+						pays_fee: Default::default(),
 					},
 				}),
 				topics: vec![],
@@ -462,21 +480,21 @@ fn full_native_block_import_works() {
 				phase: Phase::ApplyExtrinsic(1),
 				event: RuntimeEvent::Balances(pallet_balances::Event::Deposit {
 					who: pallet_treasury::Pallet::<Runtime>::account_id(),
-					amount: fees * 8 / 10,
+					amount: fees_after_refund * 8 / 10,
 				}),
 				topics: vec![],
 			},
 			EventRecord {
 				phase: Phase::ApplyExtrinsic(1),
 				event: RuntimeEvent::Treasury(pallet_treasury::Event::Deposit {
-					value: fees * 8 / 10,
+					value: fees_after_refund * 8 / 10,
 				}),
 				topics: vec![],
 			},
 			EventRecord {
 				phase: Phase::ApplyExtrinsic(1),
 				event: RuntimeEvent::Balances(pallet_balances::Event::Rescinded {
-					amount: fees - fees * 8 / 10,
+					amount: fees_after_refund - fees_after_refund * 8 / 10,
 				}),
 				topics: vec![],
 			},
@@ -485,7 +503,7 @@ fn full_native_block_import_works() {
 				event: RuntimeEvent::TransactionPayment(
 					pallet_transaction_payment::Event::TransactionFeePaid {
 						who: bob().into(),
-						actual_fee: fees,
+						actual_fee: fees_after_refund,
 						tip: 0,
 					},
 				),
@@ -494,7 +512,11 @@ fn full_native_block_import_works() {
 			EventRecord {
 				phase: Phase::ApplyExtrinsic(1),
 				event: RuntimeEvent::System(frame_system::Event::ExtrinsicSuccess {
-					dispatch_info: DispatchInfo { weight: transfer_weight, ..Default::default() },
+					dispatch_info: DispatchEventInfo {
+						weight: transfer_weight
+							.saturating_add(extension_weight.saturating_sub(weight_refund)),
+						..Default::default()
+					},
 				}),
 				topics: vec![],
 			},
@@ -519,21 +541,21 @@ fn full_native_block_import_works() {
 				phase: Phase::ApplyExtrinsic(2),
 				event: RuntimeEvent::Balances(pallet_balances::Event::Deposit {
 					who: pallet_treasury::Pallet::<Runtime>::account_id(),
-					amount: fees * 8 / 10,
+					amount: fees_after_refund * 8 / 10,
 				}),
 				topics: vec![],
 			},
 			EventRecord {
 				phase: Phase::ApplyExtrinsic(2),
 				event: RuntimeEvent::Treasury(pallet_treasury::Event::Deposit {
-					value: fees * 8 / 10,
+					value: fees_after_refund * 8 / 10,
 				}),
 				topics: vec![],
 			},
 			EventRecord {
 				phase: Phase::ApplyExtrinsic(2),
 				event: RuntimeEvent::Balances(pallet_balances::Event::Rescinded {
-					amount: fees - fees * 8 / 10,
+					amount: fees_after_refund - fees_after_refund * 8 / 10,
 				}),
 				topics: vec![],
 			},
@@ -542,7 +564,7 @@ fn full_native_block_import_works() {
 				event: RuntimeEvent::TransactionPayment(
 					pallet_transaction_payment::Event::TransactionFeePaid {
 						who: alice().into(),
-						actual_fee: fees,
+						actual_fee: fees_after_refund,
 						tip: 0,
 					},
 				),
@@ -551,7 +573,11 @@ fn full_native_block_import_works() {
 			EventRecord {
 				phase: Phase::ApplyExtrinsic(2),
 				event: RuntimeEvent::System(frame_system::Event::ExtrinsicSuccess {
-					dispatch_info: DispatchInfo { weight: transfer_weight, ..Default::default() },
+					dispatch_info: DispatchEventInfo {
+						weight: transfer_weight
+							.saturating_add(extension_weight.saturating_sub(weight_refund)),
+						..Default::default()
+					},
 				}),
 				topics: vec![],
 			},
@@ -567,26 +593,28 @@ fn full_wasm_block_import_works() {
 	let (block1, block2) = blocks();
 
 	let mut alice_last_known_balance: Balance = Default::default();
-	let mut fees = t.execute_with(|| transfer_fee(&xt()));
+	let weight_refund = Weight::zero();
+	let fees_after_refund = t.execute_with(|| transfer_fee_with_refund(&xt(), weight_refund));
 
 	executor_call(&mut t, "Core_execute_block", &block1.0).0.unwrap();
 
 	t.execute_with(|| {
-		assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - fees);
+		assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - fees_after_refund);
 		assert_eq!(Balances::total_balance(&bob()), 169 * DOLLARS);
 		alice_last_known_balance = Balances::total_balance(&alice());
 	});
 
-	fees = t.execute_with(|| transfer_fee(&xt()));
+	let weight_refund = Weight::zero();
+	let fees_after_refund = t.execute_with(|| transfer_fee_with_refund(&xt(), weight_refund));
 
 	executor_call(&mut t, "Core_execute_block", &block2.0).0.unwrap();
 
 	t.execute_with(|| {
 		assert_eq!(
 			Balances::total_balance(&alice()),
-			alice_last_known_balance - 10 * DOLLARS - fees,
+			alice_last_known_balance - 10 * DOLLARS - fees_after_refund,
 		);
-		assert_eq!(Balances::total_balance(&bob()), 179 * DOLLARS - 1 * fees);
+		assert_eq!(Balances::total_balance(&bob()), 179 * DOLLARS - 1 * fees_after_refund);
 	});
 }
 
@@ -700,11 +728,11 @@ fn deploying_wasm_contract_should_work() {
 		GENESIS_HASH.into(),
 		vec![
 			CheckedExtrinsic {
-				signed: None,
+				format: sp_runtime::generic::ExtrinsicFormat::Bare,
 				function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: time }),
 			},
 			CheckedExtrinsic {
-				signed: Some((charlie(), signed_extra(0, 0))),
+				format: sp_runtime::generic::ExtrinsicFormat::Signed(charlie(), tx_ext(0, 0)),
 				function: RuntimeCall::Contracts(pallet_contracts::Call::instantiate_with_code::<
 					Runtime,
 				> {
@@ -717,7 +745,7 @@ fn deploying_wasm_contract_should_work() {
 				}),
 			},
 			CheckedExtrinsic {
-				signed: Some((charlie(), signed_extra(1, 0))),
+				format: sp_runtime::generic::ExtrinsicFormat::Signed(charlie(), tx_ext(1, 0)),
 				function: RuntimeCall::Contracts(pallet_contracts::Call::call::<Runtime> {
 					dest: sp_runtime::MultiAddress::Id(addr.clone()),
 					value: 10,
@@ -828,7 +856,8 @@ fn successful_execution_gives_ok() {
 		assert_eq!(Balances::total_balance(&alice()), 111 * DOLLARS);
 	});
 
-	let fees = t.execute_with(|| transfer_fee(&xt()));
+	let weight_refund = Weight::zero();
+	let fees_after_refund = t.execute_with(|| transfer_fee_with_refund(&xt(), weight_refund));
 
 	let r = executor_call(&mut t, "BlockBuilder_apply_extrinsic", &vec![].and(&xt()))
 		.0
@@ -839,7 +868,7 @@ fn successful_execution_gives_ok() {
 		.expect("Extrinsic failed");
 
 	t.execute_with(|| {
-		assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - fees);
+		assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - fees_after_refund);
 		assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS);
 	});
 }
diff --git a/substrate/bin/node/cli/tests/fees.rs b/substrate/bin/node/cli/tests/fees.rs
index b49af4c1055..59ade9b8547 100644
--- a/substrate/bin/node/cli/tests/fees.rs
+++ b/substrate/bin/node/cli/tests/fees.rs
@@ -55,11 +55,11 @@ fn fee_multiplier_increases_and_decreases_on_big_weight() {
 		GENESIS_HASH.into(),
 		vec![
 			CheckedExtrinsic {
-				signed: None,
+				format: sp_runtime::generic::ExtrinsicFormat::Bare,
 				function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: time1 }),
 			},
 			CheckedExtrinsic {
-				signed: Some((charlie(), signed_extra(0, 0))),
+				format: sp_runtime::generic::ExtrinsicFormat::Signed(charlie(), tx_ext(0, 0)),
 				function: RuntimeCall::Sudo(pallet_sudo::Call::sudo {
 					call: Box::new(RuntimeCall::RootTesting(
 						pallet_root_testing::Call::fill_block { ratio: Perbill::from_percent(60) },
@@ -78,11 +78,11 @@ fn fee_multiplier_increases_and_decreases_on_big_weight() {
 		block1.1,
 		vec![
 			CheckedExtrinsic {
-				signed: None,
+				format: sp_runtime::generic::ExtrinsicFormat::Bare,
 				function: RuntimeCall::Timestamp(pallet_timestamp::Call::set { now: time2 }),
 			},
 			CheckedExtrinsic {
-				signed: Some((charlie(), signed_extra(1, 0))),
+				format: sp_runtime::generic::ExtrinsicFormat::Signed(charlie(), tx_ext(1, 0)),
 				function: RuntimeCall::System(frame_system::Call::remark { remark: vec![0; 1] }),
 			},
 		],
@@ -148,7 +148,7 @@ fn transaction_fee_is_correct() {
 
 	let tip = 1_000_000;
 	let xt = sign(CheckedExtrinsic {
-		signed: Some((alice(), signed_extra(0, tip))),
+		format: sp_runtime::generic::ExtrinsicFormat::Signed(alice(), tx_ext(0, tip)),
 		function: RuntimeCall::Balances(default_transfer_call()),
 	});
 
@@ -174,7 +174,9 @@ fn transaction_fee_is_correct() {
 		let length_fee = TransactionByteFee::get() * (xt.clone().encode().len() as Balance);
 		balance_alice -= length_fee;
 
-		let weight = default_transfer_call().get_dispatch_info().weight;
+		let mut info = default_transfer_call().get_dispatch_info();
+		info.extension_weight = xt.extension_weight();
+		let weight = info.total_weight();
 		let weight_fee = IdentityFee::<Balance>::weight_to_fee(&weight);
 
 		// we know that weight to fee multiplier is effect-less in block 1.
diff --git a/substrate/bin/node/cli/tests/submit_transaction.rs b/substrate/bin/node/cli/tests/submit_transaction.rs
index 18826e7e90a..3b7d82dcab1 100644
--- a/substrate/bin/node/cli/tests/submit_transaction.rs
+++ b/substrate/bin/node/cli/tests/submit_transaction.rs
@@ -44,10 +44,9 @@ fn should_submit_unsigned_transaction() {
 		};
 
 		let call = pallet_im_online::Call::heartbeat { heartbeat: heartbeat_data, signature };
-		SubmitTransaction::<Runtime, pallet_im_online::Call<Runtime>>::submit_unsigned_transaction(
-			call.into(),
-		)
-		.unwrap();
+		let xt = UncheckedExtrinsic::new_bare(call.into());
+		SubmitTransaction::<Runtime, pallet_im_online::Call<Runtime>>::submit_transaction(xt)
+			.unwrap();
 
 		assert_eq!(state.read().transactions.len(), 1)
 	});
@@ -131,7 +130,7 @@ fn should_submit_signed_twice_from_the_same_account() {
 		// now check that the transaction nonces are not equal
 		let s = state.read();
 		fn nonce(tx: UncheckedExtrinsic) -> frame_system::CheckNonce<Runtime> {
-			let extra = tx.signature.unwrap().2;
+			let extra = tx.preamble.to_signed().unwrap().2;
 			extra.5
 		}
 		let nonce1 = nonce(UncheckedExtrinsic::decode(&mut &*s.transactions[0]).unwrap());
@@ -180,7 +179,7 @@ fn should_submit_signed_twice_from_all_accounts() {
 		// now check that the transaction nonces are not equal
 		let s = state.read();
 		fn nonce(tx: UncheckedExtrinsic) -> frame_system::CheckNonce<Runtime> {
-			let extra = tx.signature.unwrap().2;
+			let extra = tx.preamble.to_signed().unwrap().2;
 			extra.5
 		}
 		let nonce1 = nonce(UncheckedExtrinsic::decode(&mut &*s.transactions[0]).unwrap());
@@ -237,7 +236,7 @@ fn submitted_transaction_should_be_valid() {
 		let source = TransactionSource::External;
 		let extrinsic = UncheckedExtrinsic::decode(&mut &*tx0).unwrap();
 		// add balance to the account
-		let author = extrinsic.signature.clone().unwrap().0;
+		let author = extrinsic.preamble.clone().to_signed().clone().unwrap().0;
 		let address = Indices::lookup(author).unwrap();
 		let data = pallet_balances::AccountData { free: 5_000_000_000_000, ..Default::default() };
 		let account = frame_system::AccountInfo { providers: 1, data, ..Default::default() };
diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs
index ececf0d87b2..a2112e5977f 100644
--- a/substrate/bin/node/runtime/src/lib.rs
+++ b/substrate/bin/node/runtime/src/lib.rs
@@ -102,8 +102,8 @@ use sp_runtime::{
 		MaybeConvert, NumberFor, OpaqueKeys, SaturatedConversion, StaticLookup,
 	},
 	transaction_validity::{TransactionPriority, TransactionSource, TransactionValidity},
-	ApplyExtrinsicResult, FixedPointNumber, FixedU128, Perbill, Percent, Permill, Perquintill,
-	RuntimeDebug,
+	ApplyExtrinsicResult, FixedPointNumber, FixedU128, MultiSignature, MultiSigner, Perbill,
+	Percent, Permill, Perquintill, RuntimeDebug,
 };
 #[cfg(any(feature = "std", test))]
 use sp_version::NativeVersion;
@@ -574,6 +574,7 @@ impl pallet_transaction_payment::Config for Runtime {
 		MinimumMultiplier,
 		MaximumMultiplier,
 	>;
+	type WeightInfo = pallet_transaction_payment::weights::SubstrateWeight<Runtime>;
 }
 
 impl pallet_asset_conversion_tx_payment::Config for Runtime {
@@ -585,6 +586,9 @@ impl pallet_asset_conversion_tx_payment::Config for Runtime {
 		AssetConversion,
 		ResolveAssetTo<TreasuryAccount, NativeAndAssets>,
 	>;
+	type WeightInfo = pallet_asset_conversion_tx_payment::weights::SubstrateWeight<Runtime>;
+	#[cfg(feature = "runtime-benchmarks")]
+	type BenchmarkHelper = AssetConversionTxHelper;
 }
 
 impl pallet_skip_feeless_payment::Config for Runtime {
@@ -1438,16 +1442,29 @@ parameter_types! {
 	pub const MaxPeerInHeartbeats: u32 = 10_000;
 }
 
+impl<LocalCall> frame_system::offchain::CreateTransaction<LocalCall> for Runtime
+where
+	RuntimeCall: From<LocalCall>,
+{
+	type Extension = TxExtension;
+
+	fn create_transaction(call: RuntimeCall, extension: TxExtension) -> UncheckedExtrinsic {
+		UncheckedExtrinsic::new_transaction(call, extension)
+	}
+}
+
 impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Runtime
 where
 	RuntimeCall: From<LocalCall>,
 {
-	fn create_transaction<C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>>(
+	fn create_signed_transaction<
+		C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>,
+	>(
 		call: RuntimeCall,
 		public: <Signature as traits::Verify>::Signer,
 		account: AccountId,
 		nonce: Nonce,
-	) -> Option<(RuntimeCall, <UncheckedExtrinsic as traits::Extrinsic>::SignaturePayload)> {
+	) -> Option<UncheckedExtrinsic> {
 		let tip = 0;
 		// take the biggest period possible.
 		let period =
@@ -1458,7 +1475,7 @@ where
 			// so the actual block number is `n`.
 			.saturating_sub(1);
 		let era = Era::mortal(period, current_block);
-		let extra = (
+		let tx_ext: TxExtension = (
 			frame_system::CheckNonZeroSender::<Runtime>::new(),
 			frame_system::CheckSpecVersion::<Runtime>::new(),
 			frame_system::CheckTxVersion::<Runtime>::new(),
@@ -1473,15 +1490,26 @@ where
 			),
 			frame_metadata_hash_extension::CheckMetadataHash::new(false),
 		);
-		let raw_payload = SignedPayload::new(call, extra)
+
+		let raw_payload = SignedPayload::new(call, tx_ext)
 			.map_err(|e| {
 				log::warn!("Unable to create signed payload: {:?}", e);
 			})
 			.ok()?;
 		let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?;
 		let address = Indices::unlookup(account);
-		let (call, extra, _) = raw_payload.deconstruct();
-		Some((call, (address, signature, extra)))
+		let (call, tx_ext, _) = raw_payload.deconstruct();
+		let transaction = UncheckedExtrinsic::new_signed(call, address, signature, tx_ext);
+		Some(transaction)
+	}
+}
+
+impl<LocalCall> frame_system::offchain::CreateInherent<LocalCall> for Runtime
+where
+	RuntimeCall: From<LocalCall>,
+{
+	fn create_inherent(call: RuntimeCall) -> UncheckedExtrinsic {
+		UncheckedExtrinsic::new_bare(call)
 	}
 }
 
@@ -1490,12 +1518,12 @@ impl frame_system::offchain::SigningTypes for Runtime {
 	type Signature = Signature;
 }
 
-impl<C> frame_system::offchain::SendTransactionTypes<C> for Runtime
+impl<C> frame_system::offchain::CreateTransactionBase<C> for Runtime
 where
 	RuntimeCall: From<C>,
 {
 	type Extrinsic = UncheckedExtrinsic;
-	type OverarchingCall = RuntimeCall;
+	type RuntimeCall = RuntimeCall;
 }
 
 impl pallet_im_online::Config for Runtime {
@@ -1990,6 +2018,30 @@ impl pallet_transaction_storage::Config for Runtime {
 		ConstU32<{ pallet_transaction_storage::DEFAULT_MAX_TRANSACTION_SIZE }>;
 }
 
+#[cfg(feature = "runtime-benchmarks")]
+pub struct VerifySignatureBenchmarkHelper;
+#[cfg(feature = "runtime-benchmarks")]
+impl pallet_verify_signature::BenchmarkHelper<MultiSignature, AccountId>
+	for VerifySignatureBenchmarkHelper
+{
+	fn create_signature(_entropy: &[u8], msg: &[u8]) -> (MultiSignature, AccountId) {
+		use sp_io::crypto::{sr25519_generate, sr25519_sign};
+		use sp_runtime::traits::IdentifyAccount;
+		let public = sr25519_generate(0.into(), None);
+		let who_account: AccountId = MultiSigner::Sr25519(public).into_account().into();
+		let signature = MultiSignature::Sr25519(sr25519_sign(0.into(), &public, msg).unwrap());
+		(signature, who_account)
+	}
+}
+
+impl pallet_verify_signature::Config for Runtime {
+	type Signature = MultiSignature;
+	type AccountIdentifier = MultiSigner;
+	type WeightInfo = pallet_verify_signature::weights::SubstrateWeight<Runtime>;
+	#[cfg(feature = "runtime-benchmarks")]
+	type BenchmarkHelper = VerifySignatureBenchmarkHelper;
+}
+
 impl pallet_whitelist::Config for Runtime {
 	type RuntimeEvent = RuntimeEvent;
 	type RuntimeCall = RuntimeCall;
@@ -2530,6 +2582,9 @@ mod runtime {
 
 	#[runtime::pallet_index(80)]
 	pub type Revive = pallet_revive::Pallet<Runtime>;
+
+	#[runtime::pallet_index(81)]
+	pub type VerifySignature = pallet_verify_signature::Pallet<Runtime>;
 }
 
 /// The address format for describing accounts.
@@ -2542,12 +2597,12 @@ pub type Block = generic::Block<Header, UncheckedExtrinsic>;
 pub type SignedBlock = generic::SignedBlock<Block>;
 /// BlockId type as expected by this runtime.
 pub type BlockId = generic::BlockId<Block>;
-/// The SignedExtension to the basic transaction logic.
+/// The TransactionExtension to the basic transaction logic.
 ///
 /// When you change this, you **MUST** modify [`sign`] in `bin/node/testing/src/keyring.rs`!
 ///
 /// [`sign`]: <../../testing/src/keyring.rs.html>
-pub type SignedExtra = (
+pub type TxExtension = (
 	frame_system::CheckNonZeroSender<Runtime>,
 	frame_system::CheckSpecVersion<Runtime>,
 	frame_system::CheckTxVersion<Runtime>,
@@ -2564,11 +2619,14 @@ pub type SignedExtra = (
 
 /// Unchecked extrinsic type as expected by this runtime.
 pub type UncheckedExtrinsic =
-	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
+/// Unchecked signature payload type as expected by this runtime.
+pub type UncheckedSignaturePayload =
+	generic::UncheckedSignaturePayload<Address, Signature, TxExtension>;
 /// The payload being signed in transactions.
-pub type SignedPayload = generic::SignedPayload<RuntimeCall, SignedExtra>;
+pub type SignedPayload = generic::SignedPayload<RuntimeCall, TxExtension>;
 /// Extrinsic type that has already been checked.
-pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, RuntimeCall, SignedExtra>;
+pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, RuntimeCall, TxExtension>;
 /// Executive: handles dispatch to the various modules.
 pub type Executive = frame_executive::Executive<
 	Runtime,
@@ -2624,6 +2682,62 @@ mod mmr {
 	pub type Hashing = <Runtime as pallet_mmr::Config>::Hashing;
 }
 
+#[cfg(feature = "runtime-benchmarks")]
+pub struct AssetConversionTxHelper;
+
+#[cfg(feature = "runtime-benchmarks")]
+impl
+	pallet_asset_conversion_tx_payment::BenchmarkHelperTrait<
+		AccountId,
+		NativeOrWithId<u32>,
+		NativeOrWithId<u32>,
+	> for AssetConversionTxHelper
+{
+	fn create_asset_id_parameter(seed: u32) -> (NativeOrWithId<u32>, NativeOrWithId<u32>) {
+		(NativeOrWithId::WithId(seed), NativeOrWithId::WithId(seed))
+	}
+
+	fn setup_balances_and_pool(asset_id: NativeOrWithId<u32>, account: AccountId) {
+		use frame_support::{assert_ok, traits::fungibles::Mutate};
+		let NativeOrWithId::WithId(asset_idx) = asset_id.clone() else { unimplemented!() };
+		assert_ok!(Assets::force_create(
+			RuntimeOrigin::root(),
+			asset_idx.into(),
+			account.clone().into(), /* owner */
+			true,                   /* is_sufficient */
+			1,
+		));
+
+		let lp_provider = account.clone();
+		let _ = Balances::deposit_creating(&lp_provider, ((u64::MAX as u128) * 100).into());
+		assert_ok!(Assets::mint_into(
+			asset_idx.into(),
+			&lp_provider,
+			((u64::MAX as u128) * 100).into()
+		));
+
+		let token_native = alloc::boxed::Box::new(NativeOrWithId::Native);
+		let token_second = alloc::boxed::Box::new(asset_id);
+
+		assert_ok!(AssetConversion::create_pool(
+			RuntimeOrigin::signed(lp_provider.clone()),
+			token_native.clone(),
+			token_second.clone()
+		));
+
+		assert_ok!(AssetConversion::add_liquidity(
+			RuntimeOrigin::signed(lp_provider.clone()),
+			token_native,
+			token_second,
+			u64::MAX.into(), // 1 desired
+			u64::MAX.into(), // 2 desired
+			1,               // 1 min
+			1,               // 2 min
+			lp_provider,
+		));
+	}
+}
+
 #[cfg(feature = "runtime-benchmarks")]
 mod benches {
 	polkadot_sdk::frame_benchmarking::define_benchmarks!(
@@ -2646,6 +2760,8 @@ mod benches {
 		[pallet_example_tasks, TasksExample]
 		[pallet_democracy, Democracy]
 		[pallet_asset_conversion, AssetConversion]
+		[pallet_asset_conversion_tx_payment, AssetConversionTxPayment]
+		[pallet_transaction_payment, TransactionPayment]
 		[pallet_election_provider_multi_phase, ElectionProviderMultiPhase]
 		[pallet_election_provider_support_benchmarking, EPSBench::<Runtime>]
 		[pallet_elections_phragmen, Elections]
@@ -2679,6 +2795,7 @@ mod benches {
 		[pallet_state_trie_migration, StateTrieMigration]
 		[pallet_sudo, Sudo]
 		[frame_system, SystemBench::<Runtime>]
+		[frame_system_extensions, SystemExtensionsBench::<Runtime>]
 		[pallet_timestamp, Timestamp]
 		[pallet_tips, Tips]
 		[pallet_transaction_storage, TransactionStorage]
@@ -2694,6 +2811,7 @@ mod benches {
 		[pallet_safe_mode, SafeMode]
 		[pallet_example_mbm, PalletExampleMbms]
 		[pallet_asset_conversion_ops, AssetConversionMigration]
+		[pallet_verify_signature, VerifySignature]
 	);
 }
 
@@ -3361,6 +3479,7 @@ impl_runtime_apis! {
 			use pallet_offences_benchmarking::Pallet as OffencesBench;
 			use pallet_election_provider_support_benchmarking::Pallet as EPSBench;
 			use frame_system_benchmarking::Pallet as SystemBench;
+			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
 			use baseline::Pallet as BaselineBench;
 			use pallet_nomination_pools_benchmarking::Pallet as NominationPoolsBench;
 
@@ -3385,6 +3504,7 @@ impl_runtime_apis! {
 			use pallet_offences_benchmarking::Pallet as OffencesBench;
 			use pallet_election_provider_support_benchmarking::Pallet as EPSBench;
 			use frame_system_benchmarking::Pallet as SystemBench;
+			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
 			use baseline::Pallet as BaselineBench;
 			use pallet_nomination_pools_benchmarking::Pallet as NominationPoolsBench;
 
diff --git a/substrate/bin/node/testing/src/bench.rs b/substrate/bin/node/testing/src/bench.rs
index fb0504f8fad..cce1627a2ad 100644
--- a/substrate/bin/node/testing/src/bench.rs
+++ b/substrate/bin/node/testing/src/bench.rs
@@ -53,6 +53,7 @@ use sp_core::{
 use sp_crypto_hashing::blake2_256;
 use sp_inherents::InherentData;
 use sp_runtime::{
+	generic::{ExtrinsicFormat, Preamble, EXTRINSIC_FORMAT_VERSION},
 	traits::{Block as BlockT, IdentifyAccount, Verify},
 	OpaqueExtrinsic,
 };
@@ -298,10 +299,10 @@ impl<'a> Iterator for BlockContentIterator<'a> {
 
 		let signed = self.keyring.sign(
 			CheckedExtrinsic {
-				signed: Some((
+				format: ExtrinsicFormat::Signed(
 					sender,
-					signed_extra(0, kitchensink_runtime::ExistentialDeposit::get() + 1),
-				)),
+					tx_ext(0, kitchensink_runtime::ExistentialDeposit::get() + 1),
+				),
 				function: match self.content.block_type {
 					BlockType::RandomTransfersKeepAlive =>
 						RuntimeCall::Balances(BalancesCall::transfer_keep_alive {
@@ -565,11 +566,11 @@ impl BenchKeyring {
 		tx_version: u32,
 		genesis_hash: [u8; 32],
 	) -> UncheckedExtrinsic {
-		match xt.signed {
-			Some((signed, extra)) => {
+		match xt.format {
+			ExtrinsicFormat::Signed(signed, tx_ext) => {
 				let payload = (
 					xt.function,
-					extra.clone(),
+					tx_ext.clone(),
 					spec_version,
 					tx_version,
 					genesis_hash,
@@ -586,11 +587,23 @@ impl BenchKeyring {
 					}
 				});
 				UncheckedExtrinsic {
-					signature: Some((sp_runtime::MultiAddress::Id(signed), signature, extra)),
+					preamble: Preamble::Signed(
+						sp_runtime::MultiAddress::Id(signed),
+						signature,
+						0,
+						tx_ext,
+					),
 					function: payload.0,
 				}
 			},
-			None => UncheckedExtrinsic { signature: None, function: xt.function },
+			ExtrinsicFormat::Bare => UncheckedExtrinsic {
+				preamble: Preamble::Bare(EXTRINSIC_FORMAT_VERSION),
+				function: xt.function,
+			},
+			ExtrinsicFormat::General(tx_ext) => UncheckedExtrinsic {
+				preamble: sp_runtime::generic::Preamble::General(0, tx_ext),
+				function: xt.function,
+			},
 		}
 	}
 
diff --git a/substrate/bin/node/testing/src/keyring.rs b/substrate/bin/node/testing/src/keyring.rs
index 312fba8319b..2334cb3c4df 100644
--- a/substrate/bin/node/testing/src/keyring.rs
+++ b/substrate/bin/node/testing/src/keyring.rs
@@ -19,12 +19,12 @@
 //! Test accounts.
 
 use codec::Encode;
-use kitchensink_runtime::{CheckedExtrinsic, SessionKeys, SignedExtra, UncheckedExtrinsic};
+use kitchensink_runtime::{CheckedExtrinsic, SessionKeys, TxExtension, UncheckedExtrinsic};
 use node_primitives::{AccountId, Balance, Nonce};
 use sp_core::{crypto::get_public_from_string_or_panic, ecdsa, ed25519, sr25519};
 use sp_crypto_hashing::blake2_256;
 use sp_keyring::Sr25519Keyring;
-use sp_runtime::generic::Era;
+use sp_runtime::generic::{Era, ExtrinsicFormat, EXTRINSIC_FORMAT_VERSION};
 
 /// Alice's account id.
 pub fn alice() -> AccountId {
@@ -73,7 +73,7 @@ pub fn session_keys_from_seed(seed: &str) -> SessionKeys {
 }
 
 /// Returns transaction extra.
-pub fn signed_extra(nonce: Nonce, extra_fee: Balance) -> SignedExtra {
+pub fn tx_ext(nonce: Nonce, extra_fee: Balance) -> TxExtension {
 	(
 		frame_system::CheckNonZeroSender::new(),
 		frame_system::CheckSpecVersion::new(),
@@ -97,11 +97,11 @@ pub fn sign(
 	genesis_hash: [u8; 32],
 	metadata_hash: Option<[u8; 32]>,
 ) -> UncheckedExtrinsic {
-	match xt.signed {
-		Some((signed, extra)) => {
+	match xt.format {
+		ExtrinsicFormat::Signed(signed, tx_ext) => {
 			let payload = (
 				xt.function,
-				extra.clone(),
+				tx_ext.clone(),
 				spec_version,
 				tx_version,
 				genesis_hash,
@@ -120,10 +120,22 @@ pub fn sign(
 					})
 					.into();
 			UncheckedExtrinsic {
-				signature: Some((sp_runtime::MultiAddress::Id(signed), signature, extra)),
+				preamble: sp_runtime::generic::Preamble::Signed(
+					sp_runtime::MultiAddress::Id(signed),
+					signature,
+					0,
+					tx_ext,
+				),
 				function: payload.0,
 			}
 		},
-		None => UncheckedExtrinsic { signature: None, function: xt.function },
+		ExtrinsicFormat::Bare => UncheckedExtrinsic {
+			preamble: sp_runtime::generic::Preamble::Bare(EXTRINSIC_FORMAT_VERSION),
+			function: xt.function,
+		},
+		ExtrinsicFormat::General(tx_ext) => UncheckedExtrinsic {
+			preamble: sp_runtime::generic::Preamble::General(0, tx_ext),
+			function: xt.function,
+		},
 	}
 }
diff --git a/substrate/client/api/src/notifications/tests.rs b/substrate/client/api/src/notifications/tests.rs
index fba829b1cf9..9ad7973514b 100644
--- a/substrate/client/api/src/notifications/tests.rs
+++ b/substrate/client/api/src/notifications/tests.rs
@@ -18,7 +18,7 @@
 
 use super::*;
 
-use sp_runtime::testing::{Block as RawBlock, ExtrinsicWrapper, H256 as Hash};
+use sp_runtime::testing::{Block as RawBlock, TestXt, H256 as Hash};
 use std::iter::{empty, Empty};
 
 type TestChangeSet = (
@@ -50,7 +50,7 @@ impl PartialEq for StorageChangeSet {
 	}
 }
 
-type Block = RawBlock<ExtrinsicWrapper<Hash>>;
+type Block = RawBlock<TestXt<substrate_test_runtime::RuntimeCall, ()>>;
 
 #[test]
 fn triggering_change_should_notify_wildcard_listeners() {
diff --git a/substrate/client/db/benches/state_access.rs b/substrate/client/db/benches/state_access.rs
index e47559e710d..7ea8e708018 100644
--- a/substrate/client/db/benches/state_access.rs
+++ b/substrate/client/db/benches/state_access.rs
@@ -22,12 +22,12 @@ use sc_client_api::{Backend as _, BlockImportOperation, NewBlockState, StateBack
 use sc_client_db::{Backend, BlocksPruning, DatabaseSettings, DatabaseSource, PruningMode};
 use sp_core::H256;
 use sp_runtime::{
-	testing::{Block as RawBlock, ExtrinsicWrapper, Header},
+	testing::{Block as RawBlock, Header, MockCallU64, TestXt},
 	StateVersion, Storage,
 };
 use tempfile::TempDir;
 
-pub(crate) type Block = RawBlock<ExtrinsicWrapper<u64>>;
+pub(crate) type Block = RawBlock<TestXt<MockCallU64, ()>>;
 
 fn insert_blocks(db: &Backend<Block>, storage: Vec<(Vec<u8>, Vec<u8>)>) -> H256 {
 	let mut op = db.begin_operation().unwrap();
diff --git a/substrate/client/db/src/lib.rs b/substrate/client/db/src/lib.rs
index 72707c306f5..aaa1398a13b 100644
--- a/substrate/client/db/src/lib.rs
+++ b/substrate/client/db/src/lib.rs
@@ -2567,7 +2567,7 @@ pub(crate) mod tests {
 	use sp_blockchain::{lowest_common_ancestor, tree_route};
 	use sp_core::H256;
 	use sp_runtime::{
-		testing::{Block as RawBlock, ExtrinsicWrapper, Header},
+		testing::{Block as RawBlock, Header, MockCallU64, TestXt},
 		traits::{BlakeTwo256, Hash},
 		ConsensusEngineId, StateVersion,
 	};
@@ -2575,7 +2575,8 @@ pub(crate) mod tests {
 	const CONS0_ENGINE_ID: ConsensusEngineId = *b"CON0";
 	const CONS1_ENGINE_ID: ConsensusEngineId = *b"CON1";
 
-	pub(crate) type Block = RawBlock<ExtrinsicWrapper<u64>>;
+	type UncheckedXt = TestXt<MockCallU64, ()>;
+	pub(crate) type Block = RawBlock<UncheckedXt>;
 
 	pub fn insert_header(
 		backend: &Backend<Block>,
@@ -2594,7 +2595,7 @@ pub(crate) mod tests {
 		parent_hash: H256,
 		_changes: Option<Vec<(Vec<u8>, Vec<u8>)>>,
 		extrinsics_root: H256,
-		body: Vec<ExtrinsicWrapper<u64>>,
+		body: Vec<UncheckedXt>,
 		transaction_index: Option<Vec<IndexOperation>>,
 	) -> Result<H256, sp_blockchain::Error> {
 		use sp_runtime::testing::Digest;
@@ -3680,7 +3681,7 @@ pub(crate) mod tests {
 					prev_hash,
 					None,
 					Default::default(),
-					vec![i.into()],
+					vec![UncheckedXt::new_transaction(i.into(), ())],
 					None,
 				)
 				.unwrap();
@@ -3702,11 +3703,20 @@ pub(crate) mod tests {
 				assert_eq!(None, bc.body(blocks[0]).unwrap());
 				assert_eq!(None, bc.body(blocks[1]).unwrap());
 				assert_eq!(None, bc.body(blocks[2]).unwrap());
-				assert_eq!(Some(vec![3.into()]), bc.body(blocks[3]).unwrap());
-				assert_eq!(Some(vec![4.into()]), bc.body(blocks[4]).unwrap());
+				assert_eq!(
+					Some(vec![UncheckedXt::new_transaction(3.into(), ())]),
+					bc.body(blocks[3]).unwrap()
+				);
+				assert_eq!(
+					Some(vec![UncheckedXt::new_transaction(4.into(), ())]),
+					bc.body(blocks[4]).unwrap()
+				);
 			} else {
 				for i in 0..5 {
-					assert_eq!(Some(vec![(i as u64).into()]), bc.body(blocks[i]).unwrap());
+					assert_eq!(
+						Some(vec![UncheckedXt::new_transaction((i as u64).into(), ())]),
+						bc.body(blocks[i]).unwrap()
+					);
 				}
 			}
 		}
@@ -3730,7 +3740,7 @@ pub(crate) mod tests {
 					prev_hash,
 					None,
 					Default::default(),
-					vec![i.into()],
+					vec![UncheckedXt::new_transaction(i.into(), ())],
 					None,
 				)
 				.unwrap();
@@ -3739,16 +3749,26 @@ pub(crate) mod tests {
 			}
 
 			// insert a fork at block 2
-			let fork_hash_root =
-				insert_block(&backend, 2, blocks[1], None, H256::random(), vec![2.into()], None)
-					.unwrap();
+			let fork_hash_root = insert_block(
+				&backend,
+				2,
+				blocks[1],
+				None,
+				H256::random(),
+				vec![UncheckedXt::new_transaction(2.into(), ())],
+				None,
+			)
+			.unwrap();
 			insert_block(
 				&backend,
 				3,
 				fork_hash_root,
 				None,
 				H256::random(),
-				vec![3.into(), 11.into()],
+				vec![
+					UncheckedXt::new_transaction(3.into(), ()),
+					UncheckedXt::new_transaction(11.into(), ()),
+				],
 				None,
 			)
 			.unwrap();
@@ -3758,7 +3778,10 @@ pub(crate) mod tests {
 			backend.commit_operation(op).unwrap();
 
 			let bc = backend.blockchain();
-			assert_eq!(Some(vec![2.into()]), bc.body(fork_hash_root).unwrap());
+			assert_eq!(
+				Some(vec![UncheckedXt::new_transaction(2.into(), ())]),
+				bc.body(fork_hash_root).unwrap()
+			);
 
 			for i in 1..5 {
 				let mut op = backend.begin_operation().unwrap();
@@ -3772,16 +3795,28 @@ pub(crate) mod tests {
 				assert_eq!(None, bc.body(blocks[1]).unwrap());
 				assert_eq!(None, bc.body(blocks[2]).unwrap());
 
-				assert_eq!(Some(vec![3.into()]), bc.body(blocks[3]).unwrap());
-				assert_eq!(Some(vec![4.into()]), bc.body(blocks[4]).unwrap());
+				assert_eq!(
+					Some(vec![UncheckedXt::new_transaction(3.into(), ())]),
+					bc.body(blocks[3]).unwrap()
+				);
+				assert_eq!(
+					Some(vec![UncheckedXt::new_transaction(4.into(), ())]),
+					bc.body(blocks[4]).unwrap()
+				);
 			} else {
 				for i in 0..5 {
-					assert_eq!(Some(vec![(i as u64).into()]), bc.body(blocks[i]).unwrap());
+					assert_eq!(
+						Some(vec![UncheckedXt::new_transaction((i as u64).into(), ())]),
+						bc.body(blocks[i]).unwrap()
+					);
 				}
 			}
 
 			if matches!(pruning, BlocksPruning::KeepAll) {
-				assert_eq!(Some(vec![2.into()]), bc.body(fork_hash_root).unwrap());
+				assert_eq!(
+					Some(vec![UncheckedXt::new_transaction(2.into(), ())]),
+					bc.body(fork_hash_root).unwrap()
+				);
 			} else {
 				assert_eq!(None, bc.body(fork_hash_root).unwrap());
 			}
@@ -3802,8 +3837,16 @@ pub(crate) mod tests {
 		let backend = Backend::<Block>::new_test_with_tx_storage(BlocksPruning::Some(10), 10);
 
 		let make_block = |index, parent, val: u64| {
-			insert_block(&backend, index, parent, None, H256::random(), vec![val.into()], None)
-				.unwrap()
+			insert_block(
+				&backend,
+				index,
+				parent,
+				None,
+				H256::random(),
+				vec![UncheckedXt::new_transaction(val.into(), ())],
+				None,
+			)
+			.unwrap()
 		};
 
 		let block_0 = make_block(0, Default::default(), 0x00);
@@ -3831,18 +3874,30 @@ pub(crate) mod tests {
 		let bc = backend.blockchain();
 		assert_eq!(None, bc.body(block_1b).unwrap());
 		assert_eq!(None, bc.body(block_2b).unwrap());
-		assert_eq!(Some(vec![0x00.into()]), bc.body(block_0).unwrap());
-		assert_eq!(Some(vec![0x1a.into()]), bc.body(block_1a).unwrap());
-		assert_eq!(Some(vec![0x2a.into()]), bc.body(block_2a).unwrap());
-		assert_eq!(Some(vec![0x3a.into()]), bc.body(block_3a).unwrap());
+		assert_eq!(
+			Some(vec![UncheckedXt::new_transaction(0x00.into(), ())]),
+			bc.body(block_0).unwrap()
+		);
+		assert_eq!(
+			Some(vec![UncheckedXt::new_transaction(0x1a.into(), ())]),
+			bc.body(block_1a).unwrap()
+		);
+		assert_eq!(
+			Some(vec![UncheckedXt::new_transaction(0x2a.into(), ())]),
+			bc.body(block_2a).unwrap()
+		);
+		assert_eq!(
+			Some(vec![UncheckedXt::new_transaction(0x3a.into(), ())]),
+			bc.body(block_3a).unwrap()
+		);
 	}
 
 	#[test]
 	fn indexed_data_block_body() {
 		let backend = Backend::<Block>::new_test_with_tx_storage(BlocksPruning::Some(1), 10);
 
-		let x0 = ExtrinsicWrapper::from(0u64).encode();
-		let x1 = ExtrinsicWrapper::from(1u64).encode();
+		let x0 = UncheckedXt::new_transaction(0.into(), ()).encode();
+		let x1 = UncheckedXt::new_transaction(1.into(), ()).encode();
 		let x0_hash = <HashingFor<Block> as sp_core::Hasher>::hash(&x0[1..]);
 		let x1_hash = <HashingFor<Block> as sp_core::Hasher>::hash(&x1[1..]);
 		let index = vec![
@@ -3863,7 +3918,10 @@ pub(crate) mod tests {
 			Default::default(),
 			None,
 			Default::default(),
-			vec![0u64.into(), 1u64.into()],
+			vec![
+				UncheckedXt::new_transaction(0.into(), ()),
+				UncheckedXt::new_transaction(1.into(), ()),
+			],
 			Some(index),
 		)
 		.unwrap();
@@ -3885,8 +3943,9 @@ pub(crate) mod tests {
 	fn index_invalid_size() {
 		let backend = Backend::<Block>::new_test_with_tx_storage(BlocksPruning::Some(1), 10);
 
-		let x0 = ExtrinsicWrapper::from(0u64).encode();
-		let x1 = ExtrinsicWrapper::from(1u64).encode();
+		let x0 = UncheckedXt::new_transaction(0.into(), ()).encode();
+		let x1 = UncheckedXt::new_transaction(1.into(), ()).encode();
+
 		let x0_hash = <HashingFor<Block> as sp_core::Hasher>::hash(&x0[..]);
 		let x1_hash = <HashingFor<Block> as sp_core::Hasher>::hash(&x1[..]);
 		let index = vec![
@@ -3907,7 +3966,10 @@ pub(crate) mod tests {
 			Default::default(),
 			None,
 			Default::default(),
-			vec![0u64.into(), 1u64.into()],
+			vec![
+				UncheckedXt::new_transaction(0.into(), ()),
+				UncheckedXt::new_transaction(1.into(), ()),
+			],
 			Some(index),
 		)
 		.unwrap();
@@ -3921,7 +3983,7 @@ pub(crate) mod tests {
 		let backend = Backend::<Block>::new_test_with_tx_storage(BlocksPruning::Some(2), 10);
 		let mut blocks = Vec::new();
 		let mut prev_hash = Default::default();
-		let x1 = ExtrinsicWrapper::from(0u64).encode();
+		let x1 = UncheckedXt::new_transaction(0.into(), ()).encode();
 		let x1_hash = <HashingFor<Block> as sp_core::Hasher>::hash(&x1[1..]);
 		for i in 0..10 {
 			let mut index = Vec::new();
@@ -3941,7 +4003,7 @@ pub(crate) mod tests {
 				prev_hash,
 				None,
 				Default::default(),
-				vec![i.into()],
+				vec![UncheckedXt::new_transaction(i.into(), ())],
 				Some(index),
 			)
 			.unwrap();
@@ -3975,7 +4037,7 @@ pub(crate) mod tests {
 				prev_hash,
 				None,
 				Default::default(),
-				vec![i.into()],
+				vec![UncheckedXt::new_transaction(i.into(), ())],
 				None,
 			)
 			.unwrap();
@@ -3990,7 +4052,7 @@ pub(crate) mod tests {
 				blocks[1],
 				None,
 				sp_core::H256::random(),
-				vec![i.into()],
+				vec![UncheckedXt::new_transaction(i.into(), ())],
 				None,
 			)
 			.unwrap();
@@ -4004,7 +4066,7 @@ pub(crate) mod tests {
 			blocks[0],
 			None,
 			sp_core::H256::random(),
-			vec![42.into()],
+			vec![UncheckedXt::new_transaction(42.into(), ())],
 			None,
 		)
 		.unwrap();
@@ -4478,7 +4540,7 @@ pub(crate) mod tests {
 				prev_hash,
 				None,
 				Default::default(),
-				vec![i.into()],
+				vec![UncheckedXt::new_transaction(i.into(), ())],
 				None,
 			)
 			.unwrap();
@@ -4493,7 +4555,10 @@ pub(crate) mod tests {
 
 		// Check that we can properly access values when there is reference count
 		// but no value.
-		assert_eq!(Some(vec![1.into()]), bc.body(blocks[1]).unwrap());
+		assert_eq!(
+			Some(vec![UncheckedXt::new_transaction(1.into(), ())]),
+			bc.body(blocks[1]).unwrap()
+		);
 
 		// Block 1 gets pinned three times
 		backend.pin_block(blocks[1]).unwrap();
@@ -4510,27 +4575,42 @@ pub(crate) mod tests {
 
 		// Block 0, 1, 2, 3 are pinned, so all values should be cached.
 		// Block 4 is inside the pruning window, its value is in db.
-		assert_eq!(Some(vec![0.into()]), bc.body(blocks[0]).unwrap());
+		assert_eq!(
+			Some(vec![UncheckedXt::new_transaction(0.into(), ())]),
+			bc.body(blocks[0]).unwrap()
+		);
 
-		assert_eq!(Some(vec![1.into()]), bc.body(blocks[1]).unwrap());
+		assert_eq!(
+			Some(vec![UncheckedXt::new_transaction(1.into(), ())]),
+			bc.body(blocks[1]).unwrap()
+		);
 		assert_eq!(
 			Some(Justifications::from(build_justification(1))),
 			bc.justifications(blocks[1]).unwrap()
 		);
 
-		assert_eq!(Some(vec![2.into()]), bc.body(blocks[2]).unwrap());
+		assert_eq!(
+			Some(vec![UncheckedXt::new_transaction(2.into(), ())]),
+			bc.body(blocks[2]).unwrap()
+		);
 		assert_eq!(
 			Some(Justifications::from(build_justification(2))),
 			bc.justifications(blocks[2]).unwrap()
 		);
 
-		assert_eq!(Some(vec![3.into()]), bc.body(blocks[3]).unwrap());
+		assert_eq!(
+			Some(vec![UncheckedXt::new_transaction(3.into(), ())]),
+			bc.body(blocks[3]).unwrap()
+		);
 		assert_eq!(
 			Some(Justifications::from(build_justification(3))),
 			bc.justifications(blocks[3]).unwrap()
 		);
 
-		assert_eq!(Some(vec![4.into()]), bc.body(blocks[4]).unwrap());
+		assert_eq!(
+			Some(vec![UncheckedXt::new_transaction(4.into(), ())]),
+			bc.body(blocks[4]).unwrap()
+		);
 		assert_eq!(
 			Some(Justifications::from(build_justification(4))),
 			bc.justifications(blocks[4]).unwrap()
@@ -4561,7 +4641,10 @@ pub(crate) mod tests {
 		assert!(bc.justifications(blocks[1]).unwrap().is_none());
 
 		// Block 4 is inside the pruning window and still kept
-		assert_eq!(Some(vec![4.into()]), bc.body(blocks[4]).unwrap());
+		assert_eq!(
+			Some(vec![UncheckedXt::new_transaction(4.into(), ())]),
+			bc.body(blocks[4]).unwrap()
+		);
 		assert_eq!(
 			Some(Justifications::from(build_justification(4))),
 			bc.justifications(blocks[4]).unwrap()
@@ -4569,9 +4652,16 @@ pub(crate) mod tests {
 
 		// Block tree:
 		//   0 -> 1 -> 2 -> 3 -> 4 -> 5
-		let hash =
-			insert_block(&backend, 5, prev_hash, None, Default::default(), vec![5.into()], None)
-				.unwrap();
+		let hash = insert_block(
+			&backend,
+			5,
+			prev_hash,
+			None,
+			Default::default(),
+			vec![UncheckedXt::new_transaction(5.into(), ())],
+			None,
+		)
+		.unwrap();
 		blocks.push(hash);
 
 		backend.pin_block(blocks[4]).unwrap();
@@ -4586,12 +4676,18 @@ pub(crate) mod tests {
 		assert!(bc.body(blocks[2]).unwrap().is_none());
 		assert!(bc.body(blocks[3]).unwrap().is_none());
 
-		assert_eq!(Some(vec![4.into()]), bc.body(blocks[4]).unwrap());
+		assert_eq!(
+			Some(vec![UncheckedXt::new_transaction(4.into(), ())]),
+			bc.body(blocks[4]).unwrap()
+		);
 		assert_eq!(
 			Some(Justifications::from(build_justification(4))),
 			bc.justifications(blocks[4]).unwrap()
 		);
-		assert_eq!(Some(vec![5.into()]), bc.body(blocks[5]).unwrap());
+		assert_eq!(
+			Some(vec![UncheckedXt::new_transaction(5.into(), ())]),
+			bc.body(blocks[5]).unwrap()
+		);
 		assert!(bc.header(blocks[5]).ok().flatten().is_some());
 
 		backend.unpin_block(blocks[4]);
@@ -4601,9 +4697,16 @@ pub(crate) mod tests {
 		// Append a justification to block 5.
 		backend.append_justification(blocks[5], ([0, 0, 0, 1], vec![42])).unwrap();
 
-		let hash =
-			insert_block(&backend, 6, blocks[5], None, Default::default(), vec![6.into()], None)
-				.unwrap();
+		let hash = insert_block(
+			&backend,
+			6,
+			blocks[5],
+			None,
+			Default::default(),
+			vec![UncheckedXt::new_transaction(6.into(), ())],
+			None,
+		)
+		.unwrap();
 		blocks.push(hash);
 
 		// Pin block 5 so it gets loaded into the cache on prune
@@ -4616,7 +4719,10 @@ pub(crate) mod tests {
 		op.mark_finalized(blocks[6], None).unwrap();
 		backend.commit_operation(op).unwrap();
 
-		assert_eq!(Some(vec![5.into()]), bc.body(blocks[5]).unwrap());
+		assert_eq!(
+			Some(vec![UncheckedXt::new_transaction(5.into(), ())]),
+			bc.body(blocks[5]).unwrap()
+		);
 		assert!(bc.header(blocks[5]).ok().flatten().is_some());
 		let mut expected = Justifications::from(build_justification(5));
 		expected.append(([0, 0, 0, 1], vec![42]));
@@ -4638,7 +4744,7 @@ pub(crate) mod tests {
 				prev_hash,
 				None,
 				Default::default(),
-				vec![i.into()],
+				vec![UncheckedXt::new_transaction(i.into(), ())],
 				None,
 			)
 			.unwrap();
@@ -4654,16 +4760,26 @@ pub(crate) mod tests {
 		// Block tree:
 		//   0 -> 1 -> 2 -> 3 -> 4
 		//        \ -> 2 -> 3
-		let fork_hash_root =
-			insert_block(&backend, 2, blocks[1], None, H256::random(), vec![2.into()], None)
-				.unwrap();
+		let fork_hash_root = insert_block(
+			&backend,
+			2,
+			blocks[1],
+			None,
+			H256::random(),
+			vec![UncheckedXt::new_transaction(2.into(), ())],
+			None,
+		)
+		.unwrap();
 		let fork_hash_3 = insert_block(
 			&backend,
 			3,
 			fork_hash_root,
 			None,
 			H256::random(),
-			vec![3.into(), 11.into()],
+			vec![
+				UncheckedXt::new_transaction(3.into(), ()),
+				UncheckedXt::new_transaction(11.into(), ()),
+			],
 			None,
 		)
 		.unwrap();
@@ -4684,14 +4800,35 @@ pub(crate) mod tests {
 		}
 
 		let bc = backend.blockchain();
-		assert_eq!(Some(vec![0.into()]), bc.body(blocks[0]).unwrap());
-		assert_eq!(Some(vec![1.into()]), bc.body(blocks[1]).unwrap());
-		assert_eq!(Some(vec![2.into()]), bc.body(blocks[2]).unwrap());
-		assert_eq!(Some(vec![3.into()]), bc.body(blocks[3]).unwrap());
-		assert_eq!(Some(vec![4.into()]), bc.body(blocks[4]).unwrap());
+		assert_eq!(
+			Some(vec![UncheckedXt::new_transaction(0.into(), ())]),
+			bc.body(blocks[0]).unwrap()
+		);
+		assert_eq!(
+			Some(vec![UncheckedXt::new_transaction(1.into(), ())]),
+			bc.body(blocks[1]).unwrap()
+		);
+		assert_eq!(
+			Some(vec![UncheckedXt::new_transaction(2.into(), ())]),
+			bc.body(blocks[2]).unwrap()
+		);
+		assert_eq!(
+			Some(vec![UncheckedXt::new_transaction(3.into(), ())]),
+			bc.body(blocks[3]).unwrap()
+		);
+		assert_eq!(
+			Some(vec![UncheckedXt::new_transaction(4.into(), ())]),
+			bc.body(blocks[4]).unwrap()
+		);
 		// Check the fork hashes.
 		assert_eq!(None, bc.body(fork_hash_root).unwrap());
-		assert_eq!(Some(vec![3.into(), 11.into()]), bc.body(fork_hash_3).unwrap());
+		assert_eq!(
+			Some(vec![
+				UncheckedXt::new_transaction(3.into(), ()),
+				UncheckedXt::new_transaction(11.into(), ())
+			]),
+			bc.body(fork_hash_3).unwrap()
+		);
 
 		// Unpin all blocks, except the forked one.
 		for block in &blocks {
diff --git a/substrate/client/db/src/utils.rs b/substrate/client/db/src/utils.rs
index 0b591c967e6..a79f5ab3ac7 100644
--- a/substrate/client/db/src/utils.rs
+++ b/substrate/client/db/src/utils.rs
@@ -613,14 +613,16 @@ impl<'a, 'b> codec::Input for JoinInput<'a, 'b> {
 mod tests {
 	use super::*;
 	use codec::Input;
-	use sp_runtime::testing::{Block as RawBlock, ExtrinsicWrapper};
-	type Block = RawBlock<ExtrinsicWrapper<u32>>;
+	use sp_runtime::testing::{Block as RawBlock, MockCallU64, TestXt};
+
+	pub type UncheckedXt = TestXt<MockCallU64, ()>;
+	type Block = RawBlock<UncheckedXt>;
 
 	#[cfg(feature = "rocksdb")]
 	#[test]
 	fn database_type_subdir_migration() {
 		use std::path::PathBuf;
-		type Block = RawBlock<ExtrinsicWrapper<u64>>;
+		type Block = RawBlock<UncheckedXt>;
 
 		fn check_dir_for_db_type(
 			db_type: DatabaseType,
diff --git a/substrate/client/network-gossip/src/state_machine.rs b/substrate/client/network-gossip/src/state_machine.rs
index ac3f7a1b8c7..7649c8cc637 100644
--- a/substrate/client/network-gossip/src/state_machine.rs
+++ b/substrate/client/network-gossip/src/state_machine.rs
@@ -549,7 +549,7 @@ mod tests {
 	};
 	use sc_network_types::multiaddr::Multiaddr;
 	use sp_runtime::{
-		testing::{Block as RawBlock, ExtrinsicWrapper, H256},
+		testing::{Block as RawBlock, MockCallU64, TestXt, H256},
 		traits::NumberFor,
 	};
 	use std::{
@@ -558,7 +558,7 @@ mod tests {
 		sync::{Arc, Mutex},
 	};
 
-	type Block = RawBlock<ExtrinsicWrapper<u64>>;
+	type Block = RawBlock<TestXt<MockCallU64, ()>>;
 
 	macro_rules! push_msg {
 		($consensus:expr, $topic:expr, $hash: expr, $m:expr) => {
diff --git a/substrate/client/network/sync/src/blocks.rs b/substrate/client/network/sync/src/blocks.rs
index af88c5245dc..eedba18bebe 100644
--- a/substrate/client/network/sync/src/blocks.rs
+++ b/substrate/client/network/sync/src/blocks.rs
@@ -265,9 +265,9 @@ mod test {
 	use sc_network_common::sync::message;
 	use sc_network_types::PeerId;
 	use sp_core::H256;
-	use sp_runtime::testing::{Block as RawBlock, ExtrinsicWrapper};
+	use sp_runtime::testing::{Block as RawBlock, MockCallU64, TestXt};
 
-	type Block = RawBlock<ExtrinsicWrapper<u64>>;
+	type Block = RawBlock<TestXt<MockCallU64, ()>>;
 
 	fn is_empty(bc: &BlockCollection<Block>) -> bool {
 		bc.blocks.is_empty() && bc.peer_requests.is_empty()
diff --git a/substrate/client/transaction-pool/src/fork_aware_txpool/fork_aware_txpool.rs b/substrate/client/transaction-pool/src/fork_aware_txpool/fork_aware_txpool.rs
index 404225167e5..11e30bef7ea 100644
--- a/substrate/client/transaction-pool/src/fork_aware_txpool/fork_aware_txpool.rs
+++ b/substrate/client/transaction-pool/src/fork_aware_txpool/fork_aware_txpool.rs
@@ -53,7 +53,7 @@ use sp_blockchain::{HashAndNumber, TreeRoute};
 use sp_core::traits::SpawnEssentialNamed;
 use sp_runtime::{
 	generic::BlockId,
-	traits::{Block as BlockT, Extrinsic, NumberFor},
+	traits::{Block as BlockT, NumberFor},
 };
 use std::{
 	collections::{HashMap, HashSet},
@@ -1194,8 +1194,7 @@ where
 						None
 					})
 					.unwrap_or_default()
-					.into_iter()
-					.filter(|tx| tx.is_signed().unwrap_or(true));
+					.into_iter();
 
 				let mut resubmitted_to_report = 0;
 
diff --git a/substrate/client/transaction-pool/src/single_state_txpool/single_state_txpool.rs b/substrate/client/transaction-pool/src/single_state_txpool/single_state_txpool.rs
index 6b4feca44bf..0826b95cf07 100644
--- a/substrate/client/transaction-pool/src/single_state_txpool/single_state_txpool.rs
+++ b/substrate/client/transaction-pool/src/single_state_txpool/single_state_txpool.rs
@@ -46,7 +46,7 @@ use sp_blockchain::{HashAndNumber, TreeRoute};
 use sp_core::traits::SpawnEssentialNamed;
 use sp_runtime::{
 	generic::BlockId,
-	traits::{AtLeast32Bit, Block as BlockT, Extrinsic, Header as HeaderT, NumberFor, Zero},
+	traits::{AtLeast32Bit, Block as BlockT, Header as HeaderT, NumberFor, Zero},
 };
 use std::{
 	collections::{HashMap, HashSet},
@@ -675,8 +675,7 @@ where
 						None
 					})
 					.unwrap_or_default()
-					.into_iter()
-					.filter(|tx| tx.is_signed().unwrap_or(true));
+					.into_iter();
 
 				let mut resubmitted_to_report = 0;
 
diff --git a/substrate/frame/Cargo.toml b/substrate/frame/Cargo.toml
index 41ece6c9a27..595fb5a19b0 100644
--- a/substrate/frame/Cargo.toml
+++ b/substrate/frame/Cargo.toml
@@ -67,6 +67,8 @@ pallet-examples = { workspace = true }
 default = ["runtime", "std"]
 experimental = ["frame-support/experimental"]
 runtime = [
+	"frame-executive",
+	"frame-system-rpc-runtime-api",
 	"sp-api",
 	"sp-block-builder",
 	"sp-consensus-aura",
@@ -77,9 +79,6 @@ runtime = [
 	"sp-storage",
 	"sp-transaction-pool",
 	"sp-version",
-
-	"frame-executive",
-	"frame-system-rpc-runtime-api",
 ]
 std = [
 	"codec/std",
diff --git a/substrate/frame/alliance/src/tests.rs b/substrate/frame/alliance/src/tests.rs
index ec31ebf6a47..2397ebfe7db 100644
--- a/substrate/frame/alliance/src/tests.rs
+++ b/substrate/frame/alliance/src/tests.rs
@@ -244,7 +244,7 @@ fn vote_works() {
 fn close_works() {
 	new_test_ext().execute_with(|| {
 		let (proposal, proposal_len, hash) = make_remark_proposal(42);
-		let proposal_weight = proposal.get_dispatch_info().weight;
+		let proposal_weight = proposal.get_dispatch_info().call_weight;
 		assert_ok!(Alliance::propose(
 			RuntimeOrigin::signed(1),
 			3,
@@ -645,8 +645,8 @@ fn remove_unscrupulous_items_works() {
 #[test]
 fn weights_sane() {
 	let info = crate::Call::<Test>::join_alliance {}.get_dispatch_info();
-	assert_eq!(<() as crate::WeightInfo>::join_alliance(), info.weight);
+	assert_eq!(<() as crate::WeightInfo>::join_alliance(), info.call_weight);
 
 	let info = crate::Call::<Test>::nominate_ally { who: 10 }.get_dispatch_info();
-	assert_eq!(<() as crate::WeightInfo>::nominate_ally(), info.weight);
+	assert_eq!(<() as crate::WeightInfo>::nominate_ally(), info.call_weight);
 }
diff --git a/substrate/frame/asset-conversion/src/weights.rs b/substrate/frame/asset-conversion/src/weights.rs
index 9aea19dbf57..f6e025520d7 100644
--- a/substrate/frame/asset-conversion/src/weights.rs
+++ b/substrate/frame/asset-conversion/src/weights.rs
@@ -37,6 +37,7 @@
 // --chain=dev
 // --header=./substrate/HEADER-APACHE2
 // --output=./substrate/frame/asset-conversion/src/weights.rs
+// --header=./substrate/HEADER-APACHE2
 // --template=./substrate/.maintain/frame-weight-template.hbs
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
diff --git a/substrate/frame/assets/src/tests.rs b/substrate/frame/assets/src/tests.rs
index af605c5a3c6..75a6139702c 100644
--- a/substrate/frame/assets/src/tests.rs
+++ b/substrate/frame/assets/src/tests.rs
@@ -1785,10 +1785,10 @@ fn multiple_transfer_alls_work_ok() {
 #[test]
 fn weights_sane() {
 	let info = crate::Call::<Test>::create { id: 10, admin: 4, min_balance: 3 }.get_dispatch_info();
-	assert_eq!(<() as crate::WeightInfo>::create(), info.weight);
+	assert_eq!(<() as crate::WeightInfo>::create(), info.call_weight);
 
 	let info = crate::Call::<Test>::finish_destroy { id: 10 }.get_dispatch_info();
-	assert_eq!(<() as crate::WeightInfo>::finish_destroy(), info.weight);
+	assert_eq!(<() as crate::WeightInfo>::finish_destroy(), info.call_weight);
 }
 
 #[test]
diff --git a/substrate/frame/babe/src/equivocation.rs b/substrate/frame/babe/src/equivocation.rs
index 4be07bdae1f..524ad23e58e 100644
--- a/substrate/frame/babe/src/equivocation.rs
+++ b/substrate/frame/babe/src/equivocation.rs
@@ -100,7 +100,7 @@ impl<Offender: Clone> Offence<Offender> for EquivocationOffence<Offender> {
 ///
 /// This type implements `OffenceReportSystem` such that:
 /// - Equivocation reports are published on-chain as unsigned extrinsic via
-///   `offchain::SendTransactionTypes`.
+///   `offchain::CreateTransactionBase`.
 /// - On-chain validity checks and processing are mostly delegated to the user provided generic
 ///   types implementing `KeyOwnerProofSystem` and `ReportOffence` traits.
 /// - Offence reporter for unsigned transactions is fetched via the the authorship pallet.
@@ -110,7 +110,7 @@ impl<T, R, P, L>
 	OffenceReportSystem<Option<T::AccountId>, (EquivocationProof<HeaderFor<T>>, T::KeyOwnerProof)>
 	for EquivocationReportSystem<T, R, P, L>
 where
-	T: Config + pallet_authorship::Config + frame_system::offchain::SendTransactionTypes<Call<T>>,
+	T: Config + pallet_authorship::Config + frame_system::offchain::CreateInherent<Call<T>>,
 	R: ReportOffence<
 		T::AccountId,
 		P::IdentificationTuple,
@@ -132,7 +132,8 @@ where
 			equivocation_proof: Box::new(equivocation_proof),
 			key_owner_proof,
 		};
-		let res = SubmitTransaction::<T, Call<T>>::submit_unsigned_transaction(call.into());
+		let xt = T::create_inherent(call.into());
+		let res = SubmitTransaction::<T, Call<T>>::submit_transaction(xt);
 		match res {
 			Ok(_) => info!(target: LOG_TARGET, "Submitted equivocation report"),
 			Err(e) => error!(target: LOG_TARGET, "Error submitting equivocation report: {:?}", e),
diff --git a/substrate/frame/babe/src/mock.rs b/substrate/frame/babe/src/mock.rs
index d416e31b25f..c2e24c73a7b 100644
--- a/substrate/frame/babe/src/mock.rs
+++ b/substrate/frame/babe/src/mock.rs
@@ -68,14 +68,23 @@ impl frame_system::Config for Test {
 	type AccountData = pallet_balances::AccountData<u128>;
 }
 
-impl<C> frame_system::offchain::SendTransactionTypes<C> for Test
+impl<C> frame_system::offchain::CreateTransactionBase<C> for Test
 where
 	RuntimeCall: From<C>,
 {
-	type OverarchingCall = RuntimeCall;
+	type RuntimeCall = RuntimeCall;
 	type Extrinsic = TestXt<RuntimeCall, ()>;
 }
 
+impl<C> frame_system::offchain::CreateInherent<C> for Test
+where
+	RuntimeCall: From<C>,
+{
+	fn create_inherent(call: Self::RuntimeCall) -> Self::Extrinsic {
+		TestXt::new_bare(call)
+	}
+}
+
 impl_opaque_keys! {
 	pub struct MockSessionKeys {
 		pub babe_authority: super::Pallet<Test>,
diff --git a/substrate/frame/babe/src/tests.rs b/substrate/frame/babe/src/tests.rs
index b9a214ca105..eca95816023 100644
--- a/substrate/frame/babe/src/tests.rs
+++ b/substrate/frame/babe/src/tests.rs
@@ -906,7 +906,7 @@ fn valid_equivocation_reports_dont_pay_fees() {
 
 		// it should have non-zero weight and the fee has to be paid.
 		// TODO: account for proof size weight
-		assert!(info.weight.ref_time() > 0);
+		assert!(info.call_weight.ref_time() > 0);
 		assert_eq!(info.pays_fee, Pays::Yes);
 
 		// report the equivocation.
diff --git a/substrate/frame/balances/Cargo.toml b/substrate/frame/balances/Cargo.toml
index 44899e5b7d8..f0117555c37 100644
--- a/substrate/frame/balances/Cargo.toml
+++ b/substrate/frame/balances/Cargo.toml
@@ -52,6 +52,7 @@ runtime-benchmarks = [
 	"frame-benchmarking/runtime-benchmarks",
 	"frame-support/runtime-benchmarks",
 	"frame-system/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"sp-runtime/runtime-benchmarks",
 ]
 try-runtime = [
diff --git a/substrate/frame/balances/src/tests/currency_tests.rs b/substrate/frame/balances/src/tests/currency_tests.rs
index a4984b34f6d..7fcc49d50aa 100644
--- a/substrate/frame/balances/src/tests/currency_tests.rs
+++ b/substrate/frame/balances/src/tests/currency_tests.rs
@@ -30,6 +30,7 @@ use frame_support::{
 	StorageNoopGuard,
 };
 use frame_system::Event as SysEvent;
+use sp_runtime::traits::DispatchTransaction;
 
 const ID_1: LockIdentifier = *b"1       ";
 const ID_2: LockIdentifier = *b"2       ";
@@ -258,17 +259,17 @@ fn lock_should_work_reserve() {
 				TokenError::Frozen
 			);
 			assert_noop!(Balances::reserve(&1, 1), Error::<Test>::LiquidityRestrictions,);
-			assert!(<ChargeTransactionPayment<Test> as SignedExtension>::pre_dispatch(
+			assert!(ChargeTransactionPayment::<Test>::validate_and_prepare(
 				ChargeTransactionPayment::from(1),
-				&1,
+				Some(1).into(),
 				CALL,
 				&info_from_weight(Weight::from_parts(1, 0)),
 				1,
 			)
 			.is_err());
-			assert!(<ChargeTransactionPayment<Test> as SignedExtension>::pre_dispatch(
+			assert!(ChargeTransactionPayment::<Test>::validate_and_prepare(
 				ChargeTransactionPayment::from(0),
-				&1,
+				Some(1).into(),
 				CALL,
 				&info_from_weight(Weight::from_parts(1, 0)),
 				1,
@@ -289,17 +290,17 @@ fn lock_should_work_tx_fee() {
 				TokenError::Frozen
 			);
 			assert_noop!(Balances::reserve(&1, 1), Error::<Test>::LiquidityRestrictions,);
-			assert!(<ChargeTransactionPayment<Test> as SignedExtension>::pre_dispatch(
+			assert!(ChargeTransactionPayment::<Test>::validate_and_prepare(
 				ChargeTransactionPayment::from(1),
-				&1,
+				Some(1).into(),
 				CALL,
 				&info_from_weight(Weight::from_parts(1, 0)),
 				1,
 			)
 			.is_err());
-			assert!(<ChargeTransactionPayment<Test> as SignedExtension>::pre_dispatch(
+			assert!(ChargeTransactionPayment::<Test>::validate_and_prepare(
 				ChargeTransactionPayment::from(0),
-				&1,
+				Some(1).into(),
 				CALL,
 				&info_from_weight(Weight::from_parts(1, 0)),
 				1,
diff --git a/substrate/frame/balances/src/tests/mod.rs b/substrate/frame/balances/src/tests/mod.rs
index ba0cdabdabb..bf49ad9f0a1 100644
--- a/substrate/frame/balances/src/tests/mod.rs
+++ b/substrate/frame/balances/src/tests/mod.rs
@@ -37,7 +37,7 @@ use scale_info::TypeInfo;
 use sp_core::hexdisplay::HexDisplay;
 use sp_io;
 use sp_runtime::{
-	traits::{BadOrigin, SignedExtension, Zero},
+	traits::{BadOrigin, Zero},
 	ArithmeticError, BuildStorage, DispatchError, DispatchResult, FixedPointNumber, RuntimeDebug,
 	TokenError,
 };
@@ -104,7 +104,6 @@ impl pallet_transaction_payment::Config for Test {
 	type OperationalFeeMultiplier = ConstU8<5>;
 	type WeightToFee = IdentityFee<u64>;
 	type LengthToFee = IdentityFee<u64>;
-	type FeeMultiplierUpdate = ();
 }
 
 parameter_types! {
@@ -275,7 +274,7 @@ pub fn events() -> Vec<RuntimeEvent> {
 
 /// create a transaction info struct from weight. Handy to avoid building the whole struct.
 pub fn info_from_weight(w: Weight) -> DispatchInfo {
-	DispatchInfo { weight: w, ..Default::default() }
+	DispatchInfo { call_weight: w, ..Default::default() }
 }
 
 /// Check that the total-issuance matches the sum of all accounts' total balances.
@@ -298,10 +297,10 @@ pub fn ensure_ti_valid() {
 #[test]
 fn weights_sane() {
 	let info = crate::Call::<Test>::transfer_allow_death { dest: 10, value: 4 }.get_dispatch_info();
-	assert_eq!(<() as crate::WeightInfo>::transfer_allow_death(), info.weight);
+	assert_eq!(<() as crate::WeightInfo>::transfer_allow_death(), info.call_weight);
 
 	let info = crate::Call::<Test>::force_unreserve { who: 10, amount: 4 }.get_dispatch_info();
-	assert_eq!(<() as crate::WeightInfo>::force_unreserve(), info.weight);
+	assert_eq!(<() as crate::WeightInfo>::force_unreserve(), info.call_weight);
 }
 
 #[test]
diff --git a/substrate/frame/beefy/src/equivocation.rs b/substrate/frame/beefy/src/equivocation.rs
index 15345e6ae19..3a49b9e169c 100644
--- a/substrate/frame/beefy/src/equivocation.rs
+++ b/substrate/frame/beefy/src/equivocation.rs
@@ -118,7 +118,7 @@ where
 ///
 /// This type implements `OffenceReportSystem` such that:
 /// - Equivocation reports are published on-chain as unsigned extrinsic via
-///   `offchain::SendTransactionTypes`.
+///   `offchain::CreateTransactionBase`.
 /// - On-chain validity checks and processing are mostly delegated to the user provided generic
 ///   types implementing `KeyOwnerProofSystem` and `ReportOffence` traits.
 /// - Offence reporter for unsigned transactions is fetched via the authorship pallet.
@@ -262,7 +262,7 @@ impl<T: Config> EquivocationEvidenceFor<T> {
 impl<T, R, P, L> OffenceReportSystem<Option<T::AccountId>, EquivocationEvidenceFor<T>>
 	for EquivocationReportSystem<T, R, P, L>
 where
-	T: Config + pallet_authorship::Config + frame_system::offchain::SendTransactionTypes<Call<T>>,
+	T: Config + pallet_authorship::Config + frame_system::offchain::CreateInherent<Call<T>>,
 	R: ReportOffence<
 		T::AccountId,
 		P::IdentificationTuple,
@@ -278,7 +278,8 @@ where
 		use frame_system::offchain::SubmitTransaction;
 
 		let call: Call<T> = evidence.into();
-		let res = SubmitTransaction::<T, Call<T>>::submit_unsigned_transaction(call.into());
+		let xt = T::create_inherent(call.into());
+		let res = SubmitTransaction::<T, Call<T>>::submit_transaction(xt);
 		match res {
 			Ok(_) => info!(target: LOG_TARGET, "Submitted equivocation report."),
 			Err(e) => error!(target: LOG_TARGET, "Error submitting equivocation report: {:?}", e),
diff --git a/substrate/frame/beefy/src/mock.rs b/substrate/frame/beefy/src/mock.rs
index 5c79d8f7d7d..2b75c410741 100644
--- a/substrate/frame/beefy/src/mock.rs
+++ b/substrate/frame/beefy/src/mock.rs
@@ -75,14 +75,23 @@ impl frame_system::Config for Test {
 	type AccountData = pallet_balances::AccountData<u128>;
 }
 
-impl<C> frame_system::offchain::SendTransactionTypes<C> for Test
+impl<C> frame_system::offchain::CreateTransactionBase<C> for Test
 where
 	RuntimeCall: From<C>,
 {
-	type OverarchingCall = RuntimeCall;
+	type RuntimeCall = RuntimeCall;
 	type Extrinsic = TestXt<RuntimeCall, ()>;
 }
 
+impl<C> frame_system::offchain::CreateInherent<C> for Test
+where
+	RuntimeCall: From<C>,
+{
+	fn create_inherent(call: Self::RuntimeCall) -> Self::Extrinsic {
+		TestXt::new_bare(call)
+	}
+}
+
 #[derive(Clone, Debug, Decode, Encode, PartialEq, TypeInfo)]
 pub struct MockAncestryProofContext {
 	pub is_valid: bool,
diff --git a/substrate/frame/collective/src/lib.rs b/substrate/frame/collective/src/lib.rs
index 79428689caa..8e533a7b290 100644
--- a/substrate/frame/collective/src/lib.rs
+++ b/substrate/frame/collective/src/lib.rs
@@ -629,7 +629,7 @@ pub mod pallet {
 			T::WeightInfo::execute(
 				*length_bound, // B
 				T::MaxMembers::get(), // M
-			).saturating_add(proposal.get_dispatch_info().weight), // P
+			).saturating_add(proposal.get_dispatch_info().call_weight), // P
 			DispatchClass::Operational
 		))]
 		pub fn execute(
@@ -681,7 +681,7 @@ pub mod pallet {
 				T::WeightInfo::propose_execute(
 					*length_bound, // B
 					T::MaxMembers::get(), // M
-				).saturating_add(proposal.get_dispatch_info().weight) // P1
+				).saturating_add(proposal.get_dispatch_info().call_weight) // P1
 			} else {
 				T::WeightInfo::propose_proposed(
 					*length_bound, // B
@@ -915,7 +915,7 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
 	) -> Result<(u32, DispatchResultWithPostInfo), DispatchError> {
 		let proposal_len = proposal.encoded_size();
 		ensure!(proposal_len <= length_bound as usize, Error::<T, I>::WrongProposalLength);
-		let proposal_weight = proposal.get_dispatch_info().weight;
+		let proposal_weight = proposal.get_dispatch_info().call_weight;
 		ensure!(
 			proposal_weight.all_lte(T::MaxProposalWeight::get()),
 			Error::<T, I>::WrongProposalWeight
@@ -942,7 +942,7 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
 	) -> Result<(u32, u32), DispatchError> {
 		let proposal_len = proposal.encoded_size();
 		ensure!(proposal_len <= length_bound as usize, Error::<T, I>::WrongProposalLength);
-		let proposal_weight = proposal.get_dispatch_info().weight;
+		let proposal_weight = proposal.get_dispatch_info().call_weight;
 		ensure!(
 			proposal_weight.all_lte(T::MaxProposalWeight::get()),
 			Error::<T, I>::WrongProposalWeight
@@ -1130,7 +1130,7 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
 			storage::read(&key, &mut [0; 0], 0).ok_or(Error::<T, I>::ProposalMissing)?;
 		ensure!(proposal_len <= length_bound, Error::<T, I>::WrongProposalLength);
 		let proposal = ProposalOf::<T, I>::get(hash).ok_or(Error::<T, I>::ProposalMissing)?;
-		let proposal_weight = proposal.get_dispatch_info().weight;
+		let proposal_weight = proposal.get_dispatch_info().call_weight;
 		ensure!(proposal_weight.all_lte(weight_bound), Error::<T, I>::WrongProposalWeight);
 		Ok((proposal, proposal_len as usize))
 	}
@@ -1157,7 +1157,7 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
 	) -> (Weight, u32) {
 		Self::deposit_event(Event::Approved { proposal_hash });
 
-		let dispatch_weight = proposal.get_dispatch_info().weight;
+		let dispatch_weight = proposal.get_dispatch_info().call_weight;
 		let origin = RawOrigin::Members(yes_votes, seats).into();
 		let result = proposal.dispatch(origin);
 		Self::deposit_event(Event::Executed {
diff --git a/substrate/frame/collective/src/tests.rs b/substrate/frame/collective/src/tests.rs
index 70ce221f10d..c4ed17821ae 100644
--- a/substrate/frame/collective/src/tests.rs
+++ b/substrate/frame/collective/src/tests.rs
@@ -36,7 +36,7 @@ use sp_runtime::{
 };
 
 pub type Block = sp_runtime::generic::Block<Header, UncheckedExtrinsic>;
-pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic<u32, u64, RuntimeCall, ()>;
+pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic<u32, RuntimeCall, u64, ()>;
 
 frame_support::construct_runtime!(
 	pub enum Test
@@ -316,7 +316,7 @@ fn close_works() {
 	ExtBuilder::default().build_and_execute(|| {
 		let proposal = make_proposal(42);
 		let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32);
-		let proposal_weight = proposal.get_dispatch_info().weight;
+		let proposal_weight = proposal.get_dispatch_info().call_weight;
 		let hash = BlakeTwo256::hash_of(&proposal);
 
 		assert_ok!(Collective::propose(
@@ -388,7 +388,7 @@ fn proposal_weight_limit_works_on_approve() {
 			old_count: MaxMembers::get(),
 		});
 		let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32);
-		let proposal_weight = proposal.get_dispatch_info().weight;
+		let proposal_weight = proposal.get_dispatch_info().call_weight;
 		let hash = BlakeTwo256::hash_of(&proposal);
 		// Set 1 as prime voter
 		Prime::<Test, Instance1>::set(Some(1));
@@ -430,7 +430,7 @@ fn proposal_weight_limit_ignored_on_disapprove() {
 			old_count: MaxMembers::get(),
 		});
 		let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32);
-		let proposal_weight = proposal.get_dispatch_info().weight;
+		let proposal_weight = proposal.get_dispatch_info().call_weight;
 		let hash = BlakeTwo256::hash_of(&proposal);
 
 		assert_ok!(Collective::propose(
@@ -456,7 +456,7 @@ fn close_with_prime_works() {
 	ExtBuilder::default().build_and_execute(|| {
 		let proposal = make_proposal(42);
 		let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32);
-		let proposal_weight = proposal.get_dispatch_info().weight;
+		let proposal_weight = proposal.get_dispatch_info().call_weight;
 		let hash = BlakeTwo256::hash_of(&proposal);
 		assert_ok!(Collective::set_members(
 			RuntimeOrigin::root(),
@@ -524,7 +524,7 @@ fn close_with_voting_prime_works() {
 	ExtBuilder::default().build_and_execute(|| {
 		let proposal = make_proposal(42);
 		let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32);
-		let proposal_weight = proposal.get_dispatch_info().weight;
+		let proposal_weight = proposal.get_dispatch_info().call_weight;
 		let hash = BlakeTwo256::hash_of(&proposal);
 		assert_ok!(Collective::set_members(
 			RuntimeOrigin::root(),
@@ -594,7 +594,7 @@ fn close_with_no_prime_but_majority_works() {
 	ExtBuilder::default().build_and_execute(|| {
 		let proposal = make_proposal(42);
 		let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32);
-		let proposal_weight = proposal.get_dispatch_info().weight;
+		let proposal_weight = proposal.get_dispatch_info().call_weight;
 		let hash = BlakeTwo256::hash_of(&proposal);
 		assert_ok!(CollectiveMajority::set_members(
 			RuntimeOrigin::root(),
@@ -874,7 +874,7 @@ fn correct_validate_and_get_proposal() {
 		));
 
 		let hash = BlakeTwo256::hash_of(&proposal);
-		let weight = proposal.get_dispatch_info().weight;
+		let weight = proposal.get_dispatch_info().call_weight;
 		assert_noop!(
 			Collective::validate_and_get_proposal(
 				&BlakeTwo256::hash_of(&vec![3; 4]),
@@ -1073,7 +1073,7 @@ fn motions_all_first_vote_free_works() {
 
 		// Test close() Extrinsics | Check DispatchResultWithPostInfo with Pay Info
 
-		let proposal_weight = proposal.get_dispatch_info().weight;
+		let proposal_weight = proposal.get_dispatch_info().call_weight;
 		let close_rval: DispatchResultWithPostInfo =
 			Collective::close(RuntimeOrigin::signed(2), hash, 0, proposal_weight, proposal_len);
 		assert_eq!(close_rval.unwrap().pays_fee, Pays::No);
@@ -1091,7 +1091,7 @@ fn motions_reproposing_disapproved_works() {
 	ExtBuilder::default().build_and_execute(|| {
 		let proposal = make_proposal(42);
 		let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32);
-		let proposal_weight = proposal.get_dispatch_info().weight;
+		let proposal_weight = proposal.get_dispatch_info().call_weight;
 		let hash: H256 = proposal.blake2_256().into();
 		assert_ok!(Collective::propose(
 			RuntimeOrigin::signed(1),
@@ -1123,7 +1123,7 @@ fn motions_approval_with_enough_votes_and_lower_voting_threshold_works() {
 	ExtBuilder::default().build_and_execute(|| {
 		let proposal = RuntimeCall::Democracy(mock_democracy::Call::external_propose_majority {});
 		let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32);
-		let proposal_weight = proposal.get_dispatch_info().weight;
+		let proposal_weight = proposal.get_dispatch_info().call_weight;
 		let hash: H256 = proposal.blake2_256().into();
 		// The voting threshold is 2, but the required votes for `ExternalMajorityOrigin` is 3.
 		// The proposal will be executed regardless of the voting threshold
@@ -1253,7 +1253,7 @@ fn motions_disapproval_works() {
 	ExtBuilder::default().build_and_execute(|| {
 		let proposal = make_proposal(42);
 		let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32);
-		let proposal_weight = proposal.get_dispatch_info().weight;
+		let proposal_weight = proposal.get_dispatch_info().call_weight;
 		let hash: H256 = proposal.blake2_256().into();
 		assert_ok!(Collective::propose(
 			RuntimeOrigin::signed(1),
@@ -1312,7 +1312,7 @@ fn motions_approval_works() {
 	ExtBuilder::default().build_and_execute(|| {
 		let proposal = make_proposal(42);
 		let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32);
-		let proposal_weight = proposal.get_dispatch_info().weight;
+		let proposal_weight = proposal.get_dispatch_info().call_weight;
 		let hash: H256 = proposal.blake2_256().into();
 		assert_ok!(Collective::propose(
 			RuntimeOrigin::signed(1),
@@ -1373,7 +1373,7 @@ fn motion_with_no_votes_closes_with_disapproval() {
 	ExtBuilder::default().build_and_execute(|| {
 		let proposal = make_proposal(42);
 		let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32);
-		let proposal_weight = proposal.get_dispatch_info().weight;
+		let proposal_weight = proposal.get_dispatch_info().call_weight;
 		let hash: H256 = proposal.blake2_256().into();
 		assert_ok!(Collective::propose(
 			RuntimeOrigin::signed(1),
diff --git a/substrate/frame/contracts/src/wasm/runtime.rs b/substrate/frame/contracts/src/wasm/runtime.rs
index 984e5712ae0..39f846ac431 100644
--- a/substrate/frame/contracts/src/wasm/runtime.rs
+++ b/substrate/frame/contracts/src/wasm/runtime.rs
@@ -522,7 +522,7 @@ impl<'a, E: Ext + 'a> Runtime<'a, E> {
 		run: impl FnOnce(&mut Self) -> DispatchResultWithPostInfo,
 	) -> Result<ReturnErrorCode, TrapReason> {
 		use frame_support::dispatch::extract_actual_weight;
-		let charged = self.charge_gas(runtime_cost(dispatch_info.weight))?;
+		let charged = self.charge_gas(runtime_cost(dispatch_info.call_weight))?;
 		let result = run(self);
 		let actual_weight = extract_actual_weight(&result, &dispatch_info);
 		self.adjust_gas(charged, runtime_cost(actual_weight));
@@ -2347,7 +2347,7 @@ pub mod env {
 		let execute_weight =
 			<<E::T as Config>::Xcm as ExecuteController<_, _>>::WeightInfo::execute();
 		let weight = ctx.ext.gas_meter().gas_left().max(execute_weight);
-		let dispatch_info = DispatchInfo { weight, ..Default::default() };
+		let dispatch_info = DispatchInfo { call_weight: weight, ..Default::default() };
 
 		ctx.call_dispatchable::<XcmExecutionFailed>(
 			dispatch_info,
diff --git a/substrate/frame/election-provider-multi-phase/src/lib.rs b/substrate/frame/election-provider-multi-phase/src/lib.rs
index 072cfe176b6..06cb2963d76 100644
--- a/substrate/frame/election-provider-multi-phase/src/lib.rs
+++ b/substrate/frame/election-provider-multi-phase/src/lib.rs
@@ -245,7 +245,7 @@ use frame_support::{
 	weights::Weight,
 	DefaultNoBound, EqNoBound, PartialEqNoBound,
 };
-use frame_system::{ensure_none, offchain::SendTransactionTypes, pallet_prelude::BlockNumberFor};
+use frame_system::{ensure_none, offchain::CreateInherent, pallet_prelude::BlockNumberFor};
 use scale_info::TypeInfo;
 use sp_arithmetic::{
 	traits::{CheckedAdd, Zero},
@@ -576,7 +576,7 @@ pub mod pallet {
 	use sp_runtime::traits::Convert;
 
 	#[pallet::config]
-	pub trait Config: frame_system::Config + SendTransactionTypes<Call<Self>> {
+	pub trait Config: frame_system::Config + CreateInherent<Call<Self>> {
 		type RuntimeEvent: From<Event<Self>>
 			+ IsType<<Self as frame_system::Config>::RuntimeEvent>
 			+ TryInto<Event<Self>>;
diff --git a/substrate/frame/election-provider-multi-phase/src/mock.rs b/substrate/frame/election-provider-multi-phase/src/mock.rs
index 32a099e1a26..2e5ac252720 100644
--- a/substrate/frame/election-provider-multi-phase/src/mock.rs
+++ b/substrate/frame/election-provider-multi-phase/src/mock.rs
@@ -421,14 +421,23 @@ impl Convert<usize, BalanceOf<Runtime>> for Runtime {
 	}
 }
 
-impl<LocalCall> frame_system::offchain::SendTransactionTypes<LocalCall> for Runtime
+impl<LocalCall> frame_system::offchain::CreateTransactionBase<LocalCall> for Runtime
 where
 	RuntimeCall: From<LocalCall>,
 {
-	type OverarchingCall = RuntimeCall;
+	type RuntimeCall = RuntimeCall;
 	type Extrinsic = Extrinsic;
 }
 
+impl<LocalCall> frame_system::offchain::CreateInherent<LocalCall> for Runtime
+where
+	RuntimeCall: From<LocalCall>,
+{
+	fn create_inherent(call: Self::RuntimeCall) -> Self::Extrinsic {
+		Extrinsic::new_bare(call)
+	}
+}
+
 pub type Extrinsic = sp_runtime::testing::TestXt<RuntimeCall, ()>;
 
 parameter_types! {
diff --git a/substrate/frame/election-provider-multi-phase/src/unsigned.rs b/substrate/frame/election-provider-multi-phase/src/unsigned.rs
index 4c56f02db52..191131ed3ac 100644
--- a/substrate/frame/election-provider-multi-phase/src/unsigned.rs
+++ b/substrate/frame/election-provider-multi-phase/src/unsigned.rs
@@ -31,7 +31,10 @@ use frame_support::{
 	traits::{DefensiveResult, Get},
 	BoundedVec,
 };
-use frame_system::{offchain::SubmitTransaction, pallet_prelude::BlockNumberFor};
+use frame_system::{
+	offchain::{CreateInherent, SubmitTransaction},
+	pallet_prelude::BlockNumberFor,
+};
 use scale_info::TypeInfo;
 use sp_npos_elections::{
 	assignment_ratio_to_staked_normalized, assignment_staked_to_ratio_normalized, ElectionResult,
@@ -179,7 +182,7 @@ fn ocw_solution_exists<T: Config>() -> bool {
 	matches!(StorageValueRef::persistent(OFFCHAIN_CACHED_CALL).get::<Call<T>>(), Ok(Some(_)))
 }
 
-impl<T: Config> Pallet<T> {
+impl<T: Config + CreateInherent<Call<T>>> Pallet<T> {
 	/// Mine a new npos solution.
 	///
 	/// The Npos Solver type, `S`, must have the same AccountId and Error type as the
@@ -277,7 +280,8 @@ impl<T: Config> Pallet<T> {
 	fn submit_call(call: Call<T>) -> Result<(), MinerError> {
 		log!(debug, "miner submitting a solution as an unsigned transaction");
 
-		SubmitTransaction::<T, Call<T>>::submit_unsigned_transaction(call.into())
+		let xt = T::create_inherent(call.into());
+		SubmitTransaction::<T, Call<T>>::submit_transaction(xt)
 			.map_err(|_| MinerError::PoolSubmissionFailed)
 	}
 
@@ -1818,7 +1822,7 @@ mod tests {
 
 			let encoded = pool.read().transactions[0].clone();
 			let extrinsic: Extrinsic = codec::Decode::decode(&mut &*encoded).unwrap();
-			let call = extrinsic.call;
+			let call = extrinsic.function;
 			assert!(matches!(call, RuntimeCall::MultiPhase(Call::submit_unsigned { .. })));
 		})
 	}
@@ -1835,7 +1839,7 @@ mod tests {
 
 			let encoded = pool.read().transactions[0].clone();
 			let extrinsic = Extrinsic::decode(&mut &*encoded).unwrap();
-			let call = match extrinsic.call {
+			let call = match extrinsic.function {
 				RuntimeCall::MultiPhase(call @ Call::submit_unsigned { .. }) => call,
 				_ => panic!("bad call: unexpected submission"),
 			};
diff --git a/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs b/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs
index f20e3983b09..360f14913fc 100644
--- a/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs
+++ b/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs
@@ -61,7 +61,7 @@ pub const INIT_TIMESTAMP: BlockNumber = 30_000;
 pub const BLOCK_TIME: BlockNumber = 1000;
 
 type Block = frame_system::mocking::MockBlockU32<Runtime>;
-type Extrinsic = testing::TestXt<RuntimeCall, ()>;
+type Extrinsic = sp_runtime::testing::TestXt<RuntimeCall, ()>;
 
 frame_support::construct_runtime!(
 	pub enum Runtime {
@@ -308,14 +308,23 @@ impl pallet_staking::Config for Runtime {
 	type BenchmarkingConfig = pallet_staking::TestBenchmarkingConfig;
 }
 
-impl<LocalCall> frame_system::offchain::SendTransactionTypes<LocalCall> for Runtime
+impl<LocalCall> frame_system::offchain::CreateTransactionBase<LocalCall> for Runtime
 where
 	RuntimeCall: From<LocalCall>,
 {
-	type OverarchingCall = RuntimeCall;
+	type RuntimeCall = RuntimeCall;
 	type Extrinsic = Extrinsic;
 }
 
+impl<LocalCall> frame_system::offchain::CreateInherent<LocalCall> for Runtime
+where
+	RuntimeCall: From<LocalCall>,
+{
+	fn create_inherent(call: Self::RuntimeCall) -> Self::Extrinsic {
+		Extrinsic::new_bare(call)
+	}
+}
+
 pub struct OnChainSeqPhragmen;
 
 parameter_types! {
@@ -687,7 +696,7 @@ pub fn roll_to_with_ocw(n: BlockNumber, pool: Arc<RwLock<PoolState>>, delay_solu
 			for encoded in &pool.read().transactions {
 				let extrinsic = Extrinsic::decode(&mut &encoded[..]).unwrap();
 
-				let _ = match extrinsic.call {
+				let _ = match extrinsic.function {
 					RuntimeCall::ElectionProviderMultiPhase(
 						call @ Call::submit_unsigned { .. },
 					) => {
diff --git a/substrate/frame/elections-phragmen/src/lib.rs b/substrate/frame/elections-phragmen/src/lib.rs
index a1c5f69e1b6..effbb6e786c 100644
--- a/substrate/frame/elections-phragmen/src/lib.rs
+++ b/substrate/frame/elections-phragmen/src/lib.rs
@@ -1408,7 +1408,7 @@ mod tests {
 
 	pub type Block = sp_runtime::generic::Block<Header, UncheckedExtrinsic>;
 	pub type UncheckedExtrinsic =
-		sp_runtime::generic::UncheckedExtrinsic<u32, u64, RuntimeCall, ()>;
+		sp_runtime::generic::UncheckedExtrinsic<u32, RuntimeCall, u64, ()>;
 
 	frame_support::construct_runtime!(
 		pub enum Test
diff --git a/substrate/frame/examples/Cargo.toml b/substrate/frame/examples/Cargo.toml
index ee0f8df29cf..0c6ad5ef097 100644
--- a/substrate/frame/examples/Cargo.toml
+++ b/substrate/frame/examples/Cargo.toml
@@ -25,12 +25,14 @@ pallet-example-offchain-worker = { workspace = true }
 pallet-example-split = { workspace = true }
 pallet-example-single-block-migrations = { workspace = true }
 pallet-example-tasks = { workspace = true }
+pallet-example-authorization-tx-extension = { workspace = true }
 
 [features]
 default = ["std"]
 std = [
 	"pallet-default-config-example/std",
 	"pallet-dev-mode/std",
+	"pallet-example-authorization-tx-extension/std",
 	"pallet-example-basic/std",
 	"pallet-example-frame-crate/std",
 	"pallet-example-kitchensink/std",
@@ -42,6 +44,7 @@ std = [
 try-runtime = [
 	"pallet-default-config-example/try-runtime",
 	"pallet-dev-mode/try-runtime",
+	"pallet-example-authorization-tx-extension/try-runtime",
 	"pallet-example-basic/try-runtime",
 	"pallet-example-kitchensink/try-runtime",
 	"pallet-example-offchain-worker/try-runtime",
diff --git a/substrate/frame/examples/authorization-tx-extension/Cargo.toml b/substrate/frame/examples/authorization-tx-extension/Cargo.toml
new file mode 100644
index 00000000000..9b51fc6c1e6
--- /dev/null
+++ b/substrate/frame/examples/authorization-tx-extension/Cargo.toml
@@ -0,0 +1,62 @@
+[package]
+name = "pallet-example-authorization-tx-extension"
+version = "1.0.0"
+authors.workspace = true
+edition.workspace = true
+license = "MIT-0"
+homepage.workspace = true
+repository.workspace = true
+description = "FRAME example authorization transaction extension pallet"
+publish = false
+
+[lints]
+workspace = true
+
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[dependencies]
+codec = { workspace = true }
+docify = { workspace = true }
+log = { workspace = true }
+scale-info = { features = ["derive"], workspace = true }
+
+frame-benchmarking = { optional = true, workspace = true }
+frame-support = { features = ["experimental"], workspace = true }
+frame-system = { workspace = true }
+
+sp-io = { workspace = true }
+sp-runtime = { workspace = true }
+
+[dev-dependencies]
+pallet-verify-signature = { workspace = true }
+sp-core = { workspace = true }
+sp-keyring = { workspace = true, default-features = true }
+
+[features]
+default = ["std"]
+std = [
+	"codec/std",
+	"frame-benchmarking?/std",
+	"frame-support/std",
+	"frame-system/std",
+	"log/std",
+	"pallet-verify-signature/std",
+	"scale-info/std",
+	"sp-core/std",
+	"sp-io/std",
+	"sp-runtime/std",
+]
+runtime-benchmarks = [
+	"frame-benchmarking/runtime-benchmarks",
+	"frame-support/runtime-benchmarks",
+	"frame-system/runtime-benchmarks",
+	"pallet-verify-signature/runtime-benchmarks",
+	"sp-runtime/runtime-benchmarks",
+]
+try-runtime = [
+	"frame-support/try-runtime",
+	"frame-system/try-runtime",
+	"pallet-verify-signature/try-runtime",
+	"sp-runtime/try-runtime",
+]
diff --git a/substrate/frame/examples/authorization-tx-extension/src/extensions.rs b/substrate/frame/examples/authorization-tx-extension/src/extensions.rs
new file mode 100644
index 00000000000..d1e56916d3a
--- /dev/null
+++ b/substrate/frame/examples/authorization-tx-extension/src/extensions.rs
@@ -0,0 +1,132 @@
+// This file is part of Substrate.
+
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use core::{fmt, marker::PhantomData};
+
+use codec::{Decode, Encode};
+use frame_support::{traits::OriginTrait, Parameter};
+use scale_info::TypeInfo;
+use sp_runtime::{
+	impl_tx_ext_default,
+	traits::{
+		DispatchInfoOf, DispatchOriginOf, IdentifyAccount, TransactionExtension, ValidateResult,
+		Verify,
+	},
+	transaction_validity::{InvalidTransaction, ValidTransaction},
+};
+
+use crate::pallet_coownership::{Config, Origin};
+
+/// Helper struct to organize the data needed for signature verification of both parties involved.
+#[derive(Clone, Eq, PartialEq, Encode, Decode, TypeInfo)]
+pub struct AuthCredentials<Signer, Signature> {
+	first: (Signer, Signature),
+	second: (Signer, Signature),
+}
+
+/// Extension that, if activated by providing a pair of signers and signatures, will authorize a
+/// coowner origin of the two signers. Both signers have to construct their signatures on all of the
+/// data that follows this extension in the `TransactionExtension` pipeline, their implications and
+/// the call. Essentially re-sign the transaction from this point onwards in the pipeline by using
+/// the `inherited_implication`, as shown below.
+#[derive(Clone, Eq, PartialEq, Encode, Decode, TypeInfo)]
+#[scale_info(skip_type_params(T))]
+pub struct AuthorizeCoownership<T, Signer, Signature> {
+	inner: Option<AuthCredentials<Signer, Signature>>,
+	_phantom: PhantomData<T>,
+}
+
+impl<T: Config, Signer, Signature> Default for AuthorizeCoownership<T, Signer, Signature> {
+	fn default() -> Self {
+		Self { inner: None, _phantom: Default::default() }
+	}
+}
+
+impl<T: Config, Signer, Signature> AuthorizeCoownership<T, Signer, Signature> {
+	/// Creates an active extension that will try to authorize the coownership origin.
+	pub fn new(first: (Signer, Signature), second: (Signer, Signature)) -> Self {
+		Self { inner: Some(AuthCredentials { first, second }), _phantom: Default::default() }
+	}
+}
+
+impl<T: Config, Signer, Signature> fmt::Debug for AuthorizeCoownership<T, Signer, Signature> {
+	#[cfg(feature = "std")]
+	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+		write!(f, "AuthorizeCoownership")
+	}
+
+	#[cfg(not(feature = "std"))]
+	fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
+		Ok(())
+	}
+}
+
+impl<T: Config + Send + Sync, Signer, Signature> TransactionExtension<T::RuntimeCall>
+	for AuthorizeCoownership<T, Signer, Signature>
+where
+	Signer: IdentifyAccount<AccountId = T::AccountId> + Parameter + Send + Sync + 'static,
+	Signature: Verify<Signer = Signer> + Parameter + Send + Sync + 'static,
+{
+	const IDENTIFIER: &'static str = "AuthorizeCoownership";
+	type Implicit = ();
+	type Val = ();
+	type Pre = ();
+
+	fn validate(
+		&self,
+		mut origin: DispatchOriginOf<T::RuntimeCall>,
+		_call: &T::RuntimeCall,
+		_info: &DispatchInfoOf<T::RuntimeCall>,
+		_len: usize,
+		_self_implicit: Self::Implicit,
+		inherited_implication: &impl codec::Encode,
+	) -> ValidateResult<Self::Val, T::RuntimeCall> {
+		// If the extension is inactive, just move on in the pipeline.
+		let Some(auth) = &self.inner else {
+			return Ok((ValidTransaction::default(), (), origin));
+		};
+		let first_account = auth.first.0.clone().into_account();
+		let second_account = auth.second.0.clone().into_account();
+
+		// Construct the payload to sign using the `inherited_implication`.
+		let msg = inherited_implication.using_encoded(sp_io::hashing::blake2_256);
+
+		// Both parties' signatures must be correct for the origin to be authorized.
+		// In a prod environment, we're just return a `InvalidTransaction::BadProof` if the
+		// signature isn't valid, but we return these custom errors to be able to assert them in
+		// tests.
+		if !auth.first.1.verify(&msg[..], &first_account) {
+			Err(InvalidTransaction::Custom(100))?
+		}
+		if !auth.second.1.verify(&msg[..], &second_account) {
+			Err(InvalidTransaction::Custom(200))?
+		}
+		// Construct a `pallet_coownership::Origin`.
+		let local_origin = Origin::Coowners(first_account, second_account);
+		// Turn it into a local `PalletsOrigin`.
+		let local_origin = <T as Config>::PalletsOrigin::from(local_origin);
+		// Then finally into a pallet `RuntimeOrigin`.
+		let local_origin = <T as Config>::RuntimeOrigin::from(local_origin);
+		// Which the `set_caller_from` function will convert into the overarching `RuntimeOrigin`
+		// created by `construct_runtime!`.
+		origin.set_caller_from(local_origin);
+		// Make sure to return the new origin.
+		Ok((ValidTransaction::default(), (), origin))
+	}
+	// We're not doing any special logic in `TransactionExtension::prepare`, so just impl a default.
+	impl_tx_ext_default!(T::RuntimeCall; weight prepare);
+}
diff --git a/substrate/frame/examples/authorization-tx-extension/src/lib.rs b/substrate/frame/examples/authorization-tx-extension/src/lib.rs
new file mode 100644
index 00000000000..9105155a94d
--- /dev/null
+++ b/substrate/frame/examples/authorization-tx-extension/src/lib.rs
@@ -0,0 +1,158 @@
+// This file is part of Substrate.
+
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! # Authorization Transaction Extension Example Pallet
+//!
+//! **This pallet serves as an example and is not meant to be used in production.**
+//!
+//! FRAME Transaction Extension reference implementation, origin mutation, origin authorization and
+//! integration in a `TransactionExtension` pipeline.
+//!
+//! The [TransactionExtension](sp_runtime::traits::TransactionExtension) used in this example is
+//! [AuthorizeCoownership](extensions::AuthorizeCoownership). If activated, the extension will
+//! authorize 2 signers as coowners, with a [coowner origin](pallet_coownership::Origin) specific to
+//! the [coownership example pallet](pallet_coownership), by validating a signature of the rest of
+//! the transaction from each party. This means any extensions after ours in the pipeline, their
+//! implicits and the actual call. The extension pipeline used in our example checks the genesis
+//! hash, transaction version and mortality of the transaction after the `AuthorizeCoownership` runs
+//! as we want these transactions to run regardless of what origin passes through them and/or we
+//! want their implicit data in any signature authorization happening earlier in the pipeline.
+//!
+//! In this example, aside from the [AuthorizeCoownership](extensions::AuthorizeCoownership)
+//! extension, we use the following pallets:
+//! - [pallet_coownership] - provides a coowner origin and the functionality to authorize it.
+//! - [pallet_assets] - a dummy asset pallet that tracks assets, identified by an
+//!   [AssetId](pallet_assets::AssetId), and their respective owners, which can be either an
+//!   [account](pallet_assets::Owner::Single) or a [pair of owners](pallet_assets::Owner::Double).
+//!
+//! Assets are created in [pallet_assets] using the
+//! [create_asset](pallet_assets::Call::create_asset) call, which accepts traditionally signed
+//! origins (a single account) or coowner origins, authorized through the
+//! [CoownerOrigin](pallet_assets::Config::CoownerOrigin) type.
+//!
+//! ### Example runtime setup
+#![doc = docify::embed!("src/mock.rs", example_runtime)]
+//!
+//! ### Example usage
+#![doc = docify::embed!("src/tests.rs", create_coowned_asset_works)]
+//!
+//! This example does not focus on any pallet logic or syntax, but rather on `TransactionExtension`
+//! functionality. The pallets used are just skeletons to provide storage state and custom origin
+//! choices and requirements, as shown in the examples. Any weight and/or
+//! transaction fee is out of scope for this example.
+
+#![cfg_attr(not(feature = "std"), no_std)]
+
+pub mod extensions;
+
+#[cfg(test)]
+mod mock;
+#[cfg(test)]
+mod tests;
+
+extern crate alloc;
+
+use frame_support::pallet_prelude::*;
+use frame_system::pallet_prelude::*;
+
+#[frame_support::pallet(dev_mode)]
+pub mod pallet_coownership {
+	use super::*;
+	use frame_support::traits::OriginTrait;
+
+	#[pallet::config]
+	pub trait Config: frame_system::Config {
+		/// The aggregated origin which the dispatch will take.
+		type RuntimeOrigin: OriginTrait<PalletsOrigin = Self::PalletsOrigin>
+			+ From<Self::PalletsOrigin>
+			+ IsType<<Self as frame_system::Config>::RuntimeOrigin>;
+
+		/// The caller origin, overarching type of all pallets origins.
+		type PalletsOrigin: From<Origin<Self>> + TryInto<Origin<Self>, Error = Self::PalletsOrigin>;
+	}
+
+	#[pallet::pallet]
+	pub struct Pallet<T>(_);
+
+	/// Origin that this pallet can authorize. For the purposes of this example, it's just two
+	/// accounts that own something together.
+	#[pallet::origin]
+	#[derive(Clone, PartialEq, Eq, RuntimeDebug, Encode, Decode, MaxEncodedLen, TypeInfo)]
+	pub enum Origin<T: Config> {
+		Coowners(T::AccountId, T::AccountId),
+	}
+}
+
+#[frame_support::pallet(dev_mode)]
+pub mod pallet_assets {
+	use super::*;
+
+	pub type AssetId = u32;
+
+	/// Type that describes possible owners of a particular asset.
+	#[derive(Clone, PartialEq, Eq, RuntimeDebug, Encode, Decode, MaxEncodedLen, TypeInfo)]
+	pub enum Owner<AccountId> {
+		Single(AccountId),
+		Double(AccountId, AccountId),
+	}
+
+	#[pallet::config]
+	pub trait Config: frame_system::Config {
+		/// Type that can authorize an account pair coowner origin.
+		type CoownerOrigin: EnsureOrigin<
+			Self::RuntimeOrigin,
+			Success = (Self::AccountId, Self::AccountId),
+		>;
+	}
+
+	/// Map that holds the owner information for each asset it manages.
+	#[pallet::storage]
+	pub type AssetOwners<T> =
+		StorageMap<_, Blake2_128Concat, AssetId, Owner<<T as frame_system::Config>::AccountId>>;
+
+	#[pallet::pallet]
+	pub struct Pallet<T>(_);
+
+	#[pallet::error]
+	pub enum Error<T> {
+		/// Asset already exists.
+		AlreadyExists,
+	}
+
+	#[pallet::call]
+	impl<T: Config> Pallet<T> {
+		/// Simple call that just creates an asset with a specific `AssetId`. This call will fail if
+		/// there is already an asset with the same `AssetId`.
+		///
+		/// The origin is either a single account (traditionally signed origin) or a coowner origin.
+		#[pallet::call_index(0)]
+		pub fn create_asset(origin: OriginFor<T>, asset_id: AssetId) -> DispatchResult {
+			let owner: Owner<T::AccountId> = match T::CoownerOrigin::try_origin(origin) {
+				Ok((first, second)) => Owner::Double(first, second),
+				Err(origin) => ensure_signed(origin).map(|account| Owner::Single(account))?,
+			};
+			AssetOwners::<T>::try_mutate(asset_id, |maybe_owner| {
+				if maybe_owner.is_some() {
+					return Err(Error::<T>::AlreadyExists);
+				}
+				*maybe_owner = Some(owner);
+				Ok(())
+			})?;
+			Ok(())
+		}
+	}
+}
diff --git a/substrate/frame/examples/authorization-tx-extension/src/mock.rs b/substrate/frame/examples/authorization-tx-extension/src/mock.rs
new file mode 100644
index 00000000000..aa70d12d7d8
--- /dev/null
+++ b/substrate/frame/examples/authorization-tx-extension/src/mock.rs
@@ -0,0 +1,142 @@
+// This file is part of Substrate.
+
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use crate::*;
+pub(crate) use example_runtime::*;
+use extensions::AuthorizeCoownership;
+use frame_support::derive_impl;
+use frame_system::{CheckEra, CheckGenesis, CheckNonce, CheckTxVersion};
+use pallet_verify_signature::VerifySignature;
+use sp_runtime::{
+	generic,
+	traits::{BlakeTwo256, IdentifyAccount, IdentityLookup, Verify},
+	BuildStorage, MultiSignature, MultiSigner,
+};
+
+#[docify::export]
+mod example_runtime {
+	use super::*;
+
+	/// Our `TransactionExtension` fit for general transactions.
+	pub type TxExtension = (
+		// Validate the signature of regular account transactions (substitutes the old signed
+		// transaction).
+		VerifySignature<Runtime>,
+		// Nonce check (and increment) for the caller.
+		CheckNonce<Runtime>,
+		// If activated, will mutate the origin to a `pallet_coownership` origin of 2 accounts that
+		// own something.
+		AuthorizeCoownership<Runtime, MultiSigner, MultiSignature>,
+		// Some other extensions that we want to run for every possible origin and we want captured
+		// in any and all signature and authorization schemes (such as the traditional account
+		// signature or the double signature in `pallet_coownership`).
+		CheckGenesis<Runtime>,
+		CheckTxVersion<Runtime>,
+		CheckEra<Runtime>,
+	);
+	/// Convenience type to more easily construct the signature to be signed in case
+	/// `AuthorizeCoownership` is activated.
+	pub type InnerTxExtension = (CheckGenesis<Runtime>, CheckTxVersion<Runtime>, CheckEra<Runtime>);
+	pub type UncheckedExtrinsic =
+		generic::UncheckedExtrinsic<AccountId, RuntimeCall, Signature, TxExtension>;
+	pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
+	pub type Block = generic::Block<Header, UncheckedExtrinsic>;
+	pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;
+	pub type Signature = MultiSignature;
+	pub type BlockNumber = u32;
+
+	// For testing the pallet, we construct a mock runtime.
+	frame_support::construct_runtime!(
+		pub enum Runtime
+		{
+			System: frame_system,
+			VerifySignaturePallet: pallet_verify_signature,
+
+			Assets: pallet_assets,
+			Coownership: pallet_coownership,
+		}
+	);
+
+	#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
+	impl frame_system::Config for Runtime {
+		type AccountId = AccountId;
+		type Block = Block;
+		type Lookup = IdentityLookup<Self::AccountId>;
+	}
+
+	#[cfg(feature = "runtime-benchmarks")]
+	pub struct BenchmarkHelper;
+	#[cfg(feature = "runtime-benchmarks")]
+	impl pallet_verify_signature::BenchmarkHelper<MultiSignature, AccountId> for BenchmarkHelper {
+		fn create_signature(_entropy: &[u8], msg: &[u8]) -> (MultiSignature, AccountId) {
+			use sp_io::crypto::{sr25519_generate, sr25519_sign};
+			use sp_runtime::traits::IdentifyAccount;
+			let public = sr25519_generate(0.into(), None);
+			let who_account: AccountId = MultiSigner::Sr25519(public).into_account().into();
+			let signature = MultiSignature::Sr25519(sr25519_sign(0.into(), &public, msg).unwrap());
+			(signature, who_account)
+		}
+	}
+
+	impl pallet_verify_signature::Config for Runtime {
+		type Signature = MultiSignature;
+		type AccountIdentifier = MultiSigner;
+		type WeightInfo = ();
+		#[cfg(feature = "runtime-benchmarks")]
+		type BenchmarkHelper = BenchmarkHelper;
+	}
+
+	/// Type that enables any pallet to ask for a coowner origin.
+	pub struct EnsureCoowner;
+	impl EnsureOrigin<RuntimeOrigin> for EnsureCoowner {
+		type Success = (AccountId, AccountId);
+
+		fn try_origin(o: RuntimeOrigin) -> Result<Self::Success, RuntimeOrigin> {
+			match o.clone().into() {
+				Ok(pallet_coownership::Origin::<Runtime>::Coowners(first, second)) =>
+					Ok((first, second)),
+				_ => Err(o),
+			}
+		}
+
+		#[cfg(feature = "runtime-benchmarks")]
+		fn try_successful_origin() -> Result<RuntimeOrigin, ()> {
+			unimplemented!()
+		}
+	}
+
+	impl pallet_assets::Config for Runtime {
+		type CoownerOrigin = EnsureCoowner;
+	}
+
+	impl pallet_coownership::Config for Runtime {
+		type RuntimeOrigin = RuntimeOrigin;
+		type PalletsOrigin = OriginCaller;
+	}
+}
+
+// This function basically just builds a genesis storage key/value store according to
+// our desired mockup.
+pub fn new_test_ext() -> sp_io::TestExternalities {
+	let t = RuntimeGenesisConfig {
+		// We use default for brevity, but you can configure as desired if needed.
+		system: Default::default(),
+	}
+	.build_storage()
+	.unwrap();
+	t.into()
+}
diff --git a/substrate/frame/examples/authorization-tx-extension/src/tests.rs b/substrate/frame/examples/authorization-tx-extension/src/tests.rs
new file mode 100644
index 00000000000..7ede549a2f1
--- /dev/null
+++ b/substrate/frame/examples/authorization-tx-extension/src/tests.rs
@@ -0,0 +1,269 @@
+// This file is part of Substrate.
+
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Tests for pallet-example-authorization-tx-extension.
+
+use codec::Encode;
+use frame_support::{
+	assert_noop,
+	dispatch::GetDispatchInfo,
+	pallet_prelude::{InvalidTransaction, TransactionValidityError},
+};
+use pallet_verify_signature::VerifySignature;
+use sp_keyring::AccountKeyring;
+use sp_runtime::{
+	traits::{Applyable, Checkable, IdentityLookup, TransactionExtension},
+	MultiSignature, MultiSigner,
+};
+
+use crate::{extensions::AuthorizeCoownership, mock::*, pallet_assets};
+
+#[test]
+fn create_asset_works() {
+	new_test_ext().execute_with(|| {
+		let alice_keyring = AccountKeyring::Alice;
+		let alice_account = AccountId::from(alice_keyring.public());
+		// Simple call to create asset with Id `42`.
+		let create_asset_call =
+			RuntimeCall::Assets(pallet_assets::Call::create_asset { asset_id: 42 });
+		// Create extension that will be used for dispatch.
+		let initial_nonce = 23;
+		let tx_ext = (
+			frame_system::CheckNonce::<Runtime>::from(initial_nonce),
+			AuthorizeCoownership::<Runtime, MultiSigner, MultiSignature>::default(),
+			frame_system::CheckGenesis::<Runtime>::new(),
+			frame_system::CheckTxVersion::<Runtime>::new(),
+			frame_system::CheckEra::<Runtime>::from(sp_runtime::generic::Era::immortal()),
+		);
+		// Create the transaction signature, to be used in the top level `VerifyMultiSignature`
+		// extension.
+		let tx_sign = MultiSignature::Sr25519(
+			(&create_asset_call, &tx_ext, tx_ext.implicit().unwrap())
+				.using_encoded(|e| alice_keyring.sign(&sp_io::hashing::blake2_256(e))),
+		);
+		// Add the signature to the extension.
+		let tx_ext = (
+			VerifySignature::new_with_signature(tx_sign, alice_account.clone()),
+			frame_system::CheckNonce::<Runtime>::from(initial_nonce),
+			AuthorizeCoownership::<Runtime, MultiSigner, MultiSignature>::default(),
+			frame_system::CheckGenesis::<Runtime>::new(),
+			frame_system::CheckTxVersion::<Runtime>::new(),
+			frame_system::CheckEra::<Runtime>::from(sp_runtime::generic::Era::immortal()),
+		);
+		// Create the transaction and we're ready for dispatch.
+		let uxt = UncheckedExtrinsic::new_transaction(create_asset_call, tx_ext);
+		// Check Extrinsic validity and apply it.
+		let uxt_info = uxt.get_dispatch_info();
+		let uxt_len = uxt.using_encoded(|e| e.len());
+		// Manually pay for Alice's nonce.
+		frame_system::Account::<Runtime>::mutate(&alice_account, |info| {
+			info.nonce = initial_nonce;
+			info.providers = 1;
+		});
+		// Check should pass.
+		let xt = <UncheckedExtrinsic as Checkable<IdentityLookup<AccountId>>>::check(
+			uxt,
+			&Default::default(),
+		)
+		.unwrap();
+		// Apply the extrinsic.
+		let res = xt.apply::<Runtime>(&uxt_info, uxt_len).unwrap();
+
+		// Asserting the results.
+		assert_eq!(frame_system::Account::<Runtime>::get(&alice_account).nonce, initial_nonce + 1);
+		assert_eq!(
+			pallet_assets::AssetOwners::<Runtime>::get(42),
+			Some(pallet_assets::Owner::<AccountId>::Single(alice_account))
+		);
+		assert!(res.is_ok());
+	});
+}
+
+#[docify::export]
+#[test]
+fn create_coowned_asset_works() {
+	new_test_ext().execute_with(|| {
+		let alice_keyring = AccountKeyring::Alice;
+		let bob_keyring = AccountKeyring::Bob;
+		let charlie_keyring = AccountKeyring::Charlie;
+		let alice_account = AccountId::from(alice_keyring.public());
+		let bob_account = AccountId::from(bob_keyring.public());
+		let charlie_account = AccountId::from(charlie_keyring.public());
+		// Simple call to create asset with Id `42`.
+		let create_asset_call =
+			RuntimeCall::Assets(pallet_assets::Call::create_asset { asset_id: 42 });
+		// Create the inner transaction extension, to be signed by our coowners, Alice and Bob.
+		let inner_ext: InnerTxExtension = (
+			frame_system::CheckGenesis::<Runtime>::new(),
+			frame_system::CheckTxVersion::<Runtime>::new(),
+			frame_system::CheckEra::<Runtime>::from(sp_runtime::generic::Era::immortal()),
+		);
+		// Create the payload Alice and Bob need to sign.
+		let inner_payload = (&create_asset_call, &inner_ext, inner_ext.implicit().unwrap());
+		// Create Alice's signature.
+		let alice_inner_sig = MultiSignature::Sr25519(
+			inner_payload.using_encoded(|e| alice_keyring.sign(&sp_io::hashing::blake2_256(e))),
+		);
+		// Create Bob's signature.
+		let bob_inner_sig = MultiSignature::Sr25519(
+			inner_payload.using_encoded(|e| bob_keyring.sign(&sp_io::hashing::blake2_256(e))),
+		);
+		// Create the transaction extension, to be signed by the submitter of the extrinsic, let's
+		// have it be Charlie.
+		let initial_nonce = 23;
+		let tx_ext = (
+			frame_system::CheckNonce::<Runtime>::from(initial_nonce),
+			AuthorizeCoownership::<Runtime, MultiSigner, MultiSignature>::new(
+				(alice_keyring.into(), alice_inner_sig.clone()),
+				(bob_keyring.into(), bob_inner_sig.clone()),
+			),
+			frame_system::CheckGenesis::<Runtime>::new(),
+			frame_system::CheckTxVersion::<Runtime>::new(),
+			frame_system::CheckEra::<Runtime>::from(sp_runtime::generic::Era::immortal()),
+		);
+		// Create Charlie's transaction signature, to be used in the top level
+		// `VerifyMultiSignature` extension.
+		let tx_sign = MultiSignature::Sr25519(
+			(&create_asset_call, &tx_ext, tx_ext.implicit().unwrap())
+				.using_encoded(|e| charlie_keyring.sign(&sp_io::hashing::blake2_256(e))),
+		);
+		// Add the signature to the extension.
+		let tx_ext = (
+			VerifySignature::new_with_signature(tx_sign, charlie_account.clone()),
+			frame_system::CheckNonce::<Runtime>::from(initial_nonce),
+			AuthorizeCoownership::<Runtime, MultiSigner, MultiSignature>::new(
+				(alice_keyring.into(), alice_inner_sig),
+				(bob_keyring.into(), bob_inner_sig),
+			),
+			frame_system::CheckGenesis::<Runtime>::new(),
+			frame_system::CheckTxVersion::<Runtime>::new(),
+			frame_system::CheckEra::<Runtime>::from(sp_runtime::generic::Era::immortal()),
+		);
+		// Create the transaction and we're ready for dispatch.
+		let uxt = UncheckedExtrinsic::new_transaction(create_asset_call, tx_ext);
+		// Check Extrinsic validity and apply it.
+		let uxt_info = uxt.get_dispatch_info();
+		let uxt_len = uxt.using_encoded(|e| e.len());
+		// Manually pay for Charlie's nonce.
+		frame_system::Account::<Runtime>::mutate(&charlie_account, |info| {
+			info.nonce = initial_nonce;
+			info.providers = 1;
+		});
+		// Check should pass.
+		let xt = <UncheckedExtrinsic as Checkable<IdentityLookup<AccountId>>>::check(
+			uxt,
+			&Default::default(),
+		)
+		.unwrap();
+		// Apply the extrinsic.
+		let res = xt.apply::<Runtime>(&uxt_info, uxt_len).unwrap();
+
+		// Asserting the results.
+		assert!(res.is_ok());
+		assert_eq!(frame_system::Account::<Runtime>::get(charlie_account).nonce, initial_nonce + 1);
+		assert_eq!(
+			pallet_assets::AssetOwners::<Runtime>::get(42),
+			Some(pallet_assets::Owner::<AccountId>::Double(alice_account, bob_account))
+		);
+	});
+}
+
+#[test]
+fn inner_authorization_works() {
+	new_test_ext().execute_with(|| {
+		let alice_keyring = AccountKeyring::Alice;
+		let bob_keyring = AccountKeyring::Bob;
+		let charlie_keyring = AccountKeyring::Charlie;
+		let charlie_account = AccountId::from(charlie_keyring.public());
+		// Simple call to create asset with Id `42`.
+		let create_asset_call =
+			RuntimeCall::Assets(pallet_assets::Call::create_asset { asset_id: 42 });
+		// Create the inner transaction extension, to be signed by our coowners, Alice and Bob. They
+		// are going to sign this transaction as a mortal one.
+		let inner_ext: InnerTxExtension = (
+			frame_system::CheckGenesis::<Runtime>::new(),
+			frame_system::CheckTxVersion::<Runtime>::new(),
+			// Sign with mortal era check.
+			frame_system::CheckEra::<Runtime>::from(sp_runtime::generic::Era::mortal(4, 0)),
+		);
+		// Create the payload Alice and Bob need to sign.
+		let inner_payload = (&create_asset_call, &inner_ext, inner_ext.implicit().unwrap());
+		// Create Alice's signature.
+		let alice_inner_sig = MultiSignature::Sr25519(
+			inner_payload.using_encoded(|e| alice_keyring.sign(&sp_io::hashing::blake2_256(e))),
+		);
+		// Create Bob's signature.
+		let bob_inner_sig = MultiSignature::Sr25519(
+			inner_payload.using_encoded(|e| bob_keyring.sign(&sp_io::hashing::blake2_256(e))),
+		);
+		// Create the transaction extension, to be signed by the submitter of the extrinsic, let's
+		// have it be Charlie.
+		let initial_nonce = 23;
+		let tx_ext = (
+			frame_system::CheckNonce::<Runtime>::from(initial_nonce),
+			AuthorizeCoownership::<Runtime, MultiSigner, MultiSignature>::new(
+				(alice_keyring.into(), alice_inner_sig.clone()),
+				(bob_keyring.into(), bob_inner_sig.clone()),
+			),
+			frame_system::CheckGenesis::<Runtime>::new(),
+			frame_system::CheckTxVersion::<Runtime>::new(),
+			// Construct the transaction as immortal with a different era check.
+			frame_system::CheckEra::<Runtime>::from(sp_runtime::generic::Era::immortal()),
+		);
+		// Create Charlie's transaction signature, to be used in the top level
+		// `VerifyMultiSignature` extension.
+		let tx_sign = MultiSignature::Sr25519(
+			(&create_asset_call, &tx_ext, tx_ext.implicit().unwrap())
+				.using_encoded(|e| charlie_keyring.sign(&sp_io::hashing::blake2_256(e))),
+		);
+		// Add the signature to the extension that Charlie signed.
+		let tx_ext = (
+			VerifySignature::new_with_signature(tx_sign, charlie_account.clone()),
+			frame_system::CheckNonce::<Runtime>::from(initial_nonce),
+			AuthorizeCoownership::<Runtime, MultiSigner, MultiSignature>::new(
+				(alice_keyring.into(), alice_inner_sig),
+				(bob_keyring.into(), bob_inner_sig),
+			),
+			frame_system::CheckGenesis::<Runtime>::new(),
+			frame_system::CheckTxVersion::<Runtime>::new(),
+			// Construct the transaction as immortal with a different era check.
+			frame_system::CheckEra::<Runtime>::from(sp_runtime::generic::Era::immortal()),
+		);
+		// Create the transaction and we're ready for dispatch.
+		let uxt = UncheckedExtrinsic::new_transaction(create_asset_call, tx_ext);
+		// Check Extrinsic validity and apply it.
+		let uxt_info = uxt.get_dispatch_info();
+		let uxt_len = uxt.using_encoded(|e| e.len());
+		// Manually pay for Charlie's nonce.
+		frame_system::Account::<Runtime>::mutate(charlie_account, |info| {
+			info.nonce = initial_nonce;
+			info.providers = 1;
+		});
+		// Check should pass.
+		let xt = <UncheckedExtrinsic as Checkable<IdentityLookup<AccountId>>>::check(
+			uxt,
+			&Default::default(),
+		)
+		.unwrap();
+		// The extrinsic should fail as the signature for the `AuthorizeCoownership` doesn't work
+		// for the provided payload with the changed transaction mortality.
+		assert_noop!(
+			xt.apply::<Runtime>(&uxt_info, uxt_len),
+			TransactionValidityError::Invalid(InvalidTransaction::Custom(100))
+		);
+	});
+}
diff --git a/substrate/frame/examples/basic/src/lib.rs b/substrate/frame/examples/basic/src/lib.rs
index fea04cb447a..2f1b32d964e 100644
--- a/substrate/frame/examples/basic/src/lib.rs
+++ b/substrate/frame/examples/basic/src/lib.rs
@@ -46,9 +46,10 @@
 //!   use the [`Config::WeightInfo`] trait to calculate call weights. This can also be overridden,
 //!   as demonstrated by [`Call::set_dummy`].
 //! - A private function that performs a storage update.
-//! - A simple signed extension implementation (see: [`sp_runtime::traits::SignedExtension`]) which
-//!   increases the priority of the [`Call::set_dummy`] if it's present and drops any transaction
-//!   with an encoded length higher than 200 bytes.
+//! - A simple transaction extension implementation (see:
+//!   [`sp_runtime::traits::TransactionExtension`]) which increases the priority of the
+//!   [`Call::set_dummy`] if it's present and drops any transaction with an encoded length higher
+//!   than 200 bytes.
 
 // Ensure we're `no_std` when compiling for Wasm.
 #![cfg_attr(not(feature = "std"), no_std)]
@@ -67,10 +68,12 @@ use frame_system::ensure_signed;
 use log::info;
 use scale_info::TypeInfo;
 use sp_runtime::{
-	traits::{Bounded, DispatchInfoOf, SaturatedConversion, Saturating, SignedExtension},
-	transaction_validity::{
-		InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction,
+	impl_tx_ext_default,
+	traits::{
+		Bounded, DispatchInfoOf, DispatchOriginOf, SaturatedConversion, Saturating,
+		TransactionExtension, ValidateResult,
 	},
+	transaction_validity::{InvalidTransaction, ValidTransaction},
 };
 
 // Re-export pallet items so that they can be accessed from the crate namespace.
@@ -440,42 +443,43 @@ impl<T: Config> Pallet<T> {
 	}
 }
 
-// Similar to other FRAME pallets, your pallet can also define a signed extension and perform some
-// checks and [pre/post]processing [before/after] the transaction. A signed extension can be any
-// decodable type that implements `SignedExtension`. See the trait definition for the full list of
-// bounds. As a convention, you can follow this approach to create an extension for your pallet:
+// Similar to other FRAME pallets, your pallet can also define a transaction extension and perform
+// some checks and [pre/post]processing [before/after] the transaction. A transaction extension can
+// be any decodable type that implements `TransactionExtension`. See the trait definition for the
+// full list of bounds. As a convention, you can follow this approach to create an extension for
+// your pallet:
 //   - If the extension does not carry any data, then use a tuple struct with just a `marker`
 //     (needed for the compiler to accept `T: Config`) will suffice.
 //   - Otherwise, create a tuple struct which contains the external data. Of course, for the entire
 //     struct to be decodable, each individual item also needs to be decodable.
 //
-// Note that a signed extension can also indicate that a particular data must be present in the
-// _signing payload_ of a transaction by providing an implementation for the `additional_signed`
-// method. This example will not cover this type of extension. See `CheckSpecVersion` in
-// [FRAME System](https://github.com/paritytech/polkadot-sdk/tree/master/substrate/frame/system#signed-extensions)
+// Note that a transaction extension can also indicate that a particular data must be present in the
+// _signing payload_ of a transaction by providing an implementation for the `implicit` method. This
+// example will not cover this type of extension. See `CheckSpecVersion` in [FRAME
+// System](https://github.com/paritytech/polkadot-sdk/tree/master/substrate/frame/system#signed-extensions)
 // for an example.
 //
 // Using the extension, you can add some hooks to the life cycle of each transaction. Note that by
 // default, an extension is applied to all `Call` functions (i.e. all transactions). the `Call` enum
-// variant is given to each function of `SignedExtension`. Hence, you can filter based on pallet or
-// a particular call if needed.
+// variant is given to each function of `TransactionExtension`. Hence, you can filter based on
+// pallet or a particular call if needed.
 //
 // Some extra information, such as encoded length, some static dispatch info like weight and the
 // sender of the transaction (if signed) are also provided.
 //
-// The full list of hooks that can be added to a signed extension can be found
-// [here](https://paritytech.github.io/polkadot-sdk/master/sp_runtime/traits/trait.SignedExtension.html).
+// The full list of hooks that can be added to a transaction extension can be found in the
+// `TransactionExtension` trait definition.
 //
-// The signed extensions are aggregated in the runtime file of a substrate chain. All extensions
-// should be aggregated in a tuple and passed to the `CheckedExtrinsic` and `UncheckedExtrinsic`
-// types defined in the runtime. Lookup `pub type SignedExtra = (...)` in `node/runtime` and
-// `node-template` for an example of this.
+// The transaction extensions are aggregated in the runtime file of a substrate chain. All
+// extensions should be aggregated in a tuple and passed to the `CheckedExtrinsic` and
+// `UncheckedExtrinsic` types defined in the runtime. Lookup `pub type TxExtension = (...)` in
+// `node/runtime` and `node-template` for an example of this.
 
-/// A simple signed extension that checks for the `set_dummy` call. In that case, it increases the
-/// priority and prints some log.
+/// A simple transaction extension that checks for the `set_dummy` call. In that case, it increases
+/// the priority and prints some log.
 ///
 /// Additionally, it drops any transaction with an encoded length higher than 200 bytes. No
-/// particular reason why, just to demonstrate the power of signed extensions.
+/// particular reason why, just to demonstrate the power of transaction extensions.
 #[derive(Encode, Decode, Clone, Eq, PartialEq, TypeInfo)]
 #[scale_info(skip_type_params(T))]
 pub struct WatchDummy<T: Config + Send + Sync>(PhantomData<T>);
@@ -486,52 +490,42 @@ impl<T: Config + Send + Sync> core::fmt::Debug for WatchDummy<T> {
 	}
 }
 
-impl<T: Config + Send + Sync> SignedExtension for WatchDummy<T>
+impl<T: Config + Send + Sync> TransactionExtension<<T as frame_system::Config>::RuntimeCall>
+	for WatchDummy<T>
 where
 	<T as frame_system::Config>::RuntimeCall: IsSubType<Call<T>>,
 {
 	const IDENTIFIER: &'static str = "WatchDummy";
-	type AccountId = T::AccountId;
-	type Call = <T as frame_system::Config>::RuntimeCall;
-	type AdditionalSigned = ();
+	type Implicit = ();
 	type Pre = ();
-
-	fn additional_signed(&self) -> core::result::Result<(), TransactionValidityError> {
-		Ok(())
-	}
-
-	fn pre_dispatch(
-		self,
-		who: &Self::AccountId,
-		call: &Self::Call,
-		info: &DispatchInfoOf<Self::Call>,
-		len: usize,
-	) -> Result<Self::Pre, TransactionValidityError> {
-		self.validate(who, call, info, len).map(|_| ())
-	}
+	type Val = ();
 
 	fn validate(
 		&self,
-		_who: &Self::AccountId,
-		call: &Self::Call,
-		_info: &DispatchInfoOf<Self::Call>,
+		origin: DispatchOriginOf<<T as frame_system::Config>::RuntimeCall>,
+		call: &<T as frame_system::Config>::RuntimeCall,
+		_info: &DispatchInfoOf<<T as frame_system::Config>::RuntimeCall>,
 		len: usize,
-	) -> TransactionValidity {
+		_self_implicit: Self::Implicit,
+		_inherited_implication: &impl Encode,
+	) -> ValidateResult<Self::Val, <T as frame_system::Config>::RuntimeCall> {
 		// if the transaction is too big, just drop it.
 		if len > 200 {
-			return InvalidTransaction::ExhaustsResources.into()
+			return Err(InvalidTransaction::ExhaustsResources.into())
 		}
 
 		// check for `set_dummy`
-		match call.is_sub_type() {
+		let validity = match call.is_sub_type() {
 			Some(Call::set_dummy { .. }) => {
 				sp_runtime::print("set_dummy was received.");
 
 				let valid_tx =
 					ValidTransaction { priority: Bounded::max_value(), ..Default::default() };
-				Ok(valid_tx)
+				valid_tx
 			},
-			_ => Ok(Default::default()),
-		}
+			_ => Default::default(),
+		};
+		Ok((validity, (), origin))
 	}
+	impl_tx_ext_default!(<T as frame_system::Config>::RuntimeCall; weight prepare);
 }
diff --git a/substrate/frame/examples/basic/src/tests.rs b/substrate/frame/examples/basic/src/tests.rs
index d7095eb3c94..8e33d3d0a34 100644
--- a/substrate/frame/examples/basic/src/tests.rs
+++ b/substrate/frame/examples/basic/src/tests.rs
@@ -27,7 +27,7 @@ use sp_core::H256;
 // The testing primitives are very useful for avoiding having to work with signatures
 // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required.
 use sp_runtime::{
-	traits::{BlakeTwo256, IdentityLookup},
+	traits::{BlakeTwo256, DispatchTransaction, IdentityLookup},
 	BuildStorage,
 };
 // Reexport crate as its pallet name for construct_runtime.
@@ -146,13 +146,16 @@ fn signed_ext_watch_dummy_works() {
 
 		assert_eq!(
 			WatchDummy::<Test>(PhantomData)
-				.validate(&1, &call, &info, 150)
+				.validate_only(Some(1).into(), &call, &info, 150)
 				.unwrap()
+				.0
 				.priority,
 			u64::MAX,
 		);
 		assert_eq!(
-			WatchDummy::<Test>(PhantomData).validate(&1, &call, &info, 250),
+			WatchDummy::<Test>(PhantomData)
+				.validate_only(Some(1).into(), &call, &info, 250)
+				.unwrap_err(),
 			InvalidTransaction::ExhaustsResources.into(),
 		);
 	})
@@ -174,13 +177,13 @@ fn weights_work() {
 	let info1 = default_call.get_dispatch_info();
 	// aka. `let info = <Call<Test> as GetDispatchInfo>::get_dispatch_info(&default_call);`
 	// TODO: account for proof size weight
-	assert!(info1.weight.ref_time() > 0);
-	assert_eq!(info1.weight, <Test as Config>::WeightInfo::accumulate_dummy());
+	assert!(info1.call_weight.ref_time() > 0);
+	assert_eq!(info1.call_weight, <Test as Config>::WeightInfo::accumulate_dummy());
 
 	// `set_dummy` is simpler than `accumulate_dummy`, and the weight
 	//   should be less.
 	let custom_call = pallet_example_basic::Call::<Test>::set_dummy { new_value: 20 };
 	let info2 = custom_call.get_dispatch_info();
 	// TODO: account for proof size weight
-	assert!(info1.weight.ref_time() > info2.weight.ref_time());
+	assert!(info1.call_weight.ref_time() > info2.call_weight.ref_time());
 }
diff --git a/substrate/frame/examples/offchain-worker/src/lib.rs b/substrate/frame/examples/offchain-worker/src/lib.rs
index add014f6b34..b3fdb6ea189 100644
--- a/substrate/frame/examples/offchain-worker/src/lib.rs
+++ b/substrate/frame/examples/offchain-worker/src/lib.rs
@@ -53,8 +53,8 @@ use frame_support::traits::Get;
 use frame_system::{
 	self as system,
 	offchain::{
-		AppCrypto, CreateSignedTransaction, SendSignedTransaction, SendUnsignedTransaction,
-		SignedPayload, Signer, SigningTypes, SubmitTransaction,
+		AppCrypto, CreateInherent, CreateSignedTransaction, SendSignedTransaction,
+		SendUnsignedTransaction, SignedPayload, Signer, SigningTypes, SubmitTransaction,
 	},
 	pallet_prelude::BlockNumberFor,
 };
@@ -124,7 +124,9 @@ pub mod pallet {
 
 	/// This pallet's configuration trait
 	#[pallet::config]
-	pub trait Config: CreateSignedTransaction<Call<Self>> + frame_system::Config {
+	pub trait Config:
+		CreateSignedTransaction<Call<Self>> + CreateInherent<Call<Self>> + frame_system::Config
+	{
 		/// The identifier type for an offchain worker.
 		type AuthorityId: AppCrypto<Self::Public, Self::Signature>;
 
@@ -501,7 +503,8 @@ impl<T: Config> Pallet<T> {
 		// implement unsigned validation logic, as any mistakes can lead to opening DoS or spam
 		// attack vectors. See validation logic docs for more details.
 		//
-		SubmitTransaction::<T, Call<T>>::submit_unsigned_transaction(call.into())
+		let xt = T::create_inherent(call.into());
+		SubmitTransaction::<T, Call<T>>::submit_transaction(xt)
 			.map_err(|()| "Unable to submit unsigned transaction.")?;
 
 		Ok(())
diff --git a/substrate/frame/examples/offchain-worker/src/tests.rs b/substrate/frame/examples/offchain-worker/src/tests.rs
index 741adbe6d26..755beb8b82e 100644
--- a/substrate/frame/examples/offchain-worker/src/tests.rs
+++ b/substrate/frame/examples/offchain-worker/src/tests.rs
@@ -31,7 +31,7 @@ use sp_core::{
 use sp_keystore::{testing::MemoryKeystore, Keystore, KeystoreExt};
 use sp_runtime::{
 	testing::TestXt,
-	traits::{BlakeTwo256, Extrinsic as ExtrinsicT, IdentifyAccount, IdentityLookup, Verify},
+	traits::{BlakeTwo256, IdentifyAccount, IdentityLookup, Verify},
 	RuntimeAppPublic,
 };
 
@@ -80,25 +80,47 @@ impl frame_system::offchain::SigningTypes for Test {
 	type Signature = Signature;
 }
 
-impl<LocalCall> frame_system::offchain::SendTransactionTypes<LocalCall> for Test
+impl<LocalCall> frame_system::offchain::CreateTransactionBase<LocalCall> for Test
 where
 	RuntimeCall: From<LocalCall>,
 {
-	type OverarchingCall = RuntimeCall;
+	type RuntimeCall = RuntimeCall;
 	type Extrinsic = Extrinsic;
 }
 
+impl<LocalCall> frame_system::offchain::CreateTransaction<LocalCall> for Test
+where
+	RuntimeCall: From<LocalCall>,
+{
+	type Extension = ();
+
+	fn create_transaction(call: RuntimeCall, _extension: Self::Extension) -> Extrinsic {
+		Extrinsic::new_transaction(call, ())
+	}
+}
+
 impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Test
 where
 	RuntimeCall: From<LocalCall>,
 {
-	fn create_transaction<C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>>(
+	fn create_signed_transaction<
+		C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>,
+	>(
 		call: RuntimeCall,
 		_public: <Signature as Verify>::Signer,
 		_account: AccountId,
 		nonce: u64,
-	) -> Option<(RuntimeCall, <Extrinsic as ExtrinsicT>::SignaturePayload)> {
-		Some((call, (nonce, ())))
+	) -> Option<Extrinsic> {
+		Some(Extrinsic::new_signed(call, nonce, (), ()))
+	}
+}
+
+impl<LocalCall> frame_system::offchain::CreateInherent<LocalCall> for Test
+where
+	RuntimeCall: From<LocalCall>,
+{
+	fn create_inherent(call: Self::RuntimeCall) -> Self::Extrinsic {
+		Extrinsic::new_bare(call)
 	}
 }
 
@@ -218,8 +240,8 @@ fn should_submit_signed_transaction_on_chain() {
 		let tx = pool_state.write().transactions.pop().unwrap();
 		assert!(pool_state.read().transactions.is_empty());
 		let tx = Extrinsic::decode(&mut &*tx).unwrap();
-		assert_eq!(tx.signature.unwrap().0, 0);
-		assert_eq!(tx.call, RuntimeCall::Example(crate::Call::submit_price { price: 15523 }));
+		assert!(matches!(tx.preamble, sp_runtime::generic::Preamble::Signed(0, (), 0, (),)));
+		assert_eq!(tx.function, RuntimeCall::Example(crate::Call::submit_price { price: 15523 }));
 	});
 }
 
@@ -258,11 +280,11 @@ fn should_submit_unsigned_transaction_on_chain_for_any_account() {
 		// then
 		let tx = pool_state.write().transactions.pop().unwrap();
 		let tx = Extrinsic::decode(&mut &*tx).unwrap();
-		assert_eq!(tx.signature, None);
+		assert!(tx.is_inherent());
 		if let RuntimeCall::Example(crate::Call::submit_price_unsigned_with_signed_payload {
 			price_payload: body,
 			signature,
-		}) = tx.call
+		}) = tx.function
 		{
 			assert_eq!(body, price_payload);
 
@@ -313,11 +335,11 @@ fn should_submit_unsigned_transaction_on_chain_for_all_accounts() {
 		// then
 		let tx = pool_state.write().transactions.pop().unwrap();
 		let tx = Extrinsic::decode(&mut &*tx).unwrap();
-		assert_eq!(tx.signature, None);
+		assert!(tx.is_inherent());
 		if let RuntimeCall::Example(crate::Call::submit_price_unsigned_with_signed_payload {
 			price_payload: body,
 			signature,
-		}) = tx.call
+		}) = tx.function
 		{
 			assert_eq!(body, price_payload);
 
@@ -354,9 +376,9 @@ fn should_submit_raw_unsigned_transaction_on_chain() {
 		let tx = pool_state.write().transactions.pop().unwrap();
 		assert!(pool_state.read().transactions.is_empty());
 		let tx = Extrinsic::decode(&mut &*tx).unwrap();
-		assert_eq!(tx.signature, None);
+		assert!(tx.is_inherent());
 		assert_eq!(
-			tx.call,
+			tx.function,
 			RuntimeCall::Example(crate::Call::submit_price_unsigned {
 				block_number: 1,
 				price: 15523
diff --git a/substrate/frame/examples/src/lib.rs b/substrate/frame/examples/src/lib.rs
index dee23a41379..d0d30830f2f 100644
--- a/substrate/frame/examples/src/lib.rs
+++ b/substrate/frame/examples/src/lib.rs
@@ -40,12 +40,16 @@
 //! - [`pallet_example_split`]: A simple example of a FRAME pallet demonstrating the ability to
 //!   split sections across multiple files.
 //!
-//! - [`pallet_example_frame_crate`]: Example pallet showcasing how one can be
-//! built using only the `frame` umbrella crate.
+//! - [`pallet_example_frame_crate`]: Example pallet showcasing how one can be built using only the
+//! `frame` umbrella crate.
 //!
 //! - [`pallet_example_single_block_migrations`]: An example pallet demonstrating best-practices for
 //!   writing storage migrations.
 //!
 //! - [`pallet_example_tasks`]: This pallet demonstrates the use of `Tasks` to execute service work.
 //!
+//! - [`pallet_example_authorization_tx_extension`]: An example `TransactionExtension` that
+//!   authorizes a custom origin through signature validation, along with two support pallets to
+//!   showcase the usage.
+//!
 //! **Tip**: Use `cargo doc --package <pallet-name> --open` to view each pallet's documentation.
diff --git a/substrate/frame/examples/tasks/src/lib.rs b/substrate/frame/examples/tasks/src/lib.rs
index 1908a235ba1..7d51617497d 100644
--- a/substrate/frame/examples/tasks/src/lib.rs
+++ b/substrate/frame/examples/tasks/src/lib.rs
@@ -19,7 +19,7 @@
 #![cfg_attr(not(feature = "std"), no_std)]
 
 use frame_support::dispatch::DispatchResult;
-use frame_system::offchain::SendTransactionTypes;
+use frame_system::offchain::CreateInherent;
 #[cfg(feature = "experimental")]
 use frame_system::offchain::SubmitTransaction;
 // Re-export pallet items so that they can be accessed from the crate namespace.
@@ -77,22 +77,21 @@ pub mod pallet {
 				let call = frame_system::Call::<T>::do_task { task: runtime_task.into() };
 
 				// Submit the task as an unsigned transaction
-				let res =
-					SubmitTransaction::<T, frame_system::Call<T>>::submit_unsigned_transaction(
-						call.into(),
-					);
+				let xt = <T as CreateInherent<frame_system::Call<T>>>::create_inherent(call.into());
+				let res = SubmitTransaction::<T, frame_system::Call<T>>::submit_transaction(xt);
 				match res {
 					Ok(_) => log::info!(target: LOG_TARGET, "Submitted the task."),
 					Err(e) => log::error!(target: LOG_TARGET, "Error submitting task: {:?}", e),
 				}
 			}
 		}
+
+		#[cfg(not(feature = "experimental"))]
+		fn offchain_worker(_block_number: BlockNumberFor<T>) {}
 	}
 
 	#[pallet::config]
-	pub trait Config:
-		SendTransactionTypes<frame_system::Call<Self>> + frame_system::Config
-	{
+	pub trait Config: CreateInherent<frame_system::Call<Self>> + frame_system::Config {
 		type RuntimeTask: frame_support::traits::Task
 			+ IsType<<Self as frame_system::Config>::RuntimeTask>
 			+ From<Task<Self>>;
diff --git a/substrate/frame/examples/tasks/src/mock.rs b/substrate/frame/examples/tasks/src/mock.rs
index 9a1112946f6..3dc9153c94a 100644
--- a/substrate/frame/examples/tasks/src/mock.rs
+++ b/substrate/frame/examples/tasks/src/mock.rs
@@ -40,14 +40,23 @@ impl frame_system::Config for Runtime {
 	type Block = Block;
 }
 
-impl<LocalCall> frame_system::offchain::SendTransactionTypes<LocalCall> for Runtime
+impl<LocalCall> frame_system::offchain::CreateTransactionBase<LocalCall> for Runtime
 where
 	RuntimeCall: From<LocalCall>,
 {
-	type OverarchingCall = RuntimeCall;
+	type RuntimeCall = RuntimeCall;
 	type Extrinsic = Extrinsic;
 }
 
+impl<LocalCall> frame_system::offchain::CreateInherent<LocalCall> for Runtime
+where
+	RuntimeCall: From<LocalCall>,
+{
+	fn create_inherent(call: Self::RuntimeCall) -> Self::Extrinsic {
+		Extrinsic::new_bare(call)
+	}
+}
+
 impl pallet_example_tasks::Config for Runtime {
 	type RuntimeTask = RuntimeTask;
 	type WeightInfo = ();
diff --git a/substrate/frame/examples/tasks/src/tests.rs b/substrate/frame/examples/tasks/src/tests.rs
index 6c8acb0194b..4b31849c2ea 100644
--- a/substrate/frame/examples/tasks/src/tests.rs
+++ b/substrate/frame/examples/tasks/src/tests.rs
@@ -157,6 +157,7 @@ fn task_with_offchain_worker() {
 		let tx = pool_state.write().transactions.pop().unwrap();
 		assert!(pool_state.read().transactions.is_empty());
 		let tx = Extrinsic::decode(&mut &*tx).unwrap();
-		assert_eq!(tx.signature, None);
+		use sp_runtime::traits::ExtrinsicLike;
+		assert!(tx.is_bare());
 	});
 }
diff --git a/substrate/frame/examples/tasks/src/weights.rs b/substrate/frame/examples/tasks/src/weights.rs
index 793af6e9622..c9ddea6f9a8 100644
--- a/substrate/frame/examples/tasks/src/weights.rs
+++ b/substrate/frame/examples/tasks/src/weights.rs
@@ -15,30 +15,31 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-//! Autogenerated weights for `pallet_example_tasks`
+//! Autogenerated weights for `tasks_example`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-06-02, STEPS: `20`, REPEAT: `10`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `MacBook.local`, CPU: `<UNKNOWN>`
-//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024`
 
 // Executed Command:
-// ./target/release/node-template
+// ./target/production/substrate-node
 // benchmark
 // pallet
-// --chain
-// dev
-// --pallet
-// pallet_example_tasks
-// --extrinsic
-// *
-// --steps
-// 20
-// --repeat
-// 10
-// --output
-// frame/examples/tasks/src/weights.rs
+// --chain=dev
+// --steps=50
+// --repeat=20
+// --pallet=tasks_example
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --extrinsic=*
+// --wasm-execution=compiled
+// --heap-pages=4096
+// --output=./substrate/frame/examples/tasks/src/weights.rs
+// --header=./substrate/HEADER-APACHE2
+// --template=./substrate/.maintain/frame-weight-template.hbs
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -48,37 +49,42 @@
 use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
 use core::marker::PhantomData;
 
-/// Weight functions needed for pallet_template.
+/// Weight functions needed for `tasks_example`.
 pub trait WeightInfo {
 	fn add_number_into_total() -> Weight;
 }
 
-/// Weight functions for `pallet_example_kitchensink`.
+/// Weights for `tasks_example` using the Substrate node and recommended hardware.
 pub struct SubstrateWeight<T>(PhantomData<T>);
 impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
-	/// Storage: Kitchensink OtherFoo (r:0 w:1)
-	/// Proof Skipped: Kitchensink OtherFoo (max_values: Some(1), max_size: None, mode: Measured)
+	/// Storage: `TasksExample::Numbers` (r:1 w:1)
+	/// Proof: `TasksExample::Numbers` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `TasksExample::Total` (r:1 w:1)
+	/// Proof: `TasksExample::Total` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
 	fn add_number_into_total() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `0`
-		//  Estimated: `0`
-		// Minimum execution time: 1_000_000 picoseconds.
-		Weight::from_parts(1_000_000, 0)
-			.saturating_add(Weight::from_parts(0, 0))
-			.saturating_add(T::DbWeight::get().writes(1))
+		//  Measured:  `149`
+		//  Estimated: `3614`
+		// Minimum execution time: 5_776_000 picoseconds.
+		Weight::from_parts(6_178_000, 3614)
+			.saturating_add(T::DbWeight::get().reads(2_u64))
+			.saturating_add(T::DbWeight::get().writes(2_u64))
 	}
 }
 
+// For backwards compatibility and tests.
 impl WeightInfo for () {
-	/// Storage: Kitchensink OtherFoo (r:0 w:1)
-	/// Proof Skipped: Kitchensink OtherFoo (max_values: Some(1), max_size: None, mode: Measured)
+	/// Storage: `TasksExample::Numbers` (r:1 w:1)
+	/// Proof: `TasksExample::Numbers` (`max_values`: None, `max_size`: None, mode: `Measured`)
+	/// Storage: `TasksExample::Total` (r:1 w:1)
+	/// Proof: `TasksExample::Total` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
 	fn add_number_into_total() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `0`
-		//  Estimated: `0`
-		// Minimum execution time: 1_000_000 picoseconds.
-		Weight::from_parts(1_000_000, 0)
-			.saturating_add(Weight::from_parts(0, 0))
-			.saturating_add(RocksDbWeight::get().writes(1))
+		//  Measured:  `149`
+		//  Estimated: `3614`
+		// Minimum execution time: 5_776_000 picoseconds.
+		Weight::from_parts(6_178_000, 3614)
+			.saturating_add(RocksDbWeight::get().reads(2_u64))
+			.saturating_add(RocksDbWeight::get().writes(2_u64))
 	}
 }
diff --git a/substrate/frame/executive/src/tests.rs b/substrate/frame/executive/src/tests.rs
index 69a970a89d9..3841b010325 100644
--- a/substrate/frame/executive/src/tests.rs
+++ b/substrate/frame/executive/src/tests.rs
@@ -24,7 +24,7 @@ use sp_core::H256;
 use sp_runtime::{
 	generic::{DigestItem, Era},
 	testing::{Block, Digest, Header},
-	traits::{Block as BlockT, Header as HeaderT},
+	traits::{Block as BlockT, Header as HeaderT, TransactionExtension},
 	transaction_validity::{
 		InvalidTransaction, TransactionValidityError, UnknownTransaction, ValidTransaction,
 	},
@@ -309,6 +309,34 @@ parameter_types! {
 	};
 }
 
+pub struct MockExtensionsWeights;
+impl frame_system::ExtensionsWeightInfo for MockExtensionsWeights {
+	fn check_genesis() -> Weight {
+		Weight::zero()
+	}
+	fn check_mortality_mortal_transaction() -> Weight {
+		Weight::from_parts(10, 0)
+	}
+	fn check_mortality_immortal_transaction() -> Weight {
+		Weight::from_parts(10, 0)
+	}
+	fn check_non_zero_sender() -> Weight {
+		Weight::zero()
+	}
+	fn check_nonce() -> Weight {
+		Weight::from_parts(10, 0)
+	}
+	fn check_spec_version() -> Weight {
+		Weight::zero()
+	}
+	fn check_tx_version() -> Weight {
+		Weight::zero()
+	}
+	fn check_weight() -> Weight {
+		Weight::from_parts(10, 0)
+	}
+}
+
 #[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
 impl frame_system::Config for Runtime {
 	type BlockWeights = BlockWeights;
@@ -323,6 +351,7 @@ impl frame_system::Config for Runtime {
 	type PostInherents = MockedSystemCallbacks;
 	type PostTransactions = MockedSystemCallbacks;
 	type MultiBlockMigrator = MockedModeGetter;
+	type ExtensionsWeightInfo = MockExtensionsWeights;
 }
 
 #[derive(Encode, Decode, Copy, Clone, Eq, PartialEq, MaxEncodedLen, TypeInfo, RuntimeDebug)]
@@ -336,15 +365,60 @@ impl VariantCount for FreezeReasonId {
 
 type Balance = u64;
 
+pub struct BalancesWeights;
+impl pallet_balances::WeightInfo for BalancesWeights {
+	fn transfer_allow_death() -> Weight {
+		Weight::from_parts(25, 0)
+	}
+	fn transfer_keep_alive() -> Weight {
+		Weight::zero()
+	}
+	fn force_set_balance_creating() -> Weight {
+		Weight::zero()
+	}
+	fn force_set_balance_killing() -> Weight {
+		Weight::zero()
+	}
+	fn force_transfer() -> Weight {
+		Weight::zero()
+	}
+	fn transfer_all() -> Weight {
+		Weight::zero()
+	}
+	fn force_unreserve() -> Weight {
+		Weight::zero()
+	}
+	fn upgrade_accounts(_u: u32) -> Weight {
+		Weight::zero()
+	}
+	fn force_adjust_total_issuance() -> Weight {
+		Weight::zero()
+	}
+	fn burn_allow_death() -> Weight {
+		Weight::zero()
+	}
+	fn burn_keep_alive() -> Weight {
+		Weight::zero()
+	}
+}
+
 #[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)]
 impl pallet_balances::Config for Runtime {
 	type Balance = Balance;
 	type AccountStore = System;
+	type WeightInfo = BalancesWeights;
 	type RuntimeFreezeReason = FreezeReasonId;
 	type FreezeIdentifier = FreezeReasonId;
 	type MaxFreezes = VariantCountOf<FreezeReasonId>;
 }
 
+pub struct MockTxPaymentWeights;
+impl pallet_transaction_payment::WeightInfo for MockTxPaymentWeights {
+	fn charge_transaction_payment() -> Weight {
+		Weight::from_parts(10, 0)
+	}
+}
+
 parameter_types! {
 	pub const TransactionByteFee: Balance = 0;
 }
@@ -355,6 +429,7 @@ impl pallet_transaction_payment::Config for Runtime {
 	type WeightToFee = IdentityFee<Balance>;
 	type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
 	type FeeMultiplierUpdate = ();
+	type WeightInfo = MockTxPaymentWeights;
 }
 
 impl custom::Config for Runtime {}
@@ -372,14 +447,19 @@ parameter_types! {
 		Default::default();
 }
 
-type SignedExtra = (
+type TxExtension = (
 	frame_system::CheckEra<Runtime>,
 	frame_system::CheckNonce<Runtime>,
 	frame_system::CheckWeight<Runtime>,
 	pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
 );
-type TestXt = sp_runtime::testing::TestXt<RuntimeCall, SignedExtra>;
-type TestBlock = Block<TestXt>;
+type UncheckedXt = sp_runtime::generic::UncheckedExtrinsic<
+	u64,
+	RuntimeCall,
+	sp_runtime::testing::UintAuthorityId,
+	TxExtension,
+>;
+type TestBlock = Block<UncheckedXt>;
 
 // Will contain `true` when the custom runtime logic was called.
 const CUSTOM_ON_RUNTIME_KEY: &[u8] = b":custom:on_runtime";
@@ -399,7 +479,7 @@ impl OnRuntimeUpgrade for CustomOnRuntimeUpgrade {
 
 type Executive = super::Executive<
 	Runtime,
-	Block<TestXt>,
+	Block<UncheckedXt>,
 	ChainContext<Runtime>,
 	Runtime,
 	AllPalletsWithSystem,
@@ -474,17 +554,14 @@ impl MultiStepMigrator for MockedModeGetter {
 	}
 }
 
-fn extra(nonce: u64, fee: Balance) -> SignedExtra {
+fn tx_ext(nonce: u64, fee: Balance) -> TxExtension {
 	(
 		frame_system::CheckEra::from(Era::Immortal),
 		frame_system::CheckNonce::from(nonce),
 		frame_system::CheckWeight::new(),
 		pallet_transaction_payment::ChargeTransactionPayment::from(fee),
 	)
-}
-
-fn sign_extra(who: u64, nonce: u64, fee: Balance) -> Option<(u64, SignedExtra)> {
-	Some((who, extra(nonce, fee)))
+		.into()
 }
 
 fn call_transfer(dest: u64, value: u64) -> RuntimeCall {
@@ -497,8 +574,8 @@ fn balance_transfer_dispatch_works() {
 	pallet_balances::GenesisConfig::<Runtime> { balances: vec![(1, 211)] }
 		.assimilate_storage(&mut t)
 		.unwrap();
-	let xt = TestXt::new(call_transfer(2, 69), sign_extra(1, 0, 0));
-	let weight = xt.get_dispatch_info().weight +
+	let xt = UncheckedXt::new_signed(call_transfer(2, 69), 1, 1.into(), tx_ext(0, 0));
+	let weight = xt.get_dispatch_info().total_weight() +
 		<Runtime as frame_system::Config>::BlockWeights::get()
 			.get(DispatchClass::Normal)
 			.base_extrinsic;
@@ -608,7 +685,7 @@ fn block_import_of_bad_extrinsic_root_fails() {
 fn bad_extrinsic_not_inserted() {
 	let mut t = new_test_ext(1);
 	// bad nonce check!
-	let xt = TestXt::new(call_transfer(33, 69), sign_extra(1, 30, 0));
+	let xt = UncheckedXt::new_signed(call_transfer(33, 69), 1, 1.into(), tx_ext(30, 0));
 	t.execute_with(|| {
 		Executive::initialize_block(&Header::new_from_number(1));
 		assert_err!(
@@ -622,35 +699,47 @@ fn bad_extrinsic_not_inserted() {
 #[test]
 fn block_weight_limit_enforced() {
 	let mut t = new_test_ext(10000);
-	// given: TestXt uses the encoded len as fixed Len:
-	let xt = TestXt::new(
-		RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }),
-		sign_extra(1, 0, 0),
-	);
-	let encoded = xt.encode();
-	let encoded_len = encoded.len() as u64;
+	let transfer_weight =
+			<<Runtime as pallet_balances::Config>::WeightInfo as pallet_balances::WeightInfo>::transfer_allow_death();
+	let extension_weight = tx_ext(0u32.into(), 0)
+		.weight(&RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }));
 	// on_initialize weight + base block execution weight
 	let block_weights = <Runtime as frame_system::Config>::BlockWeights::get();
 	let base_block_weight = Weight::from_parts(175, 0) + block_weights.base_block;
 	let limit = block_weights.get(DispatchClass::Normal).max_total.unwrap() - base_block_weight;
-	let num_to_exhaust_block = limit.ref_time() / (encoded_len + 5);
+	let num_to_exhaust_block =
+		limit.ref_time() / (transfer_weight.ref_time() + extension_weight.ref_time() + 5);
 	t.execute_with(|| {
 		Executive::initialize_block(&Header::new_from_number(1));
 		// Base block execution weight + `on_initialize` weight from the custom module.
 		assert_eq!(<frame_system::Pallet<Runtime>>::block_weight().total(), base_block_weight);
 
 		for nonce in 0..=num_to_exhaust_block {
-			let xt = TestXt::new(
+			let xt = UncheckedXt::new_signed(
 				RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }),
-				sign_extra(1, nonce.into(), 0),
+				1,
+				1.into(),
+				tx_ext(nonce.into(), 0),
 			);
+			let encoded = xt.encode();
+			let encoded_len = encoded.len() as u64;
 			let res = Executive::apply_extrinsic(xt);
 			if nonce != num_to_exhaust_block {
 				assert!(res.is_ok());
 				assert_eq!(
 					<frame_system::Pallet<Runtime>>::block_weight().total(),
-					//--------------------- on_initialize + block_execution + extrinsic_base weight + extrinsic len
-					Weight::from_parts((encoded_len + 5) * (nonce + 1), (nonce + 1)* encoded_len) + base_block_weight,
+					//---------------------
+					// on_initialize
+					// + block_execution
+					// + extrinsic_base weight
+					// + call weight
+					// + extension weight
+					// + extrinsic len
+					Weight::from_parts(
+						(transfer_weight.ref_time() + extension_weight.ref_time() + 5) *
+							(nonce + 1),
+						(nonce + 1) * encoded_len
+					) + base_block_weight,
 				);
 				assert_eq!(
 					<frame_system::Pallet<Runtime>>::extrinsic_index(),
@@ -665,20 +754,28 @@ fn block_weight_limit_enforced() {
 
 #[test]
 fn block_weight_and_size_is_stored_per_tx() {
-	let xt = TestXt::new(
+	let xt = UncheckedXt::new_signed(
 		RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }),
-		sign_extra(1, 0, 0),
+		1,
+		1.into(),
+		tx_ext(0, 0),
 	);
-	let x1 = TestXt::new(
+	let x1 = UncheckedXt::new_signed(
 		RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }),
-		sign_extra(1, 1, 0),
+		1,
+		1.into(),
+		tx_ext(1, 0),
 	);
-	let x2 = TestXt::new(
+	let x2 = UncheckedXt::new_signed(
 		RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }),
-		sign_extra(1, 2, 0),
+		1,
+		1.into(),
+		tx_ext(2, 0),
 	);
 	let len = xt.clone().encode().len() as u32;
-	let mut t = new_test_ext(1);
+	let extension_weight = xt.extension_weight();
+	let transfer_weight = <<Runtime as pallet_balances::Config>::WeightInfo as pallet_balances::WeightInfo>::transfer_allow_death();
+	let mut t = new_test_ext(2);
 	t.execute_with(|| {
 		// Block execution weight + on_initialize weight from custom module
 		let base_block_weight = Weight::from_parts(175, 0) +
@@ -693,8 +790,8 @@ fn block_weight_and_size_is_stored_per_tx() {
 		assert!(Executive::apply_extrinsic(x1.clone()).unwrap().is_ok());
 		assert!(Executive::apply_extrinsic(x2.clone()).unwrap().is_ok());
 
-		// default weight for `TestXt` == encoded length.
-		let extrinsic_weight = Weight::from_parts(len as u64, 0) +
+		let extrinsic_weight = transfer_weight +
+			extension_weight +
 			<Runtime as frame_system::Config>::BlockWeights::get()
 				.get(DispatchClass::Normal)
 				.base_extrinsic;
@@ -720,8 +817,8 @@ fn block_weight_and_size_is_stored_per_tx() {
 
 #[test]
 fn validate_unsigned() {
-	let valid = TestXt::new(RuntimeCall::Custom(custom::Call::allowed_unsigned {}), None);
-	let invalid = TestXt::new(RuntimeCall::Custom(custom::Call::unallowed_unsigned {}), None);
+	let valid = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::allowed_unsigned {}));
+	let invalid = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::unallowed_unsigned {}));
 	let mut t = new_test_ext(1);
 
 	t.execute_with(|| {
@@ -762,9 +859,11 @@ fn can_not_pay_for_tx_fee_on_full_lock() {
 			110,
 		)
 		.unwrap();
-		let xt = TestXt::new(
+		let xt = UncheckedXt::new_signed(
 			RuntimeCall::System(frame_system::Call::remark { remark: vec![1u8] }),
-			sign_extra(1, 0, 0),
+			1,
+			1.into(),
+			tx_ext(0, 0),
 		);
 		Executive::initialize_block(&Header::new_from_number(1));
 
@@ -889,9 +988,11 @@ fn event_from_runtime_upgrade_is_included() {
 /// used through the `ExecuteBlock` trait.
 #[test]
 fn custom_runtime_upgrade_is_called_when_using_execute_block_trait() {
-	let xt = TestXt::new(
+	let xt = UncheckedXt::new_signed(
 		RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }),
-		sign_extra(1, 0, 0),
+		1,
+		1.into(),
+		tx_ext(0, 0),
 	);
 
 	let header = new_test_ext(1).execute_with(|| {
@@ -919,7 +1020,10 @@ fn custom_runtime_upgrade_is_called_when_using_execute_block_trait() {
 			*v = sp_version::RuntimeVersion { spec_version: 1, ..Default::default() }
 		});
 
-		<Executive as ExecuteBlock<Block<TestXt>>>::execute_block(Block::new(header, vec![xt]));
+		<Executive as ExecuteBlock<Block<UncheckedXt>>>::execute_block(Block::new(
+			header,
+			vec![xt],
+		));
 
 		assert_eq!(&sp_io::storage::get(TEST_KEY).unwrap()[..], *b"module");
 		assert_eq!(sp_io::storage::get(CUSTOM_ON_RUNTIME_KEY).unwrap(), true.encode());
@@ -985,7 +1089,7 @@ fn offchain_worker_works_as_expected() {
 #[test]
 fn calculating_storage_root_twice_works() {
 	let call = RuntimeCall::Custom(custom::Call::calculate_storage_root {});
-	let xt = TestXt::new(call, sign_extra(1, 0, 0));
+	let xt = UncheckedXt::new_signed(call, 1, 1.into(), tx_ext(0, 0));
 
 	let header = new_test_ext(1).execute_with(|| {
 		// Let's build some fake block.
@@ -1004,11 +1108,13 @@ fn calculating_storage_root_twice_works() {
 #[test]
 #[should_panic(expected = "Invalid inherent position for extrinsic at index 1")]
 fn invalid_inherent_position_fail() {
-	let xt1 = TestXt::new(
+	let xt1 = UncheckedXt::new_signed(
 		RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 33, value: 0 }),
-		sign_extra(1, 0, 0),
+		1,
+		1.into(),
+		tx_ext(0, 0),
 	);
-	let xt2 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None);
+	let xt2 = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {}));
 
 	let header = new_test_ext(1).execute_with(|| {
 		// Let's build some fake block.
@@ -1027,8 +1133,8 @@ fn invalid_inherent_position_fail() {
 
 #[test]
 fn valid_inherents_position_works() {
-	let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None);
-	let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0));
+	let xt1 = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {}));
+	let xt2 = UncheckedXt::new_signed(call_transfer(33, 0), 1, 1.into(), tx_ext(0, 0));
 
 	let header = new_test_ext(1).execute_with(|| {
 		// Let's build some fake block.
@@ -1048,7 +1154,12 @@ fn valid_inherents_position_works() {
 #[test]
 #[should_panic(expected = "A call was labelled as mandatory, but resulted in an Error.")]
 fn invalid_inherents_fail_block_execution() {
-	let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), sign_extra(1, 0, 0));
+	let xt1 = UncheckedXt::new_signed(
+		RuntimeCall::Custom(custom::Call::inherent {}),
+		1,
+		1.into(),
+		tx_ext(0, 0),
+	);
 
 	new_test_ext(1).execute_with(|| {
 		Executive::execute_block(Block::new(
@@ -1061,7 +1172,7 @@ fn invalid_inherents_fail_block_execution() {
 // Inherents are created by the runtime and don't need to be validated.
 #[test]
 fn inherents_fail_validate_block() {
-	let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None);
+	let xt1 = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {}));
 
 	new_test_ext(1).execute_with(|| {
 		assert_eq!(
@@ -1075,7 +1186,7 @@ fn inherents_fail_validate_block() {
 /// Inherents still work while `initialize_block` forbids transactions.
 #[test]
 fn inherents_ok_while_exts_forbidden_works() {
-	let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None);
+	let xt1 = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {}));
 
 	let header = new_test_ext(1).execute_with(|| {
 		Executive::initialize_block(&Header::new_from_number(1));
@@ -1095,8 +1206,8 @@ fn inherents_ok_while_exts_forbidden_works() {
 #[test]
 #[should_panic = "Only inherents are allowed in this block"]
 fn transactions_in_only_inherents_block_errors() {
-	let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None);
-	let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0));
+	let xt1 = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {}));
+	let xt2 = UncheckedXt::new_signed(call_transfer(33, 0), 1, 1.into(), tx_ext(0, 0));
 
 	let header = new_test_ext(1).execute_with(|| {
 		Executive::initialize_block(&Header::new_from_number(1));
@@ -1116,8 +1227,8 @@ fn transactions_in_only_inherents_block_errors() {
 /// Same as above but no error.
 #[test]
 fn transactions_in_normal_block_works() {
-	let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None);
-	let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0));
+	let xt1 = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {}));
+	let xt2 = UncheckedXt::new_signed(call_transfer(33, 0), 1, 1.into(), tx_ext(0, 0));
 
 	let header = new_test_ext(1).execute_with(|| {
 		Executive::initialize_block(&Header::new_from_number(1));
@@ -1137,8 +1248,8 @@ fn transactions_in_normal_block_works() {
 #[test]
 #[cfg(feature = "try-runtime")]
 fn try_execute_block_works() {
-	let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None);
-	let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0));
+	let xt1 = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {}));
+	let xt2 = UncheckedXt::new_signed(call_transfer(33, 0), 1, 1.into(), tx_ext(0, 0));
 
 	let header = new_test_ext(1).execute_with(|| {
 		Executive::initialize_block(&Header::new_from_number(1));
@@ -1165,8 +1276,8 @@ fn try_execute_block_works() {
 #[cfg(feature = "try-runtime")]
 #[should_panic = "Only inherents allowed"]
 fn try_execute_tx_forbidden_errors() {
-	let xt1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None);
-	let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0));
+	let xt1 = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {}));
+	let xt2 = UncheckedXt::new_signed(call_transfer(33, 0), 1, 1.into(), tx_ext(0, 0));
 
 	let header = new_test_ext(1).execute_with(|| {
 		// Let's build some fake block.
@@ -1193,9 +1304,9 @@ fn try_execute_tx_forbidden_errors() {
 /// Check that `ensure_inherents_are_first` reports the correct indices.
 #[test]
 fn ensure_inherents_are_first_works() {
-	let in1 = TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None);
-	let in2 = TestXt::new(RuntimeCall::Custom2(custom2::Call::inherent {}), None);
-	let xt2 = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0));
+	let in1 = UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {}));
+	let in2 = UncheckedXt::new_bare(RuntimeCall::Custom2(custom2::Call::inherent {}));
+	let xt2 = UncheckedXt::new_signed(call_transfer(33, 0), 1, 1.into(), tx_ext(0, 0));
 
 	// Mocked empty header:
 	let header = new_test_ext(1).execute_with(|| {
@@ -1273,18 +1384,20 @@ fn callbacks_in_block_execution_works_inner(mbms_active: bool) {
 
 			for i in 0..n_in {
 				let xt = if i % 2 == 0 {
-					TestXt::new(RuntimeCall::Custom(custom::Call::inherent {}), None)
+					UncheckedXt::new_bare(RuntimeCall::Custom(custom::Call::inherent {}))
 				} else {
-					TestXt::new(RuntimeCall::Custom2(custom2::Call::optional_inherent {}), None)
+					UncheckedXt::new_bare(RuntimeCall::Custom2(custom2::Call::optional_inherent {}))
 				};
 				Executive::apply_extrinsic(xt.clone()).unwrap().unwrap();
 				extrinsics.push(xt);
 			}
 
 			for t in 0..n_tx {
-				let xt = TestXt::new(
+				let xt = UncheckedXt::new_signed(
 					RuntimeCall::Custom2(custom2::Call::some_call {}),
-					sign_extra(1, t as u64, 0),
+					1,
+					1.into(),
+					tx_ext(t as u64, 0),
 				);
 				// Extrinsics can be applied even when MBMs are active. Only the `execute_block`
 				// will reject it.
@@ -1324,8 +1437,13 @@ fn callbacks_in_block_execution_works_inner(mbms_active: bool) {
 
 #[test]
 fn post_inherent_called_after_all_inherents() {
-	let in1 = TestXt::new(RuntimeCall::Custom2(custom2::Call::inherent {}), None);
-	let xt1 = TestXt::new(RuntimeCall::Custom2(custom2::Call::some_call {}), sign_extra(1, 0, 0));
+	let in1 = UncheckedXt::new_bare(RuntimeCall::Custom2(custom2::Call::inherent {}));
+	let xt1 = UncheckedXt::new_signed(
+		RuntimeCall::Custom2(custom2::Call::some_call {}),
+		1,
+		1.into(),
+		tx_ext(0, 0),
+	);
 
 	let header = new_test_ext(1).execute_with(|| {
 		// Let's build some fake block.
@@ -1359,8 +1477,13 @@ fn post_inherent_called_after_all_inherents() {
 /// Regression test for AppSec finding #40.
 #[test]
 fn post_inherent_called_after_all_optional_inherents() {
-	let in1 = TestXt::new(RuntimeCall::Custom2(custom2::Call::optional_inherent {}), None);
-	let xt1 = TestXt::new(RuntimeCall::Custom2(custom2::Call::some_call {}), sign_extra(1, 0, 0));
+	let in1 = UncheckedXt::new_bare(RuntimeCall::Custom2(custom2::Call::optional_inherent {}));
+	let xt1 = UncheckedXt::new_signed(
+		RuntimeCall::Custom2(custom2::Call::some_call {}),
+		1,
+		1.into(),
+		tx_ext(0, 0),
+	);
 
 	let header = new_test_ext(1).execute_with(|| {
 		// Let's build some fake block.
@@ -1393,14 +1516,14 @@ fn post_inherent_called_after_all_optional_inherents() {
 
 #[test]
 fn is_inherent_works() {
-	let ext = TestXt::new(RuntimeCall::Custom2(custom2::Call::inherent {}), None);
+	let ext = UncheckedXt::new_bare(RuntimeCall::Custom2(custom2::Call::inherent {}));
 	assert!(Runtime::is_inherent(&ext));
-	let ext = TestXt::new(RuntimeCall::Custom2(custom2::Call::optional_inherent {}), None);
+	let ext = UncheckedXt::new_bare(RuntimeCall::Custom2(custom2::Call::optional_inherent {}));
 	assert!(Runtime::is_inherent(&ext));
 
-	let ext = TestXt::new(call_transfer(33, 0), sign_extra(1, 0, 0));
+	let ext = UncheckedXt::new_signed(call_transfer(33, 0), 1, 1.into(), tx_ext(0, 0));
 	assert!(!Runtime::is_inherent(&ext));
 
-	let ext = TestXt::new(RuntimeCall::Custom2(custom2::Call::allowed_unsigned {}), None);
+	let ext = UncheckedXt::new_bare(RuntimeCall::Custom2(custom2::Call::allowed_unsigned {}));
 	assert!(!Runtime::is_inherent(&ext), "Unsigned ext are not automatically inherents");
 }
diff --git a/substrate/frame/grandpa/src/equivocation.rs b/substrate/frame/grandpa/src/equivocation.rs
index b213c1ceb72..2366c957e9a 100644
--- a/substrate/frame/grandpa/src/equivocation.rs
+++ b/substrate/frame/grandpa/src/equivocation.rs
@@ -110,7 +110,7 @@ impl<Offender: Clone> Offence<Offender> for EquivocationOffence<Offender> {
 ///
 /// This type implements `OffenceReportSystem` such that:
 /// - Equivocation reports are published on-chain as unsigned extrinsic via
-///   `offchain::SendTransactionTypes`.
+///   `offchain::CreateTransactionBase`.
 /// - On-chain validity checks and processing are mostly delegated to the user provided generic
 ///   types implementing `KeyOwnerProofSystem` and `ReportOffence` traits.
 /// - Offence reporter for unsigned transactions is fetched via the the authorship pallet.
@@ -122,7 +122,7 @@ impl<T, R, P, L>
 		(EquivocationProof<T::Hash, BlockNumberFor<T>>, T::KeyOwnerProof),
 	> for EquivocationReportSystem<T, R, P, L>
 where
-	T: Config + pallet_authorship::Config + frame_system::offchain::SendTransactionTypes<Call<T>>,
+	T: Config + pallet_authorship::Config + frame_system::offchain::CreateInherent<Call<T>>,
 	R: ReportOffence<
 		T::AccountId,
 		P::IdentificationTuple,
@@ -144,7 +144,8 @@ where
 			equivocation_proof: Box::new(equivocation_proof),
 			key_owner_proof,
 		};
-		let res = SubmitTransaction::<T, Call<T>>::submit_unsigned_transaction(call.into());
+		let xt = T::create_inherent(call.into());
+		let res = SubmitTransaction::<T, Call<T>>::submit_transaction(xt);
 		match res {
 			Ok(_) => info!(target: LOG_TARGET, "Submitted equivocation report"),
 			Err(e) => error!(target: LOG_TARGET, "Error submitting equivocation report: {:?}", e),
diff --git a/substrate/frame/grandpa/src/mock.rs b/substrate/frame/grandpa/src/mock.rs
index caac4107cfb..cf4c29003a7 100644
--- a/substrate/frame/grandpa/src/mock.rs
+++ b/substrate/frame/grandpa/src/mock.rs
@@ -72,14 +72,23 @@ impl frame_system::Config for Test {
 	type AccountData = pallet_balances::AccountData<u128>;
 }
 
-impl<C> frame_system::offchain::SendTransactionTypes<C> for Test
+impl<C> frame_system::offchain::CreateTransactionBase<C> for Test
 where
 	RuntimeCall: From<C>,
 {
-	type OverarchingCall = RuntimeCall;
+	type RuntimeCall = RuntimeCall;
 	type Extrinsic = TestXt<RuntimeCall, ()>;
 }
 
+impl<C> frame_system::offchain::CreateInherent<C> for Test
+where
+	RuntimeCall: From<C>,
+{
+	fn create_inherent(call: Self::RuntimeCall) -> Self::Extrinsic {
+		TestXt::new_bare(call)
+	}
+}
+
 parameter_types! {
 	pub const Period: u64 = 1;
 	pub const Offset: u64 = 0;
diff --git a/substrate/frame/grandpa/src/tests.rs b/substrate/frame/grandpa/src/tests.rs
index 8b12d63adaa..e1e963ce564 100644
--- a/substrate/frame/grandpa/src/tests.rs
+++ b/substrate/frame/grandpa/src/tests.rs
@@ -882,7 +882,7 @@ fn valid_equivocation_reports_dont_pay_fees() {
 		.get_dispatch_info();
 
 		// it should have non-zero weight and the fee has to be paid.
-		assert!(info.weight.any_gt(Weight::zero()));
+		assert!(info.call_weight.any_gt(Weight::zero()));
 		assert_eq!(info.pays_fee, Pays::Yes);
 
 		// report the equivocation.
diff --git a/substrate/frame/im-online/src/lib.rs b/substrate/frame/im-online/src/lib.rs
index ee2a8451d6f..74d3bc6484d 100644
--- a/substrate/frame/im-online/src/lib.rs
+++ b/substrate/frame/im-online/src/lib.rs
@@ -95,7 +95,7 @@ use frame_support::{
 	BoundedSlice, WeakBoundedVec,
 };
 use frame_system::{
-	offchain::{SendTransactionTypes, SubmitTransaction},
+	offchain::{CreateInherent, SubmitTransaction},
 	pallet_prelude::*,
 };
 pub use pallet::*;
@@ -261,7 +261,7 @@ pub mod pallet {
 	pub struct Pallet<T>(_);
 
 	#[pallet::config]
-	pub trait Config: SendTransactionTypes<Call<Self>> + frame_system::Config {
+	pub trait Config: CreateInherent<Call<Self>> + frame_system::Config {
 		/// The identifier type for an authority.
 		type AuthorityId: Member
 			+ Parameter
@@ -642,7 +642,8 @@ impl<T: Config> Pallet<T> {
 				call,
 			);
 
-			SubmitTransaction::<T, Call<T>>::submit_unsigned_transaction(call.into())
+			let xt = T::create_inherent(call.into());
+			SubmitTransaction::<T, Call<T>>::submit_transaction(xt)
 				.map_err(|_| OffchainErr::SubmitTransaction)?;
 
 			Ok(())
diff --git a/substrate/frame/im-online/src/mock.rs b/substrate/frame/im-online/src/mock.rs
index 882581702ea..a5d9a6e20e6 100644
--- a/substrate/frame/im-online/src/mock.rs
+++ b/substrate/frame/im-online/src/mock.rs
@@ -25,11 +25,7 @@ use frame_support::{
 	weights::Weight,
 };
 use pallet_session::historical as pallet_session_historical;
-use sp_runtime::{
-	testing::{TestXt, UintAuthorityId},
-	traits::ConvertInto,
-	BuildStorage, Permill,
-};
+use sp_runtime::{testing::UintAuthorityId, traits::ConvertInto, BuildStorage, Permill};
 use sp_staking::{
 	offence::{OffenceError, ReportOffence},
 	SessionIndex,
@@ -77,7 +73,7 @@ impl pallet_session::historical::SessionManager<u64, u64> for TestSessionManager
 }
 
 /// An extrinsic type used for tests.
-pub type Extrinsic = TestXt<RuntimeCall, ()>;
+pub type Extrinsic = sp_runtime::testing::TestXt<RuntimeCall, ()>;
 type IdentificationTuple = (u64, u64);
 type Offence = crate::UnresponsivenessOffence<IdentificationTuple>;
 
@@ -191,14 +187,23 @@ impl Config for Runtime {
 	type MaxPeerInHeartbeats = ConstU32<10_000>;
 }
 
-impl<LocalCall> frame_system::offchain::SendTransactionTypes<LocalCall> for Runtime
+impl<LocalCall> frame_system::offchain::CreateTransactionBase<LocalCall> for Runtime
 where
 	RuntimeCall: From<LocalCall>,
 {
-	type OverarchingCall = RuntimeCall;
+	type RuntimeCall = RuntimeCall;
 	type Extrinsic = Extrinsic;
 }
 
+impl<LocalCall> frame_system::offchain::CreateInherent<LocalCall> for Runtime
+where
+	RuntimeCall: From<LocalCall>,
+{
+	fn create_inherent(call: Self::RuntimeCall) -> Self::Extrinsic {
+		Extrinsic::new_bare(call)
+	}
+}
+
 pub fn advance_session() {
 	let now = System::block_number().max(1);
 	System::set_block_number(now + 1);
diff --git a/substrate/frame/im-online/src/tests.rs b/substrate/frame/im-online/src/tests.rs
index 12333d59ef8..b9a2772da68 100644
--- a/substrate/frame/im-online/src/tests.rs
+++ b/substrate/frame/im-online/src/tests.rs
@@ -225,7 +225,7 @@ fn should_generate_heartbeats() {
 
 		// check stuff about the transaction.
 		let ex: Extrinsic = Decode::decode(&mut &*transaction).unwrap();
-		let heartbeat = match ex.call {
+		let heartbeat = match ex.function {
 			crate::mock::RuntimeCall::ImOnline(crate::Call::heartbeat { heartbeat, .. }) =>
 				heartbeat,
 			e => panic!("Unexpected call: {:?}", e),
@@ -339,7 +339,7 @@ fn should_not_send_a_report_if_already_online() {
 		assert_eq!(pool_state.read().transactions.len(), 0);
 		// check stuff about the transaction.
 		let ex: Extrinsic = Decode::decode(&mut &*transaction).unwrap();
-		let heartbeat = match ex.call {
+		let heartbeat = match ex.function {
 			crate::mock::RuntimeCall::ImOnline(crate::Call::heartbeat { heartbeat, .. }) =>
 				heartbeat,
 			e => panic!("Unexpected call: {:?}", e),
diff --git a/substrate/frame/lottery/src/lib.rs b/substrate/frame/lottery/src/lib.rs
index 0071b258fc4..6a15de55ebd 100644
--- a/substrate/frame/lottery/src/lib.rs
+++ b/substrate/frame/lottery/src/lib.rs
@@ -300,7 +300,7 @@ pub mod pallet {
 		#[pallet::call_index(0)]
 		#[pallet::weight(
 			T::WeightInfo::buy_ticket()
-				.saturating_add(call.get_dispatch_info().weight)
+				.saturating_add(call.get_dispatch_info().call_weight)
 		)]
 		pub fn buy_ticket(
 			origin: OriginFor<T>,
diff --git a/substrate/frame/metadata-hash-extension/src/lib.rs b/substrate/frame/metadata-hash-extension/src/lib.rs
index d09acbfb3df..9bd092c8982 100644
--- a/substrate/frame/metadata-hash-extension/src/lib.rs
+++ b/substrate/frame/metadata-hash-extension/src/lib.rs
@@ -17,14 +17,14 @@
 
 #![cfg_attr(not(feature = "std"), no_std)]
 
-//! The [`CheckMetadataHash`] signed extension.
+//! The [`CheckMetadataHash`] transaction extension.
 //!
 //! The extension for optionally checking the metadata hash. For information how it works and what
 //! it does exactly, see the docs of [`CheckMetadataHash`].
 //!
 //! # Integration
 //!
-//! As any signed extension you will need to add it to your runtime signed extensions:
+//! As any transaction extension you will need to add it to your runtime transaction extensions:
 #![doc = docify::embed!("src/tests.rs", add_metadata_hash_extension)]
 //! As the extension requires the `RUNTIME_METADATA_HASH` environment variable to be present at
 //! compile time, it requires a little bit more setup. To have this environment variable available
@@ -43,7 +43,8 @@ use frame_support::DebugNoBound;
 use frame_system::Config;
 use scale_info::TypeInfo;
 use sp_runtime::{
-	traits::{DispatchInfoOf, SignedExtension},
+	impl_tx_ext_default,
+	traits::TransactionExtension,
 	transaction_validity::{TransactionValidityError, UnknownTransaction},
 };
 
@@ -85,15 +86,15 @@ impl MetadataHash {
 /// This metadata hash should give users the confidence that what they build with an online wallet
 /// is the same they are signing with their offline wallet and then applying on chain. To ensure
 /// that the online wallet is not tricking the offline wallet into decoding and showing an incorrect
-/// extrinsic, the offline wallet will include the metadata hash into the additional signed data and
+/// extrinsic, the offline wallet will include the metadata hash into the extension implicit and
 /// the runtime will then do the same. If the metadata hash doesn't match, the signature
 /// verification will fail and thus, the transaction will be rejected. The RFC contains more details
 /// on how it works.
 ///
 /// The extension adds one byte (the `mode`) to the size of the extrinsic. This one byte is
-/// controlling if the metadata hash should be added to the signed data or not. Mode `0` means that
-/// the metadata hash is not added and thus, `None` is added to the signed data. Mode `1` means that
-/// the metadata hash is added and thus, `Some(metadata_hash)` is added to the signed data. Further
+/// controlling if the metadata hash should be added to the implicit or not. Mode `0` means that
+/// the metadata hash is not added and thus, `None` is added to the implicit. Mode `1` means that
+/// the metadata hash is added and thus, `Some(metadata_hash)` is added to the implicit. Further
 /// values of `mode` are reserved for future changes.
 ///
 /// The metadata hash is read from the environment variable `RUNTIME_METADATA_HASH`. This
@@ -110,7 +111,7 @@ pub struct CheckMetadataHash<T> {
 }
 
 impl<T> CheckMetadataHash<T> {
-	/// Creates new `SignedExtension` to check metadata hash.
+	/// Creates new `TransactionExtension` to check metadata hash.
 	pub fn new(enable: bool) -> Self {
 		Self {
 			_phantom: core::marker::PhantomData,
@@ -131,14 +132,10 @@ impl<T> CheckMetadataHash<T> {
 	}
 }
 
-impl<T: Config + Send + Sync> SignedExtension for CheckMetadataHash<T> {
-	type AccountId = T::AccountId;
-	type Call = <T as Config>::RuntimeCall;
-	type AdditionalSigned = Option<[u8; 32]>;
-	type Pre = ();
+impl<T: Config + Send + Sync> TransactionExtension<T::RuntimeCall> for CheckMetadataHash<T> {
 	const IDENTIFIER: &'static str = "CheckMetadataHash";
-
-	fn additional_signed(&self) -> Result<Self::AdditionalSigned, TransactionValidityError> {
+	type Implicit = Option<[u8; 32]>;
+	fn implicit(&self) -> Result<Self::Implicit, TransactionValidityError> {
 		let signed = match self.mode {
 			Mode::Disabled => None,
 			Mode::Enabled => match self.metadata_hash.hash() {
@@ -149,20 +146,14 @@ impl<T: Config + Send + Sync> SignedExtension for CheckMetadataHash<T> {
 
 		log::debug!(
 			target: "runtime::metadata-hash",
-			"CheckMetadataHash::additional_signed => {:?}",
+			"CheckMetadataHash::implicit => {:?}",
 			signed.as_ref().map(|h| array_bytes::bytes2hex("0x", h)),
 		);
 
 		Ok(signed)
 	}
+	type Val = ();
+	type Pre = ();
 
-	fn pre_dispatch(
-		self,
-		who: &Self::AccountId,
-		call: &Self::Call,
-		info: &DispatchInfoOf<Self::Call>,
-		len: usize,
-	) -> Result<Self::Pre, TransactionValidityError> {
-		self.validate(who, call, info, len).map(|_| ())
-	}
+	impl_tx_ext_default!(T::RuntimeCall; weight validate prepare);
 }
diff --git a/substrate/frame/metadata-hash-extension/src/tests.rs b/substrate/frame/metadata-hash-extension/src/tests.rs
index f13eecfd94b..11a3345ee15 100644
--- a/substrate/frame/metadata-hash-extension/src/tests.rs
+++ b/substrate/frame/metadata-hash-extension/src/tests.rs
@@ -25,7 +25,7 @@ use frame_support::{
 use merkleized_metadata::{generate_metadata_digest, ExtraInfo};
 use sp_api::{Metadata, ProvideRuntimeApi};
 use sp_runtime::{
-	traits::{Extrinsic as _, SignedExtension},
+	traits::{ExtrinsicLike, TransactionExtension},
 	transaction_validity::{TransactionSource, UnknownTransaction},
 };
 use sp_transaction_pool::runtime_api::TaggedTransactionQueue;
@@ -51,7 +51,7 @@ impl frame_system::Config for Test {
 #[test]
 fn rejects_when_no_metadata_hash_was_passed() {
 	let ext = CheckMetadataHash::<Test>::decode(&mut &1u8.encode()[..]).unwrap();
-	assert_eq!(Err(UnknownTransaction::CannotLookup.into()), ext.additional_signed());
+	assert_eq!(Err(UnknownTransaction::CannotLookup.into()), ext.implicit());
 }
 
 #[test]
@@ -92,7 +92,7 @@ fn ensure_check_metadata_works_on_real_extrinsics() {
 		.metadata_hash(generate_metadata_hash(metadata))
 		.build();
 	// Ensure that the transaction is signed.
-	assert!(valid_transaction.is_signed().unwrap());
+	assert!(!valid_transaction.is_bare());
 
 	runtime_api
 		.validate_transaction(best_hash, TransactionSource::External, valid_transaction, best_hash)
@@ -104,7 +104,7 @@ fn ensure_check_metadata_works_on_real_extrinsics() {
 		.metadata_hash([10u8; 32])
 		.build();
 	// Ensure that the transaction is signed.
-	assert!(invalid_transaction.is_signed().unwrap());
+	assert!(!invalid_transaction.is_bare());
 
 	assert_eq!(
 		TransactionValidityError::from(InvalidTransaction::BadProof),
@@ -132,8 +132,8 @@ mod docs {
 			}
 		}
 
-		/// The `SignedExtension` to the basic transaction logic.
-		pub type SignedExtra = (
+		/// The `TransactionExtension` to the basic transaction logic.
+		pub type TxExtension = (
 			frame_system::CheckNonZeroSender<Runtime>,
 			frame_system::CheckSpecVersion<Runtime>,
 			frame_system::CheckTxVersion<Runtime>,
@@ -153,7 +153,7 @@ mod docs {
 
 		/// Unchecked extrinsic type as expected by this runtime.
 		pub type UncheckedExtrinsic =
-			sp_runtime::generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+			sp_runtime::generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
 	}
 
 	// Put here to not have it in the docs as well.
diff --git a/substrate/frame/mixnet/src/lib.rs b/substrate/frame/mixnet/src/lib.rs
index c0505a4f010..6579ed678ae 100644
--- a/substrate/frame/mixnet/src/lib.rs
+++ b/substrate/frame/mixnet/src/lib.rs
@@ -31,7 +31,7 @@ use frame_support::{
 	BoundedVec,
 };
 use frame_system::{
-	offchain::{SendTransactionTypes, SubmitTransaction},
+	offchain::{CreateInherent, SubmitTransaction},
 	pallet_prelude::BlockNumberFor,
 };
 pub use pallet::*;
@@ -178,7 +178,7 @@ pub mod pallet {
 	pub struct Pallet<T>(_);
 
 	#[pallet::config]
-	pub trait Config: frame_system::Config + SendTransactionTypes<Call<Self>> {
+	pub trait Config: frame_system::Config + CreateInherent<Call<Self>> {
 		/// The maximum number of authorities per session.
 		#[pallet::constant]
 		type MaxAuthorities: Get<AuthorityIndex>;
@@ -531,7 +531,8 @@ impl<T: Config> Pallet<T> {
 			return false
 		};
 		let call = Call::register { registration, signature };
-		match SubmitTransaction::<T, Call<T>>::submit_unsigned_transaction(call.into()) {
+		let xt = T::create_inherent(call.into());
+		match SubmitTransaction::<T, Call<T>>::submit_transaction(xt) {
 			Ok(()) => true,
 			Err(()) => {
 				log::debug!(
diff --git a/substrate/frame/multisig/src/lib.rs b/substrate/frame/multisig/src/lib.rs
index 51c36773bda..8faae73c716 100644
--- a/substrate/frame/multisig/src/lib.rs
+++ b/substrate/frame/multisig/src/lib.rs
@@ -273,7 +273,7 @@ pub mod pallet {
 				T::WeightInfo::as_multi_threshold_1(call.using_encoded(|c| c.len() as u32))
 					// AccountData for inner call origin accountdata.
 					.saturating_add(T::DbWeight::get().reads_writes(1, 1))
-					.saturating_add(dispatch_info.weight),
+					.saturating_add(dispatch_info.call_weight),
 				dispatch_info.class,
 			)
 		})]
@@ -554,7 +554,7 @@ impl<T: Config> Pallet<T> {
 			if let Some(call) = maybe_call.filter(|_| approvals >= threshold) {
 				// verify weight
 				ensure!(
-					call.get_dispatch_info().weight.all_lte(max_weight),
+					call.get_dispatch_info().call_weight.all_lte(max_weight),
 					Error::<T>::MaxWeightTooLow
 				);
 
diff --git a/substrate/frame/multisig/src/tests.rs b/substrate/frame/multisig/src/tests.rs
index cfdd33f7dfc..4f8a7a44243 100644
--- a/substrate/frame/multisig/src/tests.rs
+++ b/substrate/frame/multisig/src/tests.rs
@@ -104,7 +104,7 @@ fn multisig_deposit_is_taken_and_returned() {
 		assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(3), multi, 5));
 
 		let call = call_transfer(6, 15);
-		let call_weight = call.get_dispatch_info().weight;
+		let call_weight = call.get_dispatch_info().call_weight;
 		assert_ok!(Multisig::as_multi(
 			RuntimeOrigin::signed(1),
 			2,
@@ -225,7 +225,7 @@ fn multisig_2_of_3_works() {
 		assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(3), multi, 5));
 
 		let call = call_transfer(6, 15);
-		let call_weight = call.get_dispatch_info().weight;
+		let call_weight = call.get_dispatch_info().call_weight;
 		let hash = blake2_256(&call.encode());
 		assert_ok!(Multisig::approve_as_multi(
 			RuntimeOrigin::signed(1),
@@ -258,7 +258,7 @@ fn multisig_3_of_3_works() {
 		assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(3), multi, 5));
 
 		let call = call_transfer(6, 15);
-		let call_weight = call.get_dispatch_info().weight;
+		let call_weight = call.get_dispatch_info().call_weight;
 		let hash = blake2_256(&call.encode());
 		assert_ok!(Multisig::approve_as_multi(
 			RuntimeOrigin::signed(1),
@@ -328,7 +328,7 @@ fn multisig_2_of_3_as_multi_works() {
 		assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(3), multi, 5));
 
 		let call = call_transfer(6, 15);
-		let call_weight = call.get_dispatch_info().weight;
+		let call_weight = call.get_dispatch_info().call_weight;
 		assert_ok!(Multisig::as_multi(
 			RuntimeOrigin::signed(1),
 			2,
@@ -360,9 +360,9 @@ fn multisig_2_of_3_as_multi_with_many_calls_works() {
 		assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(3), multi, 5));
 
 		let call1 = call_transfer(6, 10);
-		let call1_weight = call1.get_dispatch_info().weight;
+		let call1_weight = call1.get_dispatch_info().call_weight;
 		let call2 = call_transfer(7, 5);
-		let call2_weight = call2.get_dispatch_info().weight;
+		let call2_weight = call2.get_dispatch_info().call_weight;
 
 		assert_ok!(Multisig::as_multi(
 			RuntimeOrigin::signed(1),
@@ -411,7 +411,7 @@ fn multisig_2_of_3_cannot_reissue_same_call() {
 		assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(3), multi, 5));
 
 		let call = call_transfer(6, 10);
-		let call_weight = call.get_dispatch_info().weight;
+		let call_weight = call.get_dispatch_info().call_weight;
 		let hash = blake2_256(&call.encode());
 		assert_ok!(Multisig::as_multi(
 			RuntimeOrigin::signed(1),
@@ -652,7 +652,7 @@ fn multisig_handles_no_preimage_after_all_approve() {
 		assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(3), multi, 5));
 
 		let call = call_transfer(6, 15);
-		let call_weight = call.get_dispatch_info().weight;
+		let call_weight = call.get_dispatch_info().call_weight;
 		let hash = blake2_256(&call.encode());
 		assert_ok!(Multisig::approve_as_multi(
 			RuntimeOrigin::signed(1),
diff --git a/substrate/frame/offences/benchmarking/src/mock.rs b/substrate/frame/offences/benchmarking/src/mock.rs
index e243ad0e718..efaec49a65b 100644
--- a/substrate/frame/offences/benchmarking/src/mock.rs
+++ b/substrate/frame/offences/benchmarking/src/mock.rs
@@ -112,8 +112,6 @@ parameter_types! {
 	pub static ElectionsBounds: ElectionBounds = ElectionBoundsBuilder::default().build();
 }
 
-pub type Extrinsic = sp_runtime::testing::TestXt<RuntimeCall, ()>;
-
 pub struct OnChainSeqPhragmen;
 impl onchain::Config for OnChainSeqPhragmen {
 	type System = Test;
@@ -157,12 +155,21 @@ impl pallet_offences::Config for Test {
 	type OnOffenceHandler = Staking;
 }
 
-impl<T> frame_system::offchain::SendTransactionTypes<T> for Test
+impl<T> frame_system::offchain::CreateTransactionBase<T> for Test
 where
 	RuntimeCall: From<T>,
 {
-	type Extrinsic = Extrinsic;
-	type OverarchingCall = RuntimeCall;
+	type Extrinsic = UncheckedExtrinsic;
+	type RuntimeCall = RuntimeCall;
+}
+
+impl<T> frame_system::offchain::CreateInherent<T> for Test
+where
+	RuntimeCall: From<T>,
+{
+	fn create_inherent(call: Self::RuntimeCall) -> Self::Extrinsic {
+		UncheckedExtrinsic::new_bare(call)
+	}
 }
 
 impl crate::Config for Test {}
diff --git a/substrate/frame/proxy/src/lib.rs b/substrate/frame/proxy/src/lib.rs
index 016f2cf225e..c041880a59d 100644
--- a/substrate/frame/proxy/src/lib.rs
+++ b/substrate/frame/proxy/src/lib.rs
@@ -195,7 +195,7 @@ pub mod pallet {
 			(T::WeightInfo::proxy(T::MaxProxies::get())
 				 // AccountData for inner call origin accountdata.
 				.saturating_add(T::DbWeight::get().reads_writes(1, 1))
-				.saturating_add(di.weight),
+				.saturating_add(di.call_weight),
 			di.class)
 		})]
 		pub fn proxy(
@@ -487,7 +487,7 @@ pub mod pallet {
 			(T::WeightInfo::proxy_announced(T::MaxPending::get(), T::MaxProxies::get())
 				 // AccountData for inner call origin accountdata.
 				.saturating_add(T::DbWeight::get().reads_writes(1, 1))
-				.saturating_add(di.weight),
+				.saturating_add(di.call_weight),
 			di.class)
 		})]
 		pub fn proxy_announced(
diff --git a/substrate/frame/recovery/src/lib.rs b/substrate/frame/recovery/src/lib.rs
index 69be4df971b..f8622880538 100644
--- a/substrate/frame/recovery/src/lib.rs
+++ b/substrate/frame/recovery/src/lib.rs
@@ -378,7 +378,7 @@ pub mod pallet {
 		#[pallet::weight({
 			let dispatch_info = call.get_dispatch_info();
 			(
-				T::WeightInfo::as_recovered().saturating_add(dispatch_info.weight),
+				T::WeightInfo::as_recovered().saturating_add(dispatch_info.call_weight),
 				dispatch_info.class,
 			)})]
 		pub fn as_recovered(
diff --git a/substrate/frame/revive/src/wasm/runtime.rs b/substrate/frame/revive/src/wasm/runtime.rs
index 36cd03e9dd6..78c8b192965 100644
--- a/substrate/frame/revive/src/wasm/runtime.rs
+++ b/substrate/frame/revive/src/wasm/runtime.rs
@@ -643,7 +643,7 @@ impl<'a, E: Ext, M: ?Sized + Memory<E::T>> Runtime<'a, E, M> {
 		run: impl FnOnce(&mut Self) -> DispatchResultWithPostInfo,
 	) -> Result<ReturnErrorCode, TrapReason> {
 		use frame_support::dispatch::extract_actual_weight;
-		let charged = self.charge_gas(runtime_cost(dispatch_info.weight))?;
+		let charged = self.charge_gas(runtime_cost(dispatch_info.call_weight))?;
 		let result = run(self);
 		let actual_weight = extract_actual_weight(&result, &dispatch_info);
 		self.adjust_gas(charged, runtime_cost(actual_weight));
@@ -1835,7 +1835,7 @@ pub mod env {
 		let execute_weight =
 			<<E::T as Config>::Xcm as ExecuteController<_, _>>::WeightInfo::execute();
 		let weight = self.ext.gas_meter().gas_left().max(execute_weight);
-		let dispatch_info = DispatchInfo { weight, ..Default::default() };
+		let dispatch_info = DispatchInfo { call_weight: weight, ..Default::default() };
 
 		self.call_dispatchable::<XcmExecutionFailed>(
 			dispatch_info,
diff --git a/substrate/frame/sassafras/src/lib.rs b/substrate/frame/sassafras/src/lib.rs
index 285758afbe6..f6c409833e3 100644
--- a/substrate/frame/sassafras/src/lib.rs
+++ b/substrate/frame/sassafras/src/lib.rs
@@ -61,7 +61,7 @@ use frame_support::{
 	BoundedVec, WeakBoundedVec,
 };
 use frame_system::{
-	offchain::{SendTransactionTypes, SubmitTransaction},
+	offchain::{CreateInherent, SubmitTransaction},
 	pallet_prelude::BlockNumberFor,
 };
 use sp_consensus_sassafras::{
@@ -131,7 +131,7 @@ pub mod pallet {
 
 	/// Configuration parameters.
 	#[pallet::config]
-	pub trait Config: frame_system::Config + SendTransactionTypes<Call<Self>> {
+	pub trait Config: frame_system::Config + CreateInherent<Call<Self>> {
 		/// Amount of slots that each epoch should last.
 		#[pallet::constant]
 		type EpochLength: Get<u32>;
@@ -1020,7 +1020,8 @@ impl<T: Config> Pallet<T> {
 	pub fn submit_tickets_unsigned_extrinsic(tickets: Vec<TicketEnvelope>) -> bool {
 		let tickets = BoundedVec::truncate_from(tickets);
 		let call = Call::submit_tickets { tickets };
-		match SubmitTransaction::<T, Call<T>>::submit_unsigned_transaction(call.into()) {
+		let xt = T::create_inherent(call.into());
+		match SubmitTransaction::<T, Call<T>>::submit_transaction(xt) {
 			Ok(_) => true,
 			Err(e) => {
 				error!(target: LOG_TARGET, "Error submitting tickets {:?}", e);
diff --git a/substrate/frame/sassafras/src/mock.rs b/substrate/frame/sassafras/src/mock.rs
index d2b329e8a2b..d7e2fb63dc2 100644
--- a/substrate/frame/sassafras/src/mock.rs
+++ b/substrate/frame/sassafras/src/mock.rs
@@ -34,7 +34,7 @@ use sp_core::{
 	H256, U256,
 };
 use sp_runtime::{
-	testing::{Digest, DigestItem, Header, TestXt},
+	testing::{Digest, DigestItem, Header},
 	BuildStorage,
 };
 
@@ -48,12 +48,21 @@ impl frame_system::Config for Test {
 	type Block = frame_system::mocking::MockBlock<Test>;
 }
 
-impl<C> frame_system::offchain::SendTransactionTypes<C> for Test
+impl<C> frame_system::offchain::CreateTransactionBase<C> for Test
 where
 	RuntimeCall: From<C>,
 {
-	type OverarchingCall = RuntimeCall;
-	type Extrinsic = TestXt<RuntimeCall, ()>;
+	type RuntimeCall = RuntimeCall;
+	type Extrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>;
+}
+
+impl<C> frame_system::offchain::CreateInherent<C> for Test
+where
+	RuntimeCall: From<C>,
+{
+	fn create_inherent(call: Self::RuntimeCall) -> Self::Extrinsic {
+		frame_system::mocking::MockUncheckedExtrinsic::<Test>::new_bare(call)
+	}
 }
 
 impl pallet_sassafras::Config for Test {
diff --git a/substrate/frame/scheduler/src/lib.rs b/substrate/frame/scheduler/src/lib.rs
index 3eecf6d6f9e..468099010bf 100644
--- a/substrate/frame/scheduler/src/lib.rs
+++ b/substrate/frame/scheduler/src/lib.rs
@@ -1364,7 +1364,7 @@ impl<T: Config> Pallet<T> {
 			Some(&RawOrigin::Signed(_)) => T::WeightInfo::execute_dispatch_signed(),
 			_ => T::WeightInfo::execute_dispatch_unsigned(),
 		};
-		let call_weight = call.get_dispatch_info().weight;
+		let call_weight = call.get_dispatch_info().call_weight;
 		// We only allow a scheduled call if it cannot push the weight past the limit.
 		let max_weight = base_weight.saturating_add(call_weight);
 
diff --git a/substrate/frame/src/lib.rs b/substrate/frame/src/lib.rs
index e5fb15cdd07..fcd96b40c3c 100644
--- a/substrate/frame/src/lib.rs
+++ b/substrate/frame/src/lib.rs
@@ -291,8 +291,8 @@ pub mod runtime {
 
 		/// The block type, which should be fed into [`frame_system::Config`].
 		///
-		/// Should be parameterized with `T: frame_system::Config` and a tuple of `SignedExtension`.
-		/// When in doubt, use [`SystemSignedExtensionsOf`].
+		/// Should be parameterized with `T: frame_system::Config` and a tuple of
+		/// `TransactionExtension`. When in doubt, use [`SystemTransactionExtensionsOf`].
 		// Note that this cannot be dependent on `T` for block-number because it would lead to a
 		// circular dependency (self-referential generics).
 		pub type BlockOf<T, Extra = ()> = generic::Block<HeaderInner, ExtrinsicInner<T, Extra>>;
@@ -306,7 +306,7 @@ pub mod runtime {
 		/// Default set of signed extensions exposed from the `frame_system`.
 		///
 		/// crucially, this does NOT contain any tx-payment extension.
-		pub type SystemSignedExtensionsOf<T> = (
+		pub type SystemTransactionExtensionsOf<T> = (
 			frame_system::CheckNonZeroSender<T>,
 			frame_system::CheckSpecVersion<T>,
 			frame_system::CheckTxVersion<T>,
diff --git a/substrate/frame/sudo/src/benchmarking.rs b/substrate/frame/sudo/src/benchmarking.rs
index dee7d09c9d0..ff34cc3a700 100644
--- a/substrate/frame/sudo/src/benchmarking.rs
+++ b/substrate/frame/sudo/src/benchmarking.rs
@@ -21,14 +21,25 @@ use super::*;
 use crate::Pallet;
 use alloc::{boxed::Box, vec};
 use frame_benchmarking::v2::*;
+use frame_support::dispatch::{DispatchInfo, GetDispatchInfo};
 use frame_system::RawOrigin;
+use sp_runtime::traits::{
+	AsSystemOriginSigner, AsTransactionAuthorizedOrigin, DispatchTransaction, Dispatchable,
+};
 
 fn assert_last_event<T: Config>(generic_event: crate::Event<T>) {
 	let re: <T as Config>::RuntimeEvent = generic_event.into();
 	frame_system::Pallet::<T>::assert_last_event(re.into());
 }
 
-#[benchmarks(where <T as Config>::RuntimeCall: From<frame_system::Call<T>>)]
+#[benchmarks(where
+	T: Send + Sync,
+	<T as Config>::RuntimeCall: From<frame_system::Call<T>>,
+	<T as frame_system::Config>::RuntimeCall: Dispatchable<Info = DispatchInfo> + GetDispatchInfo,
+	<<T as frame_system::Config>::RuntimeCall as Dispatchable>::PostInfo: Default,
+	<<T as frame_system::Config>::RuntimeCall as Dispatchable>::RuntimeOrigin:
+		AsSystemOriginSigner<T::AccountId> + AsTransactionAuthorizedOrigin + Clone,
+)]
 mod benchmarks {
 	use super::*;
 
@@ -86,5 +97,26 @@ mod benchmarks {
 		assert_last_event::<T>(Event::KeyRemoved {});
 	}
 
+	#[benchmark]
+	fn check_only_sudo_account() {
+		let caller: T::AccountId = whitelisted_caller();
+		Key::<T>::put(&caller);
+
+		let call: <T as frame_system::Config>::RuntimeCall =
+			frame_system::Call::remark { remark: vec![] }.into();
+		let info = call.get_dispatch_info();
+		let ext = CheckOnlySudoAccount::<T>::new();
+
+		#[block]
+		{
+			assert!(ext
+				.test_run(RawOrigin::Signed(caller).into(), &call, &info, 0, |_| Ok(
+					Default::default()
+				))
+				.unwrap()
+				.is_ok());
+		}
+	}
+
 	impl_benchmark_test_suite!(Pallet, crate::mock::new_bench_ext(), crate::mock::Test);
 }
diff --git a/substrate/frame/sudo/src/extension.rs b/substrate/frame/sudo/src/extension.rs
index fb7eaf78948..573de45ba32 100644
--- a/substrate/frame/sudo/src/extension.rs
+++ b/substrate/frame/sudo/src/extension.rs
@@ -21,10 +21,11 @@ use core::{fmt, marker::PhantomData};
 use frame_support::{dispatch::DispatchInfo, ensure};
 use scale_info::TypeInfo;
 use sp_runtime::{
-	traits::{DispatchInfoOf, Dispatchable, SignedExtension},
+	impl_tx_ext_default,
+	traits::{AsSystemOriginSigner, DispatchInfoOf, Dispatchable, TransactionExtension},
 	transaction_validity::{
-		InvalidTransaction, TransactionPriority, TransactionValidity, TransactionValidityError,
-		UnknownTransaction, ValidTransaction,
+		InvalidTransaction, TransactionPriority, TransactionValidityError, UnknownTransaction,
+		ValidTransaction,
 	},
 };
 
@@ -59,49 +60,61 @@ impl<T: Config + Send + Sync> fmt::Debug for CheckOnlySudoAccount<T> {
 }
 
 impl<T: Config + Send + Sync> CheckOnlySudoAccount<T> {
-	/// Creates new `SignedExtension` to check sudo key.
+	/// Creates new `TransactionExtension` to check sudo key.
 	pub fn new() -> Self {
 		Self::default()
 	}
 }
 
-impl<T: Config + Send + Sync> SignedExtension for CheckOnlySudoAccount<T>
+impl<T: Config + Send + Sync> TransactionExtension<<T as frame_system::Config>::RuntimeCall>
+	for CheckOnlySudoAccount<T>
 where
-	<T as Config>::RuntimeCall: Dispatchable<Info = DispatchInfo>,
+	<T as frame_system::Config>::RuntimeCall: Dispatchable<Info = DispatchInfo>,
+	<<T as frame_system::Config>::RuntimeCall as Dispatchable>::RuntimeOrigin:
+		AsSystemOriginSigner<T::AccountId> + Clone,
 {
 	const IDENTIFIER: &'static str = "CheckOnlySudoAccount";
-	type AccountId = T::AccountId;
-	type Call = <T as Config>::RuntimeCall;
-	type AdditionalSigned = ();
+	type Implicit = ();
 	type Pre = ();
+	type Val = ();
 
-	fn additional_signed(&self) -> Result<Self::AdditionalSigned, TransactionValidityError> {
-		Ok(())
+	fn weight(
+		&self,
+		_: &<T as frame_system::Config>::RuntimeCall,
+	) -> frame_support::weights::Weight {
+		use crate::weights::WeightInfo;
+		T::WeightInfo::check_only_sudo_account()
 	}
 
 	fn validate(
 		&self,
-		who: &Self::AccountId,
-		_call: &Self::Call,
-		info: &DispatchInfoOf<Self::Call>,
+		origin: <<T as frame_system::Config>::RuntimeCall as Dispatchable>::RuntimeOrigin,
+		_call: &<T as frame_system::Config>::RuntimeCall,
+		info: &DispatchInfoOf<<T as frame_system::Config>::RuntimeCall>,
 		_len: usize,
-	) -> TransactionValidity {
+		_self_implicit: Self::Implicit,
+		_inherited_implication: &impl Encode,
+	) -> Result<
+		(
+			ValidTransaction,
+			Self::Val,
+			<<T as frame_system::Config>::RuntimeCall as Dispatchable>::RuntimeOrigin,
+		),
+		TransactionValidityError,
+	> {
+		let who = origin.as_system_origin_signer().ok_or(InvalidTransaction::BadSigner)?;
 		let sudo_key: T::AccountId = Key::<T>::get().ok_or(UnknownTransaction::CannotLookup)?;
 		ensure!(*who == sudo_key, InvalidTransaction::BadSigner);
 
-		Ok(ValidTransaction {
-			priority: info.weight.ref_time() as TransactionPriority,
-			..Default::default()
-		})
+		Ok((
+			ValidTransaction {
+				priority: info.total_weight().ref_time() as TransactionPriority,
+				..Default::default()
+			},
+			(),
+			origin,
+		))
 	}
 
-	fn pre_dispatch(
-		self,
-		who: &Self::AccountId,
-		call: &Self::Call,
-		info: &DispatchInfoOf<Self::Call>,
-		len: usize,
-	) -> Result<Self::Pre, TransactionValidityError> {
-		self.validate(who, call, info, len).map(|_| ())
-	}
+	impl_tx_ext_default!(<T as frame_system::Config>::RuntimeCall; prepare);
 }
diff --git a/substrate/frame/sudo/src/lib.rs b/substrate/frame/sudo/src/lib.rs
index 07296e90b64..66616bf801e 100644
--- a/substrate/frame/sudo/src/lib.rs
+++ b/substrate/frame/sudo/src/lib.rs
@@ -85,8 +85,8 @@
 //! meant to be used by constructing runtime calls from outside the runtime.
 //! </pre></div>
 //!
-//! This pallet also defines a [`SignedExtension`](sp_runtime::traits::SignedExtension) called
-//! [`CheckOnlySudoAccount`] to ensure that only signed transactions by the sudo account are
+//! This pallet also defines a [`TransactionExtension`](sp_runtime::traits::TransactionExtension)
+//! called [`CheckOnlySudoAccount`] to ensure that only signed transactions by the sudo account are
 //! accepted by the transaction pool. The intended use of this signed extension is to prevent other
 //! accounts from spamming the transaction pool for the initial phase of a chain, during which
 //! developers may only want a sudo account to be able to make transactions.
@@ -197,7 +197,7 @@ pub mod pallet {
 		#[pallet::weight({
 			let dispatch_info = call.get_dispatch_info();
 			(
-				T::WeightInfo::sudo().saturating_add(dispatch_info.weight),
+				T::WeightInfo::sudo().saturating_add(dispatch_info.call_weight),
 				dispatch_info.class
 			)
 		})]
@@ -262,7 +262,7 @@ pub mod pallet {
 		#[pallet::weight({
 			let dispatch_info = call.get_dispatch_info();
 			(
-				T::WeightInfo::sudo_as().saturating_add(dispatch_info.weight),
+				T::WeightInfo::sudo_as().saturating_add(dispatch_info.call_weight),
 				dispatch_info.class,
 			)
 		})]
diff --git a/substrate/frame/sudo/src/tests.rs b/substrate/frame/sudo/src/tests.rs
index 00bb86cc268..3ed3bd336f5 100644
--- a/substrate/frame/sudo/src/tests.rs
+++ b/substrate/frame/sudo/src/tests.rs
@@ -108,7 +108,7 @@ fn sudo_unchecked_weight_basics() {
 		let sudo_unchecked_weight_call =
 			SudoCall::sudo_unchecked_weight { call, weight: Weight::from_parts(1_000, 0) };
 		let info = sudo_unchecked_weight_call.get_dispatch_info();
-		assert_eq!(info.weight, Weight::from_parts(1_000, 0));
+		assert_eq!(info.call_weight, Weight::from_parts(1_000, 0));
 	});
 }
 
diff --git a/substrate/frame/sudo/src/weights.rs b/substrate/frame/sudo/src/weights.rs
index c166ab442d7..ac5557e68a6 100644
--- a/substrate/frame/sudo/src/weights.rs
+++ b/substrate/frame/sudo/src/weights.rs
@@ -55,6 +55,7 @@ pub trait WeightInfo {
 	fn sudo() -> Weight;
 	fn sudo_as() -> Weight;
 	fn remove_key() -> Weight;
+	fn check_only_sudo_account() -> Weight;
 }
 
 /// Weights for `pallet_sudo` using the Substrate node and recommended hardware.
@@ -102,6 +103,16 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 			.saturating_add(T::DbWeight::get().reads(1_u64))
 			.saturating_add(T::DbWeight::get().writes(1_u64))
 	}
+	/// Storage: `Sudo::Key` (r:1 w:0)
+	/// Proof: `Sudo::Key` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
+	fn check_only_sudo_account() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `165`
+		//  Estimated: `1517`
+		// Minimum execution time: 3_416_000 picoseconds.
+		Weight::from_parts(3_645_000, 1517)
+			.saturating_add(T::DbWeight::get().reads(1_u64))
+	}
 }
 
 // For backwards compatibility and tests.
@@ -148,4 +159,14 @@ impl WeightInfo for () {
 			.saturating_add(RocksDbWeight::get().reads(1_u64))
 			.saturating_add(RocksDbWeight::get().writes(1_u64))
 	}
+	/// Storage: `Sudo::Key` (r:1 w:0)
+	/// Proof: `Sudo::Key` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
+	fn check_only_sudo_account() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `165`
+		//  Estimated: `1517`
+		// Minimum execution time: 3_416_000 picoseconds.
+		Weight::from_parts(3_645_000, 1517)
+			.saturating_add(RocksDbWeight::get().reads(1_u64))
+	}
 }
diff --git a/substrate/frame/support/Cargo.toml b/substrate/frame/support/Cargo.toml
index 9e9741ee161..18ca4a3acda 100644
--- a/substrate/frame/support/Cargo.toml
+++ b/substrate/frame/support/Cargo.toml
@@ -113,9 +113,7 @@ try-runtime = [
 	"sp-debug-derive/force-debug",
 	"sp-runtime/try-runtime",
 ]
-experimental = [
-	"frame-support-procedural/experimental",
-]
+experimental = ["frame-support-procedural/experimental"]
 # By default some types have documentation, `no-metadata-docs` allows to reduce the documentation
 # in the metadata.
 no-metadata-docs = [
diff --git a/substrate/frame/support/procedural/src/construct_runtime/expand/inherent.rs b/substrate/frame/support/procedural/src/construct_runtime/expand/inherent.rs
index c5fe8440d21..e34c6ac5016 100644
--- a/substrate/frame/support/procedural/src/construct_runtime/expand/inherent.rs
+++ b/substrate/frame/support/procedural/src/construct_runtime/expand/inherent.rs
@@ -66,18 +66,16 @@ pub fn expand_outer_inherent(
 			fn create_extrinsics(&self) ->
 				#scrate::__private::Vec<<#block as #scrate::sp_runtime::traits::Block>::Extrinsic>
 			{
-				use #scrate::inherent::ProvideInherent;
+				use #scrate::{inherent::ProvideInherent, traits::InherentBuilder};
 
 				let mut inherents = #scrate::__private::Vec::new();
 
 				#(
 					#pallet_attrs
 					if let Some(inherent) = #pallet_names::create_inherent(self) {
-						let inherent = <#unchecked_extrinsic as #scrate::sp_runtime::traits::Extrinsic>::new(
+						let inherent = <#unchecked_extrinsic as InherentBuilder>::new_inherent(
 							inherent.into(),
-							None,
-						).expect("Runtime UncheckedExtrinsic is not Opaque, so it has to return \
-							`Some`; qed");
+						);
 
 						inherents.push(inherent);
 					}
@@ -123,7 +121,7 @@ pub fn expand_outer_inherent(
 				for xt in block.extrinsics() {
 					// Inherents are before any other extrinsics.
 					// And signed extrinsics are not inherents.
-					if #scrate::sp_runtime::traits::Extrinsic::is_signed(xt).unwrap_or(false) {
+					if !(#scrate::sp_runtime::traits::ExtrinsicLike::is_bare(xt)) {
 						break
 					}
 
@@ -161,10 +159,9 @@ pub fn expand_outer_inherent(
 					match #pallet_names::is_inherent_required(self) {
 						Ok(Some(e)) => {
 							let found = block.extrinsics().iter().any(|xt| {
-								let is_signed = #scrate::sp_runtime::traits::Extrinsic::is_signed(xt)
-									.unwrap_or(false);
+								let is_bare = #scrate::sp_runtime::traits::ExtrinsicLike::is_bare(xt);
 
-								if !is_signed {
+								if is_bare {
 									let call = <
 										#unchecked_extrinsic as ExtrinsicCall
 									>::call(xt);
@@ -209,8 +206,9 @@ pub fn expand_outer_inherent(
 				use #scrate::inherent::ProvideInherent;
 				use #scrate::traits::{IsSubType, ExtrinsicCall};
 
-				if #scrate::sp_runtime::traits::Extrinsic::is_signed(ext).unwrap_or(false) {
-					// Signed extrinsics are never inherents.
+				let is_bare = #scrate::sp_runtime::traits::ExtrinsicLike::is_bare(ext);
+				if !is_bare {
+					// Inherents must be bare extrinsics.
 					return false
 				}
 
diff --git a/substrate/frame/support/procedural/src/construct_runtime/expand/metadata.rs b/substrate/frame/support/procedural/src/construct_runtime/expand/metadata.rs
index 54eb290ca6c..c12fc20bc8b 100644
--- a/substrate/frame/support/procedural/src/construct_runtime/expand/metadata.rs
+++ b/substrate/frame/support/procedural/src/construct_runtime/expand/metadata.rs
@@ -101,16 +101,16 @@ pub fn expand_runtime_metadata(
 
 				let ty = #scrate::__private::scale_info::meta_type::<#extrinsic>();
 				let address_ty = #scrate::__private::scale_info::meta_type::<
-						<<#extrinsic as #scrate::sp_runtime::traits::Extrinsic>::SignaturePayload as #scrate::sp_runtime::traits::SignaturePayload>::SignatureAddress
+						<#extrinsic as #scrate::traits::SignedTransactionBuilder>::Address
 					>();
 				let call_ty = #scrate::__private::scale_info::meta_type::<
-					<#extrinsic as #scrate::sp_runtime::traits::Extrinsic>::Call
+						<#extrinsic as #scrate::traits::ExtrinsicCall>::Call
 					>();
 				let signature_ty = #scrate::__private::scale_info::meta_type::<
-						<<#extrinsic as #scrate::sp_runtime::traits::Extrinsic>::SignaturePayload as #scrate::sp_runtime::traits::SignaturePayload>::Signature
+						<#extrinsic as #scrate::traits::SignedTransactionBuilder>::Signature
 					>();
 				let extra_ty = #scrate::__private::scale_info::meta_type::<
-						<<#extrinsic as #scrate::sp_runtime::traits::Extrinsic>::SignaturePayload as #scrate::sp_runtime::traits::SignaturePayload>::SignatureExtra
+						<#extrinsic as #scrate::traits::SignedTransactionBuilder>::Extension
 					>();
 
 				#scrate::__private::metadata_ir::MetadataIR {
@@ -122,16 +122,20 @@ pub fn expand_runtime_metadata(
 						call_ty,
 						signature_ty,
 						extra_ty,
-						signed_extensions: <
+						extensions: <
 								<
 									#extrinsic as #scrate::sp_runtime::traits::ExtrinsicMetadata
-								>::SignedExtensions as #scrate::sp_runtime::traits::SignedExtension
+								>::TransactionExtensions
+								as
+								#scrate::sp_runtime::traits::TransactionExtension::<
+									<#runtime as #system_path::Config>::RuntimeCall
+								>
 							>::metadata()
 								.into_iter()
-								.map(|meta| #scrate::__private::metadata_ir::SignedExtensionMetadataIR {
+								.map(|meta| #scrate::__private::metadata_ir::TransactionExtensionMetadataIR {
 									identifier: meta.identifier,
 									ty: meta.ty,
-									additional_signed: meta.additional_signed,
+									implicit: meta.implicit,
 								})
 								.collect(),
 					},
diff --git a/substrate/frame/support/procedural/src/construct_runtime/expand/origin.rs b/substrate/frame/support/procedural/src/construct_runtime/expand/origin.rs
index 4a14853c04e..1c4ab436ad9 100644
--- a/substrate/frame/support/procedural/src/construct_runtime/expand/origin.rs
+++ b/substrate/frame/support/procedural/src/construct_runtime/expand/origin.rs
@@ -153,6 +153,10 @@ pub fn expand_outer_origin(
 				self.filter = #scrate::__private::Rc::new(#scrate::__private::Box::new(filter));
 			}
 
+			fn set_caller(&mut self, caller: OriginCaller) {
+				self.caller = caller;
+			}
+
 			fn set_caller_from(&mut self, other: impl Into<Self>) {
 				self.caller = other.into().caller;
 			}
@@ -301,6 +305,22 @@ pub fn expand_outer_origin(
 			}
 		}
 
+		impl #scrate::__private::AsSystemOriginSigner<<#runtime as #system_path::Config>::AccountId> for RuntimeOrigin {
+			fn as_system_origin_signer(&self) -> Option<&<#runtime as #system_path::Config>::AccountId> {
+				if let OriginCaller::system(#system_path::Origin::<#runtime>::Signed(ref signed)) = &self.caller {
+					Some(signed)
+				} else {
+					None
+				}
+			}
+		}
+
+		impl #scrate::__private::AsTransactionAuthorizedOrigin for RuntimeOrigin {
+			fn is_transaction_authorized(&self) -> bool {
+				!matches!(&self.caller, OriginCaller::system(#system_path::Origin::<#runtime>::None))
+			}
+		}
+
 		#pallet_conversions
 	})
 }
diff --git a/substrate/frame/support/procedural/src/pallet/expand/call.rs b/substrate/frame/support/procedural/src/pallet/expand/call.rs
index 206ffc1159f..87fb4b8967e 100644
--- a/substrate/frame/support/procedural/src/pallet/expand/call.rs
+++ b/substrate/frame/support/procedural/src/pallet/expand/call.rs
@@ -372,7 +372,8 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream {
 							>::pays_fee(&__pallet_base_weight, ( #( #args_name, )* ));
 
 							#frame_support::dispatch::DispatchInfo {
-								weight: __pallet_weight,
+								call_weight: __pallet_weight,
+								extension_weight: Default::default(),
 								class: __pallet_class,
 								pays_fee: __pallet_pays_fee,
 							}
diff --git a/substrate/frame/support/src/dispatch.rs b/substrate/frame/support/src/dispatch.rs
index 351ba3a15ef..3678f958980 100644
--- a/substrate/frame/support/src/dispatch.rs
+++ b/substrate/frame/support/src/dispatch.rs
@@ -26,7 +26,9 @@ use scale_info::TypeInfo;
 use serde::{Deserialize, Serialize};
 use sp_runtime::{
 	generic::{CheckedExtrinsic, UncheckedExtrinsic},
-	traits::SignedExtension,
+	traits::{
+		Dispatchable, ExtensionPostDispatchWeightHandler, RefundWeight, TransactionExtension,
+	},
 	DispatchError, RuntimeDebug,
 };
 use sp_weights::Weight;
@@ -236,14 +238,23 @@ impl<'a> OneOrMany<DispatchClass> for &'a [DispatchClass] {
 /// A bundle of static information collected from the `#[pallet::weight]` attributes.
 #[derive(Clone, Copy, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode, TypeInfo)]
 pub struct DispatchInfo {
-	/// Weight of this transaction.
-	pub weight: Weight,
+	/// Weight of this transaction's call.
+	pub call_weight: Weight,
+	/// Weight of this transaction's extension.
+	pub extension_weight: Weight,
 	/// Class of this transaction.
 	pub class: DispatchClass,
 	/// Does this transaction pay fees.
 	pub pays_fee: Pays,
 }
 
+impl DispatchInfo {
+	/// Returns the weight used by this extrinsic's extension and call when applied.
+	pub fn total_weight(&self) -> Weight {
+		self.call_weight.saturating_add(self.extension_weight)
+	}
+}
+
 /// A `Dispatchable` function (aka transaction) that can carry some static information along with
 /// it, using the `#[pallet::weight]` attribute.
 pub trait GetDispatchInfo {
@@ -268,7 +279,8 @@ pub fn extract_actual_weight(result: &DispatchResultWithPostInfo, info: &Dispatc
 	.calc_actual_weight(info)
 }
 
-/// Extract the actual pays_fee from a dispatch result if any or fall back to the default weight.
+/// Extract the actual pays_fee from a dispatch result if any or fall back to the default
+/// weight.
 pub fn extract_actual_pays_fee(result: &DispatchResultWithPostInfo, info: &DispatchInfo) -> Pays {
 	match result {
 		Ok(post_info) => post_info,
@@ -290,15 +302,15 @@ pub struct PostDispatchInfo {
 impl PostDispatchInfo {
 	/// Calculate how much (if any) weight was not used by the `Dispatchable`.
 	pub fn calc_unspent(&self, info: &DispatchInfo) -> Weight {
-		info.weight - self.calc_actual_weight(info)
+		info.total_weight() - self.calc_actual_weight(info)
 	}
 
 	/// Calculate how much weight was actually spent by the `Dispatchable`.
 	pub fn calc_actual_weight(&self, info: &DispatchInfo) -> Weight {
 		if let Some(actual_weight) = self.actual_weight {
-			actual_weight.min(info.weight)
+			actual_weight.min(info.total_weight())
 		} else {
-			info.weight
+			info.total_weight()
 		}
 	}
 
@@ -368,39 +380,28 @@ where
 }
 
 /// Implementation for unchecked extrinsic.
-impl<Address, Call, Signature, Extra> GetDispatchInfo
-	for UncheckedExtrinsic<Address, Call, Signature, Extra>
+impl<Address, Call: Dispatchable, Signature, Extension: TransactionExtension<Call>> GetDispatchInfo
+	for UncheckedExtrinsic<Address, Call, Signature, Extension>
 where
-	Call: GetDispatchInfo,
-	Extra: SignedExtension,
+	Call: GetDispatchInfo + Dispatchable,
 {
 	fn get_dispatch_info(&self) -> DispatchInfo {
-		self.function.get_dispatch_info()
+		let mut info = self.function.get_dispatch_info();
+		info.extension_weight = self.extension_weight();
+		info
 	}
 }
 
 /// Implementation for checked extrinsic.
-impl<AccountId, Call, Extra> GetDispatchInfo for CheckedExtrinsic<AccountId, Call, Extra>
+impl<AccountId, Call: Dispatchable, Extension: TransactionExtension<Call>> GetDispatchInfo
+	for CheckedExtrinsic<AccountId, Call, Extension>
 where
 	Call: GetDispatchInfo,
 {
 	fn get_dispatch_info(&self) -> DispatchInfo {
-		self.function.get_dispatch_info()
-	}
-}
-
-/// Implementation for test extrinsic.
-#[cfg(feature = "std")]
-impl<Call: Encode + GetDispatchInfo, Extra: Encode> GetDispatchInfo
-	for sp_runtime::testing::TestXt<Call, Extra>
-{
-	fn get_dispatch_info(&self) -> DispatchInfo {
-		// for testing: weight == size.
-		DispatchInfo {
-			weight: Weight::from_parts(self.encode().len() as _, 0),
-			pays_fee: Pays::Yes,
-			class: self.call.get_dispatch_info().class,
-		}
+		let mut info = self.function.get_dispatch_info();
+		info.extension_weight = self.extension_weight();
+		info
 	}
 }
 
@@ -579,6 +580,28 @@ impl<T> ClassifyDispatch<T> for (Weight, DispatchClass, Pays) {
 	}
 }
 
+impl RefundWeight for PostDispatchInfo {
+	fn refund(&mut self, weight: Weight) {
+		if let Some(actual_weight) = self.actual_weight.as_mut() {
+			actual_weight.saturating_reduce(weight);
+		}
+	}
+}
+
+impl ExtensionPostDispatchWeightHandler<DispatchInfo> for PostDispatchInfo {
+	fn set_extension_weight(&mut self, info: &DispatchInfo) {
+		let actual_weight = self
+			.actual_weight
+			.unwrap_or(info.call_weight)
+			.saturating_add(info.extension_weight);
+		self.actual_weight = Some(actual_weight);
+	}
+}
+
+impl ExtensionPostDispatchWeightHandler<()> for PostDispatchInfo {
+	fn set_extension_weight(&mut self, _: &()) {}
+}
+
 // TODO: Eventually remove these
 
 impl<T> ClassifyDispatch<T> for u64 {
@@ -752,6 +775,19 @@ mod weight_tests {
 			pub fn f21(_origin: OriginFor<T>) -> DispatchResult {
 				unimplemented!();
 			}
+
+			#[pallet::weight(1000)]
+			pub fn f99(_origin: OriginFor<T>) -> DispatchResult {
+				Ok(())
+			}
+
+			#[pallet::weight(1000)]
+			pub fn f100(_origin: OriginFor<T>) -> DispatchResultWithPostInfo {
+				Ok(crate::dispatch::PostDispatchInfo {
+					actual_weight: Some(Weight::from_parts(500, 0)),
+					pays_fee: Pays::Yes,
+				})
+			}
 		}
 
 		pub mod pallet_prelude {
@@ -801,57 +837,61 @@ mod weight_tests {
 	fn weights_are_correct() {
 		// #[pallet::weight(1000)]
 		let info = Call::<Runtime>::f00 {}.get_dispatch_info();
-		assert_eq!(info.weight, Weight::from_parts(1000, 0));
+		assert_eq!(info.total_weight(), Weight::from_parts(1000, 0));
 		assert_eq!(info.class, DispatchClass::Normal);
 		assert_eq!(info.pays_fee, Pays::Yes);
 
 		// #[pallet::weight((1000, DispatchClass::Mandatory))]
 		let info = Call::<Runtime>::f01 {}.get_dispatch_info();
-		assert_eq!(info.weight, Weight::from_parts(1000, 0));
+		assert_eq!(info.total_weight(), Weight::from_parts(1000, 0));
 		assert_eq!(info.class, DispatchClass::Mandatory);
 		assert_eq!(info.pays_fee, Pays::Yes);
 
 		// #[pallet::weight((1000, Pays::No))]
 		let info = Call::<Runtime>::f02 {}.get_dispatch_info();
-		assert_eq!(info.weight, Weight::from_parts(1000, 0));
+		assert_eq!(info.total_weight(), Weight::from_parts(1000, 0));
 		assert_eq!(info.class, DispatchClass::Normal);
 		assert_eq!(info.pays_fee, Pays::No);
 
 		// #[pallet::weight((1000, DispatchClass::Operational, Pays::No))]
 		let info = Call::<Runtime>::f03 {}.get_dispatch_info();
-		assert_eq!(info.weight, Weight::from_parts(1000, 0));
+		assert_eq!(info.total_weight(), Weight::from_parts(1000, 0));
 		assert_eq!(info.class, DispatchClass::Operational);
 		assert_eq!(info.pays_fee, Pays::No);
 
 		// #[pallet::weight(((_a * 10 + _eb * 1) as u64, DispatchClass::Normal, Pays::Yes))]
 		let info = Call::<Runtime>::f11 { a: 13, eb: 20 }.get_dispatch_info();
-		assert_eq!(info.weight, Weight::from_parts(150, 0)); // 13*10 + 20
+		assert_eq!(info.total_weight(), Weight::from_parts(150, 0)); // 13*10 + 20
 		assert_eq!(info.class, DispatchClass::Normal);
 		assert_eq!(info.pays_fee, Pays::Yes);
 
 		// #[pallet::weight((0, DispatchClass::Operational, Pays::Yes))]
 		let info = Call::<Runtime>::f12 { a: 10, eb: 20 }.get_dispatch_info();
-		assert_eq!(info.weight, Weight::zero());
+		assert_eq!(info.total_weight(), Weight::zero());
 		assert_eq!(info.class, DispatchClass::Operational);
 		assert_eq!(info.pays_fee, Pays::Yes);
 
 		// #[pallet::weight(T::DbWeight::get().reads(3) + T::DbWeight::get().writes(2) +
 		// Weight::from_all(10_000))]
 		let info = Call::<Runtime>::f20 {}.get_dispatch_info();
-		assert_eq!(info.weight, Weight::from_parts(12300, 10000)); // 100*3 + 1000*2 + 10_1000
+		assert_eq!(info.total_weight(), Weight::from_parts(12300, 10000)); // 100*3 + 1000*2 + 10_1000
 		assert_eq!(info.class, DispatchClass::Normal);
 		assert_eq!(info.pays_fee, Pays::Yes);
 
 		// #[pallet::weight(T::DbWeight::get().reads_writes(6, 5) + Weight::from_all(40_000))]
 		let info = Call::<Runtime>::f21 {}.get_dispatch_info();
-		assert_eq!(info.weight, Weight::from_parts(45600, 40000)); // 100*6 + 1000*5 + 40_1000
+		assert_eq!(info.total_weight(), Weight::from_parts(45600, 40000)); // 100*6 + 1000*5 + 40_1000
 		assert_eq!(info.class, DispatchClass::Normal);
 		assert_eq!(info.pays_fee, Pays::Yes);
 	}
 
 	#[test]
 	fn extract_actual_weight_works() {
-		let pre = DispatchInfo { weight: Weight::from_parts(1000, 0), ..Default::default() };
+		let pre = DispatchInfo {
+			call_weight: Weight::from_parts(1000, 0),
+			extension_weight: Weight::zero(),
+			..Default::default()
+		};
 		assert_eq!(
 			extract_actual_weight(&Ok(from_actual_ref_time(Some(7))), &pre),
 			Weight::from_parts(7, 0)
@@ -871,7 +911,11 @@ mod weight_tests {
 
 	#[test]
 	fn extract_actual_weight_caps_at_pre_weight() {
-		let pre = DispatchInfo { weight: Weight::from_parts(1000, 0), ..Default::default() };
+		let pre = DispatchInfo {
+			call_weight: Weight::from_parts(1000, 0),
+			extension_weight: Weight::zero(),
+			..Default::default()
+		};
 		assert_eq!(
 			extract_actual_weight(&Ok(from_actual_ref_time(Some(1250))), &pre),
 			Weight::from_parts(1000, 0)
@@ -887,7 +931,11 @@ mod weight_tests {
 
 	#[test]
 	fn extract_actual_pays_fee_works() {
-		let pre = DispatchInfo { weight: Weight::from_parts(1000, 0), ..Default::default() };
+		let pre = DispatchInfo {
+			call_weight: Weight::from_parts(1000, 0),
+			extension_weight: Weight::zero(),
+			..Default::default()
+		};
 		assert_eq!(extract_actual_pays_fee(&Ok(from_actual_ref_time(Some(7))), &pre), Pays::Yes);
 		assert_eq!(
 			extract_actual_pays_fee(&Ok(from_actual_ref_time(Some(1000)).into()), &pre),
@@ -920,7 +968,8 @@ mod weight_tests {
 		);
 
 		let pre = DispatchInfo {
-			weight: Weight::from_parts(1000, 0),
+			call_weight: Weight::from_parts(1000, 0),
+			extension_weight: Weight::zero(),
 			pays_fee: Pays::No,
 			..Default::default()
 		};
@@ -931,6 +980,26 @@ mod weight_tests {
 			Pays::No
 		);
 	}
+
+	#[test]
+	fn weight_accrue_works() {
+		let mut post_dispatch = PostDispatchInfo {
+			actual_weight: Some(Weight::from_parts(1100, 25)),
+			pays_fee: Pays::Yes,
+		};
+		post_dispatch.refund(Weight::from_parts(100, 15));
+		assert_eq!(
+			post_dispatch,
+			PostDispatchInfo {
+				actual_weight: Some(Weight::from_parts(1000, 10)),
+				pays_fee: Pays::Yes
+			}
+		);
+
+		let mut post_dispatch = PostDispatchInfo { actual_weight: None, pays_fee: Pays::Yes };
+		post_dispatch.refund(Weight::from_parts(100, 15));
+		assert_eq!(post_dispatch, PostDispatchInfo { actual_weight: None, pays_fee: Pays::Yes });
+	}
 }
 
 #[cfg(test)]
@@ -1107,3 +1176,407 @@ mod per_dispatch_class_tests {
 		);
 	}
 }
+
+#[cfg(test)]
+mod test_extensions {
+	use codec::{Decode, Encode};
+	use scale_info::TypeInfo;
+	use sp_runtime::{
+		impl_tx_ext_default,
+		traits::{
+			DispatchInfoOf, DispatchOriginOf, Dispatchable, PostDispatchInfoOf,
+			TransactionExtension,
+		},
+		transaction_validity::TransactionValidityError,
+	};
+	use sp_weights::Weight;
+
+	use super::{DispatchResult, PostDispatchInfo};
+
+	/// Test extension that refunds half its cost if the preset inner flag is set.
+	#[derive(Clone, Eq, PartialEq, Debug, Encode, Decode, TypeInfo)]
+	pub struct HalfCostIf(pub bool);
+
+	impl<RuntimeCall: Dispatchable> TransactionExtension<RuntimeCall> for HalfCostIf {
+		const IDENTIFIER: &'static str = "HalfCostIf";
+		type Implicit = ();
+		type Val = ();
+		type Pre = bool;
+
+		fn weight(&self, _: &RuntimeCall) -> sp_weights::Weight {
+			Weight::from_parts(100, 0)
+		}
+
+		fn prepare(
+			self,
+			_val: Self::Val,
+			_origin: &DispatchOriginOf<RuntimeCall>,
+			_call: &RuntimeCall,
+			_info: &DispatchInfoOf<RuntimeCall>,
+			_len: usize,
+		) -> Result<Self::Pre, TransactionValidityError> {
+			Ok(self.0)
+		}
+
+		fn post_dispatch_details(
+			pre: Self::Pre,
+			_info: &DispatchInfoOf<RuntimeCall>,
+			_post_info: &PostDispatchInfoOf<RuntimeCall>,
+			_len: usize,
+			_result: &DispatchResult,
+		) -> Result<Weight, TransactionValidityError> {
+			if pre {
+				Ok(Weight::from_parts(50, 0))
+			} else {
+				Ok(Weight::zero())
+			}
+		}
+		impl_tx_ext_default!(RuntimeCall; validate);
+	}
+
+	/// Test extension that refunds its cost if the actual post dispatch weight up until this point
+	/// in the extension pipeline is less than the preset inner `ref_time` amount.
+	#[derive(Clone, Eq, PartialEq, Debug, Encode, Decode, TypeInfo)]
+	pub struct FreeIfUnder(pub u64);
+
+	impl<RuntimeCall: Dispatchable> TransactionExtension<RuntimeCall> for FreeIfUnder
+	where
+		RuntimeCall: Dispatchable<PostInfo = PostDispatchInfo>,
+	{
+		const IDENTIFIER: &'static str = "FreeIfUnder";
+		type Implicit = ();
+		type Val = ();
+		type Pre = u64;
+
+		fn weight(&self, _: &RuntimeCall) -> sp_weights::Weight {
+			Weight::from_parts(200, 0)
+		}
+
+		fn prepare(
+			self,
+			_val: Self::Val,
+			_origin: &DispatchOriginOf<RuntimeCall>,
+			_call: &RuntimeCall,
+			_info: &DispatchInfoOf<RuntimeCall>,
+			_len: usize,
+		) -> Result<Self::Pre, TransactionValidityError> {
+			Ok(self.0)
+		}
+
+		fn post_dispatch_details(
+			pre: Self::Pre,
+			_info: &DispatchInfoOf<RuntimeCall>,
+			post_info: &PostDispatchInfoOf<RuntimeCall>,
+			_len: usize,
+			_result: &DispatchResult,
+		) -> Result<Weight, TransactionValidityError> {
+			if let Some(actual) = post_info.actual_weight {
+				if pre > actual.ref_time() {
+					return Ok(Weight::from_parts(200, 0));
+				}
+			}
+			Ok(Weight::zero())
+		}
+		impl_tx_ext_default!(RuntimeCall; validate);
+	}
+
+	/// Test extension that sets its actual post dispatch `ref_time` weight to the preset inner
+	/// amount.
+	#[derive(Clone, Eq, PartialEq, Debug, Encode, Decode, TypeInfo)]
+	pub struct ActualWeightIs(pub u64);
+
+	impl<RuntimeCall: Dispatchable> TransactionExtension<RuntimeCall> for ActualWeightIs {
+		const IDENTIFIER: &'static str = "ActualWeightIs";
+		type Implicit = ();
+		type Val = ();
+		type Pre = u64;
+
+		fn weight(&self, _: &RuntimeCall) -> sp_weights::Weight {
+			Weight::from_parts(300, 0)
+		}
+
+		fn prepare(
+			self,
+			_val: Self::Val,
+			_origin: &DispatchOriginOf<RuntimeCall>,
+			_call: &RuntimeCall,
+			_info: &DispatchInfoOf<RuntimeCall>,
+			_len: usize,
+		) -> Result<Self::Pre, TransactionValidityError> {
+			Ok(self.0)
+		}
+
+		fn post_dispatch_details(
+			pre: Self::Pre,
+			_info: &DispatchInfoOf<RuntimeCall>,
+			_post_info: &PostDispatchInfoOf<RuntimeCall>,
+			_len: usize,
+			_result: &DispatchResult,
+		) -> Result<Weight, TransactionValidityError> {
+			Ok(Weight::from_parts(300u64.saturating_sub(pre), 0))
+		}
+		impl_tx_ext_default!(RuntimeCall; validate);
+	}
+}
+
+#[cfg(test)]
+// Do not complain about unused `dispatch` and `dispatch_aux`.
+#[allow(dead_code)]
+mod extension_weight_tests {
+	use crate::assert_ok;
+
+	use super::*;
+	use sp_core::parameter_types;
+	use sp_runtime::{
+		generic::{self, ExtrinsicFormat},
+		traits::{Applyable, BlakeTwo256, DispatchTransaction, TransactionExtension},
+	};
+	use sp_weights::RuntimeDbWeight;
+	use test_extensions::{ActualWeightIs, FreeIfUnder, HalfCostIf};
+
+	use super::weight_tests::frame_system;
+	use frame_support::construct_runtime;
+
+	pub type TxExtension = (HalfCostIf, FreeIfUnder, ActualWeightIs);
+	pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<u64, RuntimeCall, (), TxExtension>;
+	pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
+	pub type Block = generic::Block<Header, UncheckedExtrinsic>;
+	pub type AccountId = u64;
+	pub type Balance = u32;
+	pub type BlockNumber = u32;
+
+	construct_runtime!(
+		pub enum ExtRuntime {
+			System: frame_system,
+		}
+	);
+
+	impl frame_system::Config for ExtRuntime {
+		type Block = Block;
+		type AccountId = AccountId;
+		type Balance = Balance;
+		type BaseCallFilter = crate::traits::Everything;
+		type RuntimeOrigin = RuntimeOrigin;
+		type RuntimeCall = RuntimeCall;
+		type RuntimeTask = RuntimeTask;
+		type DbWeight = DbWeight;
+		type PalletInfo = PalletInfo;
+	}
+
+	parameter_types! {
+		pub const DbWeight: RuntimeDbWeight = RuntimeDbWeight {
+			read: 100,
+			write: 1000,
+		};
+	}
+
+	pub struct ExtBuilder {}
+
+	impl Default for ExtBuilder {
+		fn default() -> Self {
+			Self {}
+		}
+	}
+
+	impl ExtBuilder {
+		pub fn build(self) -> sp_io::TestExternalities {
+			let mut ext = sp_io::TestExternalities::new(Default::default());
+			ext.execute_with(|| {});
+			ext
+		}
+
+		pub fn build_and_execute(self, test: impl FnOnce() -> ()) {
+			self.build().execute_with(|| {
+				test();
+			})
+		}
+	}
+
+	#[test]
+	fn no_post_dispatch_with_no_refund() {
+		ExtBuilder::default().build_and_execute(|| {
+			let call = RuntimeCall::System(frame_system::Call::<ExtRuntime>::f99 {});
+			let ext: TxExtension = (HalfCostIf(false), FreeIfUnder(1500), ActualWeightIs(0));
+			let uxt = UncheckedExtrinsic::new_signed(call.clone(), 0, (), ext.clone());
+			assert_eq!(uxt.extension_weight(), Weight::from_parts(600, 0));
+
+			let mut info = call.get_dispatch_info();
+			assert_eq!(info.total_weight(), Weight::from_parts(1000, 0));
+			info.extension_weight = ext.weight(&call);
+			let (pre, _) = ext.validate_and_prepare(Some(0).into(), &call, &info, 0).unwrap();
+			let res = call.dispatch(Some(0).into());
+			let mut post_info = res.unwrap();
+			assert!(post_info.actual_weight.is_none());
+			assert_ok!(<TxExtension as TransactionExtension<RuntimeCall>>::post_dispatch(
+				pre,
+				&info,
+				&mut post_info,
+				0,
+				&Ok(()),
+			));
+			assert!(post_info.actual_weight.is_none());
+		});
+	}
+
+	#[test]
+	fn no_post_dispatch_refunds_when_dispatched() {
+		ExtBuilder::default().build_and_execute(|| {
+			let call = RuntimeCall::System(frame_system::Call::<ExtRuntime>::f99 {});
+			let ext: TxExtension = (HalfCostIf(true), FreeIfUnder(100), ActualWeightIs(0));
+			let uxt = UncheckedExtrinsic::new_signed(call.clone(), 0, (), ext.clone());
+			assert_eq!(uxt.extension_weight(), Weight::from_parts(600, 0));
+
+			let mut info = call.get_dispatch_info();
+			assert_eq!(info.total_weight(), Weight::from_parts(1000, 0));
+			info.extension_weight = ext.weight(&call);
+			let post_info =
+				ext.dispatch_transaction(Some(0).into(), call, &info, 0).unwrap().unwrap();
+			// 1000 call weight + 50 + 200 + 0
+			assert_eq!(post_info.actual_weight, Some(Weight::from_parts(1250, 0)));
+		});
+	}
+
+	#[test]
+	fn post_dispatch_with_refunds() {
+		ExtBuilder::default().build_and_execute(|| {
+			let call = RuntimeCall::System(frame_system::Call::<ExtRuntime>::f100 {});
+			// First testcase
+			let ext: TxExtension = (HalfCostIf(false), FreeIfUnder(2000), ActualWeightIs(0));
+			let uxt = UncheckedExtrinsic::new_signed(call.clone(), 0, (), ext.clone());
+			assert_eq!(uxt.extension_weight(), Weight::from_parts(600, 0));
+
+			let mut info = call.get_dispatch_info();
+			assert_eq!(info.call_weight, Weight::from_parts(1000, 0));
+			info.extension_weight = ext.weight(&call);
+			assert_eq!(info.total_weight(), Weight::from_parts(1600, 0));
+			let (pre, _) = ext.validate_and_prepare(Some(0).into(), &call, &info, 0).unwrap();
+			let res = call.clone().dispatch(Some(0).into());
+			let mut post_info = res.unwrap();
+			// 500 actual call weight
+			assert_eq!(post_info.actual_weight, Some(Weight::from_parts(500, 0)));
+			// add the 600 worst case extension weight
+			post_info.set_extension_weight(&info);
+			// extension weight should be refunded
+			assert_ok!(<TxExtension as TransactionExtension<RuntimeCall>>::post_dispatch(
+				pre,
+				&info,
+				&mut post_info,
+				0,
+				&Ok(()),
+			));
+			// 500 actual call weight + 100 + 0 + 0
+			assert_eq!(post_info.actual_weight, Some(Weight::from_parts(600, 0)));
+
+			// Second testcase
+			let ext: TxExtension = (HalfCostIf(false), FreeIfUnder(1100), ActualWeightIs(200));
+			let (pre, _) = ext.validate_and_prepare(Some(0).into(), &call, &info, 0).unwrap();
+			let res = call.clone().dispatch(Some(0).into());
+			let mut post_info = res.unwrap();
+			// 500 actual call weight
+			assert_eq!(post_info.actual_weight, Some(Weight::from_parts(500, 0)));
+			// add the 600 worst case extension weight
+			post_info.set_extension_weight(&info);
+			// extension weight should be refunded
+			assert_ok!(<TxExtension as TransactionExtension<RuntimeCall>>::post_dispatch(
+				pre,
+				&info,
+				&mut post_info,
+				0,
+				&Ok(()),
+			));
+			// 500 actual call weight + 100 + 200 + 200
+			assert_eq!(post_info.actual_weight, Some(Weight::from_parts(1000, 0)));
+
+			// Third testcase
+			let ext: TxExtension = (HalfCostIf(true), FreeIfUnder(1060), ActualWeightIs(200));
+			let (pre, _) = ext.validate_and_prepare(Some(0).into(), &call, &info, 0).unwrap();
+			let res = call.clone().dispatch(Some(0).into());
+			let mut post_info = res.unwrap();
+			// 500 actual call weight
+			assert_eq!(post_info.actual_weight, Some(Weight::from_parts(500, 0)));
+			// add the 600 worst case extension weight
+			post_info.set_extension_weight(&info);
+			// extension weight should be refunded
+			assert_ok!(<TxExtension as TransactionExtension<RuntimeCall>>::post_dispatch(
+				pre,
+				&info,
+				&mut post_info,
+				0,
+				&Ok(()),
+			));
+			// 500 actual call weight + 50 + 0 + 200
+			assert_eq!(post_info.actual_weight, Some(Weight::from_parts(750, 0)));
+
+			// Fourth testcase
+			let ext: TxExtension = (HalfCostIf(false), FreeIfUnder(100), ActualWeightIs(300));
+			let (pre, _) = ext.validate_and_prepare(Some(0).into(), &call, &info, 0).unwrap();
+			let res = call.clone().dispatch(Some(0).into());
+			let mut post_info = res.unwrap();
+			// 500 actual call weight
+			assert_eq!(post_info.actual_weight, Some(Weight::from_parts(500, 0)));
+			// add the 600 worst case extension weight
+			post_info.set_extension_weight(&info);
+			// extension weight should be refunded
+			assert_ok!(<TxExtension as TransactionExtension<RuntimeCall>>::post_dispatch(
+				pre,
+				&info,
+				&mut post_info,
+				0,
+				&Ok(()),
+			));
+			// 500 actual call weight + 100 + 200 + 300
+			assert_eq!(post_info.actual_weight, Some(Weight::from_parts(1100, 0)));
+		});
+	}
+
+	#[test]
+	fn checked_extrinsic_apply() {
+		ExtBuilder::default().build_and_execute(|| {
+			let call = RuntimeCall::System(frame_system::Call::<ExtRuntime>::f100 {});
+			// First testcase
+			let ext: TxExtension = (HalfCostIf(false), FreeIfUnder(2000), ActualWeightIs(0));
+			let xt = CheckedExtrinsic {
+				format: ExtrinsicFormat::Signed(0, ext.clone()),
+				function: call.clone(),
+			};
+			assert_eq!(xt.extension_weight(), Weight::from_parts(600, 0));
+			let mut info = call.get_dispatch_info();
+			assert_eq!(info.call_weight, Weight::from_parts(1000, 0));
+			info.extension_weight = ext.weight(&call);
+			assert_eq!(info.total_weight(), Weight::from_parts(1600, 0));
+			let post_info = xt.apply::<ExtRuntime>(&info, 0).unwrap().unwrap();
+			// 500 actual call weight + 100 + 0 + 0
+			assert_eq!(post_info.actual_weight, Some(Weight::from_parts(600, 0)));
+
+			// Second testcase
+			let ext: TxExtension = (HalfCostIf(false), FreeIfUnder(1100), ActualWeightIs(200));
+			let xt = CheckedExtrinsic {
+				format: ExtrinsicFormat::Signed(0, ext),
+				function: call.clone(),
+			};
+			let post_info = xt.apply::<ExtRuntime>(&info, 0).unwrap().unwrap();
+			// 500 actual call weight + 100 + 200 + 200
+			assert_eq!(post_info.actual_weight, Some(Weight::from_parts(1000, 0)));
+
+			// Third testcase
+			let ext: TxExtension = (HalfCostIf(true), FreeIfUnder(1060), ActualWeightIs(200));
+			let xt = CheckedExtrinsic {
+				format: ExtrinsicFormat::Signed(0, ext),
+				function: call.clone(),
+			};
+			let post_info = xt.apply::<ExtRuntime>(&info, 0).unwrap().unwrap();
+			// 500 actual call weight + 50 + 0 + 200
+			assert_eq!(post_info.actual_weight, Some(Weight::from_parts(750, 0)));
+
+			// Fourth testcase
+			let ext: TxExtension = (HalfCostIf(false), FreeIfUnder(100), ActualWeightIs(300));
+			let xt = CheckedExtrinsic {
+				format: ExtrinsicFormat::Signed(0, ext),
+				function: call.clone(),
+			};
+			let post_info = xt.apply::<ExtRuntime>(&info, 0).unwrap().unwrap();
+			// 500 actual call weight + 100 + 200 + 300
+			assert_eq!(post_info.actual_weight, Some(Weight::from_parts(1100, 0)));
+		});
+	}
+}
diff --git a/substrate/frame/support/src/lib.rs b/substrate/frame/support/src/lib.rs
index 1f2ec71b191..cc805d72485 100644
--- a/substrate/frame/support/src/lib.rs
+++ b/substrate/frame/support/src/lib.rs
@@ -63,7 +63,8 @@ pub mod __private {
 	#[cfg(feature = "std")]
 	pub use sp_runtime::{bounded_btree_map, bounded_vec};
 	pub use sp_runtime::{
-		traits::Dispatchable, DispatchError, RuntimeDebug, StateVersion, TransactionOutcome,
+		traits::{AsSystemOriginSigner, AsTransactionAuthorizedOrigin, Dispatchable},
+		DispatchError, RuntimeDebug, StateVersion, TransactionOutcome,
 	};
 	#[cfg(feature = "std")]
 	pub use sp_state_machine::BasicExternalities;
@@ -1695,8 +1696,8 @@ pub mod pallet_macros {
 	/// [`ValidateUnsigned`](frame_support::pallet_prelude::ValidateUnsigned) for
 	/// type `Pallet<T>`, and some optional where clause.
 	///
-	/// NOTE: There is also the [`sp_runtime::traits::SignedExtension`] trait that can be used
-	/// to add some specific logic for transaction validation.
+	/// NOTE: There is also the [`sp_runtime::traits::TransactionExtension`] trait that can be
+	/// used to add some specific logic for transaction validation.
 	///
 	/// ## Macro expansion
 	///
diff --git a/substrate/frame/support/src/traits.rs b/substrate/frame/support/src/traits.rs
index 631225b9a32..635036d488d 100644
--- a/substrate/frame/support/src/traits.rs
+++ b/substrate/frame/support/src/traits.rs
@@ -60,10 +60,10 @@ pub use misc::{
 	AccountTouch, Backing, ConstBool, ConstI128, ConstI16, ConstI32, ConstI64, ConstI8, ConstU128,
 	ConstU16, ConstU32, ConstU64, ConstU8, DefensiveMax, DefensiveMin, DefensiveSaturating,
 	DefensiveTruncateFrom, EnsureInherentsAreFirst, EqualPrivilegeOnly, EstimateCallFee,
-	ExecuteBlock, ExtrinsicCall, Get, GetBacking, GetDefault, HandleLifetime, IsInherent,
-	IsSubType, IsType, Len, OffchainWorker, OnKilledAccount, OnNewAccount, PrivilegeCmp,
-	SameOrOther, Time, TryCollect, TryDrop, TypedGet, UnixTime, VariantCount, VariantCountOf,
-	WrapperKeepOpaque, WrapperOpaque,
+	ExecuteBlock, ExtrinsicCall, Get, GetBacking, GetDefault, HandleLifetime, InherentBuilder,
+	IsInherent, IsSubType, IsType, Len, OffchainWorker, OnKilledAccount, OnNewAccount,
+	PrivilegeCmp, SameOrOther, SignedTransactionBuilder, Time, TryCollect, TryDrop, TypedGet,
+	UnixTime, VariantCount, VariantCountOf, WrapperKeepOpaque, WrapperOpaque,
 };
 #[allow(deprecated)]
 pub use misc::{PreimageProvider, PreimageRecipient};
diff --git a/substrate/frame/support/src/traits/dispatch.rs b/substrate/frame/support/src/traits/dispatch.rs
index 7dc8d3e4f5a..dbdf0885dd2 100644
--- a/substrate/frame/support/src/traits/dispatch.rs
+++ b/substrate/frame/support/src/traits/dispatch.rs
@@ -482,7 +482,7 @@ pub trait OriginTrait: Sized {
 	type Call;
 
 	/// The caller origin, overarching type of all pallets origins.
-	type PalletsOrigin: Into<Self> + CallerTrait<Self::AccountId> + MaxEncodedLen;
+	type PalletsOrigin: Send + Sync + Into<Self> + CallerTrait<Self::AccountId> + MaxEncodedLen;
 
 	/// The AccountId used across the system.
 	type AccountId;
@@ -496,6 +496,14 @@ pub trait OriginTrait: Sized {
 	/// Replace the caller with caller from the other origin
 	fn set_caller_from(&mut self, other: impl Into<Self>);
 
+	/// Replace the caller with caller from the other origin
+	fn set_caller(&mut self, caller: Self::PalletsOrigin);
+
+	/// Replace the caller with caller from the other origin
+	fn set_caller_from_signed(&mut self, caller_account: Self::AccountId) {
+		self.set_caller(Self::PalletsOrigin::from(RawOrigin::Signed(caller_account)))
+	}
+
 	/// Filter the call if caller is not root, if false is returned then the call must be filtered
 	/// out.
 	///
@@ -544,6 +552,17 @@ pub trait OriginTrait: Sized {
 	fn as_system_ref(&self) -> Option<&RawOrigin<Self::AccountId>> {
 		self.caller().as_system_ref()
 	}
+
+	/// Extract a reference to the signer, if that's what the caller is.
+	fn as_signer(&self) -> Option<&Self::AccountId> {
+		self.caller().as_system_ref().and_then(|s| {
+			if let RawOrigin::Signed(ref who) = s {
+				Some(who)
+			} else {
+				None
+			}
+		})
+	}
 }
 
 #[cfg(test)]
diff --git a/substrate/frame/support/src/traits/misc.rs b/substrate/frame/support/src/traits/misc.rs
index 4d3b122daf6..a914b3a914c 100644
--- a/substrate/frame/support/src/traits/misc.rs
+++ b/substrate/frame/support/src/traits/misc.rs
@@ -919,32 +919,82 @@ pub trait IsInherent<Extrinsic> {
 }
 
 /// An extrinsic on which we can get access to call.
-pub trait ExtrinsicCall: sp_runtime::traits::Extrinsic {
+pub trait ExtrinsicCall: sp_runtime::traits::ExtrinsicLike {
+	type Call;
+
 	/// Get the call of the extrinsic.
 	fn call(&self) -> &Self::Call;
 }
 
-#[cfg(feature = "std")]
-impl<Call, Extra> ExtrinsicCall for sp_runtime::testing::TestXt<Call, Extra>
+impl<Address, Call, Signature, Extra> ExtrinsicCall
+	for sp_runtime::generic::UncheckedExtrinsic<Address, Call, Signature, Extra>
 where
-	Call: codec::Codec + Sync + Send + TypeInfo,
+	Address: TypeInfo,
+	Call: TypeInfo,
+	Signature: TypeInfo,
 	Extra: TypeInfo,
 {
-	fn call(&self) -> &Self::Call {
-		&self.call
+	type Call = Call;
+
+	fn call(&self) -> &Call {
+		&self.function
 	}
 }
 
-impl<Address, Call, Signature, Extra> ExtrinsicCall
+/// Interface for types capable of constructing an inherent extrinsic.
+pub trait InherentBuilder: ExtrinsicCall {
+	/// Create a new inherent from a given call.
+	fn new_inherent(call: Self::Call) -> Self;
+}
+
+impl<Address, Call, Signature, Extra> InherentBuilder
 	for sp_runtime::generic::UncheckedExtrinsic<Address, Call, Signature, Extra>
 where
 	Address: TypeInfo,
 	Call: TypeInfo,
 	Signature: TypeInfo,
-	Extra: sp_runtime::traits::SignedExtension + TypeInfo,
+	Extra: TypeInfo,
 {
-	fn call(&self) -> &Self::Call {
-		&self.function
+	fn new_inherent(call: Self::Call) -> Self {
+		Self::new_bare(call)
+	}
+}
+
+/// Interface for types capable of constructing a signed transaction.
+pub trait SignedTransactionBuilder: ExtrinsicCall {
+	type Address;
+	type Signature;
+	type Extension;
+
+	/// Create a new signed transaction from a given call and extension using the provided signature
+	/// data.
+	fn new_signed_transaction(
+		call: Self::Call,
+		signed: Self::Address,
+		signature: Self::Signature,
+		tx_ext: Self::Extension,
+	) -> Self;
+}
+
+impl<Address, Call, Signature, Extension> SignedTransactionBuilder
+	for sp_runtime::generic::UncheckedExtrinsic<Address, Call, Signature, Extension>
+where
+	Address: TypeInfo,
+	Call: TypeInfo,
+	Signature: TypeInfo,
+	Extension: TypeInfo,
+{
+	type Address = Address;
+	type Signature = Signature;
+	type Extension = Extension;
+
+	fn new_signed_transaction(
+		call: Self::Call,
+		signed: Address,
+		signature: Signature,
+		tx_ext: Extension,
+	) -> Self {
+		Self::new_signed(call, signed, signature, tx_ext)
 	}
 }
 
diff --git a/substrate/frame/support/test/Cargo.toml b/substrate/frame/support/test/Cargo.toml
index 5c12c082305..2187ee22b39 100644
--- a/substrate/frame/support/test/Cargo.toml
+++ b/substrate/frame/support/test/Cargo.toml
@@ -59,10 +59,7 @@ std = [
 	"sp-version/std",
 	"test-pallet/std",
 ]
-experimental = [
-	"frame-support/experimental",
-	"frame-system/experimental",
-]
+experimental = ["frame-support/experimental", "frame-system/experimental"]
 try-runtime = [
 	"frame-executive/try-runtime",
 	"frame-support/try-runtime",
diff --git a/substrate/frame/support/test/tests/construct_runtime_ui/undefined_inherent_part.stderr b/substrate/frame/support/test/tests/construct_runtime_ui/undefined_inherent_part.stderr
index d8dc7bd45bc..9608fa58e3c 100644
--- a/substrate/frame/support/test/tests/construct_runtime_ui/undefined_inherent_part.stderr
+++ b/substrate/frame/support/test/tests/construct_runtime_ui/undefined_inherent_part.stderr
@@ -32,8 +32,9 @@ error[E0599]: no function or associated item named `create_inherent` found for s
    | |_^ function or associated item not found in `Pallet<Runtime>`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
-   = note: the following trait defines an item `create_inherent`, perhaps you need to implement it:
-           candidate #1: `ProvideInherent`
+   = note: the following traits define an item `create_inherent`, perhaps you need to implement one of them:
+           candidate #1: `CreateInherent`
+           candidate #2: `ProvideInherent`
    = note: this error originates in the macro `construct_runtime` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0599]: no function or associated item named `is_inherent` found for struct `pallet::Pallet` in the current scope
diff --git a/substrate/frame/support/test/tests/enum_deprecation.rs b/substrate/frame/support/test/tests/enum_deprecation.rs
index ed9b2b5a735..c1167dfe339 100644
--- a/substrate/frame/support/test/tests/enum_deprecation.rs
+++ b/substrate/frame/support/test/tests/enum_deprecation.rs
@@ -132,8 +132,12 @@ impl pallet::Config for Runtime {
 
 pub type Header = sp_runtime::generic::Header<u32, sp_runtime::traits::BlakeTwo256>;
 pub type Block = sp_runtime::generic::Block<Header, UncheckedExtrinsic>;
-pub type UncheckedExtrinsic =
-	sp_runtime::testing::TestXt<RuntimeCall, frame_system::CheckNonZeroSender<Runtime>>;
+pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic<
+	u64,
+	RuntimeCall,
+	sp_runtime::testing::UintAuthorityId,
+	frame_system::CheckNonZeroSender<Runtime>,
+>;
 
 frame_support::construct_runtime!(
 	pub struct Runtime {
diff --git a/substrate/frame/support/test/tests/pallet.rs b/substrate/frame/support/test/tests/pallet.rs
index 3d6aa1d8374..b0b83f77249 100644
--- a/substrate/frame/support/test/tests/pallet.rs
+++ b/substrate/frame/support/test/tests/pallet.rs
@@ -27,19 +27,21 @@ use frame_support::{
 	storage::{unhashed, unhashed::contains_prefixed_key},
 	traits::{
 		ConstU32, GetCallIndex, GetCallName, GetStorageVersion, OnFinalize, OnGenesis,
-		OnInitialize, OnRuntimeUpgrade, PalletError, PalletInfoAccess, StorageVersion,
-		UnfilteredDispatchable,
+		OnInitialize, OnRuntimeUpgrade, PalletError, PalletInfoAccess, SignedTransactionBuilder,
+		StorageVersion, UnfilteredDispatchable,
 	},
 	weights::{RuntimeDbWeight, Weight},
 	OrdNoBound, PartialOrdNoBound,
 };
+use frame_system::offchain::{CreateSignedTransaction, CreateTransactionBase, SigningTypes};
 use scale_info::{meta_type, TypeInfo};
 use sp_io::{
 	hashing::{blake2_128, twox_128, twox_64},
 	TestExternalities,
 };
 use sp_runtime::{
-	traits::{Dispatchable, Extrinsic as ExtrinsicT, SignaturePayload as SignaturePayloadT},
+	testing::UintAuthorityId,
+	traits::{Block as BlockT, Dispatchable},
 	DispatchError, ModuleError,
 };
 
@@ -751,8 +753,51 @@ impl pallet5::Config for Runtime {
 
 pub type Header = sp_runtime::generic::Header<u32, sp_runtime::traits::BlakeTwo256>;
 pub type Block = sp_runtime::generic::Block<Header, UncheckedExtrinsic>;
-pub type UncheckedExtrinsic =
-	sp_runtime::testing::TestXt<RuntimeCall, frame_system::CheckNonZeroSender<Runtime>>;
+pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic<
+	u64,
+	RuntimeCall,
+	UintAuthorityId,
+	frame_system::CheckNonZeroSender<Runtime>,
+>;
+pub type UncheckedSignaturePayload = sp_runtime::generic::UncheckedSignaturePayload<
+	u64,
+	UintAuthorityId,
+	frame_system::CheckNonZeroSender<Runtime>,
+>;
+
+impl SigningTypes for Runtime {
+	type Public = UintAuthorityId;
+	type Signature = UintAuthorityId;
+}
+
+impl<LocalCall> CreateTransactionBase<LocalCall> for Runtime
+where
+	RuntimeCall: From<LocalCall>,
+{
+	type RuntimeCall = RuntimeCall;
+	type Extrinsic = UncheckedExtrinsic;
+}
+
+impl<LocalCall> CreateSignedTransaction<LocalCall> for Runtime
+where
+	RuntimeCall: From<LocalCall>,
+{
+	fn create_signed_transaction<
+		C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>,
+	>(
+		call: RuntimeCall,
+		_public: UintAuthorityId,
+		account: u64,
+		nonce: u64,
+	) -> Option<UncheckedExtrinsic> {
+		Some(UncheckedExtrinsic::new_signed(
+			call,
+			nonce,
+			account.into(),
+			frame_system::CheckNonZeroSender::new(),
+		))
+	}
+}
 
 frame_support::construct_runtime!(
 	pub struct Runtime {
@@ -814,7 +859,8 @@ fn call_expand() {
 	assert_eq!(
 		call_foo.get_dispatch_info(),
 		DispatchInfo {
-			weight: frame_support::weights::Weight::from_parts(3, 0),
+			call_weight: frame_support::weights::Weight::from_parts(3, 0),
+			extension_weight: Default::default(),
 			class: DispatchClass::Normal,
 			pays_fee: Pays::Yes
 		}
@@ -902,10 +948,8 @@ fn inherent_expand() {
 
 	let inherents = InherentData::new().create_extrinsics();
 
-	let expected = vec![UncheckedExtrinsic {
-		call: RuntimeCall::Example(pallet::Call::foo_no_post_info {}),
-		signature: None,
-	}];
+	let expected =
+		vec![UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo_no_post_info {}))];
 	assert_eq!(expected, inherents);
 
 	let block = Block::new(
@@ -917,14 +961,11 @@ fn inherent_expand() {
 			Digest::default(),
 		),
 		vec![
-			UncheckedExtrinsic {
-				call: RuntimeCall::Example(pallet::Call::foo_no_post_info {}),
-				signature: None,
-			},
-			UncheckedExtrinsic {
-				call: RuntimeCall::Example(pallet::Call::foo { foo: 1, bar: 0 }),
-				signature: None,
-			},
+			UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo_no_post_info {})),
+			UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo {
+				foo: 1,
+				bar: 0,
+			})),
 		],
 	);
 
@@ -939,14 +980,11 @@ fn inherent_expand() {
 			Digest::default(),
 		),
 		vec![
-			UncheckedExtrinsic {
-				call: RuntimeCall::Example(pallet::Call::foo_no_post_info {}),
-				signature: None,
-			},
-			UncheckedExtrinsic {
-				call: RuntimeCall::Example(pallet::Call::foo { foo: 0, bar: 0 }),
-				signature: None,
-			},
+			UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo_no_post_info {})),
+			UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo {
+				foo: 0,
+				bar: 0,
+			})),
 		],
 	);
 
@@ -960,10 +998,9 @@ fn inherent_expand() {
 			BlakeTwo256::hash(b"test"),
 			Digest::default(),
 		),
-		vec![UncheckedExtrinsic {
-			call: RuntimeCall::Example(pallet::Call::foo_storage_layer { foo: 0 }),
-			signature: None,
-		}],
+		vec![UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo_storage_layer {
+			foo: 0,
+		}))],
 	);
 
 	let mut inherent = InherentData::new();
@@ -978,10 +1015,12 @@ fn inherent_expand() {
 			BlakeTwo256::hash(b"test"),
 			Digest::default(),
 		),
-		vec![UncheckedExtrinsic {
-			call: RuntimeCall::Example(pallet::Call::foo_no_post_info {}),
-			signature: Some((1, Default::default())),
-		}],
+		vec![UncheckedExtrinsic::new_signed(
+			RuntimeCall::Example(pallet::Call::foo_no_post_info {}),
+			1,
+			1.into(),
+			Default::default(),
+		)],
 	);
 
 	let mut inherent = InherentData::new();
@@ -997,14 +1036,13 @@ fn inherent_expand() {
 			Digest::default(),
 		),
 		vec![
-			UncheckedExtrinsic {
-				call: RuntimeCall::Example(pallet::Call::foo { foo: 1, bar: 1 }),
-				signature: None,
-			},
-			UncheckedExtrinsic {
-				call: RuntimeCall::Example(pallet::Call::foo_storage_layer { foo: 0 }),
-				signature: None,
-			},
+			UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo {
+				foo: 1,
+				bar: 1,
+			})),
+			UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo_storage_layer {
+				foo: 0,
+			})),
 		],
 	);
 
@@ -1019,18 +1057,14 @@ fn inherent_expand() {
 			Digest::default(),
 		),
 		vec![
-			UncheckedExtrinsic {
-				call: RuntimeCall::Example(pallet::Call::foo { foo: 1, bar: 1 }),
-				signature: None,
-			},
-			UncheckedExtrinsic {
-				call: RuntimeCall::Example(pallet::Call::foo_storage_layer { foo: 0 }),
-				signature: None,
-			},
-			UncheckedExtrinsic {
-				call: RuntimeCall::Example(pallet::Call::foo_no_post_info {}),
-				signature: None,
-			},
+			UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo {
+				foo: 1,
+				bar: 1,
+			})),
+			UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo_storage_layer {
+				foo: 0,
+			})),
+			UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo_no_post_info {})),
 		],
 	);
 
@@ -1045,18 +1079,17 @@ fn inherent_expand() {
 			Digest::default(),
 		),
 		vec![
-			UncheckedExtrinsic {
-				call: RuntimeCall::Example(pallet::Call::foo { foo: 1, bar: 1 }),
-				signature: None,
-			},
-			UncheckedExtrinsic {
-				call: RuntimeCall::Example(pallet::Call::foo { foo: 1, bar: 0 }),
-				signature: Some((1, Default::default())),
-			},
-			UncheckedExtrinsic {
-				call: RuntimeCall::Example(pallet::Call::foo_no_post_info {}),
-				signature: None,
-			},
+			UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo {
+				foo: 1,
+				bar: 1,
+			})),
+			UncheckedExtrinsic::new_signed(
+				RuntimeCall::Example(pallet::Call::foo { foo: 1, bar: 0 }),
+				1,
+				1.into(),
+				Default::default(),
+			),
+			UncheckedExtrinsic::new_bare(RuntimeCall::Example(pallet::Call::foo_no_post_info {})),
 		],
 	);
 
@@ -1838,18 +1871,22 @@ fn metadata() {
 	}
 
 	let extrinsic = ExtrinsicMetadata {
-		version: 4,
+		version: 5,
 		signed_extensions: vec![SignedExtensionMetadata {
 			identifier: "UnitSignedExtension",
 			ty: meta_type::<()>(),
 			additional_signed: meta_type::<()>(),
 		}],
-		address_ty: meta_type::<<<UncheckedExtrinsic as ExtrinsicT>::SignaturePayload as SignaturePayloadT>::SignatureAddress>(),
-		call_ty: meta_type::<<UncheckedExtrinsic as ExtrinsicT>::Call>(),
+		address_ty: meta_type::<
+			<<<Runtime as frame_system::Config>::Block as BlockT>::Extrinsic as SignedTransactionBuilder>::Address
+		>(),
+		call_ty: meta_type::<<Runtime as CreateTransactionBase<RuntimeCall>>::RuntimeCall>(),
 		signature_ty: meta_type::<
-			<<UncheckedExtrinsic as ExtrinsicT>::SignaturePayload as SignaturePayloadT>::Signature
+			<<<Runtime as frame_system::Config>::Block as BlockT>::Extrinsic as SignedTransactionBuilder>::Signature
+		>(),
+		extra_ty: meta_type::<
+			<<<Runtime as frame_system::Config>::Block as BlockT>::Extrinsic as SignedTransactionBuilder>::Extension
 		>(),
-		extra_ty: meta_type::<<<UncheckedExtrinsic as ExtrinsicT>::SignaturePayload as SignaturePayloadT>::SignatureExtra>(),
 	};
 
 	let outer_enums = OuterEnums {
@@ -1929,21 +1966,28 @@ fn metadata_ir_pallet_runtime_docs() {
 fn extrinsic_metadata_ir_types() {
 	let ir = Runtime::metadata_ir().extrinsic;
 
-	assert_eq!(meta_type::<<<UncheckedExtrinsic as ExtrinsicT>::SignaturePayload as SignaturePayloadT>::SignatureAddress>(), ir.address_ty);
+	assert_eq!(
+		meta_type::<<<<Runtime as frame_system::Config>::Block as BlockT>::Extrinsic as SignedTransactionBuilder>::Address>(),
+		ir.address_ty
+	);
 	assert_eq!(meta_type::<u64>(), ir.address_ty);
 
-	assert_eq!(meta_type::<<UncheckedExtrinsic as ExtrinsicT>::Call>(), ir.call_ty);
+	assert_eq!(
+		meta_type::<<Runtime as CreateTransactionBase<RuntimeCall>>::RuntimeCall>(),
+		ir.call_ty
+	);
 	assert_eq!(meta_type::<RuntimeCall>(), ir.call_ty);
 
 	assert_eq!(
-		meta_type::<
-			<<UncheckedExtrinsic as ExtrinsicT>::SignaturePayload as SignaturePayloadT>::Signature,
-		>(),
+		meta_type::<<<<Runtime as frame_system::Config>::Block as BlockT>::Extrinsic as SignedTransactionBuilder>::Signature>(),
 		ir.signature_ty
 	);
-	assert_eq!(meta_type::<()>(), ir.signature_ty);
+	assert_eq!(meta_type::<UintAuthorityId>(), ir.signature_ty);
 
-	assert_eq!(meta_type::<<<UncheckedExtrinsic as ExtrinsicT>::SignaturePayload as SignaturePayloadT>::SignatureExtra>(), ir.extra_ty);
+	assert_eq!(
+		meta_type::<<<<Runtime as frame_system::Config>::Block as BlockT>::Extrinsic as SignedTransactionBuilder>::Extension>(),
+		ir.extra_ty
+	);
 	assert_eq!(meta_type::<frame_system::CheckNonZeroSender<Runtime>>(), ir.extra_ty);
 }
 
diff --git a/substrate/frame/support/test/tests/pallet_instance.rs b/substrate/frame/support/test/tests/pallet_instance.rs
index 09a49617044..2e4baae1db7 100644
--- a/substrate/frame/support/test/tests/pallet_instance.rs
+++ b/substrate/frame/support/test/tests/pallet_instance.rs
@@ -360,7 +360,8 @@ fn call_expand() {
 	assert_eq!(
 		call_foo.get_dispatch_info(),
 		DispatchInfo {
-			weight: Weight::from_parts(3, 0),
+			call_weight: Weight::from_parts(3, 0),
+			extension_weight: Default::default(),
 			class: DispatchClass::Normal,
 			pays_fee: Pays::Yes
 		}
@@ -372,7 +373,8 @@ fn call_expand() {
 	assert_eq!(
 		call_foo.get_dispatch_info(),
 		DispatchInfo {
-			weight: Weight::from_parts(3, 0),
+			call_weight: Weight::from_parts(3, 0),
+			extension_weight: Default::default(),
 			class: DispatchClass::Normal,
 			pays_fee: Pays::Yes
 		}
@@ -940,9 +942,9 @@ fn metadata() {
 
 	let extrinsic = ExtrinsicMetadata {
 		ty: scale_info::meta_type::<UncheckedExtrinsic>(),
-		version: 4,
+		version: 5,
 		signed_extensions: vec![SignedExtensionMetadata {
-			identifier: "UnitSignedExtension",
+			identifier: "UnitTransactionExtension",
 			ty: scale_info::meta_type::<()>(),
 			additional_signed: scale_info::meta_type::<()>(),
 		}],
diff --git a/substrate/frame/support/test/tests/runtime.rs b/substrate/frame/support/test/tests/runtime.rs
index 06c2b5b7071..5335e08837e 100644
--- a/substrate/frame/support/test/tests/runtime.rs
+++ b/substrate/frame/support/test/tests/runtime.rs
@@ -25,7 +25,10 @@ use codec::MaxEncodedLen;
 use frame_support::{
 	derive_impl, parameter_types, traits::PalletInfo as _, weights::RuntimeDbWeight,
 };
-use frame_system::limits::{BlockLength, BlockWeights};
+use frame_system::{
+	limits::{BlockLength, BlockWeights},
+	DispatchEventInfo,
+};
 use scale_info::TypeInfo;
 use sp_core::sr25519;
 use sp_runtime::{
@@ -533,8 +536,13 @@ fn origin_codec() {
 fn event_codec() {
 	use codec::Encode;
 
-	let event =
-		frame_system::Event::<Runtime>::ExtrinsicSuccess { dispatch_info: Default::default() };
+	let event = frame_system::Event::<Runtime>::ExtrinsicSuccess {
+		dispatch_info: DispatchEventInfo {
+			weight: Default::default(),
+			class: Default::default(),
+			pays_fee: Default::default(),
+		},
+	};
 	assert_eq!(RuntimeEvent::from(event).encode()[0], 30);
 
 	let event = module1::Event::<Runtime, module1::Instance1>::A(test_pub());
@@ -624,7 +632,8 @@ fn call_weight_should_attach_to_call_enum() {
 	assert_eq!(
 		module3::Call::<Runtime>::operational {}.get_dispatch_info(),
 		DispatchInfo {
-			weight: Weight::from_parts(5, 0),
+			call_weight: Weight::from_parts(5, 0),
+			extension_weight: Default::default(),
 			class: DispatchClass::Operational,
 			pays_fee: Pays::Yes
 		},
@@ -633,7 +642,8 @@ fn call_weight_should_attach_to_call_enum() {
 	assert_eq!(
 		module3::Call::<Runtime>::aux_4 {}.get_dispatch_info(),
 		DispatchInfo {
-			weight: Weight::from_parts(3, 0),
+			call_weight: Weight::from_parts(3, 0),
+			extension_weight: Default::default(),
 			class: DispatchClass::Normal,
 			pays_fee: Pays::Yes
 		},
@@ -894,7 +904,7 @@ fn test_metadata() {
 		ty: meta_type::<UncheckedExtrinsic>(),
 		version: 4,
 		signed_extensions: vec![SignedExtensionMetadata {
-			identifier: "UnitSignedExtension",
+			identifier: "UnitTransactionExtension",
 			ty: meta_type::<()>(),
 			additional_signed: meta_type::<()>(),
 		}],
diff --git a/substrate/frame/support/test/tests/runtime_legacy_ordering.rs b/substrate/frame/support/test/tests/runtime_legacy_ordering.rs
index 4233db21e20..7b92073a82b 100644
--- a/substrate/frame/support/test/tests/runtime_legacy_ordering.rs
+++ b/substrate/frame/support/test/tests/runtime_legacy_ordering.rs
@@ -25,7 +25,10 @@ use codec::MaxEncodedLen;
 use frame_support::{
 	derive_impl, parameter_types, traits::PalletInfo as _, weights::RuntimeDbWeight,
 };
-use frame_system::limits::{BlockLength, BlockWeights};
+use frame_system::{
+	limits::{BlockLength, BlockWeights},
+	DispatchEventInfo,
+};
 use scale_info::TypeInfo;
 use sp_core::sr25519;
 use sp_runtime::{
@@ -533,8 +536,13 @@ fn origin_codec() {
 fn event_codec() {
 	use codec::Encode;
 
-	let event =
-		frame_system::Event::<Runtime>::ExtrinsicSuccess { dispatch_info: Default::default() };
+	let event = frame_system::Event::<Runtime>::ExtrinsicSuccess {
+		dispatch_info: DispatchEventInfo {
+			weight: Default::default(),
+			class: Default::default(),
+			pays_fee: Default::default(),
+		},
+	};
 	assert_eq!(RuntimeEvent::from(event).encode()[0], 30);
 
 	let event = module1::Event::<Runtime, module1::Instance1>::A(test_pub());
@@ -624,7 +632,8 @@ fn call_weight_should_attach_to_call_enum() {
 	assert_eq!(
 		module3::Call::<Runtime>::operational {}.get_dispatch_info(),
 		DispatchInfo {
-			weight: Weight::from_parts(5, 0),
+			call_weight: Weight::from_parts(5, 0),
+			extension_weight: Default::default(),
 			class: DispatchClass::Operational,
 			pays_fee: Pays::Yes
 		},
@@ -633,7 +642,8 @@ fn call_weight_should_attach_to_call_enum() {
 	assert_eq!(
 		module3::Call::<Runtime>::aux_4 {}.get_dispatch_info(),
 		DispatchInfo {
-			weight: Weight::from_parts(3, 0),
+			call_weight: Weight::from_parts(3, 0),
+			extension_weight: Default::default(),
 			class: DispatchClass::Normal,
 			pays_fee: Pays::Yes
 		},
@@ -894,7 +904,7 @@ fn test_metadata() {
 		ty: meta_type::<UncheckedExtrinsic>(),
 		version: 4,
 		signed_extensions: vec![SignedExtensionMetadata {
-			identifier: "UnitSignedExtension",
+			identifier: "UnitTransactionExtension",
 			ty: meta_type::<()>(),
 			additional_signed: meta_type::<()>(),
 		}],
diff --git a/substrate/frame/system/benchmarking/src/extensions.rs b/substrate/frame/system/benchmarking/src/extensions.rs
new file mode 100644
index 00000000000..3c6626030e2
--- /dev/null
+++ b/substrate/frame/system/benchmarking/src/extensions.rs
@@ -0,0 +1,248 @@
+// This file is part of Substrate.
+
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Benchmarks for System Extensions
+
+#![cfg(feature = "runtime-benchmarks")]
+
+use alloc::vec;
+use frame_benchmarking::{account, v2::*, BenchmarkError};
+use frame_support::{
+	dispatch::{DispatchClass, DispatchInfo, PostDispatchInfo},
+	weights::Weight,
+};
+use frame_system::{
+	pallet_prelude::*, CheckGenesis, CheckMortality, CheckNonZeroSender, CheckNonce,
+	CheckSpecVersion, CheckTxVersion, CheckWeight, Config, ExtensionsWeightInfo, Pallet as System,
+	RawOrigin,
+};
+use sp_runtime::{
+	generic::Era,
+	traits::{
+		AsSystemOriginSigner, AsTransactionAuthorizedOrigin, DispatchTransaction, Dispatchable, Get,
+	},
+};
+
+pub struct Pallet<T: Config>(System<T>);
+
+#[benchmarks(where
+	T: Send + Sync,
+    T::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
+	<T::RuntimeCall as Dispatchable>::RuntimeOrigin: AsSystemOriginSigner<T::AccountId> + AsTransactionAuthorizedOrigin + Clone)
+]
+mod benchmarks {
+	use super::*;
+
+	#[benchmark]
+	fn check_genesis() -> Result<(), BenchmarkError> {
+		let len = 0_usize;
+		let caller = account("caller", 0, 0);
+		let info = DispatchInfo { call_weight: Weight::zero(), ..Default::default() };
+		let call: T::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into();
+
+		#[block]
+		{
+			CheckGenesis::<T>::new()
+				.test_run(RawOrigin::Signed(caller).into(), &call, &info, len, |_| Ok(().into()))
+				.unwrap()
+				.unwrap();
+		}
+
+		Ok(())
+	}
+
+	#[benchmark]
+	fn check_mortality_mortal_transaction() -> Result<(), BenchmarkError> {
+		let len = 0_usize;
+		let ext = CheckMortality::<T>::from(Era::mortal(16, 256));
+		let block_number: BlockNumberFor<T> = 17u32.into();
+		System::<T>::set_block_number(block_number);
+		let prev_block: BlockNumberFor<T> = 16u32.into();
+		let default_hash: T::Hash = Default::default();
+		frame_system::BlockHash::<T>::insert(prev_block, default_hash);
+		let caller = account("caller", 0, 0);
+		let info = DispatchInfo {
+			call_weight: Weight::from_parts(100, 0),
+			class: DispatchClass::Normal,
+			..Default::default()
+		};
+		let call: T::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into();
+
+		#[block]
+		{
+			ext.test_run(RawOrigin::Signed(caller).into(), &call, &info, len, |_| Ok(().into()))
+				.unwrap()
+				.unwrap();
+		}
+		Ok(())
+	}
+
+	#[benchmark]
+	fn check_mortality_immortal_transaction() -> Result<(), BenchmarkError> {
+		let len = 0_usize;
+		let ext = CheckMortality::<T>::from(Era::immortal());
+		let block_number: BlockNumberFor<T> = 17u32.into();
+		System::<T>::set_block_number(block_number);
+		let prev_block: BlockNumberFor<T> = 16u32.into();
+		let default_hash: T::Hash = Default::default();
+		frame_system::BlockHash::<T>::insert(prev_block, default_hash);
+		let genesis_block: BlockNumberFor<T> = 0u32.into();
+		frame_system::BlockHash::<T>::insert(genesis_block, default_hash);
+		let caller = account("caller", 0, 0);
+		let info = DispatchInfo {
+			call_weight: Weight::from_parts(100, 0),
+			class: DispatchClass::Normal,
+			..Default::default()
+		};
+		let call: T::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into();
+
+		#[block]
+		{
+			ext.test_run(RawOrigin::Signed(caller).into(), &call, &info, len, |_| Ok(().into()))
+				.unwrap()
+				.unwrap();
+		}
+		Ok(())
+	}
+
+	#[benchmark]
+	fn check_non_zero_sender() -> Result<(), BenchmarkError> {
+		let len = 0_usize;
+		let ext = CheckNonZeroSender::<T>::new();
+		let caller = account("caller", 0, 0);
+		let info = DispatchInfo { call_weight: Weight::zero(), ..Default::default() };
+		let call: T::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into();
+
+		#[block]
+		{
+			ext.test_run(RawOrigin::Signed(caller).into(), &call, &info, len, |_| Ok(().into()))
+				.unwrap()
+				.unwrap();
+		}
+		Ok(())
+	}
+
+	#[benchmark]
+	fn check_nonce() -> Result<(), BenchmarkError> {
+		let caller: T::AccountId = account("caller", 0, 0);
+		let mut info = frame_system::AccountInfo::default();
+		info.nonce = 1u32.into();
+		info.providers = 1;
+		let expected_nonce = info.nonce + 1u32.into();
+		frame_system::Account::<T>::insert(caller.clone(), info);
+		let len = 0_usize;
+		let ext = CheckNonce::<T>::from(1u32.into());
+		let info = DispatchInfo { call_weight: Weight::zero(), ..Default::default() };
+		let call: T::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into();
+
+		#[block]
+		{
+			ext.test_run(RawOrigin::Signed(caller.clone()).into(), &call, &info, len, |_| {
+				Ok(().into())
+			})
+			.unwrap()
+			.unwrap();
+		}
+
+		let updated_info = frame_system::Account::<T>::get(caller.clone());
+		assert_eq!(updated_info.nonce, expected_nonce);
+		Ok(())
+	}
+
+	#[benchmark]
+	fn check_spec_version() -> Result<(), BenchmarkError> {
+		let len = 0_usize;
+		let caller = account("caller", 0, 0);
+		let info = DispatchInfo { call_weight: Weight::zero(), ..Default::default() };
+		let call: T::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into();
+
+		#[block]
+		{
+			CheckSpecVersion::<T>::new()
+				.test_run(RawOrigin::Signed(caller).into(), &call, &info, len, |_| Ok(().into()))
+				.unwrap()
+				.unwrap();
+		}
+		Ok(())
+	}
+
+	#[benchmark]
+	fn check_tx_version() -> Result<(), BenchmarkError> {
+		let len = 0_usize;
+		let caller = account("caller", 0, 0);
+		let info = DispatchInfo { call_weight: Weight::zero(), ..Default::default() };
+		let call: T::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into();
+
+		#[block]
+		{
+			CheckTxVersion::<T>::new()
+				.test_run(RawOrigin::Signed(caller).into(), &call, &info, len, |_| Ok(().into()))
+				.unwrap()
+				.unwrap();
+		}
+		Ok(())
+	}
+
+	#[benchmark]
+	fn check_weight() -> Result<(), BenchmarkError> {
+		let caller = account("caller", 0, 0);
+		let base_extrinsic = <T as frame_system::Config>::BlockWeights::get()
+			.get(DispatchClass::Normal)
+			.base_extrinsic;
+		let extension_weight = <T as frame_system::Config>::ExtensionsWeightInfo::check_weight();
+		let info = DispatchInfo {
+			call_weight: Weight::from_parts(base_extrinsic.ref_time() * 5, 0),
+			extension_weight,
+			class: DispatchClass::Normal,
+			..Default::default()
+		};
+		let call: T::RuntimeCall = frame_system::Call::remark { remark: vec![] }.into();
+		let post_info = PostDispatchInfo {
+			actual_weight: Some(Weight::from_parts(base_extrinsic.ref_time() * 2, 0)),
+			pays_fee: Default::default(),
+		};
+		let len = 0_usize;
+		let base_extrinsic = <T as frame_system::Config>::BlockWeights::get()
+			.get(DispatchClass::Normal)
+			.base_extrinsic;
+
+		let ext = CheckWeight::<T>::new();
+
+		let initial_block_weight = Weight::from_parts(base_extrinsic.ref_time() * 2, 0);
+		frame_system::BlockWeight::<T>::mutate(|current_weight| {
+			current_weight.set(Weight::zero(), DispatchClass::Mandatory);
+			current_weight.set(initial_block_weight, DispatchClass::Normal);
+		});
+
+		#[block]
+		{
+			ext.test_run(RawOrigin::Signed(caller).into(), &call, &info, len, |_| Ok(post_info))
+				.unwrap()
+				.unwrap();
+		}
+
+		assert_eq!(
+			System::<T>::block_weight().total(),
+			initial_block_weight +
+				base_extrinsic +
+				post_info.actual_weight.unwrap().saturating_add(extension_weight),
+		);
+		Ok(())
+	}
+
+	impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test,);
+}
diff --git a/substrate/frame/system/benchmarking/src/lib.rs b/substrate/frame/system/benchmarking/src/lib.rs
index f66d20ac8ae..dc3c7420317 100644
--- a/substrate/frame/system/benchmarking/src/lib.rs
+++ b/substrate/frame/system/benchmarking/src/lib.rs
@@ -20,6 +20,7 @@
 #![cfg_attr(not(feature = "std"), no_std)]
 
 extern crate alloc;
+pub mod extensions;
 
 #[cfg(feature = "runtime-benchmarks")]
 pub mod inner;
diff --git a/substrate/frame/system/benchmarking/src/mock.rs b/substrate/frame/system/benchmarking/src/mock.rs
index 42e4aa0eaf4..6b126619ce5 100644
--- a/substrate/frame/system/benchmarking/src/mock.rs
+++ b/substrate/frame/system/benchmarking/src/mock.rs
@@ -20,7 +20,7 @@
 #![cfg(test)]
 
 use codec::Encode;
-use frame_support::derive_impl;
+use frame_support::{derive_impl, weights::Weight};
 use sp_runtime::BuildStorage;
 
 type Block = frame_system::mocking::MockBlock<Test>;
@@ -32,9 +32,45 @@ frame_support::construct_runtime!(
 	}
 );
 
+pub struct MockWeights;
+impl frame_system::ExtensionsWeightInfo for MockWeights {
+	fn check_genesis() -> Weight {
+		Weight::from_parts(10, 0)
+	}
+
+	fn check_mortality_mortal_transaction() -> Weight {
+		Weight::from_parts(10, 0)
+	}
+
+	fn check_mortality_immortal_transaction() -> Weight {
+		Weight::from_parts(10, 0)
+	}
+
+	fn check_non_zero_sender() -> Weight {
+		Weight::from_parts(10, 0)
+	}
+
+	fn check_nonce() -> Weight {
+		Weight::from_parts(10, 0)
+	}
+
+	fn check_spec_version() -> Weight {
+		Weight::from_parts(10, 0)
+	}
+
+	fn check_tx_version() -> Weight {
+		Weight::from_parts(10, 0)
+	}
+
+	fn check_weight() -> Weight {
+		Weight::from_parts(10, 0)
+	}
+}
+
 #[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
 impl frame_system::Config for Test {
 	type Block = Block;
+	type ExtensionsWeightInfo = MockWeights;
 }
 
 impl crate::Config for Test {}
diff --git a/substrate/frame/system/src/extensions/check_genesis.rs b/substrate/frame/system/src/extensions/check_genesis.rs
index 000ec56da64..881faa2c0ea 100644
--- a/substrate/frame/system/src/extensions/check_genesis.rs
+++ b/substrate/frame/system/src/extensions/check_genesis.rs
@@ -19,7 +19,8 @@ use crate::{pallet_prelude::BlockNumberFor, Config, Pallet};
 use codec::{Decode, Encode};
 use scale_info::TypeInfo;
 use sp_runtime::{
-	traits::{DispatchInfoOf, SignedExtension, Zero},
+	impl_tx_ext_default,
+	traits::{TransactionExtension, Zero},
 	transaction_validity::TransactionValidityError,
 };
 
@@ -46,30 +47,24 @@ impl<T: Config + Send + Sync> core::fmt::Debug for CheckGenesis<T> {
 }
 
 impl<T: Config + Send + Sync> CheckGenesis<T> {
-	/// Creates new `SignedExtension` to check genesis hash.
+	/// Creates new `TransactionExtension` to check genesis hash.
 	pub fn new() -> Self {
 		Self(core::marker::PhantomData)
 	}
 }
 
-impl<T: Config + Send + Sync> SignedExtension for CheckGenesis<T> {
-	type AccountId = T::AccountId;
-	type Call = <T as Config>::RuntimeCall;
-	type AdditionalSigned = T::Hash;
-	type Pre = ();
+impl<T: Config + Send + Sync> TransactionExtension<T::RuntimeCall> for CheckGenesis<T> {
 	const IDENTIFIER: &'static str = "CheckGenesis";
-
-	fn additional_signed(&self) -> Result<Self::AdditionalSigned, TransactionValidityError> {
+	type Implicit = T::Hash;
+	fn implicit(&self) -> Result<Self::Implicit, TransactionValidityError> {
 		Ok(<Pallet<T>>::block_hash(BlockNumberFor::<T>::zero()))
 	}
-
-	fn pre_dispatch(
-		self,
-		who: &Self::AccountId,
-		call: &Self::Call,
-		info: &DispatchInfoOf<Self::Call>,
-		len: usize,
-	) -> Result<Self::Pre, TransactionValidityError> {
-		self.validate(who, call, info, len).map(|_| ())
+	type Val = ();
+	type Pre = ();
+	fn weight(&self, _: &T::RuntimeCall) -> sp_weights::Weight {
+		// All transactions will always read the hash of the genesis block, so to avoid
+		// charging this multiple times in a block we manually set the proof size to 0.
+		<T::ExtensionsWeightInfo as super::WeightInfo>::check_genesis().set_proof_size(0)
 	}
+	impl_tx_ext_default!(T::RuntimeCall; validate prepare);
 }
diff --git a/substrate/frame/system/src/extensions/check_mortality.rs b/substrate/frame/system/src/extensions/check_mortality.rs
index 6666c4812fb..7da5521f353 100644
--- a/substrate/frame/system/src/extensions/check_mortality.rs
+++ b/substrate/frame/system/src/extensions/check_mortality.rs
@@ -20,10 +20,9 @@ use codec::{Decode, Encode};
 use scale_info::TypeInfo;
 use sp_runtime::{
 	generic::Era,
-	traits::{DispatchInfoOf, SaturatedConversion, SignedExtension},
-	transaction_validity::{
-		InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction,
-	},
+	impl_tx_ext_default,
+	traits::{DispatchInfoOf, SaturatedConversion, TransactionExtension, ValidateResult},
+	transaction_validity::{InvalidTransaction, TransactionValidityError, ValidTransaction},
 };
 
 /// Check for transaction mortality.
@@ -57,29 +56,11 @@ impl<T: Config + Send + Sync> core::fmt::Debug for CheckMortality<T> {
 	}
 }
 
-impl<T: Config + Send + Sync> SignedExtension for CheckMortality<T> {
-	type AccountId = T::AccountId;
-	type Call = T::RuntimeCall;
-	type AdditionalSigned = T::Hash;
-	type Pre = ();
+impl<T: Config + Send + Sync> TransactionExtension<T::RuntimeCall> for CheckMortality<T> {
 	const IDENTIFIER: &'static str = "CheckMortality";
+	type Implicit = T::Hash;
 
-	fn validate(
-		&self,
-		_who: &Self::AccountId,
-		_call: &Self::Call,
-		_info: &DispatchInfoOf<Self::Call>,
-		_len: usize,
-	) -> TransactionValidity {
-		let current_u64 = <Pallet<T>>::block_number().saturated_into::<u64>();
-		let valid_till = self.0.death(current_u64);
-		Ok(ValidTransaction {
-			longevity: valid_till.saturating_sub(current_u64),
-			..Default::default()
-		})
-	}
-
-	fn additional_signed(&self) -> Result<Self::AdditionalSigned, TransactionValidityError> {
+	fn implicit(&self) -> Result<Self::Implicit, TransactionValidityError> {
 		let current_u64 = <Pallet<T>>::block_number().saturated_into::<u64>();
 		let n = self.0.birth(current_u64).saturated_into::<BlockNumberFor<T>>();
 		if !<BlockHash<T>>::contains_key(n) {
@@ -88,16 +69,41 @@ impl<T: Config + Send + Sync> SignedExtension for CheckMortality<T> {
 			Ok(<Pallet<T>>::block_hash(n))
 		}
 	}
+	type Pre = ();
+	type Val = ();
+
+	fn weight(&self, _: &T::RuntimeCall) -> sp_weights::Weight {
+		if self.0.is_immortal() {
+			// All immortal transactions will always read the hash of the genesis block, so to avoid
+			// charging this multiple times in a block we manually set the proof size to 0.
+			<T::ExtensionsWeightInfo as super::WeightInfo>::check_mortality_immortal_transaction()
+				.set_proof_size(0)
+		} else {
+			<T::ExtensionsWeightInfo as super::WeightInfo>::check_mortality_mortal_transaction()
+		}
+	}
 
-	fn pre_dispatch(
-		self,
-		who: &Self::AccountId,
-		call: &Self::Call,
-		info: &DispatchInfoOf<Self::Call>,
-		len: usize,
-	) -> Result<Self::Pre, TransactionValidityError> {
-		self.validate(who, call, info, len).map(|_| ())
+	fn validate(
+		&self,
+		origin: <T as Config>::RuntimeOrigin,
+		_call: &T::RuntimeCall,
+		_info: &DispatchInfoOf<T::RuntimeCall>,
+		_len: usize,
+		_self_implicit: Self::Implicit,
+		_inherited_implication: &impl Encode,
+	) -> ValidateResult<Self::Val, T::RuntimeCall> {
+		let current_u64 = <Pallet<T>>::block_number().saturated_into::<u64>();
+		let valid_till = self.0.death(current_u64);
+		Ok((
+			ValidTransaction {
+				longevity: valid_till.saturating_sub(current_u64),
+				..Default::default()
+			},
+			(),
+			origin,
+		))
 	}
+	impl_tx_ext_default!(T::RuntimeCall; prepare);
 }
 
 #[cfg(test)]
@@ -109,23 +115,21 @@ mod tests {
 		weights::Weight,
 	};
 	use sp_core::H256;
+	use sp_runtime::traits::DispatchTransaction;
 
 	#[test]
 	fn signed_ext_check_era_should_work() {
 		new_test_ext().execute_with(|| {
 			// future
 			assert_eq!(
-				CheckMortality::<Test>::from(Era::mortal(4, 2))
-					.additional_signed()
-					.err()
-					.unwrap(),
+				CheckMortality::<Test>::from(Era::mortal(4, 2)).implicit().err().unwrap(),
 				InvalidTransaction::AncientBirthBlock.into(),
 			);
 
 			// correct
 			System::set_block_number(13);
 			<BlockHash<Test>>::insert(12, H256::repeat_byte(1));
-			assert!(CheckMortality::<Test>::from(Era::mortal(4, 12)).additional_signed().is_ok());
+			assert!(CheckMortality::<Test>::from(Era::mortal(4, 12)).implicit().is_ok());
 		})
 	}
 
@@ -133,7 +137,8 @@ mod tests {
 	fn signed_ext_check_era_should_change_longevity() {
 		new_test_ext().execute_with(|| {
 			let normal = DispatchInfo {
-				weight: Weight::from_parts(100, 0),
+				call_weight: Weight::from_parts(100, 0),
+				extension_weight: Weight::zero(),
 				class: DispatchClass::Normal,
 				pays_fee: Pays::Yes,
 			};
@@ -145,7 +150,10 @@ mod tests {
 			System::set_block_number(17);
 			<BlockHash<Test>>::insert(16, H256::repeat_byte(1));
 
-			assert_eq!(ext.validate(&1, CALL, &normal, len).unwrap().longevity, 15);
+			assert_eq!(
+				ext.validate_only(Some(1).into(), CALL, &normal, len).unwrap().0.longevity,
+				15
+			);
 		})
 	}
 }
diff --git a/substrate/frame/system/src/extensions/check_non_zero_sender.rs b/substrate/frame/system/src/extensions/check_non_zero_sender.rs
index 06dc2bf177a..ec8c12b790d 100644
--- a/substrate/frame/system/src/extensions/check_non_zero_sender.rs
+++ b/substrate/frame/system/src/extensions/check_non_zero_sender.rs
@@ -18,13 +18,12 @@
 use crate::Config;
 use codec::{Decode, Encode};
 use core::marker::PhantomData;
-use frame_support::{dispatch::DispatchInfo, DefaultNoBound};
+use frame_support::{traits::OriginTrait, DefaultNoBound};
 use scale_info::TypeInfo;
 use sp_runtime::{
-	traits::{DispatchInfoOf, Dispatchable, SignedExtension},
-	transaction_validity::{
-		InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction,
-	},
+	impl_tx_ext_default,
+	traits::{DispatchInfoOf, TransactionExtension},
+	transaction_validity::InvalidTransaction,
 };
 
 /// Check to ensure that the sender is not the zero address.
@@ -45,66 +44,80 @@ impl<T: Config + Send + Sync> core::fmt::Debug for CheckNonZeroSender<T> {
 }
 
 impl<T: Config + Send + Sync> CheckNonZeroSender<T> {
-	/// Create new `SignedExtension` to check runtime version.
+	/// Create new `TransactionExtension` to check runtime version.
 	pub fn new() -> Self {
 		Self(core::marker::PhantomData)
 	}
 }
 
-impl<T: Config + Send + Sync> SignedExtension for CheckNonZeroSender<T>
-where
-	T::RuntimeCall: Dispatchable<Info = DispatchInfo>,
-{
-	type AccountId = T::AccountId;
-	type Call = T::RuntimeCall;
-	type AdditionalSigned = ();
-	type Pre = ();
+impl<T: Config + Send + Sync> TransactionExtension<T::RuntimeCall> for CheckNonZeroSender<T> {
 	const IDENTIFIER: &'static str = "CheckNonZeroSender";
+	type Implicit = ();
+	type Val = ();
+	type Pre = ();
 
-	fn additional_signed(&self) -> core::result::Result<(), TransactionValidityError> {
-		Ok(())
-	}
-
-	fn pre_dispatch(
-		self,
-		who: &Self::AccountId,
-		call: &Self::Call,
-		info: &DispatchInfoOf<Self::Call>,
-		len: usize,
-	) -> Result<Self::Pre, TransactionValidityError> {
-		self.validate(who, call, info, len).map(|_| ())
+	fn weight(&self, _: &T::RuntimeCall) -> sp_weights::Weight {
+		<T::ExtensionsWeightInfo as super::WeightInfo>::check_non_zero_sender()
 	}
 
 	fn validate(
 		&self,
-		who: &Self::AccountId,
-		_call: &Self::Call,
-		_info: &DispatchInfoOf<Self::Call>,
+		origin: <T as Config>::RuntimeOrigin,
+		_call: &T::RuntimeCall,
+		_info: &DispatchInfoOf<T::RuntimeCall>,
 		_len: usize,
-	) -> TransactionValidity {
-		if who.using_encoded(|d| d.iter().all(|x| *x == 0)) {
-			return Err(TransactionValidityError::Invalid(InvalidTransaction::BadSigner))
+		_self_implicit: Self::Implicit,
+		_inherited_implication: &impl Encode,
+	) -> sp_runtime::traits::ValidateResult<Self::Val, T::RuntimeCall> {
+		if let Some(who) = origin.as_signer() {
+			if who.using_encoded(|d| d.iter().all(|x| *x == 0)) {
+				return Err(InvalidTransaction::BadSigner.into())
+			}
 		}
-		Ok(ValidTransaction::default())
+		Ok((Default::default(), (), origin))
 	}
+	impl_tx_ext_default!(T::RuntimeCall; prepare);
 }
 
 #[cfg(test)]
 mod tests {
 	use super::*;
 	use crate::mock::{new_test_ext, Test, CALL};
-	use frame_support::{assert_noop, assert_ok};
+	use frame_support::{assert_ok, dispatch::DispatchInfo};
+	use sp_runtime::{
+		traits::{AsTransactionAuthorizedOrigin, DispatchTransaction},
+		transaction_validity::TransactionValidityError,
+	};
 
 	#[test]
 	fn zero_account_ban_works() {
 		new_test_ext().execute_with(|| {
 			let info = DispatchInfo::default();
 			let len = 0_usize;
-			assert_noop!(
-				CheckNonZeroSender::<Test>::new().validate(&0, CALL, &info, len),
-				InvalidTransaction::BadSigner
+			assert_eq!(
+				CheckNonZeroSender::<Test>::new()
+					.validate_only(Some(0).into(), CALL, &info, len)
+					.unwrap_err(),
+				TransactionValidityError::from(InvalidTransaction::BadSigner)
 			);
-			assert_ok!(CheckNonZeroSender::<Test>::new().validate(&1, CALL, &info, len));
+			assert_ok!(CheckNonZeroSender::<Test>::new().validate_only(
+				Some(1).into(),
+				CALL,
+				&info,
+				len
+			));
+		})
+	}
+
+	#[test]
+	fn unsigned_origin_works() {
+		new_test_ext().execute_with(|| {
+			let info = DispatchInfo::default();
+			let len = 0_usize;
+			let (_, _, origin) = CheckNonZeroSender::<Test>::new()
+				.validate(None.into(), CALL, &info, len, (), CALL)
+				.unwrap();
+			assert!(!origin.is_transaction_authorized());
 		})
 	}
 }
diff --git a/substrate/frame/system/src/extensions/check_nonce.rs b/substrate/frame/system/src/extensions/check_nonce.rs
index 3535870d1b5..d96d2c2c066 100644
--- a/substrate/frame/system/src/extensions/check_nonce.rs
+++ b/substrate/frame/system/src/extensions/check_nonce.rs
@@ -18,23 +18,32 @@
 use crate::Config;
 use alloc::vec;
 use codec::{Decode, Encode};
-use frame_support::dispatch::DispatchInfo;
+use frame_support::{dispatch::DispatchInfo, RuntimeDebugNoBound};
 use scale_info::TypeInfo;
 use sp_runtime::{
-	traits::{DispatchInfoOf, Dispatchable, One, SignedExtension, Zero},
+	traits::{
+		AsSystemOriginSigner, DispatchInfoOf, Dispatchable, One, PostDispatchInfoOf,
+		TransactionExtension, ValidateResult, Zero,
+	},
 	transaction_validity::{
-		InvalidTransaction, TransactionLongevity, TransactionValidity, TransactionValidityError,
-		ValidTransaction,
+		InvalidTransaction, TransactionLongevity, TransactionValidityError, ValidTransaction,
 	},
+	DispatchResult, Saturating,
 };
+use sp_weights::Weight;
 
 /// Nonce check and increment to give replay protection for transactions.
 ///
 /// # Transaction Validity
 ///
 /// This extension affects `requires` and `provides` tags of validity, but DOES NOT
-/// set the `priority` field. Make sure that AT LEAST one of the signed extension sets
+/// set the `priority` field. Make sure that AT LEAST one of the transaction extension sets
 /// some kind of priority upon validating transactions.
+///
+/// The preparation step assumes that the nonce information has not changed since the validation
+/// step. This means that other extensions ahead of `CheckNonce` in the pipeline must not alter the
+/// nonce during their own preparation step, or else the transaction may be rejected during dispatch
+/// or lead to an inconsistent account state.
 #[derive(Encode, Decode, Clone, Eq, PartialEq, TypeInfo)]
 #[scale_info(skip_type_params(T))]
 pub struct CheckNonce<T: Config>(#[codec(compact)] pub T::Nonce);
@@ -58,83 +67,122 @@ impl<T: Config> core::fmt::Debug for CheckNonce<T> {
 	}
 }
 
-impl<T: Config> SignedExtension for CheckNonce<T>
+/// Operation to perform from `validate` to `prepare` in [`CheckNonce`] transaction extension.
+#[derive(RuntimeDebugNoBound)]
+pub enum Val<T: Config> {
+	/// Account and its nonce to check for.
+	CheckNonce((T::AccountId, T::Nonce)),
+	/// Weight to refund.
+	Refund(Weight),
+}
+
+/// Operation to perform from `prepare` to `post_dispatch_details` in [`CheckNonce`] transaction
+/// extension.
+#[derive(RuntimeDebugNoBound)]
+pub enum Pre {
+	/// The transaction extension weight should not be refunded.
+	NonceChecked,
+	/// The transaction extension weight should be refunded.
+	Refund(Weight),
+}
+
+impl<T: Config> TransactionExtension<T::RuntimeCall> for CheckNonce<T>
 where
 	T::RuntimeCall: Dispatchable<Info = DispatchInfo>,
+	<T::RuntimeCall as Dispatchable>::RuntimeOrigin: AsSystemOriginSigner<T::AccountId> + Clone,
 {
-	type AccountId = T::AccountId;
-	type Call = T::RuntimeCall;
-	type AdditionalSigned = ();
-	type Pre = ();
 	const IDENTIFIER: &'static str = "CheckNonce";
+	type Implicit = ();
+	type Val = Val<T>;
+	type Pre = Pre;
 
-	fn additional_signed(&self) -> core::result::Result<(), TransactionValidityError> {
-		Ok(())
-	}
-
-	fn pre_dispatch(
-		self,
-		who: &Self::AccountId,
-		_call: &Self::Call,
-		_info: &DispatchInfoOf<Self::Call>,
-		_len: usize,
-	) -> Result<(), TransactionValidityError> {
-		let mut account = crate::Account::<T>::get(who);
-		if account.providers.is_zero() && account.sufficients.is_zero() {
-			// Nonce storage not paid for
-			return Err(InvalidTransaction::Payment.into())
-		}
-		if self.0 != account.nonce {
-			return Err(if self.0 < account.nonce {
-				InvalidTransaction::Stale
-			} else {
-				InvalidTransaction::Future
-			}
-			.into())
-		}
-		account.nonce += T::Nonce::one();
-		crate::Account::<T>::insert(who, account);
-		Ok(())
+	fn weight(&self, _: &T::RuntimeCall) -> sp_weights::Weight {
+		<T::ExtensionsWeightInfo as super::WeightInfo>::check_nonce()
 	}
 
 	fn validate(
 		&self,
-		who: &Self::AccountId,
-		_call: &Self::Call,
-		_info: &DispatchInfoOf<Self::Call>,
+		origin: <T as Config>::RuntimeOrigin,
+		call: &T::RuntimeCall,
+		_info: &DispatchInfoOf<T::RuntimeCall>,
 		_len: usize,
-	) -> TransactionValidity {
+		_self_implicit: Self::Implicit,
+		_inherited_implication: &impl Encode,
+	) -> ValidateResult<Self::Val, T::RuntimeCall> {
+		let Some(who) = origin.as_system_origin_signer() else {
+			return Ok((Default::default(), Val::Refund(self.weight(call)), origin))
+		};
 		let account = crate::Account::<T>::get(who);
 		if account.providers.is_zero() && account.sufficients.is_zero() {
 			// Nonce storage not paid for
-			return InvalidTransaction::Payment.into()
+			return Err(InvalidTransaction::Payment.into())
 		}
 		if self.0 < account.nonce {
-			return InvalidTransaction::Stale.into()
+			return Err(InvalidTransaction::Stale.into())
 		}
 
-		let provides = vec![Encode::encode(&(who, self.0))];
+		let provides = vec![Encode::encode(&(&who, self.0))];
 		let requires = if account.nonce < self.0 {
-			vec![Encode::encode(&(who, self.0 - One::one()))]
+			vec![Encode::encode(&(&who, self.0.saturating_sub(One::one())))]
 		} else {
 			vec![]
 		};
 
-		Ok(ValidTransaction {
+		let validity = ValidTransaction {
 			priority: 0,
 			requires,
 			provides,
 			longevity: TransactionLongevity::max_value(),
 			propagate: true,
-		})
+		};
+
+		Ok((validity, Val::CheckNonce((who.clone(), account.nonce)), origin))
+	}
+
+	fn prepare(
+		self,
+		val: Self::Val,
+		_origin: &T::RuntimeOrigin,
+		_call: &T::RuntimeCall,
+		_info: &DispatchInfoOf<T::RuntimeCall>,
+		_len: usize,
+	) -> Result<Self::Pre, TransactionValidityError> {
+		let (who, mut nonce) = match val {
+			Val::CheckNonce((who, nonce)) => (who, nonce),
+			Val::Refund(weight) => return Ok(Pre::Refund(weight)),
+		};
+
+		// `self.0 < nonce` already checked in `validate`.
+		if self.0 > nonce {
+			return Err(InvalidTransaction::Future.into())
+		}
+		nonce += T::Nonce::one();
+		crate::Account::<T>::mutate(who, |account| account.nonce = nonce);
+		Ok(Pre::NonceChecked)
+	}
+
+	fn post_dispatch_details(
+		pre: Self::Pre,
+		_info: &DispatchInfo,
+		_post_info: &PostDispatchInfoOf<T::RuntimeCall>,
+		_len: usize,
+		_result: &DispatchResult,
+	) -> Result<Weight, TransactionValidityError> {
+		match pre {
+			Pre::NonceChecked => Ok(Weight::zero()),
+			Pre::Refund(weight) => Ok(weight),
+		}
 	}
 }
 
 #[cfg(test)]
 mod tests {
 	use super::*;
-	use crate::mock::{new_test_ext, Test, CALL};
-	use frame_support::{assert_noop, assert_ok};
+	use crate::mock::{new_test_ext, RuntimeCall, Test, CALL};
+	use frame_support::{
+		assert_ok, assert_storage_noop, dispatch::GetDispatchInfo, traits::OriginTrait,
+	};
+	use sp_runtime::traits::{AsTransactionAuthorizedOrigin, DispatchTransaction};
 
 	#[test]
 	fn signed_ext_check_nonce_works() {
@@ -152,22 +200,45 @@ mod tests {
 			let info = DispatchInfo::default();
 			let len = 0_usize;
 			// stale
-			assert_noop!(
-				CheckNonce::<Test>(0u64.into()).validate(&1, CALL, &info, len),
-				InvalidTransaction::Stale
-			);
-			assert_noop!(
-				CheckNonce::<Test>(0u64.into()).pre_dispatch(&1, CALL, &info, len),
-				InvalidTransaction::Stale
-			);
+			assert_storage_noop!({
+				assert_eq!(
+					CheckNonce::<Test>(0u64.into())
+						.validate_only(Some(1).into(), CALL, &info, len)
+						.unwrap_err(),
+					TransactionValidityError::Invalid(InvalidTransaction::Stale)
+				);
+				assert_eq!(
+					CheckNonce::<Test>(0u64.into())
+						.validate_and_prepare(Some(1).into(), CALL, &info, len)
+						.unwrap_err(),
+					TransactionValidityError::Invalid(InvalidTransaction::Stale)
+				);
+			});
 			// correct
-			assert_ok!(CheckNonce::<Test>(1u64.into()).validate(&1, CALL, &info, len));
-			assert_ok!(CheckNonce::<Test>(1u64.into()).pre_dispatch(&1, CALL, &info, len));
+			assert_ok!(CheckNonce::<Test>(1u64.into()).validate_only(
+				Some(1).into(),
+				CALL,
+				&info,
+				len
+			));
+			assert_ok!(CheckNonce::<Test>(1u64.into()).validate_and_prepare(
+				Some(1).into(),
+				CALL,
+				&info,
+				len
+			));
 			// future
-			assert_ok!(CheckNonce::<Test>(5u64.into()).validate(&1, CALL, &info, len));
-			assert_noop!(
-				CheckNonce::<Test>(5u64.into()).pre_dispatch(&1, CALL, &info, len),
-				InvalidTransaction::Future
+			assert_ok!(CheckNonce::<Test>(5u64.into()).validate_only(
+				Some(1).into(),
+				CALL,
+				&info,
+				len
+			));
+			assert_eq!(
+				CheckNonce::<Test>(5u64.into())
+					.validate_and_prepare(Some(1).into(), CALL, &info, len)
+					.unwrap_err(),
+				TransactionValidityError::Invalid(InvalidTransaction::Future)
 			);
 		})
 	}
@@ -198,20 +269,133 @@ mod tests {
 			let info = DispatchInfo::default();
 			let len = 0_usize;
 			// Both providers and sufficients zero
-			assert_noop!(
-				CheckNonce::<Test>(1u64.into()).validate(&1, CALL, &info, len),
-				InvalidTransaction::Payment
-			);
-			assert_noop!(
-				CheckNonce::<Test>(1u64.into()).pre_dispatch(&1, CALL, &info, len),
-				InvalidTransaction::Payment
-			);
+			assert_storage_noop!({
+				assert_eq!(
+					CheckNonce::<Test>(1u64.into())
+						.validate_only(Some(1).into(), CALL, &info, len)
+						.unwrap_err(),
+					TransactionValidityError::Invalid(InvalidTransaction::Payment)
+				);
+				assert_eq!(
+					CheckNonce::<Test>(1u64.into())
+						.validate_and_prepare(Some(1).into(), CALL, &info, len)
+						.unwrap_err(),
+					TransactionValidityError::Invalid(InvalidTransaction::Payment)
+				);
+			});
 			// Non-zero providers
-			assert_ok!(CheckNonce::<Test>(1u64.into()).validate(&2, CALL, &info, len));
-			assert_ok!(CheckNonce::<Test>(1u64.into()).pre_dispatch(&2, CALL, &info, len));
+			assert_ok!(CheckNonce::<Test>(1u64.into()).validate_only(
+				Some(2).into(),
+				CALL,
+				&info,
+				len
+			));
+			assert_ok!(CheckNonce::<Test>(1u64.into()).validate_and_prepare(
+				Some(2).into(),
+				CALL,
+				&info,
+				len
+			));
 			// Non-zero sufficients
-			assert_ok!(CheckNonce::<Test>(1u64.into()).validate(&3, CALL, &info, len));
-			assert_ok!(CheckNonce::<Test>(1u64.into()).pre_dispatch(&3, CALL, &info, len));
+			assert_ok!(CheckNonce::<Test>(1u64.into()).validate_only(
+				Some(3).into(),
+				CALL,
+				&info,
+				len
+			));
+			assert_ok!(CheckNonce::<Test>(1u64.into()).validate_and_prepare(
+				Some(3).into(),
+				CALL,
+				&info,
+				len
+			));
+		})
+	}
+
+	#[test]
+	fn unsigned_check_nonce_works() {
+		new_test_ext().execute_with(|| {
+			let info = DispatchInfo::default();
+			let len = 0_usize;
+			let (_, val, origin) = CheckNonce::<Test>(1u64.into())
+				.validate(None.into(), CALL, &info, len, (), CALL)
+				.unwrap();
+			assert!(!origin.is_transaction_authorized());
+			assert_ok!(CheckNonce::<Test>(1u64.into()).prepare(val, &origin, CALL, &info, len));
+		})
+	}
+
+	#[test]
+	fn check_nonce_preserves_account_data() {
+		new_test_ext().execute_with(|| {
+			crate::Account::<Test>::insert(
+				1,
+				crate::AccountInfo {
+					nonce: 1u64.into(),
+					consumers: 0,
+					providers: 1,
+					sufficients: 0,
+					data: 0,
+				},
+			);
+			let info = DispatchInfo::default();
+			let len = 0_usize;
+			// run the validation step
+			let (_, val, origin) = CheckNonce::<Test>(1u64.into())
+				.validate(Some(1).into(), CALL, &info, len, (), CALL)
+				.unwrap();
+			// mutate `AccountData` for the caller
+			crate::Account::<Test>::mutate(1, |info| {
+				info.data = 42;
+			});
+			// run the preparation step
+			assert_ok!(CheckNonce::<Test>(1u64.into()).prepare(val, &origin, CALL, &info, len));
+			// only the nonce should be altered by the preparation step
+			let expected_info = crate::AccountInfo {
+				nonce: 2u64.into(),
+				consumers: 0,
+				providers: 1,
+				sufficients: 0,
+				data: 42,
+			};
+			assert_eq!(crate::Account::<Test>::get(1), expected_info);
+		})
+	}
+
+	#[test]
+	fn check_nonce_skipped_and_refund_for_other_origins() {
+		new_test_ext().execute_with(|| {
+			let ext = CheckNonce::<Test>(1u64.into());
+
+			let mut info = CALL.get_dispatch_info();
+			info.extension_weight = ext.weight(CALL);
+
+			// Ensure we test the refund.
+			assert!(info.extension_weight != Weight::zero());
+
+			let len = CALL.encoded_size();
+
+			let origin = crate::RawOrigin::Root.into();
+			let (pre, origin) = ext.validate_and_prepare(origin, CALL, &info, len).unwrap();
+
+			assert!(origin.as_system_ref().unwrap().is_root());
+
+			let pd_res = Ok(());
+			let mut post_info = frame_support::dispatch::PostDispatchInfo {
+				actual_weight: Some(info.total_weight()),
+				pays_fee: Default::default(),
+			};
+
+			<CheckNonce<Test> as TransactionExtension<RuntimeCall>>::post_dispatch(
+				pre,
+				&info,
+				&mut post_info,
+				len,
+				&pd_res,
+			)
+			.unwrap();
+
+			assert_eq!(post_info.actual_weight, Some(info.call_weight));
 		})
 	}
 }
diff --git a/substrate/frame/system/src/extensions/check_spec_version.rs b/substrate/frame/system/src/extensions/check_spec_version.rs
index ee7e6f2efd0..ff86c6cd469 100644
--- a/substrate/frame/system/src/extensions/check_spec_version.rs
+++ b/substrate/frame/system/src/extensions/check_spec_version.rs
@@ -19,7 +19,7 @@ use crate::{Config, Pallet};
 use codec::{Decode, Encode};
 use scale_info::TypeInfo;
 use sp_runtime::{
-	traits::{DispatchInfoOf, SignedExtension},
+	impl_tx_ext_default, traits::TransactionExtension,
 	transaction_validity::TransactionValidityError,
 };
 
@@ -46,30 +46,24 @@ impl<T: Config + Send + Sync> core::fmt::Debug for CheckSpecVersion<T> {
 }
 
 impl<T: Config + Send + Sync> CheckSpecVersion<T> {
-	/// Create new `SignedExtension` to check runtime version.
+	/// Create new `TransactionExtension` to check runtime version.
 	pub fn new() -> Self {
 		Self(core::marker::PhantomData)
 	}
 }
 
-impl<T: Config + Send + Sync> SignedExtension for CheckSpecVersion<T> {
-	type AccountId = T::AccountId;
-	type Call = <T as Config>::RuntimeCall;
-	type AdditionalSigned = u32;
-	type Pre = ();
+impl<T: Config + Send + Sync> TransactionExtension<<T as Config>::RuntimeCall>
+	for CheckSpecVersion<T>
+{
 	const IDENTIFIER: &'static str = "CheckSpecVersion";
-
-	fn additional_signed(&self) -> Result<Self::AdditionalSigned, TransactionValidityError> {
+	type Implicit = u32;
+	fn implicit(&self) -> Result<Self::Implicit, TransactionValidityError> {
 		Ok(<Pallet<T>>::runtime_version().spec_version)
 	}
-
-	fn pre_dispatch(
-		self,
-		who: &Self::AccountId,
-		call: &Self::Call,
-		info: &DispatchInfoOf<Self::Call>,
-		len: usize,
-	) -> Result<Self::Pre, TransactionValidityError> {
-		self.validate(who, call, info, len).map(|_| ())
+	type Val = ();
+	type Pre = ();
+	fn weight(&self, _: &<T as Config>::RuntimeCall) -> sp_weights::Weight {
+		<T::ExtensionsWeightInfo as super::WeightInfo>::check_spec_version()
 	}
+	impl_tx_ext_default!(<T as Config>::RuntimeCall; validate prepare);
 }
diff --git a/substrate/frame/system/src/extensions/check_tx_version.rs b/substrate/frame/system/src/extensions/check_tx_version.rs
index 15983c2cd08..e3b7dfe7c92 100644
--- a/substrate/frame/system/src/extensions/check_tx_version.rs
+++ b/substrate/frame/system/src/extensions/check_tx_version.rs
@@ -19,7 +19,7 @@ use crate::{Config, Pallet};
 use codec::{Decode, Encode};
 use scale_info::TypeInfo;
 use sp_runtime::{
-	traits::{DispatchInfoOf, SignedExtension},
+	impl_tx_ext_default, traits::TransactionExtension,
 	transaction_validity::TransactionValidityError,
 };
 
@@ -46,29 +46,24 @@ impl<T: Config + Send + Sync> core::fmt::Debug for CheckTxVersion<T> {
 }
 
 impl<T: Config + Send + Sync> CheckTxVersion<T> {
-	/// Create new `SignedExtension` to check transaction version.
+	/// Create new `TransactionExtension` to check transaction version.
 	pub fn new() -> Self {
 		Self(core::marker::PhantomData)
 	}
 }
 
-impl<T: Config + Send + Sync> SignedExtension for CheckTxVersion<T> {
-	type AccountId = T::AccountId;
-	type Call = <T as Config>::RuntimeCall;
-	type AdditionalSigned = u32;
-	type Pre = ();
+impl<T: Config + Send + Sync> TransactionExtension<<T as Config>::RuntimeCall>
+	for CheckTxVersion<T>
+{
 	const IDENTIFIER: &'static str = "CheckTxVersion";
-
-	fn additional_signed(&self) -> Result<Self::AdditionalSigned, TransactionValidityError> {
+	type Implicit = u32;
+	fn implicit(&self) -> Result<Self::Implicit, TransactionValidityError> {
 		Ok(<Pallet<T>>::runtime_version().transaction_version)
 	}
-	fn pre_dispatch(
-		self,
-		who: &Self::AccountId,
-		call: &Self::Call,
-		info: &DispatchInfoOf<Self::Call>,
-		len: usize,
-	) -> Result<Self::Pre, TransactionValidityError> {
-		self.validate(who, call, info, len).map(|_| ())
+	type Val = ();
+	type Pre = ();
+	fn weight(&self, _: &<T as Config>::RuntimeCall) -> sp_weights::Weight {
+		<T::ExtensionsWeightInfo as super::WeightInfo>::check_tx_version()
 	}
+	impl_tx_ext_default!(<T as Config>::RuntimeCall; validate prepare);
 }
diff --git a/substrate/frame/system/src/extensions/check_weight.rs b/substrate/frame/system/src/extensions/check_weight.rs
index 22da2a5b987..131057f54a7 100644
--- a/substrate/frame/system/src/extensions/check_weight.rs
+++ b/substrate/frame/system/src/extensions/check_weight.rs
@@ -23,8 +23,10 @@ use frame_support::{
 };
 use scale_info::TypeInfo;
 use sp_runtime::{
-	traits::{DispatchInfoOf, Dispatchable, PostDispatchInfoOf, SignedExtension},
-	transaction_validity::{InvalidTransaction, TransactionValidity, TransactionValidityError},
+	traits::{
+		DispatchInfoOf, Dispatchable, PostDispatchInfoOf, TransactionExtension, ValidateResult,
+	},
+	transaction_validity::{InvalidTransaction, TransactionValidityError, ValidTransaction},
 	DispatchResult,
 };
 use sp_weights::Weight;
@@ -50,11 +52,11 @@ where
 	) -> Result<(), TransactionValidityError> {
 		let max = T::BlockWeights::get().get(info.class).max_extrinsic;
 		match max {
-			Some(max) if info.weight.any_gt(max) => {
+			Some(max) if info.total_weight().any_gt(max) => {
 				log::debug!(
 					target: LOG_TARGET,
 					"Extrinsic {} is greater than the max extrinsic {}",
-					info.weight,
+					info.total_weight(),
 					max,
 				);
 
@@ -89,43 +91,73 @@ where
 		}
 	}
 
-	/// Creates new `SignedExtension` to check weight of the extrinsic.
+	/// Creates new `TransactionExtension` to check weight of the extrinsic.
 	pub fn new() -> Self {
 		Self(Default::default())
 	}
 
+	/// Do the validate checks. This can be applied to both signed and unsigned.
+	///
+	/// It only checks that the block weight and length limit will not exceed.
+	///
+	/// Returns the transaction validity and the next block length, to be used in `prepare`.
+	pub fn do_validate(
+		info: &DispatchInfoOf<T::RuntimeCall>,
+		len: usize,
+	) -> Result<(ValidTransaction, u32), TransactionValidityError> {
+		// If they return `Ok`, then it is below the limit.
+		let next_len = Self::check_block_length(info, len)?;
+		// during validation we skip block limit check. Since the `validate_transaction`
+		// call runs on an empty block anyway, by this we prevent `on_initialize` weight
+		// consumption from causing false negatives.
+		Self::check_extrinsic_weight(info)?;
+
+		Ok((Default::default(), next_len))
+	}
+
 	/// Do the pre-dispatch checks. This can be applied to both signed and unsigned.
 	///
 	/// It checks and notes the new weight and length.
-	pub fn do_pre_dispatch(
+	pub fn do_prepare(
 		info: &DispatchInfoOf<T::RuntimeCall>,
 		len: usize,
+		next_len: u32,
 	) -> Result<(), TransactionValidityError> {
-		let next_len = Self::check_block_length(info, len)?;
-
 		let all_weight = Pallet::<T>::block_weight();
 		let maximum_weight = T::BlockWeights::get();
 		let next_weight =
 			calculate_consumed_weight::<T::RuntimeCall>(&maximum_weight, all_weight, info, len)?;
-		Self::check_extrinsic_weight(info)?;
+		// Extrinsic weight already checked in `validate`.
 
 		crate::AllExtrinsicsLen::<T>::put(next_len);
 		crate::BlockWeight::<T>::put(next_weight);
 		Ok(())
 	}
 
-	/// Do the validate checks. This can be applied to both signed and unsigned.
-	///
-	/// It only checks that the block weight and length limit will not exceed.
-	pub fn do_validate(info: &DispatchInfoOf<T::RuntimeCall>, len: usize) -> TransactionValidity {
-		// ignore the next length. If they return `Ok`, then it is below the limit.
-		let _ = Self::check_block_length(info, len)?;
-		// during validation we skip block limit check. Since the `validate_transaction`
-		// call runs on an empty block anyway, by this we prevent `on_initialize` weight
-		// consumption from causing false negatives.
-		Self::check_extrinsic_weight(info)?;
+	pub fn do_post_dispatch(
+		info: &DispatchInfoOf<T::RuntimeCall>,
+		post_info: &PostDispatchInfoOf<T::RuntimeCall>,
+	) -> Result<(), TransactionValidityError> {
+		let unspent = post_info.calc_unspent(info);
+		if unspent.any_gt(Weight::zero()) {
+			crate::BlockWeight::<T>::mutate(|current_weight| {
+				current_weight.reduce(unspent, info.class);
+			})
+		}
 
-		Ok(Default::default())
+		log::trace!(
+			target: LOG_TARGET,
+			"Used block weight: {:?}",
+			crate::BlockWeight::<T>::get(),
+		);
+
+		log::trace!(
+			target: LOG_TARGET,
+			"Used block length: {:?}",
+			Pallet::<T>::all_extrinsics_len(),
+		);
+
+		Ok(())
 	}
 }
 
@@ -143,7 +175,7 @@ where
 {
 	// Also Consider extrinsic length as proof weight.
 	let extrinsic_weight = info
-		.weight
+		.total_weight()
 		.saturating_add(maximum_weight.get(info.class).base_extrinsic)
 		.saturating_add(Weight::from_parts(0, len as u64));
 	let limit_per_class = maximum_weight.get(info.class);
@@ -201,83 +233,78 @@ where
 	Ok(all_weight)
 }
 
-impl<T: Config + Send + Sync> SignedExtension for CheckWeight<T>
+impl<T: Config + Send + Sync> TransactionExtension<T::RuntimeCall> for CheckWeight<T>
 where
 	T::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
 {
-	type AccountId = T::AccountId;
-	type Call = T::RuntimeCall;
-	type AdditionalSigned = ();
-	type Pre = ();
 	const IDENTIFIER: &'static str = "CheckWeight";
+	type Implicit = ();
+	type Pre = ();
+	type Val = u32; /* next block length */
 
-	fn additional_signed(&self) -> core::result::Result<(), TransactionValidityError> {
-		Ok(())
+	fn weight(&self, _: &T::RuntimeCall) -> Weight {
+		<T::ExtensionsWeightInfo as super::WeightInfo>::check_weight()
 	}
 
-	fn pre_dispatch(
-		self,
-		_who: &Self::AccountId,
-		_call: &Self::Call,
-		info: &DispatchInfoOf<Self::Call>,
+	fn validate(
+		&self,
+		origin: T::RuntimeOrigin,
+		_call: &T::RuntimeCall,
+		info: &DispatchInfoOf<T::RuntimeCall>,
 		len: usize,
-	) -> Result<(), TransactionValidityError> {
-		Self::do_pre_dispatch(info, len)
+		_self_implicit: Self::Implicit,
+		_inherited_implication: &impl Encode,
+	) -> ValidateResult<Self::Val, T::RuntimeCall> {
+		let (validity, next_len) = Self::do_validate(info, len)?;
+		Ok((validity, next_len, origin))
 	}
 
-	fn validate(
-		&self,
-		_who: &Self::AccountId,
-		_call: &Self::Call,
-		info: &DispatchInfoOf<Self::Call>,
+	fn prepare(
+		self,
+		val: Self::Val,
+		_origin: &T::RuntimeOrigin,
+		_call: &T::RuntimeCall,
+		info: &DispatchInfoOf<T::RuntimeCall>,
 		len: usize,
-	) -> TransactionValidity {
-		Self::do_validate(info, len)
+	) -> Result<Self::Pre, TransactionValidityError> {
+		Self::do_prepare(info, len, val)
 	}
 
-	fn pre_dispatch_unsigned(
-		_call: &Self::Call,
-		info: &DispatchInfoOf<Self::Call>,
+	fn post_dispatch_details(
+		_pre: Self::Pre,
+		info: &DispatchInfoOf<T::RuntimeCall>,
+		post_info: &PostDispatchInfoOf<T::RuntimeCall>,
+		_len: usize,
+		_result: &DispatchResult,
+	) -> Result<Weight, TransactionValidityError> {
+		Self::do_post_dispatch(info, post_info)?;
+		Ok(Weight::zero())
+	}
+
+	fn bare_validate(
+		_call: &T::RuntimeCall,
+		info: &DispatchInfoOf<T::RuntimeCall>,
 		len: usize,
-	) -> Result<(), TransactionValidityError> {
-		Self::do_pre_dispatch(info, len)
+	) -> frame_support::pallet_prelude::TransactionValidity {
+		Ok(Self::do_validate(info, len)?.0)
 	}
 
-	fn validate_unsigned(
-		_call: &Self::Call,
-		info: &DispatchInfoOf<Self::Call>,
+	fn bare_validate_and_prepare(
+		_call: &T::RuntimeCall,
+		info: &DispatchInfoOf<T::RuntimeCall>,
 		len: usize,
-	) -> TransactionValidity {
-		Self::do_validate(info, len)
+	) -> Result<(), TransactionValidityError> {
+		let (_, next_len) = Self::do_validate(info, len)?;
+		Self::do_prepare(info, len, next_len)
 	}
 
-	fn post_dispatch(
-		_pre: Option<Self::Pre>,
-		info: &DispatchInfoOf<Self::Call>,
-		post_info: &PostDispatchInfoOf<Self::Call>,
+	fn bare_post_dispatch(
+		info: &DispatchInfoOf<T::RuntimeCall>,
+		post_info: &mut PostDispatchInfoOf<T::RuntimeCall>,
 		_len: usize,
 		_result: &DispatchResult,
 	) -> Result<(), TransactionValidityError> {
-		let unspent = post_info.calc_unspent(info);
-		if unspent.any_gt(Weight::zero()) {
-			crate::BlockWeight::<T>::mutate(|current_weight| {
-				current_weight.reduce(unspent, info.class);
-			})
-		}
-
-		log::trace!(
-			target: LOG_TARGET,
-			"Used block weight: {:?}",
-			crate::BlockWeight::<T>::get(),
-		);
-
-		log::trace!(
-			target: LOG_TARGET,
-			"Used block length: {:?}",
-			Pallet::<T>::all_extrinsics_len(),
-		);
-
-		Ok(())
+		Self::do_post_dispatch(info, post_info)
 	}
 }
 
@@ -302,6 +329,7 @@ mod tests {
 	};
 	use core::marker::PhantomData;
 	use frame_support::{assert_err, assert_ok, dispatch::Pays, weights::Weight};
+	use sp_runtime::traits::DispatchTransaction;
 
 	fn block_weights() -> crate::limits::BlockWeights {
 		<Test as crate::Config>::BlockWeights::get()
@@ -327,7 +355,7 @@ mod tests {
 		fn check(call: impl FnOnce(&DispatchInfo, usize)) {
 			new_test_ext().execute_with(|| {
 				let max = DispatchInfo {
-					weight: Weight::MAX,
+					call_weight: Weight::MAX,
 					class: DispatchClass::Mandatory,
 					..Default::default()
 				};
@@ -338,7 +366,8 @@ mod tests {
 		}
 
 		check(|max, len| {
-			assert_ok!(CheckWeight::<Test>::do_pre_dispatch(max, len));
+			let next_len = CheckWeight::<Test>::check_block_length(max, len).unwrap();
+			assert_ok!(CheckWeight::<Test>::do_prepare(max, len, next_len));
 			assert_eq!(System::block_weight().total(), Weight::MAX);
 			assert!(System::block_weight().total().ref_time() > block_weight_limit().ref_time());
 		});
@@ -351,7 +380,7 @@ mod tests {
 	fn normal_extrinsic_limited_by_maximum_extrinsic_weight() {
 		new_test_ext().execute_with(|| {
 			let max = DispatchInfo {
-				weight: block_weights().get(DispatchClass::Normal).max_extrinsic.unwrap() +
+				call_weight: block_weights().get(DispatchClass::Normal).max_extrinsic.unwrap() +
 					Weight::from_parts(1, 0),
 				class: DispatchClass::Normal,
 				..Default::default()
@@ -374,11 +403,14 @@ mod tests {
 				.unwrap_or_else(|| weights.max_block);
 			let base_weight = weights.get(DispatchClass::Operational).base_extrinsic;
 
-			let weight = operational_limit - base_weight;
-			let okay =
-				DispatchInfo { weight, class: DispatchClass::Operational, ..Default::default() };
+			let call_weight = operational_limit - base_weight;
+			let okay = DispatchInfo {
+				call_weight,
+				class: DispatchClass::Operational,
+				..Default::default()
+			};
 			let max = DispatchInfo {
-				weight: weight + Weight::from_parts(1, 0),
+				call_weight: call_weight + Weight::from_parts(1, 0),
 				class: DispatchClass::Operational,
 				..Default::default()
 			};
@@ -410,18 +442,20 @@ mod tests {
 			// So normal extrinsic can be 758 weight (-5 for base extrinsic weight)
 			// And Operational can be 246 to produce a full block (-10 for base)
 			let max_normal =
-				DispatchInfo { weight: Weight::from_parts(753, 0), ..Default::default() };
+				DispatchInfo { call_weight: Weight::from_parts(753, 0), ..Default::default() };
 			let rest_operational = DispatchInfo {
-				weight: Weight::from_parts(246, 0),
+				call_weight: Weight::from_parts(246, 0),
 				class: DispatchClass::Operational,
 				..Default::default()
 			};
 
 			let len = 0_usize;
 
-			assert_ok!(CheckWeight::<Test>::do_pre_dispatch(&max_normal, len));
+			let next_len = CheckWeight::<Test>::check_block_length(&max_normal, len).unwrap();
+			assert_ok!(CheckWeight::<Test>::do_prepare(&max_normal, len, next_len));
 			assert_eq!(System::block_weight().total(), Weight::from_parts(768, 0));
-			assert_ok!(CheckWeight::<Test>::do_pre_dispatch(&rest_operational, len));
+			let next_len = CheckWeight::<Test>::check_block_length(&rest_operational, len).unwrap();
+			assert_ok!(CheckWeight::<Test>::do_prepare(&rest_operational, len, next_len));
 			assert_eq!(block_weight_limit(), Weight::from_parts(1024, u64::MAX));
 			assert_eq!(System::block_weight().total(), block_weight_limit().set_proof_size(0));
 			// Checking single extrinsic should not take current block weight into account.
@@ -434,19 +468,21 @@ mod tests {
 		new_test_ext().execute_with(|| {
 			// We switch the order of `full_block_with_normal_and_operational`
 			let max_normal =
-				DispatchInfo { weight: Weight::from_parts(753, 0), ..Default::default() };
+				DispatchInfo { call_weight: Weight::from_parts(753, 0), ..Default::default() };
 			let rest_operational = DispatchInfo {
-				weight: Weight::from_parts(246, 0),
+				call_weight: Weight::from_parts(246, 0),
 				class: DispatchClass::Operational,
 				..Default::default()
 			};
 
 			let len = 0_usize;
 
-			assert_ok!(CheckWeight::<Test>::do_pre_dispatch(&rest_operational, len));
+			let next_len = CheckWeight::<Test>::check_block_length(&rest_operational, len).unwrap();
+			assert_ok!(CheckWeight::<Test>::do_prepare(&rest_operational, len, next_len));
 			// Extra 20 here from block execution + base extrinsic weight
 			assert_eq!(System::block_weight().total(), Weight::from_parts(266, 0));
-			assert_ok!(CheckWeight::<Test>::do_pre_dispatch(&max_normal, len));
+			let next_len = CheckWeight::<Test>::check_block_length(&max_normal, len).unwrap();
+			assert_ok!(CheckWeight::<Test>::do_prepare(&max_normal, len, next_len));
 			assert_eq!(block_weight_limit(), Weight::from_parts(1024, u64::MAX));
 			assert_eq!(System::block_weight().total(), block_weight_limit().set_proof_size(0));
 		});
@@ -458,27 +494,30 @@ mod tests {
 			// An on_initialize takes up the whole block! (Every time!)
 			System::register_extra_weight_unchecked(Weight::MAX, DispatchClass::Mandatory);
 			let dispatch_normal = DispatchInfo {
-				weight: Weight::from_parts(251, 0),
+				call_weight: Weight::from_parts(251, 0),
 				class: DispatchClass::Normal,
 				..Default::default()
 			};
 			let dispatch_operational = DispatchInfo {
-				weight: Weight::from_parts(246, 0),
+				call_weight: Weight::from_parts(246, 0),
 				class: DispatchClass::Operational,
 				..Default::default()
 			};
 			let len = 0_usize;
 
+			let next_len = CheckWeight::<Test>::check_block_length(&dispatch_normal, len).unwrap();
 			assert_err!(
-				CheckWeight::<Test>::do_pre_dispatch(&dispatch_normal, len),
+				CheckWeight::<Test>::do_prepare(&dispatch_normal, len, next_len),
 				InvalidTransaction::ExhaustsResources
 			);
+			let next_len =
+				CheckWeight::<Test>::check_block_length(&dispatch_operational, len).unwrap();
 			// Thank goodness we can still do an operational transaction to possibly save the
 			// blockchain.
-			assert_ok!(CheckWeight::<Test>::do_pre_dispatch(&dispatch_operational, len));
+			assert_ok!(CheckWeight::<Test>::do_prepare(&dispatch_operational, len, next_len));
 			// Not too much though
 			assert_err!(
-				CheckWeight::<Test>::do_pre_dispatch(&dispatch_operational, len),
+				CheckWeight::<Test>::do_prepare(&dispatch_operational, len, next_len),
 				InvalidTransaction::ExhaustsResources
 			);
 			// Even with full block, validity of single transaction should be correct.
@@ -489,9 +528,11 @@ mod tests {
 	#[test]
 	fn signed_ext_check_weight_works_operational_tx() {
 		new_test_ext().execute_with(|| {
-			let normal = DispatchInfo { weight: Weight::from_parts(100, 0), ..Default::default() };
+			let normal =
+				DispatchInfo { call_weight: Weight::from_parts(100, 0), ..Default::default() };
 			let op = DispatchInfo {
-				weight: Weight::from_parts(100, 0),
+				call_weight: Weight::from_parts(100, 0),
+				extension_weight: Weight::zero(),
 				class: DispatchClass::Operational,
 				pays_fee: Pays::Yes,
 			};
@@ -503,21 +544,35 @@ mod tests {
 				current_weight.set(normal_limit, DispatchClass::Normal)
 			});
 			// will not fit.
-			assert_err!(
-				CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, &normal, len),
-				InvalidTransaction::ExhaustsResources
+			assert_eq!(
+				CheckWeight::<Test>(PhantomData)
+					.validate_and_prepare(Some(1).into(), CALL, &normal, len)
+					.unwrap_err(),
+				InvalidTransaction::ExhaustsResources.into()
 			);
 			// will fit.
-			assert_ok!(CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, &op, len));
+			assert_ok!(CheckWeight::<Test>(PhantomData).validate_and_prepare(
+				Some(1).into(),
+				CALL,
+				&op,
+				len
+			));
 
 			// likewise for length limit.
 			let len = 100_usize;
 			AllExtrinsicsLen::<Test>::put(normal_length_limit());
-			assert_err!(
-				CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, &normal, len),
-				InvalidTransaction::ExhaustsResources
+			assert_eq!(
+				CheckWeight::<Test>(PhantomData)
+					.validate_and_prepare(Some(1).into(), CALL, &normal, len)
+					.unwrap_err(),
+				InvalidTransaction::ExhaustsResources.into()
 			);
-			assert_ok!(CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, &op, len));
+			assert_ok!(CheckWeight::<Test>(PhantomData).validate_and_prepare(
+				Some(1).into(),
+				CALL,
+				&op,
+				len
+			));
 		})
 	}
 
@@ -528,7 +583,12 @@ mod tests {
 			let normal_limit = normal_weight_limit().ref_time() as usize;
 			let reset_check_weight = |tx, s, f| {
 				AllExtrinsicsLen::<Test>::put(0);
-				let r = CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, tx, s);
+				let r = CheckWeight::<Test>(PhantomData).validate_and_prepare(
+					Some(1).into(),
+					CALL,
+					tx,
+					s,
+				);
 				if f {
 					assert!(r.is_err())
 				} else {
@@ -542,7 +602,8 @@ mod tests {
 
 			// Operational ones don't have this limit.
 			let op = DispatchInfo {
-				weight: Weight::zero(),
+				call_weight: Weight::zero(),
+				extension_weight: Weight::zero(),
 				class: DispatchClass::Operational,
 				pays_fee: Pays::Yes,
 			};
@@ -557,12 +618,13 @@ mod tests {
 	fn signed_ext_check_weight_works_normal_tx() {
 		new_test_ext().execute_with(|| {
 			let normal_limit = normal_weight_limit();
-			let small = DispatchInfo { weight: Weight::from_parts(100, 0), ..Default::default() };
+			let small =
+				DispatchInfo { call_weight: Weight::from_parts(100, 0), ..Default::default() };
 			let base_extrinsic = block_weights().get(DispatchClass::Normal).base_extrinsic;
 			let medium =
-				DispatchInfo { weight: normal_limit - base_extrinsic, ..Default::default() };
+				DispatchInfo { call_weight: normal_limit - base_extrinsic, ..Default::default() };
 			let big = DispatchInfo {
-				weight: normal_limit - base_extrinsic + Weight::from_parts(1, 0),
+				call_weight: normal_limit - base_extrinsic + Weight::from_parts(1, 0),
 				..Default::default()
 			};
 			let len = 0_usize;
@@ -571,7 +633,12 @@ mod tests {
 				BlockWeight::<Test>::mutate(|current_weight| {
 					current_weight.set(s, DispatchClass::Normal)
 				});
-				let r = CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, i, len);
+				let r = CheckWeight::<Test>(PhantomData).validate_and_prepare(
+					Some(1).into(),
+					CALL,
+					i,
+					len,
+				);
 				if f {
 					assert!(r.is_err())
 				} else {
@@ -589,7 +656,8 @@ mod tests {
 	fn signed_ext_check_weight_refund_works() {
 		new_test_ext().execute_with(|| {
 			// This is half of the max block weight
-			let info = DispatchInfo { weight: Weight::from_parts(512, 0), ..Default::default() };
+			let info =
+				DispatchInfo { call_weight: Weight::from_parts(512, 0), ..Default::default() };
 			let post_info = PostDispatchInfo {
 				actual_weight: Some(Weight::from_parts(128, 0)),
 				pays_fee: Default::default(),
@@ -604,14 +672,17 @@ mod tests {
 					.set(Weight::from_parts(256, 0) - base_extrinsic, DispatchClass::Normal);
 			});
 
-			let pre = CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, &info, len).unwrap();
+			let pre = CheckWeight::<Test>(PhantomData)
+				.validate_and_prepare(Some(1).into(), CALL, &info, len)
+				.unwrap()
+				.0;
 			assert_eq!(
 				BlockWeight::<Test>::get().total(),
-				info.weight + Weight::from_parts(256, 0)
+				info.total_weight() + Weight::from_parts(256, 0)
 			);
 
-			assert_ok!(CheckWeight::<Test>::post_dispatch(
-				Some(pre),
+			assert_ok!(CheckWeight::<Test>::post_dispatch_details(
+				pre,
 				&info,
 				&post_info,
 				len,
@@ -627,7 +698,8 @@ mod tests {
 	#[test]
 	fn signed_ext_check_weight_actual_weight_higher_than_max_is_capped() {
 		new_test_ext().execute_with(|| {
-			let info = DispatchInfo { weight: Weight::from_parts(512, 0), ..Default::default() };
+			let info =
+				DispatchInfo { call_weight: Weight::from_parts(512, 0), ..Default::default() };
 			let post_info = PostDispatchInfo {
 				actual_weight: Some(Weight::from_parts(700, 0)),
 				pays_fee: Default::default(),
@@ -639,16 +711,19 @@ mod tests {
 				current_weight.set(Weight::from_parts(128, 0), DispatchClass::Normal);
 			});
 
-			let pre = CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, &info, len).unwrap();
+			let pre = CheckWeight::<Test>(PhantomData)
+				.validate_and_prepare(Some(1).into(), CALL, &info, len)
+				.unwrap()
+				.0;
 			assert_eq!(
 				BlockWeight::<Test>::get().total(),
-				info.weight +
+				info.total_weight() +
 					Weight::from_parts(128, 0) +
 					block_weights().get(DispatchClass::Normal).base_extrinsic,
 			);
 
-			assert_ok!(CheckWeight::<Test>::post_dispatch(
-				Some(pre),
+			assert_ok!(CheckWeight::<Test>::post_dispatch_details(
+				pre,
 				&info,
 				&post_info,
 				len,
@@ -656,7 +731,7 @@ mod tests {
 			));
 			assert_eq!(
 				BlockWeight::<Test>::get().total(),
-				info.weight +
+				info.total_weight() +
 					Weight::from_parts(128, 0) +
 					block_weights().get(DispatchClass::Normal).base_extrinsic,
 			);
@@ -667,12 +742,17 @@ mod tests {
 	fn zero_weight_extrinsic_still_has_base_weight() {
 		new_test_ext().execute_with(|| {
 			let weights = block_weights();
-			let free = DispatchInfo { weight: Weight::zero(), ..Default::default() };
+			let free = DispatchInfo { call_weight: Weight::zero(), ..Default::default() };
 			let len = 0_usize;
 
 			// Initial weight from `weights.base_block`
 			assert_eq!(System::block_weight().total(), weights.base_block);
-			assert_ok!(CheckWeight::<Test>(PhantomData).pre_dispatch(&1, CALL, &free, len));
+			assert_ok!(CheckWeight::<Test>(PhantomData).validate_and_prepare(
+				Some(1).into(),
+				CALL,
+				&free,
+				len
+			));
 			assert_eq!(
 				System::block_weight().total(),
 				weights.get(DispatchClass::Normal).base_extrinsic + weights.base_block
@@ -687,18 +767,20 @@ mod tests {
 			// Max normal is 768 (75%)
 			// Max mandatory is unlimited
 			let max_normal =
-				DispatchInfo { weight: Weight::from_parts(753, 0), ..Default::default() };
+				DispatchInfo { call_weight: Weight::from_parts(753, 0), ..Default::default() };
 			let mandatory = DispatchInfo {
-				weight: Weight::from_parts(1019, 0),
+				call_weight: Weight::from_parts(1019, 0),
 				class: DispatchClass::Mandatory,
 				..Default::default()
 			};
 
 			let len = 0_usize;
 
-			assert_ok!(CheckWeight::<Test>::do_pre_dispatch(&max_normal, len));
+			let next_len = CheckWeight::<Test>::check_block_length(&max_normal, len).unwrap();
+			assert_ok!(CheckWeight::<Test>::do_prepare(&max_normal, len, next_len));
 			assert_eq!(System::block_weight().total(), Weight::from_parts(768, 0));
-			assert_ok!(CheckWeight::<Test>::do_pre_dispatch(&mandatory, len));
+			let next_len = CheckWeight::<Test>::check_block_length(&mandatory, len).unwrap();
+			assert_ok!(CheckWeight::<Test>::do_prepare(&mandatory, len, next_len));
 			assert_eq!(block_weight_limit(), Weight::from_parts(1024, u64::MAX));
 			assert_eq!(System::block_weight().total(), Weight::from_parts(1024 + 768, 0));
 			assert_eq!(CheckWeight::<Test>::check_extrinsic_weight(&mandatory), Ok(()));
@@ -729,13 +811,13 @@ mod tests {
 
 		// fits into reserved
 		let mandatory1 = DispatchInfo {
-			weight: Weight::from_parts(5, 0),
+			call_weight: Weight::from_parts(5, 0),
 			class: DispatchClass::Mandatory,
 			..Default::default()
 		};
 		// does not fit into reserved and the block is full.
 		let mandatory2 = DispatchInfo {
-			weight: Weight::from_parts(6, 0),
+			call_weight: Weight::from_parts(6, 0),
 			class: DispatchClass::Mandatory,
 			..Default::default()
 		};
@@ -778,13 +860,13 @@ mod tests {
 		});
 
 		let normal = DispatchInfo {
-			weight: Weight::from_parts(5, 0),
+			call_weight: Weight::from_parts(5, 0),
 			class: DispatchClass::Normal,
 			..Default::default()
 		};
 
 		let mandatory = DispatchInfo {
-			weight: Weight::from_parts(5, 0),
+			call_weight: Weight::from_parts(5, 0),
 			class: DispatchClass::Mandatory,
 			..Default::default()
 		};
@@ -798,7 +880,7 @@ mod tests {
 		)
 		.unwrap();
 
-		assert_eq!(consumed.total().saturating_sub(all_weight.total()), normal.weight);
+		assert_eq!(consumed.total().saturating_sub(all_weight.total()), normal.total_weight());
 
 		let consumed = calculate_consumed_weight::<<Test as Config>::RuntimeCall>(
 			&maximum_weight,
@@ -807,7 +889,7 @@ mod tests {
 			0,
 		)
 		.unwrap();
-		assert_eq!(consumed.total().saturating_sub(all_weight.total()), mandatory.weight);
+		assert_eq!(consumed.total().saturating_sub(all_weight.total()), mandatory.total_weight());
 
 		// Using non zero length extrinsics.
 		let consumed = calculate_consumed_weight::<<Test as Config>::RuntimeCall>(
@@ -820,7 +902,7 @@ mod tests {
 		// Must account for the len in the proof size
 		assert_eq!(
 			consumed.total().saturating_sub(all_weight.total()),
-			normal.weight.add_proof_size(100)
+			normal.total_weight().add_proof_size(100)
 		);
 
 		let consumed = calculate_consumed_weight::<<Test as Config>::RuntimeCall>(
@@ -833,7 +915,7 @@ mod tests {
 		// Must account for the len in the proof size
 		assert_eq!(
 			consumed.total().saturating_sub(all_weight.total()),
-			mandatory.weight.add_proof_size(100)
+			mandatory.total_weight().add_proof_size(100)
 		);
 
 		// Using oversized zero length extrinsics.
diff --git a/substrate/frame/system/src/extensions/mod.rs b/substrate/frame/system/src/extensions/mod.rs
index a88c9fbf96e..d79104d2240 100644
--- a/substrate/frame/system/src/extensions/mod.rs
+++ b/substrate/frame/system/src/extensions/mod.rs
@@ -22,3 +22,6 @@ pub mod check_nonce;
 pub mod check_spec_version;
 pub mod check_tx_version;
 pub mod check_weight;
+pub mod weights;
+
+pub use weights::WeightInfo;
diff --git a/substrate/frame/system/src/extensions/weights.rs b/substrate/frame/system/src/extensions/weights.rs
new file mode 100644
index 00000000000..1c0136ae780
--- /dev/null
+++ b/substrate/frame/system/src/extensions/weights.rs
@@ -0,0 +1,217 @@
+// This file is part of Substrate.
+
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Autogenerated weights for `frame_system_extensions`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024`
+
+// Executed Command:
+// ./target/production/substrate-node
+// benchmark
+// pallet
+// --chain=dev
+// --steps=50
+// --repeat=20
+// --pallet=frame_system_extensions
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --extrinsic=*
+// --wasm-execution=compiled
+// --heap-pages=4096
+// --output=./substrate/frame/system/src/extensions/weights.rs
+// --header=./substrate/HEADER-APACHE2
+// --template=./substrate/.maintain/frame-weight-template.hbs
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
+use core::marker::PhantomData;
+
+/// Weight functions needed for `frame_system_extensions`.
+pub trait WeightInfo {
+	fn check_genesis() -> Weight;
+	fn check_mortality_mortal_transaction() -> Weight;
+	fn check_mortality_immortal_transaction() -> Weight;
+	fn check_non_zero_sender() -> Weight;
+	fn check_nonce() -> Weight;
+	fn check_spec_version() -> Weight;
+	fn check_tx_version() -> Weight;
+	fn check_weight() -> Weight;
+}
+
+/// Weights for `frame_system_extensions` using the Substrate node and recommended hardware.
+pub struct SubstrateWeight<T>(PhantomData<T>);
+impl<T: crate::Config> WeightInfo for SubstrateWeight<T> {
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_genesis() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `54`
+		//  Estimated: `3509`
+		// Minimum execution time: 3_876_000 picoseconds.
+		Weight::from_parts(4_160_000, 3509)
+			.saturating_add(T::DbWeight::get().reads(1_u64))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_mortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 6_296_000 picoseconds.
+		Weight::from_parts(6_523_000, 3509)
+			.saturating_add(T::DbWeight::get().reads(1_u64))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_immortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 6_296_000 picoseconds.
+		Weight::from_parts(6_523_000, 3509)
+			.saturating_add(T::DbWeight::get().reads(1_u64))
+	}
+	fn check_non_zero_sender() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 449_000 picoseconds.
+		Weight::from_parts(527_000, 0)
+	}
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	fn check_nonce() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `101`
+		//  Estimated: `3593`
+		// Minimum execution time: 5_689_000 picoseconds.
+		Weight::from_parts(6_000_000, 3593)
+			.saturating_add(T::DbWeight::get().reads(1_u64))
+			.saturating_add(T::DbWeight::get().writes(1_u64))
+	}
+	fn check_spec_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 399_000 picoseconds.
+		Weight::from_parts(461_000, 0)
+	}
+	fn check_tx_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 390_000 picoseconds.
+		Weight::from_parts(439_000, 0)
+	}
+	/// Storage: `System::AllExtrinsicsLen` (r:1 w:1)
+	/// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
+	fn check_weight() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `24`
+		//  Estimated: `1489`
+		// Minimum execution time: 4_375_000 picoseconds.
+		Weight::from_parts(4_747_000, 1489)
+			.saturating_add(T::DbWeight::get().reads(1_u64))
+			.saturating_add(T::DbWeight::get().writes(1_u64))
+	}
+}
+
+// For backwards compatibility and tests.
+impl WeightInfo for () {
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_genesis() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `54`
+		//  Estimated: `3509`
+		// Minimum execution time: 3_876_000 picoseconds.
+		Weight::from_parts(4_160_000, 3509)
+			.saturating_add(RocksDbWeight::get().reads(1_u64))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_mortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 6_296_000 picoseconds.
+		Weight::from_parts(6_523_000, 3509)
+			.saturating_add(RocksDbWeight::get().reads(1_u64))
+	}
+	/// Storage: `System::BlockHash` (r:1 w:0)
+	/// Proof: `System::BlockHash` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`)
+	fn check_mortality_immortal_transaction() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `92`
+		//  Estimated: `3509`
+		// Minimum execution time: 6_296_000 picoseconds.
+		Weight::from_parts(6_523_000, 3509)
+			.saturating_add(RocksDbWeight::get().reads(1_u64))
+	}
+	fn check_non_zero_sender() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 449_000 picoseconds.
+		Weight::from_parts(527_000, 0)
+	}
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	fn check_nonce() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `101`
+		//  Estimated: `3593`
+		// Minimum execution time: 5_689_000 picoseconds.
+		Weight::from_parts(6_000_000, 3593)
+			.saturating_add(RocksDbWeight::get().reads(1_u64))
+			.saturating_add(RocksDbWeight::get().writes(1_u64))
+	}
+	fn check_spec_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 399_000 picoseconds.
+		Weight::from_parts(461_000, 0)
+	}
+	fn check_tx_version() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 390_000 picoseconds.
+		Weight::from_parts(439_000, 0)
+	}
+	/// Storage: `System::AllExtrinsicsLen` (r:1 w:1)
+	/// Proof: `System::AllExtrinsicsLen` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
+	fn check_weight() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `24`
+		//  Estimated: `1489`
+		// Minimum execution time: 4_375_000 picoseconds.
+		Weight::from_parts(4_747_000, 1489)
+			.saturating_add(RocksDbWeight::get().reads(1_u64))
+			.saturating_add(RocksDbWeight::get().writes(1_u64))
+	}
+}
diff --git a/substrate/frame/system/src/lib.rs b/substrate/frame/system/src/lib.rs
index a5c5f1ed2e4..02d61921741 100644
--- a/substrate/frame/system/src/lib.rs
+++ b/substrate/frame/system/src/lib.rs
@@ -169,7 +169,7 @@ pub use extensions::{
 	check_genesis::CheckGenesis, check_mortality::CheckMortality,
 	check_non_zero_sender::CheckNonZeroSender, check_nonce::CheckNonce,
 	check_spec_version::CheckSpecVersion, check_tx_version::CheckTxVersion,
-	check_weight::CheckWeight,
+	check_weight::CheckWeight, WeightInfo as ExtensionsWeightInfo,
 };
 // Backward compatible re-export.
 pub use extensions::check_mortality::CheckMortality as CheckEra;
@@ -261,6 +261,19 @@ where
 	check_version: bool,
 }
 
+/// Information about the dispatch of a call, to be displayed in the
+/// [`ExtrinsicSuccess`](Event::ExtrinsicSuccess) and [`ExtrinsicFailed`](Event::ExtrinsicFailed)
+/// events.
+#[derive(Clone, Copy, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode, TypeInfo)]
+pub struct DispatchEventInfo {
+	/// Weight of this transaction.
+	pub weight: Weight,
+	/// Class of this transaction.
+	pub class: DispatchClass,
+	/// Does this transaction pay fees.
+	pub pays_fee: Pays,
+}
+
 #[frame_support::pallet]
 pub mod pallet {
 	use crate::{self as frame_system, pallet_prelude::*, *};
@@ -303,6 +316,7 @@ pub mod pallet {
 			type OnNewAccount = ();
 			type OnKilledAccount = ();
 			type SystemWeightInfo = ();
+			type ExtensionsWeightInfo = ();
 			type SS58Prefix = ();
 			type Version = ();
 			type BlockWeights = ();
@@ -375,6 +389,9 @@ pub mod pallet {
 			/// Weight information for the extrinsics of this pallet.
 			type SystemWeightInfo = ();
 
+			/// Weight information for the extensions of this pallet.
+			type ExtensionsWeightInfo = ();
+
 			/// This is used as an identifier of the chain.
 			type SS58Prefix = ();
 
@@ -582,8 +599,12 @@ pub mod pallet {
 		/// All resources should be cleaned up associated with the given account.
 		type OnKilledAccount: OnKilledAccount<Self::AccountId>;
 
+		/// Weight information for the extrinsics of this pallet.
 		type SystemWeightInfo: WeightInfo;
 
+		/// Weight information for the transaction extensions of this pallet.
+		type ExtensionsWeightInfo: extensions::WeightInfo;
+
 		/// The designated SS58 prefix of this chain.
 		///
 		/// This replaces the "ss58Format" property declared in the chain spec. Reason is
@@ -833,9 +854,9 @@ pub mod pallet {
 	#[pallet::event]
 	pub enum Event<T: Config> {
 		/// An extrinsic completed successfully.
-		ExtrinsicSuccess { dispatch_info: DispatchInfo },
+		ExtrinsicSuccess { dispatch_info: DispatchEventInfo },
 		/// An extrinsic failed.
-		ExtrinsicFailed { dispatch_error: DispatchError, dispatch_info: DispatchInfo },
+		ExtrinsicFailed { dispatch_error: DispatchError, dispatch_info: DispatchEventInfo },
 		/// `:code` was updated.
 		CodeUpdated,
 		/// A new account was created.
@@ -921,6 +942,7 @@ pub mod pallet {
 
 	/// Total length (in bytes) for all extrinsics put together, for the current block.
 	#[pallet::storage]
+	#[pallet::whitelist_storage]
 	pub type AllExtrinsicsLen<T: Config> = StorageValue<_, u32>;
 
 	/// Map of block numbers to block hashes.
@@ -2025,13 +2047,15 @@ impl<T: Config> Pallet<T> {
 	/// Emits an `ExtrinsicSuccess` or `ExtrinsicFailed` event depending on the outcome.
 	/// The emitted event contains the post-dispatch corrected weight including
 	/// the base-weight for its dispatch class.
-	pub fn note_applied_extrinsic(r: &DispatchResultWithPostInfo, mut info: DispatchInfo) {
-		info.weight = extract_actual_weight(r, &info)
+	pub fn note_applied_extrinsic(r: &DispatchResultWithPostInfo, info: DispatchInfo) {
+		let weight = extract_actual_weight(r, &info)
 			.saturating_add(T::BlockWeights::get().get(info.class).base_extrinsic);
-		info.pays_fee = extract_actual_pays_fee(r, &info);
+		let class = info.class;
+		let pays_fee = extract_actual_pays_fee(r, &info);
+		let dispatch_event_info = DispatchEventInfo { weight, class, pays_fee };
 
 		Self::deposit_event(match r {
-			Ok(_) => Event::ExtrinsicSuccess { dispatch_info: info },
+			Ok(_) => Event::ExtrinsicSuccess { dispatch_info: dispatch_event_info },
 			Err(err) => {
 				log::trace!(
 					target: LOG_TARGET,
@@ -2039,7 +2063,10 @@ impl<T: Config> Pallet<T> {
 					Self::block_number(),
 					err,
 				);
-				Event::ExtrinsicFailed { dispatch_error: err.error, dispatch_info: info }
+				Event::ExtrinsicFailed {
+					dispatch_error: err.error,
+					dispatch_info: dispatch_event_info,
+				}
 			},
 		});
 
diff --git a/substrate/frame/system/src/offchain.rs b/substrate/frame/system/src/offchain.rs
index 1f72ea2d374..bedfdded818 100644
--- a/substrate/frame/system/src/offchain.rs
+++ b/substrate/frame/system/src/offchain.rs
@@ -58,9 +58,10 @@
 
 use alloc::{boxed::Box, collections::btree_set::BTreeSet, vec::Vec};
 use codec::Encode;
+use scale_info::TypeInfo;
 use sp_runtime::{
 	app_crypto::RuntimeAppPublic,
-	traits::{Extrinsic as ExtrinsicT, IdentifyAccount, One},
+	traits::{ExtrinsicLike, IdentifyAccount, One},
 	RuntimeDebug,
 };
 
@@ -75,29 +76,18 @@ pub struct ForAny {}
 /// For submitting unsigned transactions, `submit_unsigned_transaction`
 /// utility function can be used. However, this struct is used by `Signer`
 /// to submit a signed transactions providing the signature along with the call.
-pub struct SubmitTransaction<T: SendTransactionTypes<OverarchingCall>, OverarchingCall> {
-	_phantom: core::marker::PhantomData<(T, OverarchingCall)>,
+pub struct SubmitTransaction<T: CreateTransactionBase<RuntimeCall>, RuntimeCall> {
+	_phantom: core::marker::PhantomData<(T, RuntimeCall)>,
 }
 
 impl<T, LocalCall> SubmitTransaction<T, LocalCall>
 where
-	T: SendTransactionTypes<LocalCall>,
+	T: CreateTransactionBase<LocalCall>,
 {
-	/// Submit transaction onchain by providing the call and an optional signature
-	pub fn submit_transaction(
-		call: <T as SendTransactionTypes<LocalCall>>::OverarchingCall,
-		signature: Option<<T::Extrinsic as ExtrinsicT>::SignaturePayload>,
-	) -> Result<(), ()> {
-		let xt = T::Extrinsic::new(call, signature).ok_or(())?;
+	/// A convenience method to submit an extrinsic onchain.
+	pub fn submit_transaction(xt: T::Extrinsic) -> Result<(), ()> {
 		sp_io::offchain::submit_transaction(xt.encode())
 	}
-
-	/// A convenience method to submit an unsigned transaction onchain.
-	pub fn submit_unsigned_transaction(
-		call: <T as SendTransactionTypes<LocalCall>>::OverarchingCall,
-	) -> Result<(), ()> {
-		SubmitTransaction::<T, LocalCall>::submit_transaction(call, None)
-	}
 }
 
 /// Provides an implementation for signing transaction payloads.
@@ -284,7 +274,7 @@ impl<
 }
 
 impl<
-		T: SigningTypes + SendTransactionTypes<LocalCall>,
+		T: SigningTypes + CreateInherent<LocalCall>,
 		C: AppCrypto<T::Public, T::Signature>,
 		LocalCall,
 	> SendUnsignedTransaction<T, LocalCall> for Signer<T, C, ForAny>
@@ -310,7 +300,7 @@ impl<
 }
 
 impl<
-		T: SigningTypes + SendTransactionTypes<LocalCall>,
+		T: SigningTypes + CreateInherent<LocalCall>,
 		C: AppCrypto<T::Public, T::Signature>,
 		LocalCall,
 	> SendUnsignedTransaction<T, LocalCall> for Signer<T, C, ForAll>
@@ -457,25 +447,32 @@ pub trait SigningTypes: crate::Config {
 	type Signature: Clone + PartialEq + core::fmt::Debug + codec::Codec + scale_info::TypeInfo;
 }
 
-/// A definition of types required to submit transactions from within the runtime.
-pub trait SendTransactionTypes<LocalCall> {
-	/// The extrinsic type expected by the runtime.
-	type Extrinsic: ExtrinsicT<Call = Self::OverarchingCall> + codec::Encode;
+/// Common interface for the `CreateTransaction` trait family to unify the `Call` type.
+pub trait CreateTransactionBase<LocalCall> {
+	/// The extrinsic.
+	type Extrinsic: ExtrinsicLike + Encode;
+
 	/// The runtime's call type.
 	///
 	/// This has additional bound to be able to be created from pallet-local `Call` types.
-	type OverarchingCall: From<LocalCall> + codec::Encode;
+	type RuntimeCall: From<LocalCall> + Encode;
 }
 
-/// Create signed transaction.
-///
-/// This trait is meant to be implemented by the runtime and is responsible for constructing
-/// a payload to be signed and contained within the extrinsic.
-/// This will most likely include creation of `SignedExtra` (a set of `SignedExtensions`).
-/// Note that the result can be altered by inspecting the `Call` (for instance adjusting
-/// fees, or mortality depending on the `pallet` being called).
+/// Interface for creating a transaction.
+pub trait CreateTransaction<LocalCall>: CreateTransactionBase<LocalCall> {
+	/// The extension.
+	type Extension: TypeInfo;
+
+	/// Create a transaction using the call and the desired transaction extension.
+	fn create_transaction(
+		call: <Self as CreateTransactionBase<LocalCall>>::RuntimeCall,
+		extension: Self::Extension,
+	) -> Self::Extrinsic;
+}
+
+/// Interface for creating an old-school signed transaction.
 pub trait CreateSignedTransaction<LocalCall>:
-	SendTransactionTypes<LocalCall> + SigningTypes
+	CreateTransactionBase<LocalCall> + SigningTypes
 {
 	/// Attempt to create signed extrinsic data that encodes call from given account.
 	///
@@ -483,12 +480,18 @@ pub trait CreateSignedTransaction<LocalCall>:
 	/// in any way it wants.
 	/// Returns `None` if signed extrinsic could not be created (either because signing failed
 	/// or because of any other runtime-specific reason).
-	fn create_transaction<C: AppCrypto<Self::Public, Self::Signature>>(
-		call: Self::OverarchingCall,
+	fn create_signed_transaction<C: AppCrypto<Self::Public, Self::Signature>>(
+		call: <Self as CreateTransactionBase<LocalCall>>::RuntimeCall,
 		public: Self::Public,
 		account: Self::AccountId,
 		nonce: Self::Nonce,
-	) -> Option<(Self::OverarchingCall, <Self::Extrinsic as ExtrinsicT>::SignaturePayload)>;
+	) -> Option<Self::Extrinsic>;
+}
+
+/// Interface for creating an inherent.
+pub trait CreateInherent<LocalCall>: CreateTransactionBase<LocalCall> {
+	/// Create an inherent.
+	fn create_inherent(call: Self::RuntimeCall) -> Self::Extrinsic;
 }
 
 /// A message signer.
@@ -516,7 +519,7 @@ pub trait SignMessage<T: SigningTypes> {
 
 /// Submit a signed transaction to the transaction pool.
 pub trait SendSignedTransaction<
-	T: SigningTypes + CreateSignedTransaction<LocalCall>,
+	T: CreateSignedTransaction<LocalCall>,
 	C: AppCrypto<T::Public, T::Signature>,
 	LocalCall,
 >
@@ -547,13 +550,14 @@ pub trait SendSignedTransaction<
 			account.id,
 			account_data.nonce,
 		);
-		let (call, signature) = T::create_transaction::<C>(
+		let transaction = T::create_signed_transaction::<C>(
 			call.into(),
 			account.public.clone(),
 			account.id.clone(),
 			account_data.nonce,
 		)?;
-		let res = SubmitTransaction::<T, LocalCall>::submit_transaction(call, Some(signature));
+
+		let res = SubmitTransaction::<T, LocalCall>::submit_transaction(transaction);
 
 		if res.is_ok() {
 			// increment the nonce. This is fine, since the code should always
@@ -567,7 +571,7 @@ pub trait SendSignedTransaction<
 }
 
 /// Submit an unsigned transaction onchain with a signed payload
-pub trait SendUnsignedTransaction<T: SigningTypes + SendTransactionTypes<LocalCall>, LocalCall> {
+pub trait SendUnsignedTransaction<T: SigningTypes + CreateInherent<LocalCall>, LocalCall> {
 	/// A submission result.
 	///
 	/// Should contain the submission result and the account(s) that signed the payload.
@@ -590,7 +594,8 @@ pub trait SendUnsignedTransaction<T: SigningTypes + SendTransactionTypes<LocalCa
 
 	/// Submits an unsigned call to the transaction pool.
 	fn submit_unsigned_transaction(&self, call: LocalCall) -> Option<Result<(), ()>> {
-		Some(SubmitTransaction::<T, LocalCall>::submit_unsigned_transaction(call.into()))
+		let xt = T::create_inherent(call.into());
+		Some(SubmitTransaction::<T, LocalCall>::submit_transaction(xt))
 	}
 }
 
@@ -630,9 +635,15 @@ mod tests {
 
 	type Extrinsic = TestXt<RuntimeCall, ()>;
 
-	impl SendTransactionTypes<RuntimeCall> for TestRuntime {
+	impl CreateTransactionBase<RuntimeCall> for TestRuntime {
 		type Extrinsic = Extrinsic;
-		type OverarchingCall = RuntimeCall;
+		type RuntimeCall = RuntimeCall;
+	}
+
+	impl CreateInherent<RuntimeCall> for TestRuntime {
+		fn create_inherent(call: Self::RuntimeCall) -> Self::Extrinsic {
+			Extrinsic::new_bare(call)
+		}
 	}
 
 	#[derive(codec::Encode, codec::Decode)]
@@ -693,7 +704,7 @@ mod tests {
 			let _tx3 = pool_state.write().transactions.pop().unwrap();
 			assert!(pool_state.read().transactions.is_empty());
 			let tx1 = Extrinsic::decode(&mut &*tx1).unwrap();
-			assert_eq!(tx1.signature, None);
+			assert!(tx1.is_inherent());
 		});
 	}
 
@@ -724,7 +735,7 @@ mod tests {
 			let tx1 = pool_state.write().transactions.pop().unwrap();
 			assert!(pool_state.read().transactions.is_empty());
 			let tx1 = Extrinsic::decode(&mut &*tx1).unwrap();
-			assert_eq!(tx1.signature, None);
+			assert!(tx1.is_inherent());
 		});
 	}
 
@@ -758,7 +769,7 @@ mod tests {
 			let _tx2 = pool_state.write().transactions.pop().unwrap();
 			assert!(pool_state.read().transactions.is_empty());
 			let tx1 = Extrinsic::decode(&mut &*tx1).unwrap();
-			assert_eq!(tx1.signature, None);
+			assert!(tx1.is_inherent());
 		});
 	}
 
@@ -790,7 +801,7 @@ mod tests {
 			let tx1 = pool_state.write().transactions.pop().unwrap();
 			assert!(pool_state.read().transactions.is_empty());
 			let tx1 = Extrinsic::decode(&mut &*tx1).unwrap();
-			assert_eq!(tx1.signature, None);
+			assert!(tx1.is_inherent());
 		});
 	}
 }
diff --git a/substrate/frame/system/src/tests.rs b/substrate/frame/system/src/tests.rs
index aa1094e3fe4..6b903f5b7e7 100644
--- a/substrate/frame/system/src/tests.rs
+++ b/substrate/frame/system/src/tests.rs
@@ -266,7 +266,10 @@ fn deposit_event_should_work() {
 				EventRecord {
 					phase: Phase::ApplyExtrinsic(0),
 					event: SysEvent::ExtrinsicSuccess {
-						dispatch_info: DispatchInfo { weight: normal_base, ..Default::default() }
+						dispatch_info: DispatchEventInfo {
+							weight: normal_base,
+							..Default::default()
+						}
 					}
 					.into(),
 					topics: vec![]
@@ -275,7 +278,10 @@ fn deposit_event_should_work() {
 					phase: Phase::ApplyExtrinsic(1),
 					event: SysEvent::ExtrinsicFailed {
 						dispatch_error: DispatchError::BadOrigin.into(),
-						dispatch_info: DispatchInfo { weight: normal_base, ..Default::default() }
+						dispatch_info: DispatchEventInfo {
+							weight: normal_base,
+							..Default::default()
+						}
 					}
 					.into(),
 					topics: vec![]
@@ -300,7 +306,8 @@ fn deposit_event_uses_actual_weight_and_pays_fee() {
 		let normal_base = <Test as crate::Config>::BlockWeights::get()
 			.get(DispatchClass::Normal)
 			.base_extrinsic;
-		let pre_info = DispatchInfo { weight: Weight::from_parts(1000, 0), ..Default::default() };
+		let pre_info =
+			DispatchInfo { call_weight: Weight::from_parts(1000, 0), ..Default::default() };
 		System::note_applied_extrinsic(&Ok(from_actual_ref_time(Some(300))), pre_info);
 		System::note_applied_extrinsic(&Ok(from_actual_ref_time(Some(1000))), pre_info);
 		System::note_applied_extrinsic(
@@ -356,7 +363,7 @@ fn deposit_event_uses_actual_weight_and_pays_fee() {
 			.base_extrinsic;
 		assert!(normal_base != operational_base, "Test pre-condition violated");
 		let pre_info = DispatchInfo {
-			weight: Weight::from_parts(1000, 0),
+			call_weight: Weight::from_parts(1000, 0),
 			class: DispatchClass::Operational,
 			..Default::default()
 		};
@@ -367,7 +374,7 @@ fn deposit_event_uses_actual_weight_and_pays_fee() {
 			EventRecord {
 				phase: Phase::ApplyExtrinsic(0),
 				event: SysEvent::ExtrinsicSuccess {
-					dispatch_info: DispatchInfo {
+					dispatch_info: DispatchEventInfo {
 						weight: Weight::from_parts(300, 0).saturating_add(normal_base),
 						..Default::default()
 					},
@@ -378,7 +385,7 @@ fn deposit_event_uses_actual_weight_and_pays_fee() {
 			EventRecord {
 				phase: Phase::ApplyExtrinsic(1),
 				event: SysEvent::ExtrinsicSuccess {
-					dispatch_info: DispatchInfo {
+					dispatch_info: DispatchEventInfo {
 						weight: Weight::from_parts(1000, 0).saturating_add(normal_base),
 						..Default::default()
 					},
@@ -389,7 +396,7 @@ fn deposit_event_uses_actual_weight_and_pays_fee() {
 			EventRecord {
 				phase: Phase::ApplyExtrinsic(2),
 				event: SysEvent::ExtrinsicSuccess {
-					dispatch_info: DispatchInfo {
+					dispatch_info: DispatchEventInfo {
 						weight: Weight::from_parts(1000, 0).saturating_add(normal_base),
 						..Default::default()
 					},
@@ -400,10 +407,10 @@ fn deposit_event_uses_actual_weight_and_pays_fee() {
 			EventRecord {
 				phase: Phase::ApplyExtrinsic(3),
 				event: SysEvent::ExtrinsicSuccess {
-					dispatch_info: DispatchInfo {
+					dispatch_info: DispatchEventInfo {
 						weight: Weight::from_parts(1000, 0).saturating_add(normal_base),
 						pays_fee: Pays::Yes,
-						..Default::default()
+						class: Default::default(),
 					},
 				}
 				.into(),
@@ -412,10 +419,10 @@ fn deposit_event_uses_actual_weight_and_pays_fee() {
 			EventRecord {
 				phase: Phase::ApplyExtrinsic(4),
 				event: SysEvent::ExtrinsicSuccess {
-					dispatch_info: DispatchInfo {
+					dispatch_info: DispatchEventInfo {
 						weight: Weight::from_parts(1000, 0).saturating_add(normal_base),
 						pays_fee: Pays::No,
-						..Default::default()
+						class: Default::default(),
 					},
 				}
 				.into(),
@@ -424,10 +431,10 @@ fn deposit_event_uses_actual_weight_and_pays_fee() {
 			EventRecord {
 				phase: Phase::ApplyExtrinsic(5),
 				event: SysEvent::ExtrinsicSuccess {
-					dispatch_info: DispatchInfo {
+					dispatch_info: DispatchEventInfo {
 						weight: Weight::from_parts(1000, 0).saturating_add(normal_base),
 						pays_fee: Pays::No,
-						..Default::default()
+						class: Default::default(),
 					},
 				}
 				.into(),
@@ -436,10 +443,10 @@ fn deposit_event_uses_actual_weight_and_pays_fee() {
 			EventRecord {
 				phase: Phase::ApplyExtrinsic(6),
 				event: SysEvent::ExtrinsicSuccess {
-					dispatch_info: DispatchInfo {
+					dispatch_info: DispatchEventInfo {
 						weight: Weight::from_parts(500, 0).saturating_add(normal_base),
 						pays_fee: Pays::No,
-						..Default::default()
+						class: Default::default(),
 					},
 				}
 				.into(),
@@ -449,7 +456,7 @@ fn deposit_event_uses_actual_weight_and_pays_fee() {
 				phase: Phase::ApplyExtrinsic(7),
 				event: SysEvent::ExtrinsicFailed {
 					dispatch_error: DispatchError::BadOrigin.into(),
-					dispatch_info: DispatchInfo {
+					dispatch_info: DispatchEventInfo {
 						weight: Weight::from_parts(999, 0).saturating_add(normal_base),
 						..Default::default()
 					},
@@ -461,10 +468,10 @@ fn deposit_event_uses_actual_weight_and_pays_fee() {
 				phase: Phase::ApplyExtrinsic(8),
 				event: SysEvent::ExtrinsicFailed {
 					dispatch_error: DispatchError::BadOrigin.into(),
-					dispatch_info: DispatchInfo {
+					dispatch_info: DispatchEventInfo {
 						weight: Weight::from_parts(1000, 0).saturating_add(normal_base),
 						pays_fee: Pays::Yes,
-						..Default::default()
+						class: Default::default(),
 					},
 				}
 				.into(),
@@ -474,10 +481,10 @@ fn deposit_event_uses_actual_weight_and_pays_fee() {
 				phase: Phase::ApplyExtrinsic(9),
 				event: SysEvent::ExtrinsicFailed {
 					dispatch_error: DispatchError::BadOrigin.into(),
-					dispatch_info: DispatchInfo {
+					dispatch_info: DispatchEventInfo {
 						weight: Weight::from_parts(800, 0).saturating_add(normal_base),
 						pays_fee: Pays::Yes,
-						..Default::default()
+						class: Default::default(),
 					},
 				}
 				.into(),
@@ -487,10 +494,10 @@ fn deposit_event_uses_actual_weight_and_pays_fee() {
 				phase: Phase::ApplyExtrinsic(10),
 				event: SysEvent::ExtrinsicFailed {
 					dispatch_error: DispatchError::BadOrigin.into(),
-					dispatch_info: DispatchInfo {
+					dispatch_info: DispatchEventInfo {
 						weight: Weight::from_parts(800, 0).saturating_add(normal_base),
 						pays_fee: Pays::No,
-						..Default::default()
+						class: Default::default(),
 					},
 				}
 				.into(),
@@ -499,10 +506,10 @@ fn deposit_event_uses_actual_weight_and_pays_fee() {
 			EventRecord {
 				phase: Phase::ApplyExtrinsic(11),
 				event: SysEvent::ExtrinsicSuccess {
-					dispatch_info: DispatchInfo {
+					dispatch_info: DispatchEventInfo {
 						weight: Weight::from_parts(300, 0).saturating_add(operational_base),
 						class: DispatchClass::Operational,
-						..Default::default()
+						pays_fee: Default::default(),
 					},
 				}
 				.into(),
diff --git a/substrate/frame/transaction-payment/Cargo.toml b/substrate/frame/transaction-payment/Cargo.toml
index 4161a97f3cd..afa03ceb12e 100644
--- a/substrate/frame/transaction-payment/Cargo.toml
+++ b/substrate/frame/transaction-payment/Cargo.toml
@@ -21,6 +21,7 @@ codec = { features = [
 ], workspace = true }
 scale-info = { features = ["derive"], workspace = true }
 serde = { optional = true, workspace = true, default-features = true }
+frame-benchmarking = { optional = true, workspace = true }
 frame-support = { workspace = true }
 frame-system = { workspace = true }
 sp-core = { workspace = true }
@@ -35,6 +36,7 @@ pallet-balances = { workspace = true, default-features = true }
 default = ["std"]
 std = [
 	"codec/std",
+	"frame-benchmarking?/std",
 	"frame-support/std",
 	"frame-system/std",
 	"pallet-balances/std",
@@ -44,6 +46,13 @@ std = [
 	"sp-io/std",
 	"sp-runtime/std",
 ]
+runtime-benchmarks = [
+	"frame-benchmarking/runtime-benchmarks",
+	"frame-support/runtime-benchmarks",
+	"frame-system/runtime-benchmarks",
+	"pallet-balances/runtime-benchmarks",
+	"sp-runtime/runtime-benchmarks",
+]
 try-runtime = [
 	"frame-support/try-runtime",
 	"frame-system/try-runtime",
diff --git a/substrate/frame/transaction-payment/asset-conversion-tx-payment/Cargo.toml b/substrate/frame/transaction-payment/asset-conversion-tx-payment/Cargo.toml
index e6a60e9c850..7c98d157f6f 100644
--- a/substrate/frame/transaction-payment/asset-conversion-tx-payment/Cargo.toml
+++ b/substrate/frame/transaction-payment/asset-conversion-tx-payment/Cargo.toml
@@ -18,6 +18,7 @@ targets = ["x86_64-unknown-linux-gnu"]
 [dependencies]
 # Substrate dependencies
 sp-runtime = { workspace = true }
+frame-benchmarking = { optional = true, workspace = true }
 frame-support = { workspace = true }
 frame-system = { workspace = true }
 pallet-asset-conversion = { workspace = true }
@@ -36,6 +37,7 @@ pallet-balances = { workspace = true, default-features = true }
 default = ["std"]
 std = [
 	"codec/std",
+	"frame-benchmarking?/std",
 	"frame-support/std",
 	"frame-system/std",
 	"pallet-asset-conversion/std",
@@ -48,6 +50,16 @@ std = [
 	"sp-runtime/std",
 	"sp-storage/std",
 ]
+runtime-benchmarks = [
+	"frame-benchmarking/runtime-benchmarks",
+	"frame-support/runtime-benchmarks",
+	"frame-system/runtime-benchmarks",
+	"pallet-asset-conversion/runtime-benchmarks",
+	"pallet-assets/runtime-benchmarks",
+	"pallet-balances/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
+	"sp-runtime/runtime-benchmarks",
+]
 try-runtime = [
 	"frame-support/try-runtime",
 	"frame-system/try-runtime",
diff --git a/substrate/frame/transaction-payment/asset-conversion-tx-payment/README.md b/substrate/frame/transaction-payment/asset-conversion-tx-payment/README.md
index eccba773673..fcd1527526e 100644
--- a/substrate/frame/transaction-payment/asset-conversion-tx-payment/README.md
+++ b/substrate/frame/transaction-payment/asset-conversion-tx-payment/README.md
@@ -16,6 +16,6 @@ asset.
 ### Integration
 This pallet wraps FRAME's transaction payment pallet and functions as a replacement. This means
 you should include both pallets in your `construct_runtime` macro, but only include this
-pallet's [`SignedExtension`] ([`ChargeAssetTxPayment`]).
+pallet's [`TransactionExtension`] ([`ChargeAssetTxPayment`]).
 
 License: Apache-2.0
diff --git a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/benchmarking.rs b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/benchmarking.rs
new file mode 100644
index 00000000000..97eff03d849
--- /dev/null
+++ b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/benchmarking.rs
@@ -0,0 +1,127 @@
+// This file is part of Substrate.
+
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Benchmarks for Asset Conversion Tx Payment Pallet's transaction extension
+
+extern crate alloc;
+
+use super::*;
+use crate::Pallet;
+use frame_benchmarking::v2::*;
+use frame_support::{
+	dispatch::{DispatchInfo, PostDispatchInfo},
+	pallet_prelude::*,
+};
+use frame_system::RawOrigin;
+use sp_runtime::traits::{
+	AsSystemOriginSigner, AsTransactionAuthorizedOrigin, DispatchTransaction, Dispatchable,
+};
+
+#[benchmarks(where
+	T::RuntimeOrigin: AsTransactionAuthorizedOrigin,
+	T::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
+	T::AssetId: Send + Sync,
+	BalanceOf<T>: Send
+		+ Sync
+		+ From<u64>,
+	<T::RuntimeCall as Dispatchable>::RuntimeOrigin: AsSystemOriginSigner<T::AccountId> + Clone,
+)]
+mod benchmarks {
+	use super::*;
+
+	#[benchmark]
+	fn charge_asset_tx_payment_zero() {
+		let caller: T::AccountId = account("caller", 0, 0);
+		let ext: ChargeAssetTxPayment<T> = ChargeAssetTxPayment::from(0u64.into(), None);
+		let inner = frame_system::Call::remark { remark: alloc::vec![] };
+		let call = T::RuntimeCall::from(inner);
+		let info = DispatchInfo {
+			call_weight: Weight::zero(),
+			extension_weight: Weight::zero(),
+			class: DispatchClass::Normal,
+			pays_fee: Pays::No,
+		};
+		let post_info = PostDispatchInfo { actual_weight: None, pays_fee: Pays::No };
+		#[block]
+		{
+			assert!(ext
+				.test_run(RawOrigin::Signed(caller).into(), &call, &info, 0, |_| Ok(post_info))
+				.unwrap()
+				.is_ok());
+		}
+	}
+
+	#[benchmark]
+	fn charge_asset_tx_payment_native() {
+		let caller: T::AccountId = account("caller", 0, 0);
+		let (fun_asset_id, _) = <T as Config>::BenchmarkHelper::create_asset_id_parameter(1);
+		<T as Config>::BenchmarkHelper::setup_balances_and_pool(fun_asset_id, caller.clone());
+		let ext: ChargeAssetTxPayment<T> = ChargeAssetTxPayment::from(10u64.into(), None);
+		let inner = frame_system::Call::remark { remark: alloc::vec![] };
+		let call = T::RuntimeCall::from(inner);
+		let info = DispatchInfo {
+			call_weight: Weight::from_parts(10, 0),
+			extension_weight: Weight::zero(),
+			class: DispatchClass::Operational,
+			pays_fee: Pays::Yes,
+		};
+		// Submit a lower post info weight to trigger the refund path.
+		let post_info =
+			PostDispatchInfo { actual_weight: Some(Weight::from_parts(5, 0)), pays_fee: Pays::Yes };
+
+		#[block]
+		{
+			assert!(ext
+				.test_run(RawOrigin::Signed(caller).into(), &call, &info, 0, |_| Ok(post_info))
+				.unwrap()
+				.is_ok());
+		}
+	}
+
+	#[benchmark]
+	fn charge_asset_tx_payment_asset() {
+		let caller: T::AccountId = account("caller", 0, 0);
+		let (fun_asset_id, asset_id) = <T as Config>::BenchmarkHelper::create_asset_id_parameter(1);
+		<T as Config>::BenchmarkHelper::setup_balances_and_pool(fun_asset_id, caller.clone());
+
+		let tip = 10u64.into();
+		let ext: ChargeAssetTxPayment<T> = ChargeAssetTxPayment::from(tip, Some(asset_id));
+		let inner = frame_system::Call::remark { remark: alloc::vec![] };
+		let call = T::RuntimeCall::from(inner);
+		let info = DispatchInfo {
+			call_weight: Weight::from_parts(10, 0),
+			extension_weight: Weight::zero(),
+			class: DispatchClass::Operational,
+			pays_fee: Pays::Yes,
+		};
+		// Submit a lower post info weight to trigger the refund path.
+		let post_info =
+			PostDispatchInfo { actual_weight: Some(Weight::from_parts(5, 0)), pays_fee: Pays::Yes };
+
+		#[block]
+		{
+			assert!(ext
+				.test_run(RawOrigin::Signed(caller.clone()).into(), &call, &info, 0, |_| Ok(
+					post_info
+				))
+				.unwrap()
+				.is_ok());
+		}
+	}
+
+	impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Runtime);
+}
diff --git a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/lib.rs b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/lib.rs
index 825a35e6213..787f6b122e8 100644
--- a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/lib.rs
+++ b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/lib.rs
@@ -20,8 +20,8 @@
 //!
 //! ## Overview
 //!
-//! This pallet provides a `SignedExtension` with an optional `AssetId` that specifies the asset
-//! to be used for payment (defaulting to the native token on `None`). It expects an
+//! This pallet provides a `TransactionExtension` with an optional `AssetId` that specifies the
+//! asset to be used for payment (defaulting to the native token on `None`). It expects an
 //! [`OnChargeAssetTransaction`] implementation analogous to [`pallet-transaction-payment`]. The
 //! included [`SwapAssetAdapter`] (implementing [`OnChargeAssetTransaction`]) determines the
 //! fee amount by converting the fee calculated by [`pallet-transaction-payment`] in the native
@@ -31,7 +31,7 @@
 //!
 //! This pallet does not have any dispatchable calls or storage. It wraps FRAME's Transaction
 //! Payment pallet and functions as a replacement. This means you should include both pallets in
-//! your `construct_runtime` macro, but only include this pallet's [`SignedExtension`]
+//! your `construct_runtime` macro, but only include this pallet's [`TransactionExtension`]
 //! ([`ChargeAssetTxPayment`]).
 //!
 //! ## Terminology
@@ -50,21 +50,29 @@ use frame_support::{
 	traits::IsType,
 	DefaultNoBound,
 };
-use pallet_transaction_payment::OnChargeTransaction;
+use pallet_transaction_payment::{ChargeTransactionPayment, OnChargeTransaction};
 use scale_info::TypeInfo;
 use sp_runtime::{
-	traits::{DispatchInfoOf, Dispatchable, PostDispatchInfoOf, SignedExtension, Zero},
-	transaction_validity::{TransactionValidity, TransactionValidityError, ValidTransaction},
+	traits::{
+		AsSystemOriginSigner, DispatchInfoOf, Dispatchable, PostDispatchInfoOf, RefundWeight,
+		TransactionExtension, ValidateResult, Zero,
+	},
+	transaction_validity::{InvalidTransaction, TransactionValidityError, ValidTransaction},
 };
 
 #[cfg(test)]
 mod mock;
 #[cfg(test)]
 mod tests;
+pub mod weights;
+
+#[cfg(feature = "runtime-benchmarks")]
+mod benchmarking;
 
 mod payment;
-use frame_support::traits::tokens::AssetId;
+use frame_support::{pallet_prelude::Weight, traits::tokens::AssetId};
 pub use payment::*;
+pub use weights::WeightInfo;
 
 /// Balance type alias for balances of the chain's native asset.
 pub(crate) type BalanceOf<T> = <OnChargeTransactionOf<T> as OnChargeTransaction<T>>::Balance;
@@ -112,11 +120,30 @@ pub mod pallet {
 			Balance = BalanceOf<Self>,
 			AssetId = Self::AssetId,
 		>;
+		/// The weight information of this pallet.
+		type WeightInfo: WeightInfo;
+		#[cfg(feature = "runtime-benchmarks")]
+		/// Benchmark helper
+		type BenchmarkHelper: BenchmarkHelperTrait<
+			Self::AccountId,
+			Self::AssetId,
+			<<Self as Config>::OnChargeAssetTransaction as OnChargeAssetTransaction<Self>>::AssetId,
+		>;
 	}
 
 	#[pallet::pallet]
 	pub struct Pallet<T>(_);
 
+	#[cfg(feature = "runtime-benchmarks")]
+	/// Helper trait to benchmark the `ChargeAssetTxPayment` transaction extension.
+	pub trait BenchmarkHelperTrait<AccountId, FunAssetIdParameter, AssetIdParameter> {
+		/// Returns the `AssetId` to be used in the liquidity pool by the benchmarking code.
+		fn create_asset_id_parameter(id: u32) -> (FunAssetIdParameter, AssetIdParameter);
+		/// Create a liquidity pool for a given asset and sufficiently endow accounts to benchmark
+		/// the extension.
+		fn setup_balances_and_pool(asset_id: FunAssetIdParameter, account: AccountId);
+	}
+
 	#[pallet::event]
 	#[pallet::generate_deposit(pub(super) fn deposit_event)]
 	pub enum Event<T: Config> {
@@ -168,9 +195,8 @@ where
 		who: &T::AccountId,
 		call: &T::RuntimeCall,
 		info: &DispatchInfoOf<T::RuntimeCall>,
-		len: usize,
+		fee: BalanceOf<T>,
 	) -> Result<(BalanceOf<T>, InitialPayment<T>), TransactionValidityError> {
-		let fee = pallet_transaction_payment::Pallet::<T>::compute_fee(len as u32, info, self.tip);
 		debug_assert!(self.tip <= fee, "tip should be included in the computed fee");
 		if fee.is_zero() {
 			Ok((fee, InitialPayment::Nothing))
@@ -189,6 +215,28 @@ where
 				.map(|payment| (fee, InitialPayment::Native(payment)))
 		}
 	}
+
+	/// Fee withdrawal logic dry-run that dispatches to either `OnChargeAssetTransaction` or
+	/// `OnChargeTransaction`.
+	fn can_withdraw_fee(
+		&self,
+		who: &T::AccountId,
+		call: &T::RuntimeCall,
+		info: &DispatchInfoOf<T::RuntimeCall>,
+		fee: BalanceOf<T>,
+	) -> Result<(), TransactionValidityError> {
+		debug_assert!(self.tip <= fee, "tip should be included in the computed fee");
+		if fee.is_zero() {
+			Ok(())
+		} else if let Some(asset_id) = &self.asset_id {
+			T::OnChargeAssetTransaction::can_withdraw_fee(who, asset_id.clone(), fee.into())
+		} else {
+			<OnChargeTransactionOf<T> as OnChargeTransaction<T>>::can_withdraw_fee(
+				who, call, info, fee, self.tip,
+			)
+			.map_err(|_| -> TransactionValidityError { InvalidTransaction::Payment.into() })
+		}
+	}
 }
 
 impl<T: Config> core::fmt::Debug for ChargeAssetTxPayment<T> {
@@ -202,108 +250,179 @@ impl<T: Config> core::fmt::Debug for ChargeAssetTxPayment<T> {
 	}
 }
 
-impl<T: Config> SignedExtension for ChargeAssetTxPayment<T>
+/// The info passed between the validate and prepare steps for the `ChargeAssetTxPayment` extension.
+pub enum Val<T: Config> {
+	Charge {
+		tip: BalanceOf<T>,
+		// who paid the fee
+		who: T::AccountId,
+		// transaction fee
+		fee: BalanceOf<T>,
+	},
+	NoCharge,
+}
+
+/// The info passed between the prepare and post-dispatch steps for the `ChargeAssetTxPayment`
+/// extension.
+pub enum Pre<T: Config> {
+	Charge {
+		tip: BalanceOf<T>,
+		// who paid the fee
+		who: T::AccountId,
+		// imbalance resulting from withdrawing the fee
+		initial_payment: InitialPayment<T>,
+		// weight used by the extension
+		weight: Weight,
+	},
+	NoCharge {
+		// weight initially estimated by the extension, to be refunded
+		refund: Weight,
+	},
+}
+
+impl<T: Config> TransactionExtension<T::RuntimeCall> for ChargeAssetTxPayment<T>
 where
 	T::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
-	BalanceOf<T>: Send + Sync,
+	BalanceOf<T>: Send + Sync + From<u64>,
 	T::AssetId: Send + Sync,
+	<T::RuntimeCall as Dispatchable>::RuntimeOrigin: AsSystemOriginSigner<T::AccountId> + Clone,
 {
 	const IDENTIFIER: &'static str = "ChargeAssetTxPayment";
-	type AccountId = T::AccountId;
-	type Call = T::RuntimeCall;
-	type AdditionalSigned = ();
-	type Pre = (
-		// tip
-		BalanceOf<T>,
-		// who paid the fee
-		Self::AccountId,
-		// imbalance resulting from withdrawing the fee
-		InitialPayment<T>,
-	);
+	type Implicit = ();
+	type Val = Val<T>;
+	type Pre = Pre<T>;
 
-	fn additional_signed(&self) -> core::result::Result<(), TransactionValidityError> {
-		Ok(())
+	fn weight(&self, _: &T::RuntimeCall) -> Weight {
+		if self.asset_id.is_some() {
+			<T as Config>::WeightInfo::charge_asset_tx_payment_asset()
+		} else {
+			<T as Config>::WeightInfo::charge_asset_tx_payment_native()
+		}
 	}
 
 	fn validate(
 		&self,
-		who: &Self::AccountId,
-		call: &Self::Call,
-		info: &DispatchInfoOf<Self::Call>,
+		origin: <T::RuntimeCall as Dispatchable>::RuntimeOrigin,
+		call: &T::RuntimeCall,
+		info: &DispatchInfoOf<T::RuntimeCall>,
 		len: usize,
-	) -> TransactionValidity {
-		use pallet_transaction_payment::ChargeTransactionPayment;
-		let (fee, _) = self.withdraw_fee(who, call, info, len)?;
+		_self_implicit: Self::Implicit,
+		_inherited_implication: &impl Encode,
+	) -> ValidateResult<Self::Val, T::RuntimeCall> {
+		let Some(who) = origin.as_system_origin_signer() else {
+			return Ok((ValidTransaction::default(), Val::NoCharge, origin))
+		};
+		// Non-mutating call of `compute_fee` to calculate the fee used in the transaction priority.
+		let fee = pallet_transaction_payment::Pallet::<T>::compute_fee(len as u32, info, self.tip);
+		self.can_withdraw_fee(&who, call, info, fee)?;
 		let priority = ChargeTransactionPayment::<T>::get_priority(info, len, self.tip, fee);
-		Ok(ValidTransaction { priority, ..Default::default() })
+		let validity = ValidTransaction { priority, ..Default::default() };
+		let val = Val::Charge { tip: self.tip, who: who.clone(), fee };
+		Ok((validity, val, origin))
 	}
 
-	fn pre_dispatch(
+	fn prepare(
 		self,
-		who: &Self::AccountId,
-		call: &Self::Call,
-		info: &DispatchInfoOf<Self::Call>,
-		len: usize,
+		val: Self::Val,
+		_origin: &<T::RuntimeCall as Dispatchable>::RuntimeOrigin,
+		call: &T::RuntimeCall,
+		info: &DispatchInfoOf<T::RuntimeCall>,
+		_len: usize,
 	) -> Result<Self::Pre, TransactionValidityError> {
-		let (_fee, initial_payment) = self.withdraw_fee(who, call, info, len)?;
-		Ok((self.tip, who.clone(), initial_payment))
+		match val {
+			Val::Charge { tip, who, fee } => {
+				// Mutating call of `withdraw_fee` to actually charge for the transaction.
+				let (_fee, initial_payment) = self.withdraw_fee(&who, call, info, fee)?;
+				Ok(Pre::Charge { tip, who, initial_payment, weight: self.weight(call) })
+			},
+			Val::NoCharge => Ok(Pre::NoCharge { refund: self.weight(call) }),
+		}
 	}
 
-	fn post_dispatch(
-		pre: Option<Self::Pre>,
-		info: &DispatchInfoOf<Self::Call>,
-		post_info: &PostDispatchInfoOf<Self::Call>,
+	fn post_dispatch_details(
+		pre: Self::Pre,
+		info: &DispatchInfoOf<T::RuntimeCall>,
+		post_info: &PostDispatchInfoOf<T::RuntimeCall>,
 		len: usize,
 		_result: &DispatchResult,
-	) -> Result<(), TransactionValidityError> {
-		if let Some((tip, who, initial_payment)) = pre {
-			match initial_payment {
-				InitialPayment::Native(already_withdrawn) => {
-					let actual_fee = pallet_transaction_payment::Pallet::<T>::compute_actual_fee(
-						len as u32, info, post_info, tip,
-					);
-					T::OnChargeTransaction::correct_and_deposit_fee(
-						&who,
-						info,
-						post_info,
-						actual_fee,
-						tip,
-						already_withdrawn,
-					)?;
-					pallet_transaction_payment::Pallet::<T>::deposit_fee_paid_event(
-						who, actual_fee, tip,
-					);
-				},
-				InitialPayment::Asset((asset_id, already_withdrawn)) => {
-					let actual_fee = pallet_transaction_payment::Pallet::<T>::compute_actual_fee(
-						len as u32, info, post_info, tip,
-					);
-					let converted_fee = T::OnChargeAssetTransaction::correct_and_deposit_fee(
-						&who,
-						info,
-						post_info,
-						actual_fee,
-						tip,
-						asset_id.clone(),
-						already_withdrawn,
-					)?;
-					Pallet::<T>::deposit_event(Event::<T>::AssetTxFeePaid {
-						who,
-						actual_fee: converted_fee,
-						tip,
-						asset_id,
-					});
-				},
-				InitialPayment::Nothing => {
-					// `actual_fee` should be zero here for any signed extrinsic. It would be
-					// non-zero here in case of unsigned extrinsics as they don't pay fees but
-					// `compute_actual_fee` is not aware of them. In both cases it's fine to just
-					// move ahead without adjusting the fee, though, so we do nothing.
-					debug_assert!(tip.is_zero(), "tip should be zero if initial fee was zero.");
-				},
-			}
-		}
+	) -> Result<Weight, TransactionValidityError> {
+		let (tip, who, initial_payment, extension_weight) = match pre {
+			Pre::Charge { tip, who, initial_payment, weight } =>
+				(tip, who, initial_payment, weight),
+			Pre::NoCharge { refund } => {
+				// No-op: Refund everything
+				return Ok(refund)
+			},
+		};
 
-		Ok(())
+		match initial_payment {
+			InitialPayment::Native(already_withdrawn) => {
+				// Take into account the weight used by this extension before calculating the
+				// refund.
+				let actual_ext_weight = <T as Config>::WeightInfo::charge_asset_tx_payment_native();
+				let unspent_weight = extension_weight.saturating_sub(actual_ext_weight);
+				let mut actual_post_info = *post_info;
+				actual_post_info.refund(unspent_weight);
+				let actual_fee = pallet_transaction_payment::Pallet::<T>::compute_actual_fee(
+					len as u32,
+					info,
+					&actual_post_info,
+					tip,
+				);
+				T::OnChargeTransaction::correct_and_deposit_fee(
+					&who,
+					info,
+					&actual_post_info,
+					actual_fee,
+					tip,
+					already_withdrawn,
+				)?;
+				pallet_transaction_payment::Pallet::<T>::deposit_fee_paid_event(
+					who, actual_fee, tip,
+				);
+				Ok(unspent_weight)
+			},
+			InitialPayment::Asset((asset_id, already_withdrawn)) => {
+				// Take into account the weight used by this extension before calculating the
+				// refund.
+				let actual_ext_weight = <T as Config>::WeightInfo::charge_asset_tx_payment_asset();
+				let unspent_weight = extension_weight.saturating_sub(actual_ext_weight);
+				let mut actual_post_info = *post_info;
+				actual_post_info.refund(unspent_weight);
+				let actual_fee = pallet_transaction_payment::Pallet::<T>::compute_actual_fee(
+					len as u32,
+					info,
+					&actual_post_info,
+					tip,
+				);
+				let converted_fee = T::OnChargeAssetTransaction::correct_and_deposit_fee(
+					&who,
+					info,
+					&actual_post_info,
+					actual_fee,
+					tip,
+					asset_id.clone(),
+					already_withdrawn,
+				)?;
+
+				Pallet::<T>::deposit_event(Event::<T>::AssetTxFeePaid {
+					who,
+					actual_fee: converted_fee,
+					tip,
+					asset_id,
+				});
+
+				Ok(unspent_weight)
+			},
+			InitialPayment::Nothing => {
+				// `actual_fee` should be zero here for any signed extrinsic. It would be
+				// non-zero here in case of unsigned extrinsics as they don't pay fees but
+				// `compute_actual_fee` is not aware of them. In both cases it's fine to just
+				// move ahead without adjusting the fee, though, so we do nothing.
+				debug_assert!(tip.is_zero(), "tip should be zero if initial fee was zero.");
+				Ok(extension_weight
+					.saturating_sub(<T as Config>::WeightInfo::charge_asset_tx_payment_zero()))
+			},
+		}
 	}
 }
diff --git a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/mock.rs b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/mock.rs
index acfd43d0a7c..a86b86c223e 100644
--- a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/mock.rs
+++ b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/mock.rs
@@ -145,6 +145,14 @@ impl OnUnbalanced<fungible::Credit<<Runtime as frame_system::Config>::AccountId,
 	}
 }
 
+pub struct MockTxPaymentWeights;
+
+impl pallet_transaction_payment::WeightInfo for MockTxPaymentWeights {
+	fn charge_transaction_payment() -> Weight {
+		Weight::from_parts(10, 0)
+	}
+}
+
 pub struct DealWithFungiblesFees;
 impl OnUnbalanced<fungibles::Credit<AccountId, NativeAndAssets>> for DealWithFungiblesFees {
 	fn on_unbalanceds(
@@ -167,8 +175,8 @@ impl pallet_transaction_payment::Config for Runtime {
 	type OnChargeTransaction = FungibleAdapter<Balances, DealWithFees>;
 	type WeightToFee = WeightToFee;
 	type LengthToFee = TransactionByteFee;
-	type FeeMultiplierUpdate = ();
 	type OperationalFeeMultiplier = ConstU8<5>;
+	type WeightInfo = MockTxPaymentWeights;
 }
 
 type AssetId = u32;
@@ -266,9 +274,95 @@ impl pallet_asset_conversion::Config for Runtime {
 	}
 }
 
+/// Weights used in testing.
+pub struct MockWeights;
+
+impl WeightInfo for MockWeights {
+	fn charge_asset_tx_payment_zero() -> Weight {
+		Weight::from_parts(0, 0)
+	}
+
+	fn charge_asset_tx_payment_native() -> Weight {
+		Weight::from_parts(15, 0)
+	}
+
+	fn charge_asset_tx_payment_asset() -> Weight {
+		Weight::from_parts(20, 0)
+	}
+}
+
 impl Config for Runtime {
 	type RuntimeEvent = RuntimeEvent;
 	type AssetId = NativeOrWithId<u32>;
 	type OnChargeAssetTransaction =
 		SwapAssetAdapter<Native, NativeAndAssets, AssetConversion, DealWithFungiblesFees>;
+	type WeightInfo = MockWeights;
+	#[cfg(feature = "runtime-benchmarks")]
+	type BenchmarkHelper = Helper;
+}
+
+#[cfg(feature = "runtime-benchmarks")]
+pub fn new_test_ext() -> sp_io::TestExternalities {
+	let base_weight = 5;
+	let balance_factor = 100;
+	crate::tests::ExtBuilder::default()
+		.balance_factor(balance_factor)
+		.base_weight(Weight::from_parts(base_weight, 0))
+		.build()
+}
+
+#[cfg(feature = "runtime-benchmarks")]
+pub struct Helper;
+
+#[cfg(feature = "runtime-benchmarks")]
+impl BenchmarkHelperTrait<u64, NativeOrWithId<u32>, NativeOrWithId<u32>> for Helper {
+	fn create_asset_id_parameter(id: u32) -> (NativeOrWithId<u32>, NativeOrWithId<u32>) {
+		(NativeOrWithId::WithId(id), NativeOrWithId::WithId(id))
+	}
+
+	fn setup_balances_and_pool(asset_id: NativeOrWithId<u32>, account: u64) {
+		use frame_support::{assert_ok, traits::fungibles::Mutate};
+		use sp_runtime::traits::StaticLookup;
+		let NativeOrWithId::WithId(asset_idx) = asset_id.clone() else { unimplemented!() };
+		assert_ok!(Assets::force_create(
+			RuntimeOrigin::root(),
+			asset_idx.into(),
+			42,   /* owner */
+			true, /* is_sufficient */
+			1,
+		));
+
+		let lp_provider = 12;
+		assert_ok!(Balances::force_set_balance(RuntimeOrigin::root(), lp_provider, u64::MAX / 2));
+		let lp_provider_account = <Runtime as system::Config>::Lookup::unlookup(lp_provider);
+		assert_ok!(Assets::mint_into(asset_idx, &lp_provider_account, u64::MAX / 2));
+
+		let token_1 = Box::new(NativeOrWithId::Native);
+		let token_2 = Box::new(asset_id);
+		assert_ok!(AssetConversion::create_pool(
+			RuntimeOrigin::signed(lp_provider),
+			token_1.clone(),
+			token_2.clone()
+		));
+
+		assert_ok!(AssetConversion::add_liquidity(
+			RuntimeOrigin::signed(lp_provider),
+			token_1,
+			token_2,
+			(u32::MAX / 8).into(), // 1 desired
+			u32::MAX.into(),       // 2 desired
+			1,                     // 1 min
+			1,                     // 2 min
+			lp_provider_account,
+		));
+
+		use frame_support::traits::Currency;
+		let _ = Balances::deposit_creating(&account, u32::MAX.into());
+
+		let beneficiary = <Runtime as system::Config>::Lookup::unlookup(account);
+		let balance = 1000;
+
+		assert_ok!(Assets::mint_into(asset_idx, &beneficiary, balance));
+		assert_eq!(Assets::balance(asset_idx, account), balance);
+	}
 }
diff --git a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/payment.rs b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/payment.rs
index dc7faecd560..05182c3c9ee 100644
--- a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/payment.rs
+++ b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/payment.rs
@@ -23,7 +23,7 @@ use frame_support::{
 	defensive, ensure,
 	traits::{
 		fungibles,
-		tokens::{Balance, Fortitude, Precision, Preservation},
+		tokens::{Balance, Fortitude, Precision, Preservation, WithdrawConsequence},
 		Defensive, OnUnbalanced, SameOrOther,
 	},
 	unsigned::TransactionValidityError,
@@ -56,6 +56,15 @@ pub trait OnChargeAssetTransaction<T: Config> {
 		tip: Self::Balance,
 	) -> Result<Self::LiquidityInfo, TransactionValidityError>;
 
+	/// Ensure payment of the transaction fees can be withdrawn.
+	///
+	/// Note: The `fee` already includes the tip.
+	fn can_withdraw_fee(
+		who: &T::AccountId,
+		asset_id: Self::AssetId,
+		fee: Self::Balance,
+	) -> Result<(), TransactionValidityError>;
+
 	/// Refund any overpaid fees and deposit the corrected amount.
 	/// The actual fee gets calculated once the transaction is executed.
 	///
@@ -162,6 +171,51 @@ where
 		Ok((fee_credit, asset_fee))
 	}
 
+	/// Dry run of swap & withdraw the predicted fee from the transaction origin.
+	///
+	/// Note: The `fee` already includes the tip.
+	///
+	/// Returns an error if the total amount in native currency can't be exchanged for `asset_id`.
+	fn can_withdraw_fee(
+		who: &T::AccountId,
+		asset_id: Self::AssetId,
+		fee: BalanceOf<T>,
+	) -> Result<(), TransactionValidityError> {
+		if asset_id == A::get() {
+			// The `asset_id` is the target asset, we do not need to swap.
+			match F::can_withdraw(asset_id.clone(), who, fee) {
+				WithdrawConsequence::BalanceLow |
+				WithdrawConsequence::UnknownAsset |
+				WithdrawConsequence::Underflow |
+				WithdrawConsequence::Overflow |
+				WithdrawConsequence::Frozen =>
+					return Err(TransactionValidityError::from(InvalidTransaction::Payment)),
+				WithdrawConsequence::Success |
+				WithdrawConsequence::ReducedToZero(_) |
+				WithdrawConsequence::WouldDie => return Ok(()),
+			}
+		}
+
+		let asset_fee =
+			S::quote_price_tokens_for_exact_tokens(asset_id.clone(), A::get(), fee, true)
+				.ok_or(InvalidTransaction::Payment)?;
+
+		// Ensure we can withdraw enough `asset_id` for the swap.
+		match F::can_withdraw(asset_id.clone(), who, asset_fee) {
+			WithdrawConsequence::BalanceLow |
+			WithdrawConsequence::UnknownAsset |
+			WithdrawConsequence::Underflow |
+			WithdrawConsequence::Overflow |
+			WithdrawConsequence::Frozen =>
+				return Err(TransactionValidityError::from(InvalidTransaction::Payment)),
+			WithdrawConsequence::Success |
+			WithdrawConsequence::ReducedToZero(_) |
+			WithdrawConsequence::WouldDie => {},
+		};
+
+		Ok(())
+	}
+
 	fn correct_and_deposit_fee(
 		who: &T::AccountId,
 		_dispatch_info: &DispatchInfoOf<<T>::RuntimeCall>,
diff --git a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/tests.rs b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/tests.rs
index aab65719953..4312aa9a452 100644
--- a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/tests.rs
+++ b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/tests.rs
@@ -17,19 +17,23 @@ use super::*;
 
 use frame_support::{
 	assert_ok,
-	dispatch::{DispatchInfo, PostDispatchInfo},
+	dispatch::{DispatchInfo, GetDispatchInfo, PostDispatchInfo},
 	pallet_prelude::*,
 	traits::{
 		fungible::{Inspect, NativeOrWithId},
 		fungibles::{Inspect as FungiblesInspect, Mutate},
 		tokens::{Fortitude, Precision, Preservation},
+		OriginTrait,
 	},
 	weights::Weight,
 };
 use frame_system as system;
 use mock::{ExtrinsicBaseWeight, *};
 use pallet_balances::Call as BalancesCall;
-use sp_runtime::{traits::StaticLookup, BuildStorage};
+use sp_runtime::{
+	traits::{DispatchTransaction, StaticLookup},
+	BuildStorage,
+};
 
 const CALL: &<Runtime as frame_system::Config>::RuntimeCall =
 	&RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 2, value: 69 });
@@ -92,7 +96,7 @@ impl ExtBuilder {
 /// create a transaction info struct from weight. Handy to avoid building the whole struct.
 pub fn info_from_weight(w: Weight) -> DispatchInfo {
 	// pays_fee: Pays::Yes -- class: DispatchClass::Normal
-	DispatchInfo { weight: w, ..Default::default() }
+	DispatchInfo { call_weight: w, ..Default::default() }
 }
 
 fn post_info_from_weight(w: Weight) -> PostDispatchInfo {
@@ -161,35 +165,45 @@ fn transaction_payment_in_native_possible() {
 		.build()
 		.execute_with(|| {
 			let len = 10;
-			let pre = ChargeAssetTxPayment::<Runtime>::from(0, None)
-				.pre_dispatch(&1, CALL, &info_from_weight(WEIGHT_5), len)
-				.unwrap();
+			let mut info = info_from_weight(WEIGHT_5);
+			let ext = ChargeAssetTxPayment::<Runtime>::from(0, None);
+			info.extension_weight = ext.weight(CALL);
+			let (pre, _) = ext.validate_and_prepare(Some(1).into(), CALL, &info, len).unwrap();
 			let initial_balance = 10 * balance_factor;
-			assert_eq!(Balances::free_balance(1), initial_balance - 5 - 5 - 10);
+			assert_eq!(Balances::free_balance(1), initial_balance - 5 - 5 - 15 - 10);
 
-			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch(
-				Some(pre),
-				&info_from_weight(WEIGHT_5),
+			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch_details(
+				pre,
+				&info,
 				&default_post_info(),
 				len,
-				&Ok(())
+				&Ok(()),
 			));
-			assert_eq!(Balances::free_balance(1), initial_balance - 5 - 5 - 10);
+			assert_eq!(Balances::free_balance(1), initial_balance - 5 - 5 - 15 - 10);
 
-			let pre = ChargeAssetTxPayment::<Runtime>::from(5 /* tipped */, None)
-				.pre_dispatch(&2, CALL, &info_from_weight(WEIGHT_100), len)
-				.unwrap();
+			let mut info = info_from_weight(WEIGHT_100);
+			let ext = ChargeAssetTxPayment::<Runtime>::from(5 /* tipped */, None);
+			let extension_weight = ext.weight(CALL);
+			info.extension_weight = extension_weight;
+			let (pre, _) = ext.validate_and_prepare(Some(2).into(), CALL, &info, len).unwrap();
 			let initial_balance_for_2 = 20 * balance_factor;
 
-			assert_eq!(Balances::free_balance(2), initial_balance_for_2 - 5 - 10 - 100 - 5);
-			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch(
-				Some(pre),
-				&info_from_weight(WEIGHT_100),
-				&post_info_from_weight(WEIGHT_50),
+			assert_eq!(Balances::free_balance(2), initial_balance_for_2 - 5 - 10 - 100 - 15 - 5);
+			let call_actual_weight = WEIGHT_50;
+			let post_info = post_info_from_weight(
+				info.call_weight
+					.saturating_sub(call_actual_weight)
+					.saturating_add(extension_weight),
+			);
+			// The extension weight refund should be taken into account in `post_dispatch`.
+			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch_details(
+				pre,
+				&info,
+				&post_info,
 				len,
-				&Ok(())
+				&Ok(()),
 			));
-			assert_eq!(Balances::free_balance(2), initial_balance_for_2 - 5 - 10 - 50 - 5);
+			assert_eq!(Balances::free_balance(2), initial_balance_for_2 - 5 - 10 - 50 - 15 - 5);
 		});
 }
 
@@ -240,8 +254,8 @@ fn transaction_payment_in_asset_possible() {
 			let fee_in_asset = input_quote.unwrap();
 			assert_eq!(Assets::balance(asset_id, caller), balance);
 
-			let pre = ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id.into()))
-				.pre_dispatch(&caller, CALL, &info_from_weight(WEIGHT_5), len)
+			let (pre, _) = ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id.into()))
+				.validate_and_prepare(Some(caller).into(), CALL, &info_from_weight(WEIGHT_5), len)
 				.unwrap();
 			// assert that native balance is not used
 			assert_eq!(Balances::free_balance(caller), 10 * balance_factor);
@@ -255,12 +269,12 @@ fn transaction_payment_in_asset_possible() {
 				amount: fee_in_asset,
 			}));
 
-			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch(
-				Some(pre),
+			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch_details(
+				pre,
 				&info_from_weight(WEIGHT_5), // estimated tx weight
 				&default_post_info(),        // weight actually used == estimated
 				len,
-				&Ok(())
+				&Ok(()),
 			));
 
 			assert_eq!(Assets::balance(asset_id, caller), balance - fee_in_asset);
@@ -298,12 +312,8 @@ fn transaction_payment_in_asset_fails_if_no_pool_for_that_asset() {
 			assert_eq!(Assets::balance(asset_id, caller), balance);
 
 			let len = 10;
-			let pre = ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id.into())).pre_dispatch(
-				&caller,
-				CALL,
-				&info_from_weight(WEIGHT_5),
-				len,
-			);
+			let pre = ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id.into()))
+				.validate_and_prepare(Some(caller).into(), CALL, &info_from_weight(WEIGHT_5), len);
 
 			// As there is no pool in the dex set up for this asset, conversion should fail.
 			assert!(pre.is_err());
@@ -353,8 +363,8 @@ fn transaction_payment_without_fee() {
 			assert_eq!(input_quote, Some(201));
 
 			let fee_in_asset = input_quote.unwrap();
-			let pre = ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id.into()))
-				.pre_dispatch(&caller, CALL, &info_from_weight(WEIGHT_5), len)
+			let (pre, _) = ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id.into()))
+				.validate_and_prepare(Some(caller).into(), CALL, &info_from_weight(WEIGHT_5), len)
 				.unwrap();
 
 			// assert that native balance is not used
@@ -371,12 +381,12 @@ fn transaction_payment_without_fee() {
 			.unwrap();
 			assert_eq!(refund, 199);
 
-			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch(
-				Some(pre),
+			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch_details(
+				pre,
 				&info_from_weight(WEIGHT_5),
 				&post_info_from_pays(Pays::No),
 				len,
-				&Ok(())
+				&Ok(()),
 			));
 
 			// caller should get refunded
@@ -419,24 +429,29 @@ fn asset_transaction_payment_with_tip_and_refund() {
 
 			let weight = 100;
 			let tip = 5;
+			let ext = ChargeAssetTxPayment::<Runtime>::from(tip, Some(asset_id.into()));
+			let ext_weight = ext.weight(CALL);
 			let len = 10;
-			let fee_in_native = base_weight + weight + len as u64 + tip;
+			let fee_in_native = base_weight + weight + ext_weight.ref_time() + len as u64 + tip;
 			let input_quote = AssetConversion::quote_price_tokens_for_exact_tokens(
 				NativeOrWithId::WithId(asset_id),
 				NativeOrWithId::Native,
 				fee_in_native,
 				true,
 			);
-			assert_eq!(input_quote, Some(1206));
+			assert_eq!(input_quote, Some(1407));
 
 			let fee_in_asset = input_quote.unwrap();
-			let pre = ChargeAssetTxPayment::<Runtime>::from(tip, Some(asset_id.into()))
-				.pre_dispatch(&caller, CALL, &info_from_weight(WEIGHT_100), len)
-				.unwrap();
+			let mut info = info_from_weight(WEIGHT_100);
+			let ext = ChargeAssetTxPayment::<Runtime>::from(tip, Some(asset_id.into()));
+			info.extension_weight = ext.weight(CALL);
+			let (pre, _) = ext.validate_and_prepare(Some(caller).into(), CALL, &info, len).unwrap();
 			assert_eq!(Assets::balance(asset_id, caller), balance - fee_in_asset);
 
 			let final_weight = 50;
-			let expected_fee = fee_in_native - final_weight - tip;
+			let weight_refund = weight - final_weight;
+			let ext_weight_refund = ext_weight - MockWeights::charge_asset_tx_payment_asset();
+			let expected_fee = fee_in_native - weight_refund - ext_weight_refund.ref_time() - tip;
 			let expected_token_refund = AssetConversion::quote_price_exact_tokens_for_tokens(
 				NativeOrWithId::Native,
 				NativeOrWithId::WithId(asset_id),
@@ -451,12 +466,13 @@ fn asset_transaction_payment_with_tip_and_refund() {
 				amount: fee_in_asset,
 			}));
 
-			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch(
-				Some(pre),
-				&info_from_weight(WEIGHT_100),
-				&post_info_from_weight(WEIGHT_50),
+			let post_info = post_info_from_weight(WEIGHT_50.saturating_add(ext_weight));
+			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch_details(
+				pre,
+				&info,
+				&post_info,
 				len,
-				&Ok(())
+				&Ok(()),
 			));
 
 			assert_eq!(TipUnbalancedAmount::get(), tip);
@@ -522,18 +538,18 @@ fn payment_from_account_with_only_assets() {
 			.unwrap();
 			assert_eq!(fee_in_asset, 201);
 
-			let pre = ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id.into()))
-				.pre_dispatch(&caller, CALL, &info_from_weight(WEIGHT_5), len)
+			let (pre, _) = ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id.into()))
+				.validate_and_prepare(Some(caller).into(), CALL, &info_from_weight(WEIGHT_5), len)
 				.unwrap();
 			// check that fee was charged in the given asset
 			assert_eq!(Assets::balance(asset_id, caller), balance - fee_in_asset);
 
-			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch(
-				Some(pre),
+			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch_details(
+				pre,
 				&info_from_weight(WEIGHT_5),
 				&default_post_info(),
 				len,
-				&Ok(())
+				&Ok(()),
 			));
 			assert_eq!(Assets::balance(asset_id, caller), balance - fee_in_asset);
 			assert_eq!(Balances::free_balance(caller), 0);
@@ -578,18 +594,18 @@ fn converted_fee_is_never_zero_if_input_fee_is_not() {
 
 			// there will be no conversion when the fee is zero
 			{
-				let pre = ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id.into()))
-					.pre_dispatch(&caller, CALL, &info_from_pays(Pays::No), len)
+				let (pre, _) = ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id.into()))
+					.validate_and_prepare(Some(caller).into(), CALL, &info_from_pays(Pays::No), len)
 					.unwrap();
 				// `Pays::No` implies there are no fees
 				assert_eq!(Assets::balance(asset_id, caller), balance);
 
-				assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch(
-					Some(pre),
+				assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch_details(
+					pre,
 					&info_from_pays(Pays::No),
 					&post_info_from_pays(Pays::No),
 					len,
-					&Ok(())
+					&Ok(()),
 				));
 				assert_eq!(Assets::balance(asset_id, caller), balance);
 			}
@@ -604,17 +620,22 @@ fn converted_fee_is_never_zero_if_input_fee_is_not() {
 			)
 			.unwrap();
 
-			let pre = ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id.into()))
-				.pre_dispatch(&caller, CALL, &info_from_weight(Weight::from_parts(weight, 0)), len)
+			let (pre, _) = ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id.into()))
+				.validate_and_prepare(
+					Some(caller).into(),
+					CALL,
+					&info_from_weight(Weight::from_parts(weight, 0)),
+					len,
+				)
 				.unwrap();
 			assert_eq!(Assets::balance(asset_id, caller), balance - fee_in_asset);
 
-			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch(
-				Some(pre),
+			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch_details(
+				pre,
 				&info_from_weight(Weight::from_parts(weight, 0)),
 				&default_post_info(),
 				len,
-				&Ok(())
+				&Ok(()),
 			));
 			assert_eq!(Assets::balance(asset_id, caller), balance - fee_in_asset);
 		});
@@ -654,14 +675,16 @@ fn post_dispatch_fee_is_zero_if_pre_dispatch_fee_is_zero() {
 			// calculated fee is greater than 0
 			assert!(fee > 0);
 
-			let pre = ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id.into()))
-				.pre_dispatch(&caller, CALL, &info_from_pays(Pays::No), len)
+			let (pre, _) = ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id.into()))
+				.validate_and_prepare(Some(caller).into(), CALL, &info_from_pays(Pays::No), len)
 				.unwrap();
 			// `Pays::No` implies no pre-dispatch fees
 
 			assert_eq!(Assets::balance(asset_id, caller), balance);
 
-			let (_tip, _who, initial_payment) = &pre;
+			let Pre::Charge { initial_payment, .. } = &pre else {
+				panic!("Expected Charge");
+			};
 			let not_paying = match initial_payment {
 				&InitialPayment::Nothing => true,
 				_ => false,
@@ -670,63 +693,12 @@ fn post_dispatch_fee_is_zero_if_pre_dispatch_fee_is_zero() {
 
 			// `Pays::Yes` on post-dispatch does not mean we pay (we never charge more than the
 			// initial fee)
-			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch(
-				Some(pre),
+			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch_details(
+				pre,
 				&info_from_pays(Pays::No),
 				&post_info_from_pays(Pays::Yes),
 				len,
-				&Ok(())
-			));
-			assert_eq!(Assets::balance(asset_id, caller), balance);
-		});
-}
-
-#[test]
-fn post_dispatch_fee_is_zero_if_unsigned_pre_dispatch_fee_is_zero() {
-	let base_weight = 1;
-	ExtBuilder::default()
-		.balance_factor(100)
-		.base_weight(Weight::from_parts(base_weight, 0))
-		.build()
-		.execute_with(|| {
-			// create the asset
-			let asset_id = 1;
-			let min_balance = 100;
-			assert_ok!(Assets::force_create(
-				RuntimeOrigin::root(),
-				asset_id.into(),
-				42,   /* owner */
-				true, /* is_sufficient */
-				min_balance
-			));
-
-			// mint into the caller account
-			let caller = 333;
-			let beneficiary = <Runtime as system::Config>::Lookup::unlookup(caller);
-			let balance = 1000;
-
-			assert_ok!(Assets::mint_into(asset_id.into(), &beneficiary, balance));
-			assert_eq!(Assets::balance(asset_id, caller), balance);
-
-			let weight = 1;
-			let len = 1;
-			ChargeAssetTxPayment::<Runtime>::pre_dispatch_unsigned(
-				CALL,
-				&info_from_weight(Weight::from_parts(weight, 0)),
-				len,
-			)
-			.unwrap();
-
-			assert_eq!(Assets::balance(asset_id, caller), balance);
-
-			// `Pays::Yes` on post-dispatch does not mean we pay (we never charge more than the
-			// initial fee)
-			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch(
-				None,
-				&info_from_weight(Weight::from_parts(weight, 0)),
-				&post_info_from_pays(Pays::Yes),
-				len,
-				&Ok(())
+				&Ok(()),
 			));
 			assert_eq!(Assets::balance(asset_id, caller), balance);
 		});
@@ -749,25 +721,34 @@ fn fee_with_native_asset_passed_with_id() {
 			assert_eq!(Balances::free_balance(caller), caller_balance);
 
 			let tip = 10;
-			let weight = 100;
+			let call_weight = 100;
+			let ext = ChargeAssetTxPayment::<Runtime>::from(tip, Some(asset_id.into()));
+			let extension_weight = ext.weight(CALL);
 			let len = 5;
-			let initial_fee = base_weight + weight + len as u64 + tip;
+			let initial_fee =
+				base_weight + call_weight + extension_weight.ref_time() + len as u64 + tip;
 
-			let pre = ChargeAssetTxPayment::<Runtime>::from(tip, Some(asset_id.into()))
-				.pre_dispatch(&caller, CALL, &info_from_weight(WEIGHT_100), len)
-				.unwrap();
+			let mut info = info_from_weight(WEIGHT_100);
+			info.extension_weight = extension_weight;
+			let (pre, _) = ext.validate_and_prepare(Some(caller).into(), CALL, &info, len).unwrap();
 			assert_eq!(Balances::free_balance(caller), caller_balance - initial_fee);
 
 			let final_weight = 50;
+			// No refunds from the extension weight itself.
 			let expected_fee = initial_fee - final_weight;
 
-			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch(
-				Some(pre),
-				&info_from_weight(WEIGHT_100),
-				&post_info_from_weight(WEIGHT_50),
-				len,
-				&Ok(())
-			));
+			let post_info = post_info_from_weight(WEIGHT_50.saturating_add(extension_weight));
+			assert_eq!(
+				ChargeAssetTxPayment::<Runtime>::post_dispatch_details(
+					pre,
+					&info_from_weight(WEIGHT_100),
+					&post_info,
+					len,
+					&Ok(()),
+				)
+				.unwrap(),
+				Weight::zero()
+			);
 
 			assert_eq!(Balances::free_balance(caller), caller_balance - expected_fee);
 
@@ -809,10 +790,13 @@ fn transfer_add_and_remove_account() {
 			assert_ok!(Assets::mint_into(asset_id.into(), &beneficiary, balance));
 			assert_eq!(Assets::balance(asset_id, caller), balance);
 
-			let weight = 100;
+			let call_weight = 100;
 			let tip = 5;
+			let ext = ChargeAssetTxPayment::<Runtime>::from(tip, Some(asset_id.into()));
+			let extension_weight = ext.weight(CALL);
 			let len = 10;
-			let fee_in_native = base_weight + weight + len as u64 + tip;
+			let fee_in_native =
+				base_weight + call_weight + extension_weight.ref_time() + len as u64 + tip;
 			let input_quote = AssetConversion::quote_price_tokens_for_exact_tokens(
 				NativeOrWithId::WithId(asset_id),
 				NativeOrWithId::Native,
@@ -822,8 +806,10 @@ fn transfer_add_and_remove_account() {
 			assert!(!input_quote.unwrap().is_zero());
 
 			let fee_in_asset = input_quote.unwrap();
-			let pre = ChargeAssetTxPayment::<Runtime>::from(tip, Some(asset_id.into()))
-				.pre_dispatch(&caller, CALL, &info_from_weight(WEIGHT_100), len)
+			let mut info = info_from_weight(WEIGHT_100);
+			info.extension_weight = extension_weight;
+			let (pre, _) = ChargeAssetTxPayment::<Runtime>::from(tip, Some(asset_id.into()))
+				.validate_and_prepare(Some(caller).into(), CALL, &info, len)
 				.unwrap();
 
 			assert_eq!(Assets::balance(asset_id, &caller), balance - fee_in_asset);
@@ -838,7 +824,8 @@ fn transfer_add_and_remove_account() {
 				Fortitude::Force
 			));
 
-			let final_weight = 50;
+			// Actual call weight + actual extension weight.
+			let final_weight = 50 + 20;
 			let final_fee_in_native = fee_in_native - final_weight - tip;
 			let token_refund = AssetConversion::quote_price_exact_tokens_for_tokens(
 				NativeOrWithId::Native,
@@ -851,12 +838,12 @@ fn transfer_add_and_remove_account() {
 			// make sure the refund amount is enough to create the account.
 			assert!(token_refund >= min_balance);
 
-			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch(
-				Some(pre),
-				&info_from_weight(WEIGHT_100),
+			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch_details(
+				pre,
+				&info,
 				&post_info_from_weight(WEIGHT_50),
 				len,
-				&Ok(())
+				&Ok(()),
 			));
 
 			// fee paid with no refund.
@@ -867,3 +854,40 @@ fn transfer_add_and_remove_account() {
 			assert_eq!(Assets::balance(asset_id, caller), 0);
 		});
 }
+
+#[test]
+fn no_fee_and_no_weight_for_other_origins() {
+	ExtBuilder::default().build().execute_with(|| {
+		let ext = ChargeAssetTxPayment::<Runtime>::from(0, None);
+
+		let mut info = CALL.get_dispatch_info();
+		info.extension_weight = ext.weight(CALL);
+
+		// Ensure we test the refund.
+		assert!(info.extension_weight != Weight::zero());
+
+		let len = CALL.encoded_size();
+
+		let origin = frame_system::RawOrigin::Root.into();
+		let (pre, origin) = ext.validate_and_prepare(origin, CALL, &info, len).unwrap();
+
+		assert!(origin.as_system_ref().unwrap().is_root());
+
+		let pd_res = Ok(());
+		let mut post_info = frame_support::dispatch::PostDispatchInfo {
+			actual_weight: Some(info.total_weight()),
+			pays_fee: Default::default(),
+		};
+
+		<ChargeAssetTxPayment<Runtime> as TransactionExtension<RuntimeCall>>::post_dispatch(
+			pre,
+			&info,
+			&mut post_info,
+			len,
+			&pd_res,
+		)
+		.unwrap();
+
+		assert_eq!(post_info.actual_weight, Some(info.call_weight));
+	})
+}
diff --git a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/weights.rs b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/weights.rs
new file mode 100644
index 00000000000..f95e49f8073
--- /dev/null
+++ b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/weights.rs
@@ -0,0 +1,150 @@
+// This file is part of Substrate.
+
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Autogenerated weights for `pallet_asset_conversion_tx_payment`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024`
+
+// Executed Command:
+// ./target/production/substrate-node
+// benchmark
+// pallet
+// --chain=dev
+// --steps=50
+// --repeat=20
+// --pallet=pallet_asset_conversion_tx_payment
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --extrinsic=*
+// --wasm-execution=compiled
+// --heap-pages=4096
+// --output=./substrate/frame/transaction-payment/asset-conversion-tx-payment/src/weights.rs
+// --header=./substrate/HEADER-APACHE2
+// --template=./substrate/.maintain/frame-weight-template.hbs
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
+use core::marker::PhantomData;
+
+/// Weight functions needed for `pallet_asset_conversion_tx_payment`.
+pub trait WeightInfo {
+	fn charge_asset_tx_payment_zero() -> Weight;
+	fn charge_asset_tx_payment_native() -> Weight;
+	fn charge_asset_tx_payment_asset() -> Weight;
+}
+
+/// Weights for `pallet_asset_conversion_tx_payment` using the Substrate node and recommended hardware.
+pub struct SubstrateWeight<T>(PhantomData<T>);
+impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
+	fn charge_asset_tx_payment_zero() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 628_000 picoseconds.
+		Weight::from_parts(694_000, 0)
+	}
+	/// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0)
+	/// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
+	/// Storage: `Authorship::Author` (r:1 w:0)
+	/// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
+	/// Storage: `System::Digest` (r:1 w:0)
+	/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	fn charge_asset_tx_payment_native() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `248`
+		//  Estimated: `1733`
+		// Minimum execution time: 34_410_000 picoseconds.
+		Weight::from_parts(35_263_000, 1733)
+			.saturating_add(T::DbWeight::get().reads(3_u64))
+	}
+	/// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0)
+	/// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
+	/// Storage: `Assets::Asset` (r:1 w:1)
+	/// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
+	/// Storage: `Assets::Account` (r:2 w:2)
+	/// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `Authorship::Author` (r:1 w:0)
+	/// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
+	/// Storage: `System::Digest` (r:1 w:0)
+	/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	fn charge_asset_tx_payment_asset() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `888`
+		//  Estimated: `6208`
+		// Minimum execution time: 112_432_000 picoseconds.
+		Weight::from_parts(113_992_000, 6208)
+			.saturating_add(T::DbWeight::get().reads(7_u64))
+			.saturating_add(T::DbWeight::get().writes(4_u64))
+	}
+}
+
+// For backwards compatibility and tests.
+impl WeightInfo for () {
+	fn charge_asset_tx_payment_zero() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 628_000 picoseconds.
+		Weight::from_parts(694_000, 0)
+	}
+	/// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0)
+	/// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
+	/// Storage: `Authorship::Author` (r:1 w:0)
+	/// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
+	/// Storage: `System::Digest` (r:1 w:0)
+	/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	fn charge_asset_tx_payment_native() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `248`
+		//  Estimated: `1733`
+		// Minimum execution time: 34_410_000 picoseconds.
+		Weight::from_parts(35_263_000, 1733)
+			.saturating_add(RocksDbWeight::get().reads(3_u64))
+	}
+	/// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0)
+	/// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
+	/// Storage: `Assets::Asset` (r:1 w:1)
+	/// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
+	/// Storage: `Assets::Account` (r:2 w:2)
+	/// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
+	/// Storage: `System::Account` (r:1 w:1)
+	/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
+	/// Storage: `Authorship::Author` (r:1 w:0)
+	/// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
+	/// Storage: `System::Digest` (r:1 w:0)
+	/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	fn charge_asset_tx_payment_asset() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `888`
+		//  Estimated: `6208`
+		// Minimum execution time: 112_432_000 picoseconds.
+		Weight::from_parts(113_992_000, 6208)
+			.saturating_add(RocksDbWeight::get().reads(7_u64))
+			.saturating_add(RocksDbWeight::get().writes(4_u64))
+	}
+}
diff --git a/substrate/frame/transaction-payment/asset-tx-payment/Cargo.toml b/substrate/frame/transaction-payment/asset-tx-payment/Cargo.toml
index 8d39dea8c62..89fe5bfe7a4 100644
--- a/substrate/frame/transaction-payment/asset-tx-payment/Cargo.toml
+++ b/substrate/frame/transaction-payment/asset-tx-payment/Cargo.toml
@@ -64,6 +64,7 @@ runtime-benchmarks = [
 	"frame-system/runtime-benchmarks",
 	"pallet-assets/runtime-benchmarks",
 	"pallet-balances/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"sp-runtime/runtime-benchmarks",
 ]
 try-runtime = [
diff --git a/substrate/frame/transaction-payment/asset-tx-payment/README.md b/substrate/frame/transaction-payment/asset-tx-payment/README.md
index fc860347d85..933ce13b0ee 100644
--- a/substrate/frame/transaction-payment/asset-tx-payment/README.md
+++ b/substrate/frame/transaction-payment/asset-tx-payment/README.md
@@ -16,6 +16,6 @@ asset.
 ### Integration
 This pallet wraps FRAME's transaction payment pallet and functions as a replacement. This means
 you should include both pallets in your `construct_runtime` macro, but only include this
-pallet's [`SignedExtension`] ([`ChargeAssetTxPayment`]).
+pallet's [`TransactionExtension`] ([`ChargeAssetTxPayment`]).
 
 License: Apache-2.0
diff --git a/substrate/frame/transaction-payment/asset-tx-payment/src/benchmarking.rs b/substrate/frame/transaction-payment/asset-tx-payment/src/benchmarking.rs
new file mode 100644
index 00000000000..25902bf452b
--- /dev/null
+++ b/substrate/frame/transaction-payment/asset-tx-payment/src/benchmarking.rs
@@ -0,0 +1,131 @@
+// This file is part of Substrate.
+
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Benchmarks for Asset Tx Payment Pallet's transaction extension
+
+extern crate alloc;
+
+use super::*;
+use crate::Pallet;
+use frame_benchmarking::v2::*;
+use frame_support::{
+	dispatch::{DispatchInfo, PostDispatchInfo},
+	pallet_prelude::*,
+};
+use frame_system::RawOrigin;
+use sp_runtime::traits::{
+	AsSystemOriginSigner, AsTransactionAuthorizedOrigin, DispatchTransaction, Dispatchable,
+};
+
+#[benchmarks(where
+	T::RuntimeOrigin: AsTransactionAuthorizedOrigin,
+	T::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
+	AssetBalanceOf<T>: Send + Sync,
+	BalanceOf<T>: Send + Sync + From<u64> + IsType<ChargeAssetBalanceOf<T>>,
+	ChargeAssetIdOf<T>: Send + Sync,
+	<T::RuntimeCall as Dispatchable>::RuntimeOrigin: AsSystemOriginSigner<T::AccountId> + Clone,
+    Credit<T::AccountId, T::Fungibles>: IsType<ChargeAssetLiquidityOf<T>>,
+)]
+mod benchmarks {
+	use super::*;
+
+	#[benchmark]
+	fn charge_asset_tx_payment_zero() {
+		let caller: T::AccountId = account("caller", 0, 0);
+		let ext: ChargeAssetTxPayment<T> = ChargeAssetTxPayment::from(0u32.into(), None);
+		let inner = frame_system::Call::remark { remark: alloc::vec![] };
+		let call = T::RuntimeCall::from(inner);
+		let info = DispatchInfo {
+			call_weight: Weight::zero(),
+			extension_weight: Weight::zero(),
+			class: DispatchClass::Normal,
+			pays_fee: Pays::No,
+		};
+		let post_info = PostDispatchInfo { actual_weight: None, pays_fee: Pays::No };
+		#[block]
+		{
+			assert!(ext
+				.test_run(RawOrigin::Signed(caller).into(), &call, &info, 0, |_| Ok(post_info))
+				.unwrap()
+				.is_ok());
+		}
+	}
+
+	#[benchmark]
+	fn charge_asset_tx_payment_native() {
+		let caller: T::AccountId = account("caller", 0, 0);
+		let (fun_asset_id, _) = <T as Config>::BenchmarkHelper::create_asset_id_parameter(1);
+		<T as Config>::BenchmarkHelper::setup_balances_and_pool(fun_asset_id, caller.clone());
+		let ext: ChargeAssetTxPayment<T> = ChargeAssetTxPayment::from(10u32.into(), None);
+		let inner = frame_system::Call::remark { remark: alloc::vec![] };
+		let call = T::RuntimeCall::from(inner);
+		let info = DispatchInfo {
+			call_weight: Weight::from_parts(10, 0),
+			extension_weight: Weight::zero(),
+			class: DispatchClass::Operational,
+			pays_fee: Pays::Yes,
+		};
+		let post_info = PostDispatchInfo {
+			actual_weight: Some(Weight::from_parts(10, 0)),
+			pays_fee: Pays::Yes,
+		};
+
+		#[block]
+		{
+			assert!(ext
+				.test_run(RawOrigin::Signed(caller).into(), &call, &info, 0, |_| Ok(post_info))
+				.unwrap()
+				.is_ok());
+		}
+	}
+
+	#[benchmark]
+	fn charge_asset_tx_payment_asset() {
+		let caller: T::AccountId = account("caller", 0, 0);
+		let (fun_asset_id, asset_id) = <T as Config>::BenchmarkHelper::create_asset_id_parameter(1);
+		<T as Config>::BenchmarkHelper::setup_balances_and_pool(
+			fun_asset_id.clone(),
+			caller.clone(),
+		);
+		let tip = 10u32.into();
+		let ext: ChargeAssetTxPayment<T> = ChargeAssetTxPayment::from(tip, Some(asset_id));
+		let inner = frame_system::Call::remark { remark: alloc::vec![] };
+		let call = T::RuntimeCall::from(inner);
+		let info = DispatchInfo {
+			call_weight: Weight::from_parts(10, 0),
+			extension_weight: Weight::zero(),
+			class: DispatchClass::Operational,
+			pays_fee: Pays::Yes,
+		};
+		let post_info = PostDispatchInfo {
+			actual_weight: Some(Weight::from_parts(10, 0)),
+			pays_fee: Pays::Yes,
+		};
+
+		#[block]
+		{
+			assert!(ext
+				.test_run(RawOrigin::Signed(caller.clone()).into(), &call, &info, 0, |_| Ok(
+					post_info
+				))
+				.unwrap()
+				.is_ok());
+		}
+	}
+
+	impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Runtime);
+}
diff --git a/substrate/frame/transaction-payment/asset-tx-payment/src/lib.rs b/substrate/frame/transaction-payment/asset-tx-payment/src/lib.rs
index 97f1116993f..25aa272ba01 100644
--- a/substrate/frame/transaction-payment/asset-tx-payment/src/lib.rs
+++ b/substrate/frame/transaction-payment/asset-tx-payment/src/lib.rs
@@ -31,13 +31,14 @@
 
 //! This pallet wraps FRAME's transaction payment pallet and functions as a replacement. This means
 //! you should include both pallets in your `construct_runtime` macro, but only include this
-//! pallet's [`SignedExtension`] ([`ChargeAssetTxPayment`]).
+//! pallet's [`TransactionExtension`] ([`ChargeAssetTxPayment`]).
 
 #![cfg_attr(not(feature = "std"), no_std)]
 
 use codec::{Decode, Encode};
 use frame_support::{
 	dispatch::{DispatchInfo, DispatchResult, PostDispatchInfo},
+	pallet_prelude::Weight,
 	traits::{
 		tokens::{
 			fungibles::{Balanced, Credit, Inspect},
@@ -50,10 +51,11 @@ use frame_support::{
 use pallet_transaction_payment::OnChargeTransaction;
 use scale_info::TypeInfo;
 use sp_runtime::{
-	traits::{DispatchInfoOf, Dispatchable, PostDispatchInfoOf, SignedExtension, Zero},
-	transaction_validity::{
-		InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction,
+	traits::{
+		AsSystemOriginSigner, DispatchInfoOf, Dispatchable, PostDispatchInfoOf, RefundWeight,
+		TransactionExtension, Zero,
 	},
+	transaction_validity::{InvalidTransaction, TransactionValidityError, ValidTransaction},
 };
 
 #[cfg(test)]
@@ -61,8 +63,14 @@ mod mock;
 #[cfg(test)]
 mod tests;
 
+#[cfg(feature = "runtime-benchmarks")]
+mod benchmarking;
+
 mod payment;
+pub mod weights;
+
 pub use payment::*;
+pub use weights::WeightInfo;
 
 /// Type aliases used for interaction with `OnChargeTransaction`.
 pub(crate) type OnChargeTransactionOf<T> =
@@ -118,11 +126,30 @@ pub mod pallet {
 		type Fungibles: Balanced<Self::AccountId>;
 		/// The actual transaction charging logic that charges the fees.
 		type OnChargeAssetTransaction: OnChargeAssetTransaction<Self>;
+		/// The weight information of this pallet.
+		type WeightInfo: WeightInfo;
+		/// Benchmark helper
+		#[cfg(feature = "runtime-benchmarks")]
+		type BenchmarkHelper: BenchmarkHelperTrait<
+			Self::AccountId,
+			<<Self as Config>::Fungibles as Inspect<Self::AccountId>>::AssetId,
+			<<Self as Config>::OnChargeAssetTransaction as OnChargeAssetTransaction<Self>>::AssetId,
+		>;
 	}
 
 	#[pallet::pallet]
 	pub struct Pallet<T>(_);
 
+	#[cfg(feature = "runtime-benchmarks")]
+	/// Helper trait to benchmark the `ChargeAssetTxPayment` transaction extension.
+	pub trait BenchmarkHelperTrait<AccountId, FunAssetIdParameter, AssetIdParameter> {
+		/// Returns the `AssetId` to be used in the liquidity pool by the benchmarking code.
+		fn create_asset_id_parameter(id: u32) -> (FunAssetIdParameter, AssetIdParameter);
+		/// Create a liquidity pool for a given asset and sufficiently endow accounts to benchmark
+		/// the extension.
+		fn setup_balances_and_pool(asset_id: FunAssetIdParameter, account: AccountId);
+	}
+
 	#[pallet::event]
 	#[pallet::generate_deposit(pub(super) fn deposit_event)]
 	pub enum Event<T: Config> {
@@ -170,9 +197,8 @@ where
 		who: &T::AccountId,
 		call: &T::RuntimeCall,
 		info: &DispatchInfoOf<T::RuntimeCall>,
-		len: usize,
+		fee: BalanceOf<T>,
 	) -> Result<(BalanceOf<T>, InitialPayment<T>), TransactionValidityError> {
-		let fee = pallet_transaction_payment::Pallet::<T>::compute_fee(len as u32, info, self.tip);
 		debug_assert!(self.tip <= fee, "tip should be included in the computed fee");
 		if fee.is_zero() {
 			Ok((fee, InitialPayment::Nothing))
@@ -194,6 +220,35 @@ where
 			.map_err(|_| -> TransactionValidityError { InvalidTransaction::Payment.into() })
 		}
 	}
+
+	/// Fee withdrawal logic dry-run that dispatches to either `OnChargeAssetTransaction` or
+	/// `OnChargeTransaction`.
+	fn can_withdraw_fee(
+		&self,
+		who: &T::AccountId,
+		call: &T::RuntimeCall,
+		info: &DispatchInfoOf<T::RuntimeCall>,
+		fee: BalanceOf<T>,
+	) -> Result<(), TransactionValidityError> {
+		debug_assert!(self.tip <= fee, "tip should be included in the computed fee");
+		if fee.is_zero() {
+			Ok(())
+		} else if let Some(asset_id) = self.asset_id {
+			T::OnChargeAssetTransaction::can_withdraw_fee(
+				who,
+				call,
+				info,
+				asset_id,
+				fee.into(),
+				self.tip.into(),
+			)
+		} else {
+			<OnChargeTransactionOf<T> as OnChargeTransaction<T>>::can_withdraw_fee(
+				who, call, info, fee, self.tip,
+			)
+			.map_err(|_| -> TransactionValidityError { InvalidTransaction::Payment.into() })
+		}
+	}
 }
 
 impl<T: Config> core::fmt::Debug for ChargeAssetTxPayment<T> {
@@ -207,106 +262,184 @@ impl<T: Config> core::fmt::Debug for ChargeAssetTxPayment<T> {
 	}
 }
 
-impl<T: Config> SignedExtension for ChargeAssetTxPayment<T>
+/// The info passed between the validate and prepare steps for the `ChargeAssetTxPayment` extension.
+pub enum Val<T: Config> {
+	Charge {
+		tip: BalanceOf<T>,
+		// who paid the fee
+		who: T::AccountId,
+		// transaction fee
+		fee: BalanceOf<T>,
+	},
+	NoCharge,
+}
+
+/// The info passed between the prepare and post-dispatch steps for the `ChargeAssetTxPayment`
+/// extension.
+pub enum Pre<T: Config> {
+	Charge {
+		tip: BalanceOf<T>,
+		// who paid the fee
+		who: T::AccountId,
+		// imbalance resulting from withdrawing the fee
+		initial_payment: InitialPayment<T>,
+		// asset_id for the transaction payment
+		asset_id: Option<ChargeAssetIdOf<T>>,
+		// weight used by the extension
+		weight: Weight,
+	},
+	NoCharge {
+		// weight initially estimated by the extension, to be refunded
+		refund: Weight,
+	},
+}
+
+impl<T: Config> TransactionExtension<T::RuntimeCall> for ChargeAssetTxPayment<T>
 where
 	T::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
 	AssetBalanceOf<T>: Send + Sync,
 	BalanceOf<T>: Send + Sync + From<u64> + IsType<ChargeAssetBalanceOf<T>>,
 	ChargeAssetIdOf<T>: Send + Sync,
 	Credit<T::AccountId, T::Fungibles>: IsType<ChargeAssetLiquidityOf<T>>,
+	<T::RuntimeCall as Dispatchable>::RuntimeOrigin: AsSystemOriginSigner<T::AccountId> + Clone,
 {
 	const IDENTIFIER: &'static str = "ChargeAssetTxPayment";
-	type AccountId = T::AccountId;
-	type Call = T::RuntimeCall;
-	type AdditionalSigned = ();
-	type Pre = (
-		// tip
-		BalanceOf<T>,
-		// who paid the fee
-		Self::AccountId,
-		// imbalance resulting from withdrawing the fee
-		InitialPayment<T>,
-		// asset_id for the transaction payment
-		Option<ChargeAssetIdOf<T>>,
-	);
+	type Implicit = ();
+	type Val = Val<T>;
+	type Pre = Pre<T>;
 
-	fn additional_signed(&self) -> core::result::Result<(), TransactionValidityError> {
-		Ok(())
+	fn weight(&self, _: &T::RuntimeCall) -> Weight {
+		if self.asset_id.is_some() {
+			<T as Config>::WeightInfo::charge_asset_tx_payment_asset()
+		} else {
+			<T as Config>::WeightInfo::charge_asset_tx_payment_native()
+		}
 	}
 
 	fn validate(
 		&self,
-		who: &Self::AccountId,
-		call: &Self::Call,
-		info: &DispatchInfoOf<Self::Call>,
+		origin: <T::RuntimeCall as Dispatchable>::RuntimeOrigin,
+		call: &T::RuntimeCall,
+		info: &DispatchInfoOf<T::RuntimeCall>,
 		len: usize,
-	) -> TransactionValidity {
+		_self_implicit: Self::Implicit,
+		_inherited_implication: &impl Encode,
+	) -> Result<
+		(ValidTransaction, Self::Val, <T::RuntimeCall as Dispatchable>::RuntimeOrigin),
+		TransactionValidityError,
+	> {
 		use pallet_transaction_payment::ChargeTransactionPayment;
-		let (fee, _) = self.withdraw_fee(who, call, info, len)?;
+		let Some(who) = origin.as_system_origin_signer() else {
+			return Ok((ValidTransaction::default(), Val::NoCharge, origin))
+		};
+		// Non-mutating call of `compute_fee` to calculate the fee used in the transaction priority.
+		let fee = pallet_transaction_payment::Pallet::<T>::compute_fee(len as u32, info, self.tip);
+		self.can_withdraw_fee(&who, call, info, fee)?;
 		let priority = ChargeTransactionPayment::<T>::get_priority(info, len, self.tip, fee);
-		Ok(ValidTransaction { priority, ..Default::default() })
+		let val = Val::Charge { tip: self.tip, who: who.clone(), fee };
+		let validity = ValidTransaction { priority, ..Default::default() };
+		Ok((validity, val, origin))
 	}
 
-	fn pre_dispatch(
+	fn prepare(
 		self,
-		who: &Self::AccountId,
-		call: &Self::Call,
-		info: &DispatchInfoOf<Self::Call>,
-		len: usize,
+		val: Self::Val,
+		_origin: &<T::RuntimeCall as Dispatchable>::RuntimeOrigin,
+		call: &T::RuntimeCall,
+		info: &DispatchInfoOf<T::RuntimeCall>,
+		_len: usize,
 	) -> Result<Self::Pre, TransactionValidityError> {
-		let (_fee, initial_payment) = self.withdraw_fee(who, call, info, len)?;
-		Ok((self.tip, who.clone(), initial_payment, self.asset_id))
+		match val {
+			Val::Charge { tip, who, fee } => {
+				// Mutating call of `withdraw_fee` to actually charge for the transaction.
+				let (_fee, initial_payment) = self.withdraw_fee(&who, call, info, fee)?;
+				Ok(Pre::Charge {
+					tip,
+					who,
+					initial_payment,
+					asset_id: self.asset_id,
+					weight: self.weight(call),
+				})
+			},
+			Val::NoCharge => Ok(Pre::NoCharge { refund: self.weight(call) }),
+		}
 	}
 
-	fn post_dispatch(
-		pre: Option<Self::Pre>,
-		info: &DispatchInfoOf<Self::Call>,
-		post_info: &PostDispatchInfoOf<Self::Call>,
+	fn post_dispatch_details(
+		pre: Self::Pre,
+		info: &DispatchInfoOf<T::RuntimeCall>,
+		post_info: &PostDispatchInfoOf<T::RuntimeCall>,
 		len: usize,
 		result: &DispatchResult,
-	) -> Result<(), TransactionValidityError> {
-		if let Some((tip, who, initial_payment, asset_id)) = pre {
-			match initial_payment {
-				InitialPayment::Native(already_withdrawn) => {
-					pallet_transaction_payment::ChargeTransactionPayment::<T>::post_dispatch(
-						Some((tip, who, already_withdrawn)),
+	) -> Result<Weight, TransactionValidityError> {
+		let (tip, who, initial_payment, asset_id, extension_weight) = match pre {
+			Pre::Charge { tip, who, initial_payment, asset_id, weight } =>
+				(tip, who, initial_payment, asset_id, weight),
+			Pre::NoCharge { refund } => {
+				// No-op: Refund everything
+				return Ok(refund)
+			},
+		};
+
+		match initial_payment {
+			InitialPayment::Native(already_withdrawn) => {
+				// Take into account the weight used by this extension before calculating the
+				// refund.
+				let actual_ext_weight = <T as Config>::WeightInfo::charge_asset_tx_payment_native();
+				let unspent_weight = extension_weight.saturating_sub(actual_ext_weight);
+				let mut actual_post_info = *post_info;
+				actual_post_info.refund(unspent_weight);
+				pallet_transaction_payment::ChargeTransactionPayment::<T>::post_dispatch_details(
+					pallet_transaction_payment::Pre::Charge {
+						tip,
+						who,
+						imbalance: already_withdrawn,
+					},
+					info,
+					&actual_post_info,
+					len,
+					result,
+				)?;
+				Ok(unspent_weight)
+			},
+			InitialPayment::Asset(already_withdrawn) => {
+				let actual_ext_weight = <T as Config>::WeightInfo::charge_asset_tx_payment_asset();
+				let unspent_weight = extension_weight.saturating_sub(actual_ext_weight);
+				let mut actual_post_info = *post_info;
+				actual_post_info.refund(unspent_weight);
+				let actual_fee = pallet_transaction_payment::Pallet::<T>::compute_actual_fee(
+					len as u32,
+					info,
+					&actual_post_info,
+					tip,
+				);
+
+				let (converted_fee, converted_tip) =
+					T::OnChargeAssetTransaction::correct_and_deposit_fee(
+						&who,
 						info,
-						post_info,
-						len,
-						result,
+						&actual_post_info,
+						actual_fee.into(),
+						tip.into(),
+						already_withdrawn.into(),
 					)?;
-				},
-				InitialPayment::Asset(already_withdrawn) => {
-					let actual_fee = pallet_transaction_payment::Pallet::<T>::compute_actual_fee(
-						len as u32, info, post_info, tip,
-					);
-
-					let (converted_fee, converted_tip) =
-						T::OnChargeAssetTransaction::correct_and_deposit_fee(
-							&who,
-							info,
-							post_info,
-							actual_fee.into(),
-							tip.into(),
-							already_withdrawn.into(),
-						)?;
-					Pallet::<T>::deposit_event(Event::<T>::AssetTxFeePaid {
-						who,
-						actual_fee: converted_fee,
-						tip: converted_tip,
-						asset_id,
-					});
-				},
-				InitialPayment::Nothing => {
-					// `actual_fee` should be zero here for any signed extrinsic. It would be
-					// non-zero here in case of unsigned extrinsics as they don't pay fees but
-					// `compute_actual_fee` is not aware of them. In both cases it's fine to just
-					// move ahead without adjusting the fee, though, so we do nothing.
-					debug_assert!(tip.is_zero(), "tip should be zero if initial fee was zero.");
-				},
-			}
+				Pallet::<T>::deposit_event(Event::<T>::AssetTxFeePaid {
+					who,
+					actual_fee: converted_fee,
+					tip: converted_tip,
+					asset_id,
+				});
+				Ok(unspent_weight)
+			},
+			InitialPayment::Nothing => {
+				// `actual_fee` should be zero here for any signed extrinsic. It would be
+				// non-zero here in case of unsigned extrinsics as they don't pay fees but
+				// `compute_actual_fee` is not aware of them. In both cases it's fine to just
+				// move ahead without adjusting the fee, though, so we do nothing.
+				debug_assert!(tip.is_zero(), "tip should be zero if initial fee was zero.");
+				Ok(extension_weight
+					.saturating_sub(<T as Config>::WeightInfo::charge_asset_tx_payment_zero()))
+			},
 		}
-
-		Ok(())
 	}
 }
diff --git a/substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs b/substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs
index e84df1e4eb9..fce029bb4bf 100644
--- a/substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs
+++ b/substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs
@@ -105,14 +105,22 @@ impl WeightToFeeT for TransactionByteFee {
 	}
 }
 
+pub struct MockTxPaymentWeights;
+
+impl pallet_transaction_payment::WeightInfo for MockTxPaymentWeights {
+	fn charge_transaction_payment() -> Weight {
+		Weight::from_parts(10, 0)
+	}
+}
+
 #[derive_impl(pallet_transaction_payment::config_preludes::TestDefaultConfig)]
 impl pallet_transaction_payment::Config for Runtime {
 	type RuntimeEvent = RuntimeEvent;
 	type OnChargeTransaction = FungibleAdapter<Balances, ()>;
 	type WeightToFee = WeightToFee;
 	type LengthToFee = TransactionByteFee;
-	type FeeMultiplierUpdate = ();
 	type OperationalFeeMultiplier = ConstU8<5>;
+	type WeightInfo = MockTxPaymentWeights;
 }
 
 type AssetId = u32;
@@ -168,6 +176,23 @@ impl HandleCredit<AccountId, Assets> for CreditToBlockAuthor {
 	}
 }
 
+/// Weights used in testing.
+pub struct MockWeights;
+
+impl WeightInfo for MockWeights {
+	fn charge_asset_tx_payment_zero() -> Weight {
+		Weight::from_parts(0, 0)
+	}
+
+	fn charge_asset_tx_payment_native() -> Weight {
+		Weight::from_parts(15, 0)
+	}
+
+	fn charge_asset_tx_payment_asset() -> Weight {
+		Weight::from_parts(20, 0)
+	}
+}
+
 impl Config for Runtime {
 	type RuntimeEvent = RuntimeEvent;
 	type Fungibles = Assets;
@@ -175,4 +200,56 @@ impl Config for Runtime {
 		pallet_assets::BalanceToAssetBalance<Balances, Runtime, ConvertInto>,
 		CreditToBlockAuthor,
 	>;
+	type WeightInfo = MockWeights;
+	#[cfg(feature = "runtime-benchmarks")]
+	type BenchmarkHelper = Helper;
+}
+
+#[cfg(feature = "runtime-benchmarks")]
+pub fn new_test_ext() -> sp_io::TestExternalities {
+	let base_weight = 5;
+	let balance_factor = 100;
+	crate::tests::ExtBuilder::default()
+		.balance_factor(balance_factor)
+		.base_weight(Weight::from_parts(base_weight, 0))
+		.build()
+}
+
+#[cfg(feature = "runtime-benchmarks")]
+pub struct Helper;
+
+#[cfg(feature = "runtime-benchmarks")]
+impl BenchmarkHelperTrait<u64, u32, u32> for Helper {
+	fn create_asset_id_parameter(id: u32) -> (u32, u32) {
+		(id.into(), id.into())
+	}
+
+	fn setup_balances_and_pool(asset_id: u32, account: u64) {
+		use frame_support::{assert_ok, traits::fungibles::Mutate};
+		use sp_runtime::traits::StaticLookup;
+		let min_balance = 1;
+		assert_ok!(Assets::force_create(
+			RuntimeOrigin::root(),
+			asset_id.into(),
+			42,   /* owner */
+			true, /* is_sufficient */
+			min_balance
+		));
+
+		// mint into the caller account
+		let caller = 2;
+		let beneficiary = <Runtime as system::Config>::Lookup::unlookup(caller);
+		let balance = 1000;
+		assert_ok!(Assets::mint_into(asset_id.into(), &beneficiary, balance));
+		assert_eq!(Assets::balance(asset_id, caller), balance);
+
+		use frame_support::traits::Currency;
+		let _ = Balances::deposit_creating(&account, u32::MAX.into());
+
+		let beneficiary = <Runtime as system::Config>::Lookup::unlookup(account);
+		let balance = 1000;
+
+		assert_ok!(Assets::mint_into(asset_id.into(), &beneficiary, balance));
+		assert_eq!(Assets::balance(asset_id, account), balance);
+	}
 }
diff --git a/substrate/frame/transaction-payment/asset-tx-payment/src/payment.rs b/substrate/frame/transaction-payment/asset-tx-payment/src/payment.rs
index 2486474bad4..2074b1476f4 100644
--- a/substrate/frame/transaction-payment/asset-tx-payment/src/payment.rs
+++ b/substrate/frame/transaction-payment/asset-tx-payment/src/payment.rs
@@ -56,6 +56,18 @@ pub trait OnChargeAssetTransaction<T: Config> {
 		tip: Self::Balance,
 	) -> Result<Self::LiquidityInfo, TransactionValidityError>;
 
+	/// Ensure payment of the transaction fees can be withdrawn.
+	///
+	/// Note: The `fee` already includes the `tip`.
+	fn can_withdraw_fee(
+		who: &T::AccountId,
+		call: &T::RuntimeCall,
+		dispatch_info: &DispatchInfoOf<T::RuntimeCall>,
+		asset_id: Self::AssetId,
+		fee: Self::Balance,
+		tip: Self::Balance,
+	) -> Result<(), TransactionValidityError>;
+
 	/// After the transaction was executed the actual fee can be calculated.
 	/// This function should refund any overpaid fees and optionally deposit
 	/// the corrected amount.
@@ -140,6 +152,32 @@ where
 		.map_err(|_| TransactionValidityError::from(InvalidTransaction::Payment))
 	}
 
+	/// Ensure payment of the transaction fees can be withdrawn.
+	///
+	/// Note: The `fee` already includes the `tip`.
+	fn can_withdraw_fee(
+		who: &T::AccountId,
+		_call: &T::RuntimeCall,
+		_info: &DispatchInfoOf<T::RuntimeCall>,
+		asset_id: Self::AssetId,
+		fee: Self::Balance,
+		_tip: Self::Balance,
+	) -> Result<(), TransactionValidityError> {
+		// We don't know the precision of the underlying asset. Because the converted fee could be
+		// less than one (e.g. 0.5) but gets rounded down by integer division we introduce a minimum
+		// fee.
+		let min_converted_fee = if fee.is_zero() { Zero::zero() } else { One::one() };
+		let converted_fee = CON::to_asset_balance(fee, asset_id)
+			.map_err(|_| TransactionValidityError::from(InvalidTransaction::Payment))?
+			.max(min_converted_fee);
+		let can_withdraw =
+			<T::Fungibles as Inspect<T::AccountId>>::can_withdraw(asset_id, who, converted_fee);
+		if can_withdraw != WithdrawConsequence::Success {
+			return Err(InvalidTransaction::Payment.into())
+		}
+		Ok(())
+	}
+
 	/// Hand the fee and the tip over to the `[HandleCredit]` implementation.
 	/// Since the predicted fee might have been too high, parts of the fee may be refunded.
 	///
diff --git a/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs b/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs
index 098ecf11dd9..cd694c3e81a 100644
--- a/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs
+++ b/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs
@@ -17,15 +17,18 @@ use super::*;
 
 use frame_support::{
 	assert_ok,
-	dispatch::{DispatchInfo, PostDispatchInfo},
+	dispatch::{DispatchInfo, GetDispatchInfo, PostDispatchInfo},
 	pallet_prelude::*,
-	traits::fungibles::Mutate,
+	traits::{fungibles::Mutate, OriginTrait},
 	weights::Weight,
 };
 use frame_system as system;
 use mock::{ExtrinsicBaseWeight, *};
 use pallet_balances::Call as BalancesCall;
-use sp_runtime::{traits::StaticLookup, BuildStorage};
+use sp_runtime::{
+	traits::{DispatchTransaction, StaticLookup},
+	BuildStorage,
+};
 
 const CALL: &<Runtime as frame_system::Config>::RuntimeCall =
 	&RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 2, value: 69 });
@@ -88,7 +91,7 @@ impl ExtBuilder {
 /// create a transaction info struct from weight. Handy to avoid building the whole struct.
 pub fn info_from_weight(w: Weight) -> DispatchInfo {
 	// pays_fee: Pays::Yes -- class: DispatchClass::Normal
-	DispatchInfo { weight: w, ..Default::default() }
+	DispatchInfo { call_weight: w, ..Default::default() }
 }
 
 fn post_info_from_weight(w: Weight) -> PostDispatchInfo {
@@ -116,35 +119,49 @@ fn transaction_payment_in_native_possible() {
 		.build()
 		.execute_with(|| {
 			let len = 10;
-			let pre = ChargeAssetTxPayment::<Runtime>::from(0, None)
-				.pre_dispatch(&1, CALL, &info_from_weight(Weight::from_parts(5, 0)), len)
-				.unwrap();
+			let mut info = info_from_weight(Weight::from_parts(5, 0));
+			let ext = ChargeAssetTxPayment::<Runtime>::from(0, None);
+			info.extension_weight = ext.weight(CALL);
+			let (pre, _) = ext.validate_and_prepare(Some(1).into(), CALL, &info, len).unwrap();
 			let initial_balance = 10 * balance_factor;
-			assert_eq!(Balances::free_balance(1), initial_balance - 5 - 5 - 10);
+			assert_eq!(Balances::free_balance(1), initial_balance - 5 - 5 - 15 - 10);
 
-			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch(
-				Some(pre),
-				&info_from_weight(Weight::from_parts(5, 0)),
+			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch_details(
+				pre,
+				&info,
 				&default_post_info(),
 				len,
-				&Ok(())
+				&Ok(()),
 			));
-			assert_eq!(Balances::free_balance(1), initial_balance - 5 - 5 - 10);
+			assert_eq!(Balances::free_balance(1), initial_balance - 5 - 5 - 15 - 10);
 
-			let pre = ChargeAssetTxPayment::<Runtime>::from(5 /* tipped */, None)
-				.pre_dispatch(&2, CALL, &info_from_weight(Weight::from_parts(100, 0)), len)
-				.unwrap();
+			let mut info = info_from_weight(Weight::from_parts(100, 0));
+			let ext = ChargeAssetTxPayment::<Runtime>::from(5 /* tipped */, None);
+			info.extension_weight = ext.weight(CALL);
+			let (pre, _) = ext.validate_and_prepare(Some(2).into(), CALL, &info, len).unwrap();
 			let initial_balance_for_2 = 20 * balance_factor;
-			assert_eq!(Balances::free_balance(2), initial_balance_for_2 - 5 - 10 - 100 - 5);
+			assert_eq!(Balances::free_balance(2), initial_balance_for_2 - 5 - 10 - 100 - 15 - 5);
 
-			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch(
-				Some(pre),
-				&info_from_weight(Weight::from_parts(100, 0)),
-				&post_info_from_weight(Weight::from_parts(50, 0)),
+			let call_actual_weight = Weight::from_parts(50, 0);
+			// The extension weight refund should be taken into account in `post_dispatch`.
+			let post_info = post_info_from_weight(call_actual_weight.saturating_add(
+				ChargeAssetTxPayment::<Runtime>::from(5 /* tipped */, None).weight(CALL),
+			));
+			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch_details(
+				pre,
+				&info,
+				&post_info,
 				len,
-				&Ok(())
+				&Ok(()),
 			));
-			assert_eq!(Balances::free_balance(2), initial_balance_for_2 - 5 - 10 - 50 - 5);
+			assert_eq!(
+				post_info.actual_weight,
+				Some(
+					call_actual_weight
+						.saturating_add(MockWeights::charge_asset_tx_payment_native())
+				)
+			);
+			assert_eq!(Balances::free_balance(2), initial_balance_for_2 - 5 - 10 - 50 - 15 - 5);
 		});
 }
 
@@ -181,8 +198,13 @@ fn transaction_payment_in_asset_possible() {
 			// we convert the from weight to fee based on the ratio between asset min balance and
 			// existential deposit
 			let fee = (base_weight + weight + len as u64) * min_balance / ExistentialDeposit::get();
-			let pre = ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id))
-				.pre_dispatch(&caller, CALL, &info_from_weight(Weight::from_parts(weight, 0)), len)
+			let (pre, _) = ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id))
+				.validate_and_prepare(
+					Some(caller).into(),
+					CALL,
+					&info_from_weight(Weight::from_parts(weight, 0)),
+					len,
+				)
 				.unwrap();
 			// assert that native balance is not used
 			assert_eq!(Balances::free_balance(caller), 10 * balance_factor);
@@ -196,12 +218,12 @@ fn transaction_payment_in_asset_possible() {
 				amount: fee,
 			}));
 
-			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch(
-				Some(pre),
+			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch_details(
+				pre,
 				&info_from_weight(Weight::from_parts(weight, 0)),
 				&default_post_info(),
 				len,
-				&Ok(())
+				&Ok(()),
 			));
 			assert_eq!(Assets::balance(asset_id, caller), balance - fee);
 			// check that the block author gets rewarded
@@ -246,8 +268,13 @@ fn transaction_payment_without_fee() {
 			// we convert the from weight to fee based on the ratio between asset min balance and
 			// existential deposit
 			let fee = (base_weight + weight + len as u64) * min_balance / ExistentialDeposit::get();
-			let pre = ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id))
-				.pre_dispatch(&caller, CALL, &info_from_weight(Weight::from_parts(weight, 0)), len)
+			let (pre, _) = ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id))
+				.validate_and_prepare(
+					Some(caller).into(),
+					CALL,
+					&info_from_weight(Weight::from_parts(weight, 0)),
+					len,
+				)
 				.unwrap();
 			// assert that native balance is not used
 			assert_eq!(Balances::free_balance(caller), 10 * balance_factor);
@@ -255,12 +282,12 @@ fn transaction_payment_without_fee() {
 			assert_eq!(Assets::balance(asset_id, caller), balance - fee);
 			assert_eq!(Assets::balance(asset_id, BLOCK_AUTHOR), 0);
 
-			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch(
-				Some(pre),
+			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch_details(
+				pre,
 				&info_from_weight(Weight::from_parts(weight, 0)),
 				&post_info_from_pays(Pays::No),
 				len,
-				&Ok(())
+				&Ok(()),
 			));
 			// caller should be refunded
 			assert_eq!(Assets::balance(asset_id, caller), balance);
@@ -298,14 +325,16 @@ fn asset_transaction_payment_with_tip_and_refund() {
 			assert_eq!(Assets::balance(asset_id, caller), balance);
 			let weight = 100;
 			let tip = 5;
+			let ext = ChargeAssetTxPayment::<Runtime>::from(tip, Some(asset_id));
+			let ext_weight = ext.weight(CALL);
 			let len = 10;
 			// we convert the from weight to fee based on the ratio between asset min balance and
 			// existential deposit
-			let fee_with_tip =
-				(base_weight + weight + len as u64 + tip) * min_balance / ExistentialDeposit::get();
-			let pre = ChargeAssetTxPayment::<Runtime>::from(tip, Some(asset_id))
-				.pre_dispatch(&caller, CALL, &info_from_weight(Weight::from_parts(weight, 0)), len)
-				.unwrap();
+			let fee_with_tip = (base_weight + weight + ext_weight.ref_time() + len as u64 + tip) *
+				min_balance / ExistentialDeposit::get();
+			let mut info = info_from_weight(Weight::from_parts(weight, 0));
+			info.extension_weight = ext_weight;
+			let (pre, _) = ext.validate_and_prepare(Some(caller).into(), CALL, &info, len).unwrap();
 			assert_eq!(Assets::balance(asset_id, caller), balance - fee_with_tip);
 
 			System::assert_has_event(RuntimeEvent::Assets(pallet_assets::Event::Withdrawn {
@@ -315,15 +344,22 @@ fn asset_transaction_payment_with_tip_and_refund() {
 			}));
 
 			let final_weight = 50;
-			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch(
-				Some(pre),
-				&info_from_weight(Weight::from_parts(weight, 0)),
-				&post_info_from_weight(Weight::from_parts(final_weight, 0)),
+			let mut post_info = post_info_from_weight(Weight::from_parts(final_weight, 0));
+			post_info
+				.actual_weight
+				.as_mut()
+				.map(|w| w.saturating_accrue(MockWeights::charge_asset_tx_payment_asset()));
+			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch_details(
+				pre,
+				&info,
+				&post_info,
 				len,
-				&Ok(())
+				&Ok(()),
 			));
-			let final_fee =
-				fee_with_tip - (weight - final_weight) * min_balance / ExistentialDeposit::get();
+			let final_fee = fee_with_tip -
+				(weight - final_weight + ext_weight.ref_time() -
+					MockWeights::charge_asset_tx_payment_asset().ref_time()) *
+					min_balance / ExistentialDeposit::get();
 			assert_eq!(Assets::balance(asset_id, caller), balance - (final_fee));
 			assert_eq!(Assets::balance(asset_id, BLOCK_AUTHOR), final_fee);
 
@@ -367,19 +403,24 @@ fn payment_from_account_with_only_assets() {
 			// we convert the from weight to fee based on the ratio between asset min balance and
 			// existential deposit
 			let fee = (base_weight + weight + len as u64) * min_balance / ExistentialDeposit::get();
-			let pre = ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id))
-				.pre_dispatch(&caller, CALL, &info_from_weight(Weight::from_parts(weight, 0)), len)
+			let (pre, _) = ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id))
+				.validate_and_prepare(
+					Some(caller).into(),
+					CALL,
+					&info_from_weight(Weight::from_parts(weight, 0)),
+					len,
+				)
 				.unwrap();
 			assert_eq!(Balances::free_balance(caller), 0);
 			// check that fee was charged in the given asset
 			assert_eq!(Assets::balance(asset_id, caller), balance - fee);
 
-			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch(
-				Some(pre),
+			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch_details(
+				pre,
 				&info_from_weight(Weight::from_parts(weight, 0)),
 				&default_post_info(),
 				len,
-				&Ok(())
+				&Ok(()),
 			));
 			assert_eq!(Assets::balance(asset_id, caller), balance - fee);
 			assert_eq!(Balances::free_balance(caller), 0);
@@ -400,7 +441,12 @@ fn payment_only_with_existing_sufficient_asset() {
 			let len = 10;
 			// pre_dispatch fails for non-existent asset
 			assert!(ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id))
-				.pre_dispatch(&caller, CALL, &info_from_weight(Weight::from_parts(weight, 0)), len)
+				.validate_and_prepare(
+					Some(caller).into(),
+					CALL,
+					&info_from_weight(Weight::from_parts(weight, 0)),
+					len
+				)
 				.is_err());
 
 			// create the non-sufficient asset
@@ -414,7 +460,12 @@ fn payment_only_with_existing_sufficient_asset() {
 			));
 			// pre_dispatch fails for non-sufficient asset
 			assert!(ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id))
-				.pre_dispatch(&caller, CALL, &info_from_weight(Weight::from_parts(weight, 0)), len)
+				.validate_and_prepare(
+					Some(caller).into(),
+					CALL,
+					&info_from_weight(Weight::from_parts(weight, 0)),
+					len
+				)
 				.is_err());
 		});
 }
@@ -452,33 +503,38 @@ fn converted_fee_is_never_zero_if_input_fee_is_not() {
 			// naive fee calculation would round down to zero
 			assert_eq!(fee, 0);
 			{
-				let pre = ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id))
-					.pre_dispatch(&caller, CALL, &info_from_pays(Pays::No), len)
+				let (pre, _) = ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id))
+					.validate_and_prepare(Some(caller).into(), CALL, &info_from_pays(Pays::No), len)
 					.unwrap();
 				// `Pays::No` still implies no fees
 				assert_eq!(Assets::balance(asset_id, caller), balance);
 
-				assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch(
-					Some(pre),
+				assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch_details(
+					pre,
 					&info_from_pays(Pays::No),
 					&post_info_from_pays(Pays::No),
 					len,
-					&Ok(())
+					&Ok(()),
 				));
 				assert_eq!(Assets::balance(asset_id, caller), balance);
 			}
-			let pre = ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id))
-				.pre_dispatch(&caller, CALL, &info_from_weight(Weight::from_parts(weight, 0)), len)
+			let (pre, _) = ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id))
+				.validate_and_prepare(
+					Some(caller).into(),
+					CALL,
+					&info_from_weight(Weight::from_parts(weight, 0)),
+					len,
+				)
 				.unwrap();
 			// check that at least one coin was charged in the given asset
 			assert_eq!(Assets::balance(asset_id, caller), balance - 1);
 
-			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch(
-				Some(pre),
+			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch_details(
+				pre,
 				&info_from_weight(Weight::from_parts(weight, 0)),
 				&default_post_info(),
 				len,
-				&Ok(())
+				&Ok(()),
 			));
 			assert_eq!(Assets::balance(asset_id, caller), balance - 1);
 		});
@@ -516,12 +572,14 @@ fn post_dispatch_fee_is_zero_if_pre_dispatch_fee_is_zero() {
 			let fee = (base_weight + weight + len as u64) * min_balance / ExistentialDeposit::get();
 			// calculated fee is greater than 0
 			assert!(fee > 0);
-			let pre = ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id))
-				.pre_dispatch(&caller, CALL, &info_from_pays(Pays::No), len)
+			let (pre, _) = ChargeAssetTxPayment::<Runtime>::from(0, Some(asset_id))
+				.validate_and_prepare(Some(caller).into(), CALL, &info_from_pays(Pays::No), len)
 				.unwrap();
 			// `Pays::No` implies no pre-dispatch fees
 			assert_eq!(Assets::balance(asset_id, caller), balance);
-			let (_tip, _who, initial_payment, _asset_id) = &pre;
+			let Pre::Charge { initial_payment, .. } = &pre else {
+				panic!("Expected Charge");
+			};
 			let not_paying = match initial_payment {
 				&InitialPayment::Nothing => true,
 				_ => false,
@@ -530,62 +588,50 @@ fn post_dispatch_fee_is_zero_if_pre_dispatch_fee_is_zero() {
 
 			// `Pays::Yes` on post-dispatch does not mean we pay (we never charge more than the
 			// initial fee)
-			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch(
-				Some(pre),
+			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch_details(
+				pre,
 				&info_from_pays(Pays::No),
 				&post_info_from_pays(Pays::Yes),
 				len,
-				&Ok(())
+				&Ok(()),
 			));
 			assert_eq!(Assets::balance(asset_id, caller), balance);
 		});
 }
 
 #[test]
-fn post_dispatch_fee_is_zero_if_unsigned_pre_dispatch_fee_is_zero() {
-	let base_weight = 1;
-	ExtBuilder::default()
-		.balance_factor(100)
-		.base_weight(Weight::from_parts(base_weight, 0))
-		.build()
-		.execute_with(|| {
-			// create the asset
-			let asset_id = 1;
-			let min_balance = 100;
-			assert_ok!(Assets::force_create(
-				RuntimeOrigin::root(),
-				asset_id.into(),
-				42,   /* owner */
-				true, /* is_sufficient */
-				min_balance
-			));
+fn no_fee_and_no_weight_for_other_origins() {
+	ExtBuilder::default().build().execute_with(|| {
+		let ext = ChargeAssetTxPayment::<Runtime>::from(0, None);
 
-			// mint into the caller account
-			let caller = 333;
-			let beneficiary = <Runtime as system::Config>::Lookup::unlookup(caller);
-			let balance = 100;
-			assert_ok!(Assets::mint_into(asset_id.into(), &beneficiary, balance));
-			assert_eq!(Assets::balance(asset_id, caller), balance);
-			let weight = 1;
-			let len = 1;
-			ChargeAssetTxPayment::<Runtime>::pre_dispatch_unsigned(
-				CALL,
-				&info_from_weight(Weight::from_parts(weight, 0)),
-				len,
-			)
-			.unwrap();
+		let mut info = CALL.get_dispatch_info();
+		info.extension_weight = ext.weight(CALL);
 
-			assert_eq!(Assets::balance(asset_id, caller), balance);
+		// Ensure we test the refund.
+		assert!(info.extension_weight != Weight::zero());
 
-			// `Pays::Yes` on post-dispatch does not mean we pay (we never charge more than the
-			// initial fee)
-			assert_ok!(ChargeAssetTxPayment::<Runtime>::post_dispatch(
-				None,
-				&info_from_weight(Weight::from_parts(weight, 0)),
-				&post_info_from_pays(Pays::Yes),
-				len,
-				&Ok(())
-			));
-			assert_eq!(Assets::balance(asset_id, caller), balance);
-		});
+		let len = CALL.encoded_size();
+
+		let origin = frame_system::RawOrigin::Root.into();
+		let (pre, origin) = ext.validate_and_prepare(origin, CALL, &info, len).unwrap();
+
+		assert!(origin.as_system_ref().unwrap().is_root());
+
+		let pd_res = Ok(());
+		let mut post_info = frame_support::dispatch::PostDispatchInfo {
+			actual_weight: Some(info.total_weight()),
+			pays_fee: Default::default(),
+		};
+
+		<ChargeAssetTxPayment<Runtime> as TransactionExtension<RuntimeCall>>::post_dispatch(
+			pre,
+			&info,
+			&mut post_info,
+			len,
+			&pd_res,
+		)
+		.unwrap();
+
+		assert_eq!(post_info.actual_weight, Some(info.call_weight));
+	})
 }
diff --git a/substrate/frame/transaction-payment/asset-tx-payment/src/weights.rs b/substrate/frame/transaction-payment/asset-tx-payment/src/weights.rs
new file mode 100644
index 00000000000..1af1c94177d
--- /dev/null
+++ b/substrate/frame/transaction-payment/asset-tx-payment/src/weights.rs
@@ -0,0 +1,146 @@
+// This file is part of Substrate.
+
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Autogenerated weights for `pallet_asset_tx_payment`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024`
+
+// Executed Command:
+// ./target/production/substrate-node
+// benchmark
+// pallet
+// --chain=dev
+// --steps=50
+// --repeat=20
+// --pallet=pallet_asset_tx_payment
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --extrinsic=*
+// --wasm-execution=compiled
+// --heap-pages=4096
+// --output=./substrate/frame/transaction-payment/asset-tx-payment/src/weights.rs
+// --header=./substrate/HEADER-APACHE2
+// --template=./substrate/.maintain/frame-weight-template.hbs
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
+use core::marker::PhantomData;
+
+/// Weight functions needed for `pallet_asset_tx_payment`.
+pub trait WeightInfo {
+	fn charge_asset_tx_payment_zero() -> Weight;
+	fn charge_asset_tx_payment_native() -> Weight;
+	fn charge_asset_tx_payment_asset() -> Weight;
+}
+
+/// Weights for `pallet_asset_tx_payment` using the Substrate node and recommended hardware.
+pub struct SubstrateWeight<T>(PhantomData<T>);
+impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
+	fn charge_asset_tx_payment_zero() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 542_000 picoseconds.
+		Weight::from_parts(597_000, 0)
+	}
+	/// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0)
+	/// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
+	/// Storage: `Authorship::Author` (r:1 w:0)
+	/// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
+	/// Storage: `System::Digest` (r:1 w:0)
+	/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	fn charge_asset_tx_payment_native() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `248`
+		//  Estimated: `1733`
+		// Minimum execution time: 33_162_000 picoseconds.
+		Weight::from_parts(34_716_000, 1733)
+			.saturating_add(T::DbWeight::get().reads(3_u64))
+	}
+	/// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0)
+	/// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
+	/// Storage: `Assets::Asset` (r:1 w:1)
+	/// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
+	/// Storage: `Assets::Account` (r:1 w:1)
+	/// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
+	/// Storage: `Authorship::Author` (r:1 w:0)
+	/// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
+	/// Storage: `System::Digest` (r:1 w:0)
+	/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	fn charge_asset_tx_payment_asset() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `747`
+		//  Estimated: `3675`
+		// Minimum execution time: 44_230_000 picoseconds.
+		Weight::from_parts(45_297_000, 3675)
+			.saturating_add(T::DbWeight::get().reads(5_u64))
+			.saturating_add(T::DbWeight::get().writes(2_u64))
+	}
+}
+
+// For backwards compatibility and tests.
+impl WeightInfo for () {
+	fn charge_asset_tx_payment_zero() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 542_000 picoseconds.
+		Weight::from_parts(597_000, 0)
+	}
+	/// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0)
+	/// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
+	/// Storage: `Authorship::Author` (r:1 w:0)
+	/// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
+	/// Storage: `System::Digest` (r:1 w:0)
+	/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	fn charge_asset_tx_payment_native() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `248`
+		//  Estimated: `1733`
+		// Minimum execution time: 33_162_000 picoseconds.
+		Weight::from_parts(34_716_000, 1733)
+			.saturating_add(RocksDbWeight::get().reads(3_u64))
+	}
+	/// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0)
+	/// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
+	/// Storage: `Assets::Asset` (r:1 w:1)
+	/// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
+	/// Storage: `Assets::Account` (r:1 w:1)
+	/// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
+	/// Storage: `Authorship::Author` (r:1 w:0)
+	/// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
+	/// Storage: `System::Digest` (r:1 w:0)
+	/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	fn charge_asset_tx_payment_asset() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `747`
+		//  Estimated: `3675`
+		// Minimum execution time: 44_230_000 picoseconds.
+		Weight::from_parts(45_297_000, 3675)
+			.saturating_add(RocksDbWeight::get().reads(5_u64))
+			.saturating_add(RocksDbWeight::get().writes(2_u64))
+	}
+}
diff --git a/substrate/frame/transaction-payment/skip-feeless-payment/src/lib.rs b/substrate/frame/transaction-payment/skip-feeless-payment/src/lib.rs
index 3ab38743baf..d6ac648cefd 100644
--- a/substrate/frame/transaction-payment/skip-feeless-payment/src/lib.rs
+++ b/substrate/frame/transaction-payment/skip-feeless-payment/src/lib.rs
@@ -21,7 +21,7 @@
 //!
 //! ## Overview
 //!
-//! It does this by wrapping an existing [`SignedExtension`] implementation (e.g.
+//! It does this by wrapping an existing [`TransactionExtension`] implementation (e.g.
 //! [`pallet-transaction-payment`]) and checking if the dispatchable is feeless before applying the
 //! wrapped extension. If the dispatchable is indeed feeless, the extension is skipped and a custom
 //! event is emitted instead. Otherwise, the extension is applied as usual.
@@ -31,7 +31,7 @@
 //!
 //! This pallet wraps an existing transaction payment pallet. This means you should both pallets
 //! in your [`construct_runtime`](frame_support::construct_runtime) macro and
-//! include this pallet's [`SignedExtension`] ([`SkipCheckIfFeeless`]) that would accept the
+//! include this pallet's [`TransactionExtension`] ([`SkipCheckIfFeeless`]) that would accept the
 //! existing one as an argument.
 
 #![cfg_attr(not(feature = "std"), no_std)]
@@ -40,11 +40,14 @@ use codec::{Decode, Encode};
 use frame_support::{
 	dispatch::{CheckIfFeeless, DispatchResult},
 	traits::{IsType, OriginTrait},
+	weights::Weight,
 };
 use scale_info::{StaticTypeInfo, TypeInfo};
 use sp_runtime::{
-	traits::{DispatchInfoOf, PostDispatchInfoOf, SignedExtension},
-	transaction_validity::{TransactionValidity, TransactionValidityError, ValidTransaction},
+	traits::{
+		DispatchInfoOf, DispatchOriginOf, PostDispatchInfoOf, TransactionExtension, ValidateResult,
+	},
+	transaction_validity::TransactionValidityError,
 };
 
 #[cfg(test)]
@@ -71,11 +74,11 @@ pub mod pallet {
 	#[pallet::generate_deposit(pub(super) fn deposit_event)]
 	pub enum Event<T: Config> {
 		/// A transaction fee was skipped.
-		FeeSkipped { who: T::AccountId },
+		FeeSkipped { origin: <T::RuntimeOrigin as OriginTrait>::PalletsOrigin },
 	}
 }
 
-/// A [`SignedExtension`] that skips the wrapped extension if the dispatchable is feeless.
+/// A [`TransactionExtension`] that skips the wrapped extension if the dispatchable is feeless.
 #[derive(Encode, Decode, Clone, Eq, PartialEq)]
 pub struct SkipCheckIfFeeless<T, S>(pub S, core::marker::PhantomData<T>);
 
@@ -104,67 +107,83 @@ impl<T, S> From<S> for SkipCheckIfFeeless<T, S> {
 	}
 }
 
-impl<T: Config + Send + Sync, S: SignedExtension<AccountId = T::AccountId>> SignedExtension
-	for SkipCheckIfFeeless<T, S>
+pub enum Intermediate<T, O> {
+	/// The wrapped extension should be applied.
+	Apply(T),
+	/// The wrapped extension should be skipped.
+	Skip(O),
+}
+use Intermediate::*;
+
+impl<T: Config + Send + Sync, S: TransactionExtension<T::RuntimeCall>>
+	TransactionExtension<T::RuntimeCall> for SkipCheckIfFeeless<T, S>
 where
-	S::Call: CheckIfFeeless<Origin = frame_system::pallet_prelude::OriginFor<T>>,
+	T::RuntimeCall: CheckIfFeeless<Origin = frame_system::pallet_prelude::OriginFor<T>>,
 {
-	type AccountId = T::AccountId;
-	type Call = S::Call;
-	type AdditionalSigned = S::AdditionalSigned;
-	type Pre = (Self::AccountId, Option<<S as SignedExtension>::Pre>);
 	// From the outside this extension should be "invisible", because it just extends the wrapped
 	// extension with an extra check in `pre_dispatch` and `post_dispatch`. Thus, we should forward
 	// the identifier of the wrapped extension to let wallets see this extension as it would only be
 	// the wrapped extension itself.
 	const IDENTIFIER: &'static str = S::IDENTIFIER;
+	type Implicit = S::Implicit;
+
+	fn implicit(&self) -> Result<Self::Implicit, TransactionValidityError> {
+		self.0.implicit()
+	}
+	type Val =
+		Intermediate<S::Val, <DispatchOriginOf<T::RuntimeCall> as OriginTrait>::PalletsOrigin>;
+	type Pre =
+		Intermediate<S::Pre, <DispatchOriginOf<T::RuntimeCall> as OriginTrait>::PalletsOrigin>;
 
-	fn additional_signed(&self) -> Result<Self::AdditionalSigned, TransactionValidityError> {
-		self.0.additional_signed()
+	fn weight(&self, call: &T::RuntimeCall) -> frame_support::weights::Weight {
+		self.0.weight(call)
 	}
 
 	fn validate(
 		&self,
-		who: &Self::AccountId,
-		call: &Self::Call,
-		info: &DispatchInfoOf<Self::Call>,
+		origin: DispatchOriginOf<T::RuntimeCall>,
+		call: &T::RuntimeCall,
+		info: &DispatchInfoOf<T::RuntimeCall>,
 		len: usize,
-	) -> TransactionValidity {
-		if call.is_feeless(&<T as frame_system::Config>::RuntimeOrigin::signed(who.clone())) {
-			Ok(ValidTransaction::default())
+		self_implicit: S::Implicit,
+		inherited_implication: &impl Encode,
+	) -> ValidateResult<Self::Val, T::RuntimeCall> {
+		if call.is_feeless(&origin) {
+			Ok((Default::default(), Skip(origin.caller().clone()), origin))
 		} else {
-			self.0.validate(who, call, info, len)
+			let (x, y, z) =
+				self.0.validate(origin, call, info, len, self_implicit, inherited_implication)?;
+			Ok((x, Apply(y), z))
 		}
 	}
 
-	fn pre_dispatch(
+	fn prepare(
 		self,
-		who: &Self::AccountId,
-		call: &Self::Call,
-		info: &DispatchInfoOf<Self::Call>,
+		val: Self::Val,
+		origin: &DispatchOriginOf<T::RuntimeCall>,
+		call: &T::RuntimeCall,
+		info: &DispatchInfoOf<T::RuntimeCall>,
 		len: usize,
 	) -> Result<Self::Pre, TransactionValidityError> {
-		if call.is_feeless(&<T as frame_system::Config>::RuntimeOrigin::signed(who.clone())) {
-			Ok((who.clone(), None))
-		} else {
-			Ok((who.clone(), Some(self.0.pre_dispatch(who, call, info, len)?)))
+		match val {
+			Apply(val) => self.0.prepare(val, origin, call, info, len).map(Apply),
+			Skip(origin) => Ok(Skip(origin)),
 		}
 	}
 
-	fn post_dispatch(
-		pre: Option<Self::Pre>,
-		info: &DispatchInfoOf<Self::Call>,
-		post_info: &PostDispatchInfoOf<Self::Call>,
+	fn post_dispatch_details(
+		pre: Self::Pre,
+		info: &DispatchInfoOf<T::RuntimeCall>,
+		post_info: &PostDispatchInfoOf<T::RuntimeCall>,
 		len: usize,
 		result: &DispatchResult,
-	) -> Result<(), TransactionValidityError> {
-		if let Some(pre) = pre {
-			if let Some(pre) = pre.1 {
-				S::post_dispatch(Some(pre), info, post_info, len, result)?;
-			} else {
-				Pallet::<T>::deposit_event(Event::<T>::FeeSkipped { who: pre.0 });
-			}
+	) -> Result<Weight, TransactionValidityError> {
+		match pre {
+			Apply(pre) => S::post_dispatch_details(pre, info, post_info, len, result),
+			Skip(origin) => {
+				Pallet::<T>::deposit_event(Event::<T>::FeeSkipped { origin });
+				Ok(Weight::zero())
+			},
 		}
-		Ok(())
 	}
 }
diff --git a/substrate/frame/transaction-payment/skip-feeless-payment/src/mock.rs b/substrate/frame/transaction-payment/skip-feeless-payment/src/mock.rs
index d6d600f24e7..83f7b7dfe2b 100644
--- a/substrate/frame/transaction-payment/skip-feeless-payment/src/mock.rs
+++ b/substrate/frame/transaction-payment/skip-feeless-payment/src/mock.rs
@@ -18,9 +18,12 @@ use crate as pallet_skip_feeless_payment;
 
 use frame_support::{derive_impl, parameter_types};
 use frame_system as system;
+use sp_runtime::{
+	traits::{DispatchOriginOf, TransactionExtension},
+	transaction_validity::ValidTransaction,
+};
 
 type Block = frame_system::mocking::MockBlock<Runtime>;
-type AccountId = u64;
 
 #[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
 impl frame_system::Config for Runtime {
@@ -32,42 +35,45 @@ impl Config for Runtime {
 }
 
 parameter_types! {
-	pub static PreDispatchCount: u32 = 0;
+	pub static PrepareCount: u32 = 0;
 	pub static ValidateCount: u32 = 0;
 }
 
 #[derive(Clone, Eq, PartialEq, Debug, Encode, Decode, TypeInfo)]
 pub struct DummyExtension;
 
-impl SignedExtension for DummyExtension {
-	type AccountId = AccountId;
-	type Call = RuntimeCall;
-	type AdditionalSigned = ();
-	type Pre = ();
+impl TransactionExtension<RuntimeCall> for DummyExtension {
 	const IDENTIFIER: &'static str = "DummyExtension";
-	fn additional_signed(&self) -> core::result::Result<(), TransactionValidityError> {
-		Ok(())
+	type Implicit = ();
+	type Val = ();
+	type Pre = ();
+
+	fn weight(&self, _: &RuntimeCall) -> Weight {
+		Weight::zero()
 	}
 
 	fn validate(
 		&self,
-		_who: &Self::AccountId,
-		_call: &Self::Call,
-		_info: &DispatchInfoOf<Self::Call>,
+		origin: DispatchOriginOf<RuntimeCall>,
+		_call: &RuntimeCall,
+		_info: &DispatchInfoOf<RuntimeCall>,
 		_len: usize,
-	) -> TransactionValidity {
+		_self_implicit: Self::Implicit,
+		_inherited_implication: &impl Encode,
+	) -> ValidateResult<Self::Val, RuntimeCall> {
 		ValidateCount::mutate(|c| *c += 1);
-		Ok(Default::default())
+		Ok((ValidTransaction::default(), (), origin))
 	}
 
-	fn pre_dispatch(
+	fn prepare(
 		self,
-		_who: &Self::AccountId,
-		_call: &Self::Call,
-		_info: &DispatchInfoOf<Self::Call>,
+		_val: Self::Val,
+		_origin: &DispatchOriginOf<RuntimeCall>,
+		_call: &RuntimeCall,
+		_info: &DispatchInfoOf<RuntimeCall>,
 		_len: usize,
 	) -> Result<Self::Pre, TransactionValidityError> {
-		PreDispatchCount::mutate(|c| *c += 1);
+		PrepareCount::mutate(|c| *c += 1);
 		Ok(())
 	}
 }
diff --git a/substrate/frame/transaction-payment/skip-feeless-payment/src/tests.rs b/substrate/frame/transaction-payment/skip-feeless-payment/src/tests.rs
index adee52d6b3c..666844c883b 100644
--- a/substrate/frame/transaction-payment/skip-feeless-payment/src/tests.rs
+++ b/substrate/frame/transaction-payment/skip-feeless-payment/src/tests.rs
@@ -15,23 +15,24 @@
 
 use super::*;
 use crate::mock::{
-	pallet_dummy::Call, DummyExtension, PreDispatchCount, Runtime, RuntimeCall, ValidateCount,
+	pallet_dummy::Call, DummyExtension, PrepareCount, Runtime, RuntimeCall, ValidateCount,
 };
 use frame_support::dispatch::DispatchInfo;
+use sp_runtime::traits::DispatchTransaction;
 
 #[test]
 fn skip_feeless_payment_works() {
 	let call = RuntimeCall::DummyPallet(Call::<Runtime>::aux { data: 1 });
 	SkipCheckIfFeeless::<Runtime, DummyExtension>::from(DummyExtension)
-		.pre_dispatch(&0, &call, &DispatchInfo::default(), 0)
+		.validate_and_prepare(Some(0).into(), &call, &DispatchInfo::default(), 0)
 		.unwrap();
-	assert_eq!(PreDispatchCount::get(), 1);
+	assert_eq!(PrepareCount::get(), 1);
 
 	let call = RuntimeCall::DummyPallet(Call::<Runtime>::aux { data: 0 });
 	SkipCheckIfFeeless::<Runtime, DummyExtension>::from(DummyExtension)
-		.pre_dispatch(&0, &call, &DispatchInfo::default(), 0)
+		.validate_and_prepare(Some(0).into(), &call, &DispatchInfo::default(), 0)
 		.unwrap();
-	assert_eq!(PreDispatchCount::get(), 1);
+	assert_eq!(PrepareCount::get(), 1);
 }
 
 #[test]
@@ -40,13 +41,42 @@ fn validate_works() {
 
 	let call = RuntimeCall::DummyPallet(Call::<Runtime>::aux { data: 1 });
 	SkipCheckIfFeeless::<Runtime, DummyExtension>::from(DummyExtension)
-		.validate(&0, &call, &DispatchInfo::default(), 0)
+		.validate_only(Some(0).into(), &call, &DispatchInfo::default(), 0)
 		.unwrap();
 	assert_eq!(ValidateCount::get(), 1);
+	assert_eq!(PrepareCount::get(), 0);
 
 	let call = RuntimeCall::DummyPallet(Call::<Runtime>::aux { data: 0 });
 	SkipCheckIfFeeless::<Runtime, DummyExtension>::from(DummyExtension)
-		.validate(&0, &call, &DispatchInfo::default(), 0)
+		.validate_only(Some(0).into(), &call, &DispatchInfo::default(), 0)
 		.unwrap();
 	assert_eq!(ValidateCount::get(), 1);
+	assert_eq!(PrepareCount::get(), 0);
+}
+
+#[test]
+fn validate_prepare_works() {
+	assert_eq!(ValidateCount::get(), 0);
+
+	let call = RuntimeCall::DummyPallet(Call::<Runtime>::aux { data: 1 });
+	SkipCheckIfFeeless::<Runtime, DummyExtension>::from(DummyExtension)
+		.validate_and_prepare(Some(0).into(), &call, &DispatchInfo::default(), 0)
+		.unwrap();
+	assert_eq!(ValidateCount::get(), 1);
+	assert_eq!(PrepareCount::get(), 1);
+
+	let call = RuntimeCall::DummyPallet(Call::<Runtime>::aux { data: 0 });
+	SkipCheckIfFeeless::<Runtime, DummyExtension>::from(DummyExtension)
+		.validate_and_prepare(Some(0).into(), &call, &DispatchInfo::default(), 0)
+		.unwrap();
+	assert_eq!(ValidateCount::get(), 1);
+	assert_eq!(PrepareCount::get(), 1);
+
+	// Changes from previous prepare calls persist.
+	let call = RuntimeCall::DummyPallet(Call::<Runtime>::aux { data: 1 });
+	SkipCheckIfFeeless::<Runtime, DummyExtension>::from(DummyExtension)
+		.validate_and_prepare(Some(0).into(), &call, &DispatchInfo::default(), 0)
+		.unwrap();
+	assert_eq!(ValidateCount::get(), 2);
+	assert_eq!(PrepareCount::get(), 2);
 }
diff --git a/substrate/frame/transaction-payment/src/benchmarking.rs b/substrate/frame/transaction-payment/src/benchmarking.rs
new file mode 100644
index 00000000000..c5f87fb8c12
--- /dev/null
+++ b/substrate/frame/transaction-payment/src/benchmarking.rs
@@ -0,0 +1,86 @@
+// This file is part of Substrate.
+
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Benchmarks for Transaction Payment Pallet's transaction extension
+
+extern crate alloc;
+
+use super::*;
+use crate::Pallet;
+use frame_benchmarking::v2::*;
+use frame_support::dispatch::{DispatchInfo, PostDispatchInfo};
+use frame_system::{EventRecord, RawOrigin};
+use sp_runtime::traits::{AsTransactionAuthorizedOrigin, DispatchTransaction, Dispatchable};
+
+fn assert_last_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) {
+	let events = frame_system::Pallet::<T>::events();
+	let system_event: <T as frame_system::Config>::RuntimeEvent = generic_event.into();
+	// compare to the last event record
+	let EventRecord { event, .. } = &events[events.len() - 1];
+	assert_eq!(event, &system_event);
+}
+
+#[benchmarks(where
+	T: Config,
+	T::RuntimeOrigin: AsTransactionAuthorizedOrigin,
+	T::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
+)]
+mod benchmarks {
+	use super::*;
+
+	#[benchmark]
+	fn charge_transaction_payment() {
+		let caller: T::AccountId = account("caller", 0, 0);
+		<T::OnChargeTransaction as OnChargeTransaction<T>>::endow_account(
+			&caller,
+			<T::OnChargeTransaction as OnChargeTransaction<T>>::minimum_balance() * 1000u32.into(),
+		);
+		let tip = <T::OnChargeTransaction as OnChargeTransaction<T>>::minimum_balance();
+		let ext: ChargeTransactionPayment<T> = ChargeTransactionPayment::from(tip);
+		let inner = frame_system::Call::remark { remark: alloc::vec![] };
+		let call = T::RuntimeCall::from(inner);
+		let extension_weight = ext.weight(&call);
+		let info = DispatchInfo {
+			call_weight: Weight::from_parts(100, 0),
+			extension_weight,
+			class: DispatchClass::Operational,
+			pays_fee: Pays::Yes,
+		};
+		let mut post_info = PostDispatchInfo {
+			actual_weight: Some(Weight::from_parts(10, 0)),
+			pays_fee: Pays::Yes,
+		};
+
+		#[block]
+		{
+			assert!(ext
+				.test_run(RawOrigin::Signed(caller.clone()).into(), &call, &info, 10, |_| Ok(
+					post_info
+				))
+				.unwrap()
+				.is_ok());
+		}
+
+		post_info.actual_weight.as_mut().map(|w| w.saturating_accrue(extension_weight));
+		let actual_fee = Pallet::<T>::compute_actual_fee(10, &info, &post_info, tip);
+		assert_last_event::<T>(
+			Event::<T>::TransactionFeePaid { who: caller, actual_fee, tip }.into(),
+		);
+	}
+
+	impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Runtime);
+}
diff --git a/substrate/frame/transaction-payment/src/lib.rs b/substrate/frame/transaction-payment/src/lib.rs
index c17ab393b5d..711189be8d0 100644
--- a/substrate/frame/transaction-payment/src/lib.rs
+++ b/substrate/frame/transaction-payment/src/lib.rs
@@ -56,28 +56,32 @@ use frame_support::{
 	},
 	traits::{Defensive, EstimateCallFee, Get},
 	weights::{Weight, WeightToFee},
+	RuntimeDebugNoBound,
 };
 pub use pallet::*;
 pub use payment::*;
 use sp_runtime::{
 	traits::{
 		Convert, DispatchInfoOf, Dispatchable, One, PostDispatchInfoOf, SaturatedConversion,
-		Saturating, SignedExtension, Zero,
-	},
-	transaction_validity::{
-		TransactionPriority, TransactionValidity, TransactionValidityError, ValidTransaction,
+		Saturating, TransactionExtension, Zero,
 	},
+	transaction_validity::{TransactionPriority, TransactionValidityError, ValidTransaction},
 	FixedPointNumber, FixedU128, Perbill, Perquintill, RuntimeDebug,
 };
 pub use types::{FeeDetails, InclusionFee, RuntimeDispatchInfo};
+pub use weights::WeightInfo;
 
 #[cfg(test)]
 mod mock;
 #[cfg(test)]
 mod tests;
 
+#[cfg(feature = "runtime-benchmarks")]
+mod benchmarking;
+
 mod payment;
 mod types;
+pub mod weights;
 
 /// Fee multiplier.
 pub type Multiplier = FixedU128;
@@ -334,6 +338,7 @@ pub mod pallet {
 			type RuntimeEvent = ();
 			type FeeMultiplierUpdate = ();
 			type OperationalFeeMultiplier = ();
+			type WeightInfo = ();
 		}
 	}
 
@@ -386,6 +391,9 @@ pub mod pallet {
 		/// transactions.
 		#[pallet::constant]
 		type OperationalFeeMultiplier: Get<u8>;
+
+		/// The weight information of this pallet.
+		type WeightInfo: WeightInfo;
 	}
 
 	#[pallet::type_value]
@@ -496,7 +504,7 @@ impl<T: Config> Pallet<T> {
 	///
 	/// All dispatchables must be annotated with weight and will have some fee info. This function
 	/// always returns.
-	pub fn query_info<Extrinsic: sp_runtime::traits::Extrinsic + GetDispatchInfo>(
+	pub fn query_info<Extrinsic: sp_runtime::traits::ExtrinsicLike + GetDispatchInfo>(
 		unchecked_extrinsic: Extrinsic,
 		len: u32,
 	) -> RuntimeDispatchInfo<BalanceOf<T>>
@@ -510,20 +518,20 @@ impl<T: Config> Pallet<T> {
 		// a very very little potential gain in the future.
 		let dispatch_info = <Extrinsic as GetDispatchInfo>::get_dispatch_info(&unchecked_extrinsic);
 
-		let partial_fee = if unchecked_extrinsic.is_signed().unwrap_or(false) {
-			Self::compute_fee(len, &dispatch_info, 0u32.into())
-		} else {
-			// Unsigned extrinsics have no partial fee.
+		let partial_fee = if unchecked_extrinsic.is_bare() {
+			// Bare extrinsics have no partial fee.
 			0u32.into()
+		} else {
+			Self::compute_fee(len, &dispatch_info, 0u32.into())
 		};
 
-		let DispatchInfo { weight, class, .. } = dispatch_info;
+		let DispatchInfo { class, .. } = dispatch_info;
 
-		RuntimeDispatchInfo { weight, class, partial_fee }
+		RuntimeDispatchInfo { weight: dispatch_info.total_weight(), class, partial_fee }
 	}
 
 	/// Query the detailed fee of a given `call`.
-	pub fn query_fee_details<Extrinsic: sp_runtime::traits::Extrinsic + GetDispatchInfo>(
+	pub fn query_fee_details<Extrinsic: sp_runtime::traits::ExtrinsicLike + GetDispatchInfo>(
 		unchecked_extrinsic: Extrinsic,
 		len: u32,
 	) -> FeeDetails<BalanceOf<T>>
@@ -534,11 +542,11 @@ impl<T: Config> Pallet<T> {
 
 		let tip = 0u32.into();
 
-		if unchecked_extrinsic.is_signed().unwrap_or(false) {
-			Self::compute_fee_details(len, &dispatch_info, tip)
-		} else {
-			// Unsigned extrinsics have no inclusion fee.
+		if unchecked_extrinsic.is_bare() {
+			// Bare extrinsics have no inclusion fee.
 			FeeDetails { inclusion_fee: None, tip }
+		} else {
+			Self::compute_fee_details(len, &dispatch_info, tip)
 		}
 	}
 
@@ -548,10 +556,10 @@ impl<T: Config> Pallet<T> {
 		T::RuntimeCall: Dispatchable<Info = DispatchInfo> + GetDispatchInfo,
 	{
 		let dispatch_info = <T::RuntimeCall as GetDispatchInfo>::get_dispatch_info(&call);
-		let DispatchInfo { weight, class, .. } = dispatch_info;
+		let DispatchInfo { class, .. } = dispatch_info;
 
 		RuntimeDispatchInfo {
-			weight,
+			weight: dispatch_info.total_weight(),
 			class,
 			partial_fee: Self::compute_fee(len, &dispatch_info, 0u32.into()),
 		}
@@ -589,7 +597,7 @@ impl<T: Config> Pallet<T> {
 	where
 		T::RuntimeCall: Dispatchable<Info = DispatchInfo>,
 	{
-		Self::compute_fee_raw(len, info.weight, tip, info.pays_fee, info.class)
+		Self::compute_fee_raw(len, info.total_weight(), tip, info.pays_fee, info.class)
 	}
 
 	/// Compute the actual post dispatch fee for a particular transaction.
@@ -722,7 +730,7 @@ where
 		who: &T::AccountId,
 		call: &T::RuntimeCall,
 		info: &DispatchInfoOf<T::RuntimeCall>,
-		len: usize,
+		fee: BalanceOf<T>,
 	) -> Result<
 		(
 			BalanceOf<T>,
@@ -731,7 +739,6 @@ where
 		TransactionValidityError,
 	> {
 		let tip = self.0;
-		let fee = Pallet::<T>::compute_fee(len as u32, info, tip);
 
 		<<T as Config>::OnChargeTransaction as OnChargeTransaction<T>>::withdraw_fee(
 			who, call, info, fee, tip,
@@ -739,6 +746,22 @@ where
 		.map(|i| (fee, i))
 	}
 
+	fn can_withdraw_fee(
+		&self,
+		who: &T::AccountId,
+		call: &T::RuntimeCall,
+		info: &DispatchInfoOf<T::RuntimeCall>,
+		len: usize,
+	) -> Result<BalanceOf<T>, TransactionValidityError> {
+		let tip = self.0;
+		let fee = Pallet::<T>::compute_fee(len as u32, info, tip);
+
+		<<T as Config>::OnChargeTransaction as OnChargeTransaction<T>>::can_withdraw_fee(
+			who, call, info, fee, tip,
+		)?;
+		Ok(fee)
+	}
+
 	/// Get an appropriate priority for a transaction with the given `DispatchInfo`, encoded length
 	/// and user-included tip.
 	///
@@ -764,7 +787,8 @@ where
 		let max_block_length = *T::BlockLength::get().max.get(info.class) as u64;
 
 		// bounded_weight is used as a divisor later so we keep it non-zero.
-		let bounded_weight = info.weight.max(Weight::from_parts(1, 1)).min(max_block_weight);
+		let bounded_weight =
+			info.total_weight().max(Weight::from_parts(1, 1)).min(max_block_weight);
 		let bounded_length = (len as u64).clamp(1, max_block_length);
 
 		// returns the scarce resource, i.e. the one that is limiting the number of transactions.
@@ -825,68 +849,130 @@ impl<T: Config> core::fmt::Debug for ChargeTransactionPayment<T> {
 	}
 }
 
-impl<T: Config> SignedExtension for ChargeTransactionPayment<T>
+/// The info passed between the validate and prepare steps for the `ChargeAssetTxPayment` extension.
+#[derive(RuntimeDebugNoBound)]
+pub enum Val<T: Config> {
+	Charge {
+		tip: BalanceOf<T>,
+		// who paid the fee
+		who: T::AccountId,
+		// transaction fee
+		fee: BalanceOf<T>,
+	},
+	NoCharge,
+}
+
+/// The info passed between the prepare and post-dispatch steps for the `ChargeAssetTxPayment`
+/// extension.
+pub enum Pre<T: Config> {
+	Charge {
+		tip: BalanceOf<T>,
+		// who paid the fee
+		who: T::AccountId,
+		// imbalance resulting from withdrawing the fee
+		imbalance: <<T as Config>::OnChargeTransaction as OnChargeTransaction<T>>::LiquidityInfo,
+	},
+	NoCharge {
+		// weight initially estimated by the extension, to be refunded
+		refund: Weight,
+	},
+}
+
+impl<T: Config> core::fmt::Debug for Pre<T> {
+	#[cfg(feature = "std")]
+	fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
+		match self {
+			Pre::Charge { tip, who, imbalance: _ } => {
+				write!(f, "Charge {{ tip: {:?}, who: {:?}, imbalance: <stripped> }}", tip, who)
+			},
+			Pre::NoCharge { refund } => write!(f, "NoCharge {{ refund: {:?} }}", refund),
+		}
+	}
+
+	#[cfg(not(feature = "std"))]
+	fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
+		f.write_str("<wasm:stripped>")
+	}
+}
+
+impl<T: Config> TransactionExtension<T::RuntimeCall> for ChargeTransactionPayment<T>
 where
-	BalanceOf<T>: Send + Sync + From<u64>,
 	T::RuntimeCall: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
 {
 	const IDENTIFIER: &'static str = "ChargeTransactionPayment";
-	type AccountId = T::AccountId;
-	type Call = T::RuntimeCall;
-	type AdditionalSigned = ();
-	type Pre = (
-		// tip
-		BalanceOf<T>,
-		// who paid the fee - this is an option to allow for a Default impl.
-		Self::AccountId,
-		// imbalance resulting from withdrawing the fee
-		<<T as Config>::OnChargeTransaction as OnChargeTransaction<T>>::LiquidityInfo,
-	);
-	fn additional_signed(&self) -> core::result::Result<(), TransactionValidityError> {
-		Ok(())
+	type Implicit = ();
+	type Val = Val<T>;
+	type Pre = Pre<T>;
+
+	fn weight(&self, _: &T::RuntimeCall) -> Weight {
+		T::WeightInfo::charge_transaction_payment()
 	}
 
 	fn validate(
 		&self,
-		who: &Self::AccountId,
-		call: &Self::Call,
-		info: &DispatchInfoOf<Self::Call>,
+		origin: <T::RuntimeCall as Dispatchable>::RuntimeOrigin,
+		call: &T::RuntimeCall,
+		info: &DispatchInfoOf<T::RuntimeCall>,
 		len: usize,
-	) -> TransactionValidity {
-		let (final_fee, _) = self.withdraw_fee(who, call, info, len)?;
+		_: (),
+		_implication: &impl Encode,
+	) -> Result<
+		(ValidTransaction, Self::Val, <T::RuntimeCall as Dispatchable>::RuntimeOrigin),
+		TransactionValidityError,
+	> {
+		let Ok(who) = frame_system::ensure_signed(origin.clone()) else {
+			return Ok((ValidTransaction::default(), Val::NoCharge, origin));
+		};
+		let final_fee = self.can_withdraw_fee(&who, call, info, len)?;
 		let tip = self.0;
-		Ok(ValidTransaction {
-			priority: Self::get_priority(info, len, tip, final_fee),
-			..Default::default()
-		})
+		Ok((
+			ValidTransaction {
+				priority: Self::get_priority(info, len, tip, final_fee),
+				..Default::default()
+			},
+			Val::Charge { tip: self.0, who, fee: final_fee },
+			origin,
+		))
 	}
 
-	fn pre_dispatch(
+	fn prepare(
 		self,
-		who: &Self::AccountId,
-		call: &Self::Call,
-		info: &DispatchInfoOf<Self::Call>,
-		len: usize,
+		val: Self::Val,
+		_origin: &<T::RuntimeCall as Dispatchable>::RuntimeOrigin,
+		call: &T::RuntimeCall,
+		info: &DispatchInfoOf<T::RuntimeCall>,
+		_len: usize,
 	) -> Result<Self::Pre, TransactionValidityError> {
-		let (_fee, imbalance) = self.withdraw_fee(who, call, info, len)?;
-		Ok((self.0, who.clone(), imbalance))
+		match val {
+			Val::Charge { tip, who, fee } => {
+				// Mutating call to `withdraw_fee` to actually charge for the transaction.
+				let (_final_fee, imbalance) = self.withdraw_fee(&who, call, info, fee)?;
+				Ok(Pre::Charge { tip, who, imbalance })
+			},
+			Val::NoCharge => Ok(Pre::NoCharge { refund: self.weight(call) }),
+		}
 	}
 
-	fn post_dispatch(
-		maybe_pre: Option<Self::Pre>,
-		info: &DispatchInfoOf<Self::Call>,
-		post_info: &PostDispatchInfoOf<Self::Call>,
+	fn post_dispatch_details(
+		pre: Self::Pre,
+		info: &DispatchInfoOf<T::RuntimeCall>,
+		post_info: &PostDispatchInfoOf<T::RuntimeCall>,
 		len: usize,
 		_result: &DispatchResult,
-	) -> Result<(), TransactionValidityError> {
-		if let Some((tip, who, imbalance)) = maybe_pre {
-			let actual_fee = Pallet::<T>::compute_actual_fee(len as u32, info, post_info, tip);
-			T::OnChargeTransaction::correct_and_deposit_fee(
-				&who, info, post_info, actual_fee, tip, imbalance,
-			)?;
-			Pallet::<T>::deposit_event(Event::<T>::TransactionFeePaid { who, actual_fee, tip });
-		}
-		Ok(())
+	) -> Result<Weight, TransactionValidityError> {
+		let (tip, who, imbalance) = match pre {
+			Pre::Charge { tip, who, imbalance } => (tip, who, imbalance),
+			Pre::NoCharge { refund } => {
+				// No-op: Refund everything
+				return Ok(refund)
+			},
+		};
+		let actual_fee = Pallet::<T>::compute_actual_fee(len as u32, info, &post_info, tip);
+		T::OnChargeTransaction::correct_and_deposit_fee(
+			&who, info, &post_info, actual_fee, tip, imbalance,
+		)?;
+		Pallet::<T>::deposit_event(Event::<T>::TransactionFeePaid { who, actual_fee, tip });
+		Ok(Weight::zero())
 	}
 }
 
diff --git a/substrate/frame/transaction-payment/src/mock.rs b/substrate/frame/transaction-payment/src/mock.rs
index 8767024ee23..3995c41e8b1 100644
--- a/substrate/frame/transaction-payment/src/mock.rs
+++ b/substrate/frame/transaction-payment/src/mock.rs
@@ -119,6 +119,15 @@ impl OnUnbalanced<fungible::Credit<<Runtime as frame_system::Config>::AccountId,
 	}
 }
 
+/// Weights used in testing.
+pub struct MockWeights;
+
+impl WeightInfo for MockWeights {
+	fn charge_transaction_payment() -> Weight {
+		Weight::from_parts(10, 0)
+	}
+}
+
 impl Config for Runtime {
 	type RuntimeEvent = RuntimeEvent;
 	type OnChargeTransaction = FungibleAdapter<Balances, DealWithFees>;
@@ -126,4 +135,14 @@ impl Config for Runtime {
 	type WeightToFee = WeightToFee;
 	type LengthToFee = TransactionByteFee;
 	type FeeMultiplierUpdate = ();
+	type WeightInfo = MockWeights;
+}
+
+#[cfg(feature = "runtime-benchmarks")]
+pub fn new_test_ext() -> sp_io::TestExternalities {
+	crate::tests::ExtBuilder::default()
+		.base_weight(Weight::from_parts(100, 0))
+		.byte_fee(10)
+		.balance_factor(0)
+		.build()
 }
diff --git a/substrate/frame/transaction-payment/src/payment.rs b/substrate/frame/transaction-payment/src/payment.rs
index 0fe61678290..4b39cd3fe53 100644
--- a/substrate/frame/transaction-payment/src/payment.rs
+++ b/substrate/frame/transaction-payment/src/payment.rs
@@ -20,14 +20,14 @@ use crate::Config;
 
 use core::marker::PhantomData;
 use sp_runtime::{
-	traits::{DispatchInfoOf, PostDispatchInfoOf, Saturating, Zero},
+	traits::{CheckedSub, DispatchInfoOf, PostDispatchInfoOf, Saturating, Zero},
 	transaction_validity::InvalidTransaction,
 };
 
 use frame_support::{
 	traits::{
 		fungible::{Balanced, Credit, Debt, Inspect},
-		tokens::Precision,
+		tokens::{Precision, WithdrawConsequence},
 		Currency, ExistenceRequirement, Imbalance, OnUnbalanced, WithdrawReasons,
 	},
 	unsigned::TransactionValidityError,
@@ -55,6 +55,17 @@ pub trait OnChargeTransaction<T: Config> {
 		tip: Self::Balance,
 	) -> Result<Self::LiquidityInfo, TransactionValidityError>;
 
+	/// Check if the predicted fee from the transaction origin can be withdrawn.
+	///
+	/// Note: The `fee` already includes the `tip`.
+	fn can_withdraw_fee(
+		who: &T::AccountId,
+		call: &T::RuntimeCall,
+		dispatch_info: &DispatchInfoOf<T::RuntimeCall>,
+		fee: Self::Balance,
+		tip: Self::Balance,
+	) -> Result<(), TransactionValidityError>;
+
 	/// After the transaction was executed the actual fee can be calculated.
 	/// This function should refund any overpaid fees and optionally deposit
 	/// the corrected amount.
@@ -68,6 +79,12 @@ pub trait OnChargeTransaction<T: Config> {
 		tip: Self::Balance,
 		already_withdrawn: Self::LiquidityInfo,
 	) -> Result<(), TransactionValidityError>;
+
+	#[cfg(feature = "runtime-benchmarks")]
+	fn endow_account(who: &T::AccountId, amount: Self::Balance);
+
+	#[cfg(feature = "runtime-benchmarks")]
+	fn minimum_balance() -> Self::Balance;
 }
 
 /// Implements transaction payment for a pallet implementing the [`frame_support::traits::fungible`]
@@ -110,6 +127,23 @@ where
 		}
 	}
 
+	fn can_withdraw_fee(
+		who: &T::AccountId,
+		_call: &T::RuntimeCall,
+		_dispatch_info: &DispatchInfoOf<T::RuntimeCall>,
+		fee: Self::Balance,
+		_tip: Self::Balance,
+	) -> Result<(), TransactionValidityError> {
+		if fee.is_zero() {
+			return Ok(())
+		}
+
+		match F::can_withdraw(who, fee) {
+			WithdrawConsequence::Success => Ok(()),
+			_ => Err(InvalidTransaction::Payment.into()),
+		}
+	}
+
 	fn correct_and_deposit_fee(
 		who: &<T>::AccountId,
 		_dispatch_info: &DispatchInfoOf<<T>::RuntimeCall>,
@@ -141,6 +175,16 @@ where
 
 		Ok(())
 	}
+
+	#[cfg(feature = "runtime-benchmarks")]
+	fn endow_account(who: &T::AccountId, amount: Self::Balance) {
+		let _ = F::deposit(who, amount, Precision::BestEffort);
+	}
+
+	#[cfg(feature = "runtime-benchmarks")]
+	fn minimum_balance() -> Self::Balance {
+		F::minimum_balance()
+	}
 }
 
 /// Implements the transaction payment for a pallet implementing the [`Currency`]
@@ -202,6 +246,33 @@ where
 		}
 	}
 
+	/// Check if the predicted fee from the transaction origin can be withdrawn.
+	///
+	/// Note: The `fee` already includes the `tip`.
+	fn can_withdraw_fee(
+		who: &T::AccountId,
+		_call: &T::RuntimeCall,
+		_info: &DispatchInfoOf<T::RuntimeCall>,
+		fee: Self::Balance,
+		tip: Self::Balance,
+	) -> Result<(), TransactionValidityError> {
+		if fee.is_zero() {
+			return Ok(())
+		}
+
+		let withdraw_reason = if tip.is_zero() {
+			WithdrawReasons::TRANSACTION_PAYMENT
+		} else {
+			WithdrawReasons::TRANSACTION_PAYMENT | WithdrawReasons::TIP
+		};
+
+		let new_balance =
+			C::free_balance(who).checked_sub(&fee).ok_or(InvalidTransaction::Payment)?;
+		C::ensure_can_withdraw(who, fee, withdraw_reason, new_balance)
+			.map(|_| ())
+			.map_err(|_| InvalidTransaction::Payment.into())
+	}
+
 	/// Hand the fee and the tip over to the `[OnUnbalanced]` implementation.
 	/// Since the predicted fee might have been too high, parts of the fee may
 	/// be refunded.
@@ -234,4 +305,14 @@ where
 		}
 		Ok(())
 	}
+
+	#[cfg(feature = "runtime-benchmarks")]
+	fn endow_account(who: &T::AccountId, amount: Self::Balance) {
+		let _ = C::deposit_creating(who, amount);
+	}
+
+	#[cfg(feature = "runtime-benchmarks")]
+	fn minimum_balance() -> Self::Balance {
+		C::minimum_balance()
+	}
 }
diff --git a/substrate/frame/transaction-payment/src/tests.rs b/substrate/frame/transaction-payment/src/tests.rs
index bac89967d6a..e8f5ab99529 100644
--- a/substrate/frame/transaction-payment/src/tests.rs
+++ b/substrate/frame/transaction-payment/src/tests.rs
@@ -21,13 +21,16 @@ use crate as pallet_transaction_payment;
 use codec::Encode;
 
 use sp_runtime::{
-	testing::TestXt, traits::One, transaction_validity::InvalidTransaction, BuildStorage,
+	generic::UncheckedExtrinsic,
+	traits::{DispatchTransaction, One},
+	transaction_validity::InvalidTransaction,
+	BuildStorage,
 };
 
 use frame_support::{
-	assert_noop, assert_ok,
+	assert_ok,
 	dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo, PostDispatchInfo},
-	traits::Currency,
+	traits::{Currency, OriginTrait},
 	weights::Weight,
 };
 use frame_system as system;
@@ -113,7 +116,7 @@ impl ExtBuilder {
 /// create a transaction info struct from weight. Handy to avoid building the whole struct.
 pub fn info_from_weight(w: Weight) -> DispatchInfo {
 	// pays_fee: Pays::Yes -- class: DispatchClass::Normal
-	DispatchInfo { weight: w, ..Default::default() }
+	DispatchInfo { call_weight: w, ..Default::default() }
 }
 
 fn post_info_from_weight(w: Weight) -> PostDispatchInfo {
@@ -128,88 +131,82 @@ fn default_post_info() -> PostDispatchInfo {
 	PostDispatchInfo { actual_weight: None, pays_fee: Default::default() }
 }
 
+type Ext = ChargeTransactionPayment<Runtime>;
+
 #[test]
-fn signed_extension_transaction_payment_work() {
+fn transaction_extension_transaction_payment_work() {
 	ExtBuilder::default()
 		.balance_factor(10)
 		.base_weight(Weight::from_parts(5, 0))
 		.build()
 		.execute_with(|| {
-			let len = 10;
-			let pre = ChargeTransactionPayment::<Runtime>::from(0)
-				.pre_dispatch(&1, CALL, &info_from_weight(Weight::from_parts(5, 0)), len)
-				.unwrap();
-			assert_eq!(Balances::free_balance(1), 100 - 5 - 5 - 10);
-
-			assert_ok!(ChargeTransactionPayment::<Runtime>::post_dispatch(
-				Some(pre),
-				&info_from_weight(Weight::from_parts(5, 0)),
-				&default_post_info(),
-				len,
-				&Ok(())
-			));
-			assert_eq!(Balances::free_balance(1), 100 - 5 - 5 - 10);
-			assert_eq!(FeeUnbalancedAmount::get(), 5 + 5 + 10);
+			let mut info = info_from_weight(Weight::from_parts(5, 0));
+			let ext = Ext::from(0);
+			let ext_weight = ext.weight(CALL);
+			info.extension_weight = ext_weight;
+			ext.test_run(Some(1).into(), CALL, &info, 10, |_| {
+				assert_eq!(Balances::free_balance(1), 100 - 5 - 5 - 10 - 10);
+				Ok(default_post_info())
+			})
+			.unwrap()
+			.unwrap();
+			assert_eq!(Balances::free_balance(1), 100 - 5 - 5 - 10 - 10);
+			assert_eq!(FeeUnbalancedAmount::get(), 5 + 5 + 10 + 10);
 			assert_eq!(TipUnbalancedAmount::get(), 0);
 
 			FeeUnbalancedAmount::mutate(|a| *a = 0);
 
-			let pre = ChargeTransactionPayment::<Runtime>::from(5 /* tipped */)
-				.pre_dispatch(&2, CALL, &info_from_weight(Weight::from_parts(100, 0)), len)
+			let mut info = info_from_weight(Weight::from_parts(100, 0));
+			info.extension_weight = ext_weight;
+			Ext::from(5 /* tipped */)
+				.test_run(Some(2).into(), CALL, &info, 10, |_| {
+					assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 10 - 5);
+					Ok(post_info_from_weight(Weight::from_parts(50, 0)))
+				})
+				.unwrap()
 				.unwrap();
-			assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5);
-
-			assert_ok!(ChargeTransactionPayment::<Runtime>::post_dispatch(
-				Some(pre),
-				&info_from_weight(Weight::from_parts(100, 0)),
-				&post_info_from_weight(Weight::from_parts(50, 0)),
-				len,
-				&Ok(())
-			));
-			assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 50 - 5);
-			assert_eq!(FeeUnbalancedAmount::get(), 5 + 10 + 50);
+			assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 50 - 10 - 5);
+			assert_eq!(FeeUnbalancedAmount::get(), 5 + 10 + 50 + 10);
 			assert_eq!(TipUnbalancedAmount::get(), 5);
 		});
 }
 
 #[test]
-fn signed_extension_transaction_payment_multiplied_refund_works() {
+fn transaction_extension_transaction_payment_multiplied_refund_works() {
 	ExtBuilder::default()
 		.balance_factor(10)
 		.base_weight(Weight::from_parts(5, 0))
 		.build()
 		.execute_with(|| {
-			let len = 10;
 			NextFeeMultiplier::<Runtime>::put(Multiplier::saturating_from_rational(3, 2));
 
-			let pre = ChargeTransactionPayment::<Runtime>::from(5 /* tipped */)
-				.pre_dispatch(&2, CALL, &info_from_weight(Weight::from_parts(100, 0)), len)
-				.unwrap();
-			// 5 base fee, 10 byte fee, 3/2 * 100 weight fee, 5 tip
-			assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 150 - 5);
-
-			assert_ok!(ChargeTransactionPayment::<Runtime>::post_dispatch(
-				Some(pre),
-				&info_from_weight(Weight::from_parts(100, 0)),
-				&post_info_from_weight(Weight::from_parts(50, 0)),
-				len,
-				&Ok(())
-			));
-			// 75 (3/2 of the returned 50 units of weight) is refunded
-			assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 75 - 5);
+			let len = 10;
+			let origin = Some(2).into();
+			let mut info = info_from_weight(Weight::from_parts(100, 0));
+			let ext = Ext::from(5 /* tipped */);
+			let ext_weight = ext.weight(CALL);
+			info.extension_weight = ext_weight;
+			ext.test_run(origin, CALL, &info, len, |_| {
+				// 5 base fee, 10 byte fee, 3/2 * (100 call weight fee + 10 ext weight fee), 5
+				// tip
+				assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 165 - 5);
+				Ok(post_info_from_weight(Weight::from_parts(50, 0)))
+			})
+			.unwrap()
+			.unwrap();
+
+			// 75 (3/2 of the returned 50 units of call weight, 0 returned of ext weight) is
+			// refunded
+			assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - (165 - 75) - 5);
 		});
 }
 
 #[test]
-fn signed_extension_transaction_payment_is_bounded() {
+fn transaction_extension_transaction_payment_is_bounded() {
 	ExtBuilder::default().balance_factor(1000).byte_fee(0).build().execute_with(|| {
 		// maximum weight possible
-		assert_ok!(ChargeTransactionPayment::<Runtime>::from(0).pre_dispatch(
-			&1,
-			CALL,
-			&info_from_weight(Weight::MAX),
-			10
-		));
+		let info = info_from_weight(Weight::MAX);
+		assert_ok!(Ext::from(0).validate_and_prepare(Some(1).into(), CALL, &info, 10));
 		// fee will be proportional to what is the actual maximum weight in the runtime.
 		assert_eq!(
 			Balances::free_balance(&1),
@@ -220,7 +217,7 @@ fn signed_extension_transaction_payment_is_bounded() {
 }
 
 #[test]
-fn signed_extension_allows_free_transactions() {
+fn transaction_extension_allows_free_transactions() {
 	ExtBuilder::default()
 		.base_weight(Weight::from_parts(100, 0))
 		.balance_factor(0)
@@ -232,38 +229,30 @@ fn signed_extension_allows_free_transactions() {
 			let len = 100;
 
 			// This is a completely free (and thus wholly insecure/DoS-ridden) transaction.
-			let operational_transaction = DispatchInfo {
-				weight: Weight::from_parts(0, 0),
+			let op_tx = DispatchInfo {
+				call_weight: Weight::from_parts(0, 0),
+				extension_weight: Weight::zero(),
 				class: DispatchClass::Operational,
 				pays_fee: Pays::No,
 			};
-			assert_ok!(ChargeTransactionPayment::<Runtime>::from(0).validate(
-				&1,
-				CALL,
-				&operational_transaction,
-				len
-			));
+			assert_ok!(Ext::from(0).validate_only(Some(1).into(), CALL, &op_tx, len));
 
 			// like a InsecureFreeNormal
-			let free_transaction = DispatchInfo {
-				weight: Weight::from_parts(0, 0),
+			let free_tx = DispatchInfo {
+				call_weight: Weight::from_parts(0, 0),
+				extension_weight: Weight::zero(),
 				class: DispatchClass::Normal,
 				pays_fee: Pays::Yes,
 			};
-			assert_noop!(
-				ChargeTransactionPayment::<Runtime>::from(0).validate(
-					&1,
-					CALL,
-					&free_transaction,
-					len
-				),
+			assert_eq!(
+				Ext::from(0).validate_only(Some(1).into(), CALL, &free_tx, len).unwrap_err(),
 				TransactionValidityError::Invalid(InvalidTransaction::Payment),
 			);
 		});
 }
 
 #[test]
-fn signed_ext_length_fee_is_also_updated_per_congestion() {
+fn transaction_ext_length_fee_is_also_updated_per_congestion() {
 	ExtBuilder::default()
 		.base_weight(Weight::from_parts(5, 0))
 		.balance_factor(10)
@@ -272,18 +261,15 @@ fn signed_ext_length_fee_is_also_updated_per_congestion() {
 			// all fees should be x1.5
 			NextFeeMultiplier::<Runtime>::put(Multiplier::saturating_from_rational(3, 2));
 			let len = 10;
-
-			assert_ok!(
-				ChargeTransactionPayment::<Runtime>::from(10) // tipped
-					.pre_dispatch(&1, CALL, &info_from_weight(Weight::from_parts(3, 0)), len)
-			);
+			let info = info_from_weight(Weight::from_parts(3, 0));
+			assert_ok!(Ext::from(10).validate_and_prepare(Some(1).into(), CALL, &info, len));
 			assert_eq!(
 				Balances::free_balance(1),
 				100 // original
-            - 10 // tip
-            - 5 // base
-            - 10 // len
-            - (3 * 3 / 2) // adjusted weight
+			- 10 // tip
+			- 5 // base
+			- 10 // len
+			- (3 * 3 / 2) // adjusted weight
 			);
 		})
 }
@@ -293,62 +279,62 @@ fn query_info_and_fee_details_works() {
 	let call = RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 2, value: 69 });
 	let origin = 111111;
 	let extra = ();
-	let xt = TestXt::new(call.clone(), Some((origin, extra)));
+	let xt = UncheckedExtrinsic::new_signed(call.clone(), origin, (), extra);
 	let info = xt.get_dispatch_info();
 	let ext = xt.encode();
 	let len = ext.len() as u32;
 
-	let unsigned_xt = TestXt::<_, ()>::new(call, None);
+	let unsigned_xt = UncheckedExtrinsic::<u64, _, (), ()>::new_bare(call);
 	let unsigned_xt_info = unsigned_xt.get_dispatch_info();
 
 	ExtBuilder::default()
-        .base_weight(Weight::from_parts(5, 0))
-        .weight_fee(2)
-        .build()
-        .execute_with(|| {
-            // all fees should be x1.5
-            NextFeeMultiplier::<Runtime>::put(Multiplier::saturating_from_rational(3, 2));
-
-            assert_eq!(
-                TransactionPayment::query_info(xt.clone(), len),
-                RuntimeDispatchInfo {
-                    weight: info.weight,
-                    class: info.class,
-                    partial_fee: 5 * 2 /* base * weight_fee */
-                    + len as u64  /* len * 1 */
-                    + info.weight.min(BlockWeights::get().max_block).ref_time() as u64 * 2 * 3 / 2 /* weight */
-                },
-            );
-
-            assert_eq!(
-                TransactionPayment::query_info(unsigned_xt.clone(), len),
-                RuntimeDispatchInfo {
-                    weight: unsigned_xt_info.weight,
-                    class: unsigned_xt_info.class,
-                    partial_fee: 0,
-                },
-            );
-
-            assert_eq!(
-                TransactionPayment::query_fee_details(xt, len),
-                FeeDetails {
-                    inclusion_fee: Some(InclusionFee {
-                        base_fee: 5 * 2,
-                        len_fee: len as u64,
-                        adjusted_weight_fee: info
-                            .weight
-                            .min(BlockWeights::get().max_block)
-                            .ref_time() as u64 * 2 * 3 / 2
-                    }),
-                    tip: 0,
-                },
-            );
-
-            assert_eq!(
-                TransactionPayment::query_fee_details(unsigned_xt, len),
-                FeeDetails { inclusion_fee: None, tip: 0 },
-            );
-        });
+		.base_weight(Weight::from_parts(5, 0))
+		.weight_fee(2)
+		.build()
+		.execute_with(|| {
+			// all fees should be x1.5
+			NextFeeMultiplier::<Runtime>::put(Multiplier::saturating_from_rational(3, 2));
+
+			assert_eq!(
+				TransactionPayment::query_info(xt.clone(), len),
+				RuntimeDispatchInfo {
+					weight: info.total_weight(),
+					class: info.class,
+					partial_fee: 5 * 2 /* base * weight_fee */
+					+ len as u64  /* len * 1 */
+					+ info.total_weight().min(BlockWeights::get().max_block).ref_time() as u64 * 2 * 3 / 2 /* weight */
+				},
+			);
+
+			assert_eq!(
+				TransactionPayment::query_info(unsigned_xt.clone(), len),
+				RuntimeDispatchInfo {
+					weight: unsigned_xt_info.call_weight,
+					class: unsigned_xt_info.class,
+					partial_fee: 0,
+				},
+			);
+
+			assert_eq!(
+				TransactionPayment::query_fee_details(xt, len),
+				FeeDetails {
+					inclusion_fee: Some(InclusionFee {
+						base_fee: 5 * 2,
+						len_fee: len as u64,
+						adjusted_weight_fee: info
+							.total_weight()
+							.min(BlockWeights::get().max_block)
+							.ref_time() as u64 * 2 * 3 / 2
+					}),
+					tip: 0,
+				},
+			);
+
+			assert_eq!(
+				TransactionPayment::query_fee_details(unsigned_xt, len),
+				FeeDetails { inclusion_fee: None, tip: 0 },
+			);
+		});
 }
 
 #[test]
@@ -359,39 +345,39 @@ fn query_call_info_and_fee_details_works() {
 	let len = encoded_call.len() as u32;
 
 	ExtBuilder::default()
-        .base_weight(Weight::from_parts(5, 0))
-        .weight_fee(2)
-        .build()
-        .execute_with(|| {
-            // all fees should be x1.5
-            NextFeeMultiplier::<Runtime>::put(Multiplier::saturating_from_rational(3, 2));
-
-            assert_eq!(
-                TransactionPayment::query_call_info(call.clone(), len),
-                RuntimeDispatchInfo {
-                    weight: info.weight,
-                    class: info.class,
-                    partial_fee: 5 * 2 /* base * weight_fee */
-                    + len as u64  /* len * 1 */
-                    + info.weight.min(BlockWeights::get().max_block).ref_time() as u64 * 2 * 3 / 2 /* weight */
-                },
-            );
-
-            assert_eq!(
-                TransactionPayment::query_call_fee_details(call, len),
-                FeeDetails {
-                    inclusion_fee: Some(InclusionFee {
-                        base_fee: 5 * 2,     /* base * weight_fee */
-                        len_fee: len as u64, /* len * 1 */
-                        adjusted_weight_fee: info
-                            .weight
-                            .min(BlockWeights::get().max_block)
-                            .ref_time() as u64 * 2 * 3 / 2  /* weight * weight_fee * multiplier */
-                    }),
-                    tip: 0,
-                },
-            );
-        });
+		.base_weight(Weight::from_parts(5, 0))
+		.weight_fee(2)
+		.build()
+		.execute_with(|| {
+			// all fees should be x1.5
+			NextFeeMultiplier::<Runtime>::put(Multiplier::saturating_from_rational(3, 2));
+
+			assert_eq!(
+				TransactionPayment::query_call_info(call.clone(), len),
+				RuntimeDispatchInfo {
+					weight: info.total_weight(),
+					class: info.class,
+					partial_fee: 5 * 2 /* base * weight_fee */
+					+ len as u64  /* len * 1 */
+					+ info.total_weight().min(BlockWeights::get().max_block).ref_time() as u64 * 2 * 3 / 2 /* weight */
+				},
+			);
+
+			assert_eq!(
+				TransactionPayment::query_call_fee_details(call, len),
+				FeeDetails {
+					inclusion_fee: Some(InclusionFee {
+						base_fee: 5 * 2,     /* base * weight_fee */
+						len_fee: len as u64, /* len * 1 */
+						adjusted_weight_fee: info
+							.total_weight()
+							.min(BlockWeights::get().max_block)
+							.ref_time() as u64 * 2 * 3 / 2  /* weight * weight_fee * multipler */
+					}),
+					tip: 0,
+				},
+			);
+		});
 }
 
 #[test]
@@ -407,14 +393,16 @@ fn compute_fee_works_without_multiplier() {
 
 			// Tip only, no fees works
 			let dispatch_info = DispatchInfo {
-				weight: Weight::from_parts(0, 0),
+				call_weight: Weight::from_parts(0, 0),
+				extension_weight: Weight::zero(),
 				class: DispatchClass::Operational,
 				pays_fee: Pays::No,
 			};
 			assert_eq!(Pallet::<Runtime>::compute_fee(0, &dispatch_info, 10), 10);
 			// No tip, only base fee works
 			let dispatch_info = DispatchInfo {
-				weight: Weight::from_parts(0, 0),
+				call_weight: Weight::from_parts(0, 0),
+				extension_weight: Weight::zero(),
 				class: DispatchClass::Operational,
 				pays_fee: Pays::Yes,
 			};
@@ -425,7 +413,8 @@ fn compute_fee_works_without_multiplier() {
 			assert_eq!(Pallet::<Runtime>::compute_fee(42, &dispatch_info, 0), 520);
 			// Weight fee + base fee works
 			let dispatch_info = DispatchInfo {
-				weight: Weight::from_parts(1000, 0),
+				call_weight: Weight::from_parts(1000, 0),
+				extension_weight: Weight::zero(),
 				class: DispatchClass::Operational,
 				pays_fee: Pays::Yes,
 			};
@@ -445,7 +434,8 @@ fn compute_fee_works_with_multiplier() {
 			NextFeeMultiplier::<Runtime>::put(Multiplier::saturating_from_rational(3, 2));
 			// Base fee is unaffected by multiplier
 			let dispatch_info = DispatchInfo {
-				weight: Weight::from_parts(0, 0),
+				call_weight: Weight::from_parts(0, 0),
+				extension_weight: Weight::zero(),
 				class: DispatchClass::Operational,
 				pays_fee: Pays::Yes,
 			};
@@ -453,7 +443,8 @@ fn compute_fee_works_with_multiplier() {
 
 			// Everything works together :)
 			let dispatch_info = DispatchInfo {
-				weight: Weight::from_parts(123, 0),
+				call_weight: Weight::from_parts(123, 0),
+				extension_weight: Weight::zero(),
 				class: DispatchClass::Operational,
 				pays_fee: Pays::Yes,
 			};
@@ -478,7 +469,8 @@ fn compute_fee_works_with_negative_multiplier() {
 
 			// Base fee is unaffected by multiplier.
 			let dispatch_info = DispatchInfo {
-				weight: Weight::from_parts(0, 0),
+				call_weight: Weight::from_parts(0, 0),
+				extension_weight: Weight::zero(),
 				class: DispatchClass::Operational,
 				pays_fee: Pays::Yes,
 			};
@@ -486,7 +478,8 @@ fn compute_fee_works_with_negative_multiplier() {
 
 			// Everything works together.
 			let dispatch_info = DispatchInfo {
-				weight: Weight::from_parts(123, 0),
+				call_weight: Weight::from_parts(123, 0),
+				extension_weight: Weight::zero(),
 				class: DispatchClass::Operational,
 				pays_fee: Pays::Yes,
 			};
@@ -508,7 +501,8 @@ fn compute_fee_does_not_overflow() {
 		.execute_with(|| {
 			// Overflow is handled
 			let dispatch_info = DispatchInfo {
-				weight: Weight::MAX,
+				call_weight: Weight::MAX,
+				extension_weight: Weight::zero(),
 				class: DispatchClass::Operational,
 				pays_fee: Pays::Yes,
 			};
@@ -528,27 +522,23 @@ fn refund_does_not_recreate_account() {
 		.execute_with(|| {
 			// So events are emitted
 			System::set_block_number(10);
-			let len = 10;
-			let pre = ChargeTransactionPayment::<Runtime>::from(5 /* tipped */)
-				.pre_dispatch(&2, CALL, &info_from_weight(Weight::from_parts(100, 0)), len)
+			let info = info_from_weight(Weight::from_parts(100, 0));
+			Ext::from(5 /* tipped */)
+				.test_run(Some(2).into(), CALL, &info, 10, |origin| {
+					assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5);
+
+					// kill the account between pre and post dispatch
+					assert_ok!(Balances::transfer_allow_death(
+						origin,
+						3,
+						Balances::free_balance(2)
+					));
+					assert_eq!(Balances::free_balance(2), 0);
+
+					Ok(post_info_from_weight(Weight::from_parts(50, 0)))
+				})
+				.unwrap()
 				.unwrap();
-			assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5);
-
-			// kill the account between pre and post dispatch
-			assert_ok!(Balances::transfer_allow_death(
-				Some(2).into(),
-				3,
-				Balances::free_balance(2)
-			));
-			assert_eq!(Balances::free_balance(2), 0);
-
-			assert_ok!(ChargeTransactionPayment::<Runtime>::post_dispatch(
-				Some(pre),
-				&info_from_weight(Weight::from_parts(100, 0)),
-				&post_info_from_weight(Weight::from_parts(50, 0)),
-				len,
-				&Ok(())
-			));
 			assert_eq!(Balances::free_balance(2), 0);
 			// Transfer Event
 			System::assert_has_event(RuntimeEvent::Balances(pallet_balances::Event::Transfer {
@@ -570,20 +560,15 @@ fn actual_weight_higher_than_max_refunds_nothing() {
 		.base_weight(Weight::from_parts(5, 0))
 		.build()
 		.execute_with(|| {
-			let len = 10;
-			let pre = ChargeTransactionPayment::<Runtime>::from(5 /* tipped */)
-				.pre_dispatch(&2, CALL, &info_from_weight(Weight::from_parts(100, 0)), len)
+			let info = info_from_weight(Weight::from_parts(100, 0));
+			Ext::from(5 /* tipped */)
+				.test_run(Some(2).into(), CALL, &info, 10, |_| {
+					assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5);
+					Ok(post_info_from_weight(Weight::from_parts(101, 0)))
+				})
+				.unwrap()
 				.unwrap();
 			assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5);
-
-			assert_ok!(ChargeTransactionPayment::<Runtime>::post_dispatch(
-				Some(pre),
-				&info_from_weight(Weight::from_parts(100, 0)),
-				&post_info_from_weight(Weight::from_parts(101, 0)),
-				len,
-				&Ok(())
-			));
-			assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5);
 		});
 }
 
@@ -596,25 +581,21 @@ fn zero_transfer_on_free_transaction() {
 		.execute_with(|| {
 			// So events are emitted
 			System::set_block_number(10);
-			let len = 10;
-			let dispatch_info = DispatchInfo {
-				weight: Weight::from_parts(100, 0),
+			let info = DispatchInfo {
+				call_weight: Weight::from_parts(100, 0),
+				extension_weight: Weight::zero(),
 				pays_fee: Pays::No,
 				class: DispatchClass::Normal,
 			};
 			let user = 69;
-			let pre = ChargeTransactionPayment::<Runtime>::from(0)
-				.pre_dispatch(&user, CALL, &dispatch_info, len)
+			Ext::from(0)
+				.test_run(Some(user).into(), CALL, &info, 10, |_| {
+					assert_eq!(Balances::total_balance(&user), 0);
+					Ok(default_post_info())
+				})
+				.unwrap()
 				.unwrap();
 			assert_eq!(Balances::total_balance(&user), 0);
-			assert_ok!(ChargeTransactionPayment::<Runtime>::post_dispatch(
-				Some(pre),
-				&dispatch_info,
-				&default_post_info(),
-				len,
-				&Ok(())
-			));
-			assert_eq!(Balances::total_balance(&user), 0);
 			// TransactionFeePaid Event
 			System::assert_has_event(RuntimeEvent::TransactionPayment(
 				pallet_transaction_payment::Event::TransactionFeePaid {
@@ -633,33 +614,33 @@ fn refund_consistent_with_actual_weight() {
 		.base_weight(Weight::from_parts(7, 0))
 		.build()
 		.execute_with(|| {
-			let info = info_from_weight(Weight::from_parts(100, 0));
-			let post_info = post_info_from_weight(Weight::from_parts(33, 0));
+			let mut info = info_from_weight(Weight::from_parts(100, 0));
+			let tip = 5;
+			let ext = Ext::from(tip);
+			let ext_weight = ext.weight(CALL);
+			info.extension_weight = ext_weight;
+			let mut post_info = post_info_from_weight(Weight::from_parts(33, 0));
 			let prev_balance = Balances::free_balance(2);
 			let len = 10;
-			let tip = 5;
 
 			NextFeeMultiplier::<Runtime>::put(Multiplier::saturating_from_rational(5, 4));
 
-			let pre = ChargeTransactionPayment::<Runtime>::from(tip)
-				.pre_dispatch(&2, CALL, &info, len)
+			let actual_post_info = ext
+				.test_run(Some(2).into(), CALL, &info, len, |_| Ok(post_info))
+				.unwrap()
 				.unwrap();
-
-			ChargeTransactionPayment::<Runtime>::post_dispatch(
-				Some(pre),
-				&info,
-				&post_info,
-				len,
-				&Ok(()),
-			)
-			.unwrap();
+			post_info
+				.actual_weight
+				.as_mut()
+				.map(|w| w.saturating_accrue(Ext::from(tip).weight(CALL)));
+			assert_eq!(post_info, actual_post_info);
 
 			let refund_based_fee = prev_balance - Balances::free_balance(2);
 			let actual_fee =
-				Pallet::<Runtime>::compute_actual_fee(len as u32, &info, &post_info, tip);
+				Pallet::<Runtime>::compute_actual_fee(len as u32, &info, &actual_post_info, tip);
 
-			// 33 weight, 10 length, 7 base, 5 tip
-			assert_eq!(actual_fee, 7 + 10 + (33 * 5 / 4) + 5);
+			// 33 call weight, 10 ext weight, 10 length, 7 base, 5 tip
+			assert_eq!(actual_fee, 7 + 10 + ((33 + 10) * 5 / 4) + 5);
 			assert_eq!(refund_based_fee, actual_fee);
 		});
 }
@@ -671,41 +652,35 @@ fn should_alter_operational_priority() {
 
 	ExtBuilder::default().balance_factor(100).build().execute_with(|| {
 		let normal = DispatchInfo {
-			weight: Weight::from_parts(100, 0),
+			call_weight: Weight::from_parts(100, 0),
+			extension_weight: Weight::zero(),
 			class: DispatchClass::Normal,
 			pays_fee: Pays::Yes,
 		};
-		let priority = ChargeTransactionPayment::<Runtime>(tip)
-			.validate(&2, CALL, &normal, len)
-			.unwrap()
-			.priority;
 
+		let ext = Ext::from(tip);
+		let priority = ext.validate_only(Some(2).into(), CALL, &normal, len).unwrap().0.priority;
 		assert_eq!(priority, 60);
 
-		let priority = ChargeTransactionPayment::<Runtime>(2 * tip)
-			.validate(&2, CALL, &normal, len)
-			.unwrap()
-			.priority;
-
+		let ext = Ext::from(2 * tip);
+		let priority = ext.validate_only(Some(2).into(), CALL, &normal, len).unwrap().0.priority;
 		assert_eq!(priority, 110);
 	});
 
 	ExtBuilder::default().balance_factor(100).build().execute_with(|| {
 		let op = DispatchInfo {
-			weight: Weight::from_parts(100, 0),
+			call_weight: Weight::from_parts(100, 0),
+			extension_weight: Weight::zero(),
 			class: DispatchClass::Operational,
 			pays_fee: Pays::Yes,
 		};
-		let priority = ChargeTransactionPayment::<Runtime>(tip)
-			.validate(&2, CALL, &op, len)
-			.unwrap()
-			.priority;
+
+		let ext = Ext::from(tip);
+		let priority = ext.validate_only(Some(2).into(), CALL, &op, len).unwrap().0.priority;
 		assert_eq!(priority, 5810);
 
-		let priority = ChargeTransactionPayment::<Runtime>(2 * tip)
-			.validate(&2, CALL, &op, len)
-			.unwrap()
-			.priority;
+		let ext = Ext::from(2 * tip);
+		let priority = ext.validate_only(Some(2).into(), CALL, &op, len).unwrap().0.priority;
 		assert_eq!(priority, 6110);
 	});
 }
@@ -717,28 +692,25 @@ fn no_tip_has_some_priority() {
 
 	ExtBuilder::default().balance_factor(100).build().execute_with(|| {
 		let normal = DispatchInfo {
-			weight: Weight::from_parts(100, 0),
+			call_weight: Weight::from_parts(100, 0),
+			extension_weight: Weight::zero(),
 			class: DispatchClass::Normal,
 			pays_fee: Pays::Yes,
 		};
-		let priority = ChargeTransactionPayment::<Runtime>(tip)
-			.validate(&2, CALL, &normal, len)
-			.unwrap()
-			.priority;
-
+		let ext = Ext::from(tip);
+		let priority = ext.validate_only(Some(2).into(), CALL, &normal, len).unwrap().0.priority;
 		assert_eq!(priority, 10);
 	});
 
 	ExtBuilder::default().balance_factor(100).build().execute_with(|| {
 		let op = DispatchInfo {
-			weight: Weight::from_parts(100, 0),
+			call_weight: Weight::from_parts(100, 0),
+			extension_weight: Weight::zero(),
 			class: DispatchClass::Operational,
 			pays_fee: Pays::Yes,
 		};
-		let priority = ChargeTransactionPayment::<Runtime>(tip)
-			.validate(&2, CALL, &op, len)
-			.unwrap()
-			.priority;
+		let ext = Ext::from(tip);
+		let priority = ext.validate_only(Some(2).into(), CALL, &op, len).unwrap().0.priority;
 		assert_eq!(priority, 5510);
 	});
 }
@@ -746,34 +718,32 @@ fn no_tip_has_some_priority() {
 #[test]
 fn higher_tip_have_higher_priority() {
 	let get_priorities = |tip: u64| {
-		let mut priority1 = 0;
-		let mut priority2 = 0;
+		let mut pri1 = 0;
+		let mut pri2 = 0;
 		let len = 10;
 		ExtBuilder::default().balance_factor(100).build().execute_with(|| {
 			let normal = DispatchInfo {
-				weight: Weight::from_parts(100, 0),
+				call_weight: Weight::from_parts(100, 0),
+				extension_weight: Weight::zero(),
 				class: DispatchClass::Normal,
 				pays_fee: Pays::Yes,
 			};
-			priority1 = ChargeTransactionPayment::<Runtime>(tip)
-				.validate(&2, CALL, &normal, len)
-				.unwrap()
-				.priority;
+			let ext = Ext::from(tip);
+			pri1 = ext.validate_only(Some(2).into(), CALL, &normal, len).unwrap().0.priority;
 		});
 
 		ExtBuilder::default().balance_factor(100).build().execute_with(|| {
 			let op = DispatchInfo {
-				weight: Weight::from_parts(100, 0),
+				call_weight: Weight::from_parts(100, 0),
+				extension_weight: Weight::zero(),
 				class: DispatchClass::Operational,
 				pays_fee: Pays::Yes,
 			};
-			priority2 = ChargeTransactionPayment::<Runtime>(tip)
-				.validate(&2, CALL, &op, len)
-				.unwrap()
-				.priority;
+			let ext = Ext::from(tip);
+			pri2 = ext.validate_only(Some(2).into(), CALL, &op, len).unwrap().0.priority;
 		});
 
-		(priority1, priority2)
+		(pri1, pri2)
 	};
 
 	let mut prev_priorities = get_priorities(0);
@@ -801,19 +771,11 @@ fn post_info_can_change_pays_fee() {
 
 			NextFeeMultiplier::<Runtime>::put(Multiplier::saturating_from_rational(5, 4));
 
-			let pre = ChargeTransactionPayment::<Runtime>::from(tip)
-				.pre_dispatch(&2, CALL, &info, len)
+			let post_info = ChargeTransactionPayment::<Runtime>::from(tip)
+				.test_run(Some(2).into(), CALL, &info, len, |_| Ok(post_info))
+				.unwrap()
 				.unwrap();
 
-			ChargeTransactionPayment::<Runtime>::post_dispatch(
-				Some(pre),
-				&info,
-				&post_info,
-				len,
-				&Ok(()),
-			)
-			.unwrap();
-
 			let refund_based_fee = prev_balance - Balances::free_balance(2);
 			let actual_fee =
 				Pallet::<Runtime>::compute_actual_fee(len as u32, &info, &post_info, tip);
@@ -843,3 +805,40 @@ fn genesis_default_works() {
 		assert_eq!(NextFeeMultiplier::<Runtime>::get(), Multiplier::saturating_from_integer(1));
 	});
 }
+
+#[test]
+fn no_fee_and_no_weight_for_other_origins() {
+	ExtBuilder::default().build().execute_with(|| {
+		let ext = Ext::from(0);
+
+		let mut info = CALL.get_dispatch_info();
+		info.extension_weight = ext.weight(CALL);
+
+		// Ensure we test the refund.
+		assert!(info.extension_weight != Weight::zero());
+
+		let len = CALL.encoded_size();
+
+		let origin = frame_system::RawOrigin::Root.into();
+		let (pre, origin) = ext.validate_and_prepare(origin, CALL, &info, len).unwrap();
+
+		assert!(origin.as_system_ref().unwrap().is_root());
+
+		let pd_res = Ok(());
+		let mut post_info = frame_support::dispatch::PostDispatchInfo {
+			actual_weight: Some(info.total_weight()),
+			pays_fee: Default::default(),
+		};
+
+		<Ext as TransactionExtension<RuntimeCall>>::post_dispatch(
+			pre,
+			&info,
+			&mut post_info,
+			len,
+			&pd_res,
+		)
+		.unwrap();
+
+		assert_eq!(post_info.actual_weight, Some(info.call_weight));
+	})
+}
diff --git a/substrate/frame/transaction-payment/src/types.rs b/substrate/frame/transaction-payment/src/types.rs
index 67c7311d0ca..d6b4a655744 100644
--- a/substrate/frame/transaction-payment/src/types.rs
+++ b/substrate/frame/transaction-payment/src/types.rs
@@ -111,7 +111,7 @@ pub struct RuntimeDispatchInfo<Balance, Weight = frame_support::weights::Weight>
 	/// The inclusion fee of this dispatch.
 	///
 	/// This does not include a tip or anything else that
-	/// depends on the signature (i.e. depends on a `SignedExtension`).
+	/// depends on the signature (i.e. depends on a `TransactionExtension`).
 	#[cfg_attr(feature = "std", serde(with = "serde_balance"))]
 	pub partial_fee: Balance,
 }
diff --git a/substrate/frame/transaction-payment/src/weights.rs b/substrate/frame/transaction-payment/src/weights.rs
new file mode 100644
index 00000000000..bcffb2eb331
--- /dev/null
+++ b/substrate/frame/transaction-payment/src/weights.rs
@@ -0,0 +1,92 @@
+// This file is part of Substrate.
+
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Autogenerated weights for `pallet_transaction_payment`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-03-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `runner-bn-ce5rx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024`
+
+// Executed Command:
+// ./target/production/substrate-node
+// benchmark
+// pallet
+// --chain=dev
+// --steps=50
+// --repeat=20
+// --pallet=pallet_transaction_payment
+// --no-storage-info
+// --no-median-slopes
+// --no-min-squares
+// --extrinsic=*
+// --wasm-execution=compiled
+// --heap-pages=4096
+// --output=./substrate/frame/transaction-payment/src/weights.rs
+// --header=./substrate/HEADER-APACHE2
+// --template=./substrate/.maintain/frame-weight-template.hbs
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
+use core::marker::PhantomData;
+
+/// Weight functions needed for `pallet_transaction_payment`.
+pub trait WeightInfo {
+	fn charge_transaction_payment() -> Weight;
+}
+
+/// Weights for `pallet_transaction_payment` using the Substrate node and recommended hardware.
+pub struct SubstrateWeight<T>(PhantomData<T>);
+impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
+	/// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0)
+	/// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
+	/// Storage: `Authorship::Author` (r:1 w:0)
+	/// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
+	/// Storage: `System::Digest` (r:1 w:0)
+	/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	fn charge_transaction_payment() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `248`
+		//  Estimated: `1733`
+		// Minimum execution time: 40_506_000 picoseconds.
+		Weight::from_parts(41_647_000, 1733)
+			.saturating_add(T::DbWeight::get().reads(3_u64))
+	}
+}
+
+// For backwards compatibility and tests.
+impl WeightInfo for () {
+	/// Storage: `TransactionPayment::NextFeeMultiplier` (r:1 w:0)
+	/// Proof: `TransactionPayment::NextFeeMultiplier` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
+	/// Storage: `Authorship::Author` (r:1 w:0)
+	/// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
+	/// Storage: `System::Digest` (r:1 w:0)
+	/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
+	fn charge_transaction_payment() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `248`
+		//  Estimated: `1733`
+		// Minimum execution time: 40_506_000 picoseconds.
+		Weight::from_parts(41_647_000, 1733)
+			.saturating_add(RocksDbWeight::get().reads(3_u64))
+	}
+}
diff --git a/substrate/frame/utility/src/lib.rs b/substrate/frame/utility/src/lib.rs
index a4f66298f3f..26c38d1f045 100644
--- a/substrate/frame/utility/src/lib.rs
+++ b/substrate/frame/utility/src/lib.rs
@@ -249,7 +249,7 @@ pub mod pallet {
 				T::WeightInfo::as_derivative()
 					// AccountData for inner call origin accountdata.
 					.saturating_add(T::DbWeight::get().reads_writes(1, 1))
-					.saturating_add(dispatch_info.weight),
+					.saturating_add(dispatch_info.call_weight),
 				dispatch_info.class,
 			)
 		})]
@@ -354,7 +354,7 @@ pub mod pallet {
 			let dispatch_info = call.get_dispatch_info();
 			(
 				T::WeightInfo::dispatch_as()
-					.saturating_add(dispatch_info.weight),
+					.saturating_add(dispatch_info.call_weight),
 				dispatch_info.class,
 			)
 		})]
@@ -466,7 +466,7 @@ pub mod pallet {
 				(Weight::zero(), DispatchClass::Operational),
 				|(total_weight, dispatch_class): (Weight, DispatchClass), di| {
 					(
-						total_weight.saturating_add(di.weight),
+						total_weight.saturating_add(di.call_weight),
 						// If not all are `Operational`, we want to use `DispatchClass::Normal`.
 						if di.class == DispatchClass::Normal { di.class } else { dispatch_class },
 					)
diff --git a/substrate/frame/utility/src/tests.rs b/substrate/frame/utility/src/tests.rs
index 9755efaea41..274a90d77cf 100644
--- a/substrate/frame/utility/src/tests.rs
+++ b/substrate/frame/utility/src/tests.rs
@@ -296,7 +296,7 @@ fn as_derivative_handles_weight_refund() {
 		let info = call.get_dispatch_info();
 		let result = call.dispatch(RuntimeOrigin::signed(1));
 		assert_ok!(result);
-		assert_eq!(extract_actual_weight(&result, &info), info.weight);
+		assert_eq!(extract_actual_weight(&result, &info), info.call_weight);
 
 		// Refund weight when ok
 		let inner_call = call_foobar(false, start_weight, Some(end_weight));
@@ -308,7 +308,7 @@ fn as_derivative_handles_weight_refund() {
 		let result = call.dispatch(RuntimeOrigin::signed(1));
 		assert_ok!(result);
 		// Diff is refunded
-		assert_eq!(extract_actual_weight(&result, &info), info.weight - diff);
+		assert_eq!(extract_actual_weight(&result, &info), info.call_weight - diff);
 
 		// Full weight when err
 		let inner_call = call_foobar(true, start_weight, None);
@@ -323,7 +323,7 @@ fn as_derivative_handles_weight_refund() {
 			DispatchErrorWithPostInfo {
 				post_info: PostDispatchInfo {
 					// No weight is refunded
-					actual_weight: Some(info.weight),
+					actual_weight: Some(info.call_weight),
 					pays_fee: Pays::Yes,
 				},
 				error: DispatchError::Other("The cake is a lie."),
@@ -343,7 +343,7 @@ fn as_derivative_handles_weight_refund() {
 			DispatchErrorWithPostInfo {
 				post_info: PostDispatchInfo {
 					// Diff is refunded
-					actual_weight: Some(info.weight - diff),
+					actual_weight: Some(info.call_weight - diff),
 					pays_fee: Pays::Yes,
 				},
 				error: DispatchError::Other("The cake is a lie."),
@@ -456,14 +456,14 @@ fn batch_weight_calculation_doesnt_overflow() {
 		let big_call = RuntimeCall::RootTesting(RootTestingCall::fill_block {
 			ratio: Perbill::from_percent(50),
 		});
-		assert_eq!(big_call.get_dispatch_info().weight, Weight::MAX / 2);
+		assert_eq!(big_call.get_dispatch_info().call_weight, Weight::MAX / 2);
 
 		// 3 * 50% saturates to 100%
 		let batch_call = RuntimeCall::Utility(crate::Call::batch {
 			calls: vec![big_call.clone(), big_call.clone(), big_call.clone()],
 		});
 
-		assert_eq!(batch_call.get_dispatch_info().weight, Weight::MAX);
+		assert_eq!(batch_call.get_dispatch_info().call_weight, Weight::MAX);
 	});
 }
 
@@ -482,7 +482,7 @@ fn batch_handles_weight_refund() {
 		let info = call.get_dispatch_info();
 		let result = call.dispatch(RuntimeOrigin::signed(1));
 		assert_ok!(result);
-		assert_eq!(extract_actual_weight(&result, &info), info.weight);
+		assert_eq!(extract_actual_weight(&result, &info), info.call_weight);
 
 		// Refund weight when ok
 		let inner_call = call_foobar(false, start_weight, Some(end_weight));
@@ -492,7 +492,7 @@ fn batch_handles_weight_refund() {
 		let result = call.dispatch(RuntimeOrigin::signed(1));
 		assert_ok!(result);
 		// Diff is refunded
-		assert_eq!(extract_actual_weight(&result, &info), info.weight - diff * batch_len);
+		assert_eq!(extract_actual_weight(&result, &info), info.call_weight - diff * batch_len);
 
 		// Full weight when err
 		let good_call = call_foobar(false, start_weight, None);
@@ -506,7 +506,7 @@ fn batch_handles_weight_refund() {
 			utility::Event::BatchInterrupted { index: 1, error: DispatchError::Other("") }.into(),
 		);
 		// No weight is refunded
-		assert_eq!(extract_actual_weight(&result, &info), info.weight);
+		assert_eq!(extract_actual_weight(&result, &info), info.call_weight);
 
 		// Refund weight when err
 		let good_call = call_foobar(false, start_weight, Some(end_weight));
@@ -520,7 +520,7 @@ fn batch_handles_weight_refund() {
 		System::assert_last_event(
 			utility::Event::BatchInterrupted { index: 1, error: DispatchError::Other("") }.into(),
 		);
-		assert_eq!(extract_actual_weight(&result, &info), info.weight - diff * batch_len);
+		assert_eq!(extract_actual_weight(&result, &info), info.call_weight - diff * batch_len);
 
 		// Partial batch completion
 		let good_call = call_foobar(false, start_weight, Some(end_weight));
@@ -571,7 +571,7 @@ fn batch_all_revert() {
 			DispatchErrorWithPostInfo {
 				post_info: PostDispatchInfo {
 					actual_weight: Some(
-						<Test as Config>::WeightInfo::batch_all(2) + info.weight * 2
+						<Test as Config>::WeightInfo::batch_all(2) + info.call_weight * 2
 					),
 					pays_fee: Pays::Yes
 				},
@@ -598,7 +598,7 @@ fn batch_all_handles_weight_refund() {
 		let info = call.get_dispatch_info();
 		let result = call.dispatch(RuntimeOrigin::signed(1));
 		assert_ok!(result);
-		assert_eq!(extract_actual_weight(&result, &info), info.weight);
+		assert_eq!(extract_actual_weight(&result, &info), info.call_weight);
 
 		// Refund weight when ok
 		let inner_call = call_foobar(false, start_weight, Some(end_weight));
@@ -608,7 +608,7 @@ fn batch_all_handles_weight_refund() {
 		let result = call.dispatch(RuntimeOrigin::signed(1));
 		assert_ok!(result);
 		// Diff is refunded
-		assert_eq!(extract_actual_weight(&result, &info), info.weight - diff * batch_len);
+		assert_eq!(extract_actual_weight(&result, &info), info.call_weight - diff * batch_len);
 
 		// Full weight when err
 		let good_call = call_foobar(false, start_weight, None);
@@ -619,7 +619,7 @@ fn batch_all_handles_weight_refund() {
 		let result = call.dispatch(RuntimeOrigin::signed(1));
 		assert_err_ignore_postinfo!(result, "The cake is a lie.");
 		// No weight is refunded
-		assert_eq!(extract_actual_weight(&result, &info), info.weight);
+		assert_eq!(extract_actual_weight(&result, &info), info.call_weight);
 
 		// Refund weight when err
 		let good_call = call_foobar(false, start_weight, Some(end_weight));
@@ -630,7 +630,7 @@ fn batch_all_handles_weight_refund() {
 		let info = call.get_dispatch_info();
 		let result = call.dispatch(RuntimeOrigin::signed(1));
 		assert_err_ignore_postinfo!(result, "The cake is a lie.");
-		assert_eq!(extract_actual_weight(&result, &info), info.weight - diff * batch_len);
+		assert_eq!(extract_actual_weight(&result, &info), info.call_weight - diff * batch_len);
 
 		// Partial batch completion
 		let good_call = call_foobar(false, start_weight, Some(end_weight));
@@ -664,7 +664,9 @@ fn batch_all_does_not_nest() {
 			Utility::batch_all(RuntimeOrigin::signed(1), vec![batch_all.clone()]),
 			DispatchErrorWithPostInfo {
 				post_info: PostDispatchInfo {
-					actual_weight: Some(<Test as Config>::WeightInfo::batch_all(1) + info.weight),
+					actual_weight: Some(
+						<Test as Config>::WeightInfo::batch_all(1) + info.call_weight
+					),
 					pays_fee: Pays::Yes
 				},
 				error: frame_system::Error::<Test>::CallFiltered.into(),
@@ -789,7 +791,7 @@ fn batch_all_doesnt_work_with_inherents() {
 			batch_all.dispatch(RuntimeOrigin::signed(1)),
 			DispatchErrorWithPostInfo {
 				post_info: PostDispatchInfo {
-					actual_weight: Some(info.weight),
+					actual_weight: Some(info.call_weight),
 					pays_fee: Pays::Yes
 				},
 				error: frame_system::Error::<Test>::CallFiltered.into(),
@@ -805,7 +807,7 @@ fn batch_works_with_council_origin() {
 			calls: vec![RuntimeCall::Democracy(mock_democracy::Call::external_propose_majority {})],
 		});
 		let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32);
-		let proposal_weight = proposal.get_dispatch_info().weight;
+		let proposal_weight = proposal.get_dispatch_info().call_weight;
 		let hash = BlakeTwo256::hash_of(&proposal);
 
 		assert_ok!(Council::propose(
@@ -842,7 +844,7 @@ fn force_batch_works_with_council_origin() {
 			calls: vec![RuntimeCall::Democracy(mock_democracy::Call::external_propose_majority {})],
 		});
 		let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32);
-		let proposal_weight = proposal.get_dispatch_info().weight;
+		let proposal_weight = proposal.get_dispatch_info().call_weight;
 		let hash = BlakeTwo256::hash_of(&proposal);
 
 		assert_ok!(Council::propose(
@@ -892,7 +894,7 @@ fn with_weight_works() {
 			}));
 		// Weight before is max.
 		assert_eq!(
-			upgrade_code_call.get_dispatch_info().weight,
+			upgrade_code_call.get_dispatch_info().call_weight,
 			<Test as frame_system::Config>::SystemWeightInfo::set_code()
 		);
 		assert_eq!(
@@ -905,7 +907,7 @@ fn with_weight_works() {
 			weight: Weight::from_parts(123, 456),
 		};
 		// Weight after is set by Root.
-		assert_eq!(with_weight_call.get_dispatch_info().weight, Weight::from_parts(123, 456));
+		assert_eq!(with_weight_call.get_dispatch_info().call_weight, Weight::from_parts(123, 456));
 		assert_eq!(
 			with_weight_call.get_dispatch_info().class,
 			frame_support::dispatch::DispatchClass::Operational
diff --git a/substrate/frame/verify-signature/Cargo.toml b/substrate/frame/verify-signature/Cargo.toml
new file mode 100644
index 00000000000..3c5fd5e6515
--- /dev/null
+++ b/substrate/frame/verify-signature/Cargo.toml
@@ -0,0 +1,70 @@
+[package]
+name = "pallet-verify-signature"
+version = "1.0.0"
+authors.workspace = true
+edition.workspace = true
+license = "Apache-2.0"
+homepage.workspace = true
+repository.workspace = true
+description = "FRAME verify signature pallet"
+readme = "README.md"
+
+[lints]
+workspace = true
+
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[dependencies]
+codec = { workspace = true }
+scale-info = { features = ["derive"], workspace = true }
+frame-benchmarking = { optional = true, workspace = true }
+frame-support = { workspace = true }
+frame-system = { workspace = true }
+sp-core = { workspace = true }
+sp-io = { workspace = true }
+sp-runtime = { workspace = true }
+sp-weights = { features = ["serde"], workspace = true }
+
+[dev-dependencies]
+pallet-balances = { workspace = true, default-features = true }
+pallet-root-testing = { workspace = true, default-features = true }
+pallet-collective = { workspace = true, default-features = true }
+pallet-timestamp = { workspace = true, default-features = true }
+sp-core = { workspace = true, default-features = true }
+
+[features]
+default = ["std"]
+std = [
+	"codec/std",
+	"frame-benchmarking?/std",
+	"frame-support/std",
+	"frame-system/std",
+	"pallet-balances/std",
+	"pallet-collective/std",
+	"pallet-root-testing/std",
+	"pallet-timestamp/std",
+	"scale-info/std",
+	"sp-core/std",
+	"sp-io/std",
+	"sp-runtime/std",
+	"sp-weights/std",
+]
+runtime-benchmarks = [
+	"frame-benchmarking/runtime-benchmarks",
+	"frame-support/runtime-benchmarks",
+	"frame-system/runtime-benchmarks",
+	"pallet-balances/runtime-benchmarks",
+	"pallet-collective/runtime-benchmarks",
+	"pallet-timestamp/runtime-benchmarks",
+	"sp-runtime/runtime-benchmarks",
+]
+try-runtime = [
+	"frame-support/try-runtime",
+	"frame-system/try-runtime",
+	"pallet-balances/try-runtime",
+	"pallet-collective/try-runtime",
+	"pallet-root-testing/try-runtime",
+	"pallet-timestamp/try-runtime",
+	"sp-runtime/try-runtime",
+]
diff --git a/substrate/frame/verify-signature/README.md b/substrate/frame/verify-signature/README.md
new file mode 100644
index 00000000000..7748315c61c
--- /dev/null
+++ b/substrate/frame/verify-signature/README.md
@@ -0,0 +1,19 @@
+# Verify Signature Module
+A module that provides a `TransactionExtension` that validates a signature against a payload and
+authorizes the origin.
+
+## Overview
+
+This module serves two purposes:
+- `VerifySignature`: A `TransactionExtension` that checks the provided signature against a payload
+  constructed through hashing the inherited implication with `blake2b_256`. If the signature is
+  valid, then the extension authorizes the origin as signed. The extension can be disabled, or
+  passthrough, allowing users to use other extensions to authorize different origins other than the
+  traditionally signed origin.
+- Benchmarking: The extension is bound within a pallet to leverage the benchmarking functionality in
+  FRAME. The `Signature` and `Signer` types are specified in the pallet configuration and a
+  benchmark helper trait is used to create a signature which is then validated in the benchmark.
+
+[`Config`]: ./trait.Config.html
+
+License: Apache-2.0
diff --git a/substrate/frame/verify-signature/src/benchmarking.rs b/substrate/frame/verify-signature/src/benchmarking.rs
new file mode 100644
index 00000000000..2b592a4023e
--- /dev/null
+++ b/substrate/frame/verify-signature/src/benchmarking.rs
@@ -0,0 +1,65 @@
+// This file is part of Substrate.
+
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Benchmarks for Verify Signature Pallet
+
+#![cfg(feature = "runtime-benchmarks")]
+
+extern crate alloc;
+
+use super::*;
+
+#[allow(unused)]
+use crate::{extension::VerifySignature, Config, Pallet as VerifySignaturePallet};
+use alloc::vec;
+use frame_benchmarking::{v2::*, BenchmarkError};
+use frame_support::dispatch::{DispatchInfo, GetDispatchInfo};
+use frame_system::{Call as SystemCall, RawOrigin};
+use sp_io::hashing::blake2_256;
+use sp_runtime::traits::{AsTransactionAuthorizedOrigin, Dispatchable, TransactionExtension};
+
+pub trait BenchmarkHelper<Signature, Signer> {
+	fn create_signature(entropy: &[u8], msg: &[u8]) -> (Signature, Signer);
+}
+
+#[benchmarks(where
+	T: Config + Send + Sync,
+	T::RuntimeCall: Dispatchable<Info = DispatchInfo> + GetDispatchInfo,
+	T::RuntimeOrigin: AsTransactionAuthorizedOrigin,
+)]
+mod benchmarks {
+	use super::*;
+
+	#[benchmark]
+	fn verify_signature() -> Result<(), BenchmarkError> {
+		let entropy = [42u8; 256];
+		let call: T::RuntimeCall = SystemCall::remark { remark: vec![] }.into();
+		let info = call.get_dispatch_info();
+		let msg = call.using_encoded(blake2_256).to_vec();
+		let (signature, signer) = T::BenchmarkHelper::create_signature(&entropy, &msg[..]);
+		let ext = VerifySignature::<T>::new_with_signature(signature, signer);
+
+		#[block]
+		{
+			assert!(ext.validate(RawOrigin::None.into(), &call, &info, 0, (), &call).is_ok());
+		}
+
+		Ok(())
+	}
+
+	impl_benchmark_test_suite!(Pallet, crate::tests::new_test_ext(), crate::tests::Test);
+}
diff --git a/substrate/frame/verify-signature/src/extension.rs b/substrate/frame/verify-signature/src/extension.rs
new file mode 100644
index 00000000000..4490a0a600b
--- /dev/null
+++ b/substrate/frame/verify-signature/src/extension.rs
@@ -0,0 +1,157 @@
+// This file is part of Substrate.
+
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Transaction extension which validates a signature against a payload constructed from a call and
+//! the rest of the transaction extension pipeline.
+
+use crate::{Config, WeightInfo};
+use codec::{Decode, Encode};
+use frame_support::traits::OriginTrait;
+use scale_info::TypeInfo;
+use sp_io::hashing::blake2_256;
+use sp_runtime::{
+	impl_tx_ext_default,
+	traits::{
+		transaction_extension::TransactionExtension, AsTransactionAuthorizedOrigin, DispatchInfoOf,
+		Dispatchable, Verify,
+	},
+	transaction_validity::{InvalidTransaction, TransactionValidityError, ValidTransaction},
+};
+use sp_weights::Weight;
+
+/// Extension that, if enabled, validates a signature type against the payload constructed from the
+/// call and the rest of the transaction extension pipeline. This extension provides the
+/// functionality that traditionally signed transactions had with the implicit signature checking
+/// implemented in [`Checkable`](sp_runtime::traits::Checkable). It is meant to be placed ahead of
+/// any other extensions that do authorization work in the [`TransactionExtension`] pipeline.
+#[derive(Encode, Decode, Clone, Eq, PartialEq, TypeInfo)]
+#[scale_info(skip_type_params(T))]
+pub enum VerifySignature<T>
+where
+	T: Config + Send + Sync,
+{
+	/// The extension will verify the signature and, if successful, authorize a traditionally
+	/// signed transaction.
+	Signed {
+		/// The signature provided by the transaction submitter.
+		signature: T::Signature,
+		/// The account that signed the payload.
+		account: T::AccountId,
+	},
+	/// The extension is disabled and will be passthrough.
+	Disabled,
+}
+
+impl<T> core::fmt::Debug for VerifySignature<T>
+where
+	T: Config + Send + Sync,
+{
+	#[cfg(feature = "std")]
+	fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
+		write!(f, "VerifySignature")
+	}
+
+	#[cfg(not(feature = "std"))]
+	fn fmt(&self, _: &mut core::fmt::Formatter) -> core::fmt::Result {
+		Ok(())
+	}
+}
+
+impl<T> VerifySignature<T>
+where
+	T: Config + Send + Sync,
+{
+	/// Create a new extension instance that will validate the provided signature.
+	pub fn new_with_signature(signature: T::Signature, account: T::AccountId) -> Self {
+		Self::Signed { signature, account }
+	}
+
+	/// Create a new passthrough extension instance.
+	pub fn new_disabled() -> Self {
+		Self::Disabled
+	}
+}
+
+impl<T> TransactionExtension<T::RuntimeCall> for VerifySignature<T>
+where
+	T: Config + Send + Sync,
+	<T::RuntimeCall as Dispatchable>::RuntimeOrigin: AsTransactionAuthorizedOrigin,
+{
+	const IDENTIFIER: &'static str = "VerifyMultiSignature";
+	type Implicit = ();
+	type Val = ();
+	type Pre = ();
+
+	fn weight(&self, _call: &T::RuntimeCall) -> Weight {
+		match &self {
+			// The benchmarked weight of the payload construction and signature checking.
+			Self::Signed { .. } => T::WeightInfo::verify_signature(),
+			// When the extension is passthrough, it consumes no weight.
+			Self::Disabled => Weight::zero(),
+		}
+	}
+
+	fn validate(
+		&self,
+		mut origin: <T::RuntimeCall as Dispatchable>::RuntimeOrigin,
+		_call: &T::RuntimeCall,
+		_info: &DispatchInfoOf<T::RuntimeCall>,
+		_len: usize,
+		_: (),
+		inherited_implication: &impl Encode,
+	) -> Result<
+		(ValidTransaction, Self::Val, <T::RuntimeCall as Dispatchable>::RuntimeOrigin),
+		TransactionValidityError,
+	> {
+		// If the extension is disabled, return early.
+		let (signature, account) = match &self {
+			Self::Signed { signature, account } => (signature, account),
+			Self::Disabled => return Ok((Default::default(), (), origin)),
+		};
+
+		// This extension must receive an unauthorized origin as it is meant to headline the
+		// authorization extension pipeline. Any extensions that precede this one must not authorize
+		// any origin and serve some other functional purpose.
+		if origin.is_transaction_authorized() {
+			return Err(InvalidTransaction::BadSigner.into());
+		}
+
+		// Construct the payload that the signature will be validated against. The inherited
+		// implication contains the encoded bytes of the call and all of the extension data of the
+		// extensions that follow in the `TransactionExtension` pipeline.
+		//
+		// In other words:
+		// - extensions that precede this extension are ignored in terms of signature validation;
+		// - extensions that follow this extension are included in the payload to be signed (as if
+		//   they were the entire `SignedExtension` pipeline in the traditional signed transaction
+		//   model).
+		//
+		// The encoded bytes of the payload are then hashed using `blake2_256`.
+		let msg = inherited_implication.using_encoded(blake2_256);
+
+		// The extension was enabled, so the signature must match.
+		if !signature.verify(&msg[..], account) {
+			Err(InvalidTransaction::BadProof)?
+		}
+
+		// Return the signer as the transaction origin.
+		origin.set_caller_from_signed(account.clone());
+		Ok((ValidTransaction::default(), (), origin))
+	}
+
+	impl_tx_ext_default!(T::RuntimeCall; prepare);
+}
diff --git a/substrate/frame/verify-signature/src/lib.rs b/substrate/frame/verify-signature/src/lib.rs
new file mode 100644
index 00000000000..96d83dbef9f
--- /dev/null
+++ b/substrate/frame/verify-signature/src/lib.rs
@@ -0,0 +1,68 @@
+// This file is part of Substrate.
+
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Transaction extension which validates a signature against a payload constructed from a call and
+//! the rest of the transaction extension pipeline.
+
+// Ensure we're `no_std` when compiling for Wasm.
+#![cfg_attr(not(feature = "std"), no_std)]
+
+#[cfg(feature = "runtime-benchmarks")]
+mod benchmarking;
+pub mod extension;
+#[cfg(test)]
+mod tests;
+pub mod weights;
+
+extern crate alloc;
+
+#[cfg(feature = "runtime-benchmarks")]
+pub use benchmarking::BenchmarkHelper;
+use codec::{Decode, Encode};
+pub use extension::VerifySignature;
+use frame_support::Parameter;
+pub use weights::WeightInfo;
+
+pub use pallet::*;
+
+#[frame_support::pallet]
+pub mod pallet {
+	use super::*;
+	use sp_runtime::traits::{IdentifyAccount, Verify};
+
+	#[pallet::pallet]
+	pub struct Pallet<T>(_);
+
+	/// Configuration trait.
+	#[pallet::config]
+	pub trait Config: frame_system::Config {
+		/// Signature type that the extension of this pallet can verify.
+		type Signature: Verify<Signer = Self::AccountIdentifier>
+			+ Parameter
+			+ Encode
+			+ Decode
+			+ Send
+			+ Sync;
+		/// The account identifier used by this pallet's signature type.
+		type AccountIdentifier: IdentifyAccount<AccountId = Self::AccountId>;
+		/// Weight information for extrinsics in this pallet.
+		type WeightInfo: WeightInfo;
+		/// Helper to create a signature to be benchmarked.
+		#[cfg(feature = "runtime-benchmarks")]
+		type BenchmarkHelper: BenchmarkHelper<Self::Signature, Self::AccountId>;
+	}
+}
diff --git a/substrate/frame/verify-signature/src/tests.rs b/substrate/frame/verify-signature/src/tests.rs
new file mode 100644
index 00000000000..3e4c8db12fe
--- /dev/null
+++ b/substrate/frame/verify-signature/src/tests.rs
@@ -0,0 +1,132 @@
+// This file is part of Substrate.
+
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Tests for Utility Pallet
+
+#![cfg(test)]
+
+use super::*;
+
+use extension::VerifySignature;
+use frame_support::{
+	derive_impl,
+	dispatch::GetDispatchInfo,
+	pallet_prelude::{InvalidTransaction, TransactionValidityError},
+	traits::OriginTrait,
+};
+use frame_system::Call as SystemCall;
+use sp_io::hashing::blake2_256;
+use sp_runtime::{
+	testing::{TestSignature, UintAuthorityId},
+	traits::DispatchTransaction,
+};
+
+type Block = frame_system::mocking::MockBlock<Test>;
+
+frame_support::construct_runtime!(
+	pub enum Test
+	{
+		System: frame_system,
+		VerifySignaturePallet: crate,
+	}
+);
+
+#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
+impl frame_system::Config for Test {
+	type Block = Block;
+}
+
+#[cfg(feature = "runtime-benchmarks")]
+pub struct BenchmarkHelper;
+#[cfg(feature = "runtime-benchmarks")]
+impl crate::BenchmarkHelper<TestSignature, u64> for BenchmarkHelper {
+	fn create_signature(_entropy: &[u8], msg: &[u8]) -> (TestSignature, u64) {
+		(TestSignature(0, msg.to_vec()), 0)
+	}
+}
+
+impl crate::Config for Test {
+	type Signature = TestSignature;
+	type AccountIdentifier = UintAuthorityId;
+	type WeightInfo = ();
+	#[cfg(feature = "runtime-benchmarks")]
+	type BenchmarkHelper = BenchmarkHelper;
+}
+
+#[cfg(feature = "runtime-benchmarks")]
+pub fn new_test_ext() -> sp_io::TestExternalities {
+	use sp_runtime::BuildStorage;
+	let t = frame_system::GenesisConfig::<Test>::default().build_storage().unwrap();
+	let mut ext = sp_io::TestExternalities::new(t);
+	ext.execute_with(|| System::set_block_number(1));
+	ext
+}
+
+#[test]
+fn verification_works() {
+	let who = 0;
+	let call: RuntimeCall = SystemCall::remark { remark: vec![] }.into();
+	let sig = TestSignature(0, call.using_encoded(blake2_256).to_vec());
+	let info = call.get_dispatch_info();
+
+	let (_, _, origin) = VerifySignature::<Test>::new_with_signature(sig, who)
+		.validate_only(None.into(), &call, &info, 0)
+		.unwrap();
+	assert_eq!(origin.as_signer().unwrap(), &who)
+}
+
+#[test]
+fn bad_signature() {
+	let who = 0;
+	let call: RuntimeCall = SystemCall::remark { remark: vec![] }.into();
+	let sig = TestSignature(0, b"bogus message".to_vec());
+	let info = call.get_dispatch_info();
+
+	assert_eq!(
+		VerifySignature::<Test>::new_with_signature(sig, who)
+			.validate_only(None.into(), &call, &info, 0)
+			.unwrap_err(),
+		TransactionValidityError::Invalid(InvalidTransaction::BadProof)
+	);
+}
+
+#[test]
+fn bad_starting_origin() {
+	let who = 0;
+	let call: RuntimeCall = SystemCall::remark { remark: vec![] }.into();
+	let sig = TestSignature(0, b"bogus message".to_vec());
+	let info = call.get_dispatch_info();
+
+	assert_eq!(
+		VerifySignature::<Test>::new_with_signature(sig, who)
+			.validate_only(Some(42).into(), &call, &info, 0)
+			.unwrap_err(),
+		TransactionValidityError::Invalid(InvalidTransaction::BadSigner)
+	);
+}
+
+#[test]
+fn disabled_extension_works() {
+	let who = 42;
+	let call: RuntimeCall = SystemCall::remark { remark: vec![] }.into();
+	let info = call.get_dispatch_info();
+
+	let (_, _, origin) = VerifySignature::<Test>::new_disabled()
+		.validate_only(Some(who).into(), &call, &info, 0)
+		.unwrap();
+	assert_eq!(origin.as_signer().unwrap(), &who)
+}
diff --git a/substrate/frame/verify-signature/src/weights.rs b/substrate/frame/verify-signature/src/weights.rs
new file mode 100644
index 00000000000..2c1f0f79542
--- /dev/null
+++ b/substrate/frame/verify-signature/src/weights.rs
@@ -0,0 +1,75 @@
+// This file is part of Substrate.
+
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Autogenerated weights for `pallet_verify_signature`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-09-24, STEPS: `2`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `gleipnir`, CPU: `AMD Ryzen 9 7900X 12-Core Processor`
+//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024`
+
+// Executed Command:
+// ./target/debug/substrate-node
+// benchmark
+// pallet
+// --steps=2
+// --repeat=2
+// --extrinsic=*
+// --wasm-execution=compiled
+// --heap-pages=4096
+// --pallet=pallet-verify-signature
+// --chain=dev
+// --output=./substrate/frame/verify-signature/src/weights.rs
+// --header=./substrate/HEADER-APACHE2
+// --template=./substrate/.maintain/frame-weight-template.hbs
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+#![allow(missing_docs)]
+
+use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
+use core::marker::PhantomData;
+
+/// Weight functions needed for `pallet_verify_signature`.
+pub trait WeightInfo {
+	fn verify_signature() -> Weight;
+}
+
+/// Weights for `pallet_verify_signature` using the Substrate node and recommended hardware.
+pub struct SubstrateWeight<T>(PhantomData<T>);
+impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
+	fn verify_signature() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 48_953_000 picoseconds.
+		Weight::from_parts(49_254_000, 0)
+	}
+}
+
+// For backwards compatibility and tests.
+impl WeightInfo for () {
+	fn verify_signature() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `0`
+		//  Estimated: `0`
+		// Minimum execution time: 48_953_000 picoseconds.
+		Weight::from_parts(49_254_000, 0)
+	}
+}
diff --git a/substrate/frame/whitelist/src/benchmarking.rs b/substrate/frame/whitelist/src/benchmarking.rs
index cbe6ee4becd..0d7605d9752 100644
--- a/substrate/frame/whitelist/src/benchmarking.rs
+++ b/substrate/frame/whitelist/src/benchmarking.rs
@@ -75,7 +75,7 @@ mod benchmarks {
 			.map_err(|_| BenchmarkError::Weightless)?;
 		let remark = alloc::vec![1u8; n as usize];
 		let call: <T as Config>::RuntimeCall = frame_system::Call::remark { remark }.into();
-		let call_weight = call.get_dispatch_info().weight;
+		let call_weight = call.get_dispatch_info().call_weight;
 		let encoded_call = call.encode();
 		let call_encoded_len = encoded_call.len() as u32;
 		let call_hash = T::Hashing::hash_of(&call);
diff --git a/substrate/frame/whitelist/src/lib.rs b/substrate/frame/whitelist/src/lib.rs
index de16c2c2da8..28887e0ca4a 100644
--- a/substrate/frame/whitelist/src/lib.rs
+++ b/substrate/frame/whitelist/src/lib.rs
@@ -178,7 +178,7 @@ pub mod pallet {
 			.map_err(|_| Error::<T>::UndecodableCall)?;
 
 			ensure!(
-				call.get_dispatch_info().weight.all_lte(call_weight_witness),
+				call.get_dispatch_info().call_weight.all_lte(call_weight_witness),
 				Error::<T>::InvalidCallWeightWitness
 			);
 
@@ -191,7 +191,7 @@ pub mod pallet {
 
 		#[pallet::call_index(3)]
 		#[pallet::weight({
-			let call_weight = call.get_dispatch_info().weight;
+			let call_weight = call.get_dispatch_info().call_weight;
 			let call_len = call.encoded_size() as u32;
 
 			T::WeightInfo::dispatch_whitelisted_call_with_preimage(call_len)
diff --git a/substrate/frame/whitelist/src/tests.rs b/substrate/frame/whitelist/src/tests.rs
index 3a60adbcfbe..b53cc93b195 100644
--- a/substrate/frame/whitelist/src/tests.rs
+++ b/substrate/frame/whitelist/src/tests.rs
@@ -73,7 +73,7 @@ fn test_whitelist_call_and_remove() {
 fn test_whitelist_call_and_execute() {
 	new_test_ext().execute_with(|| {
 		let call = RuntimeCall::System(frame_system::Call::remark_with_event { remark: vec![1] });
-		let call_weight = call.get_dispatch_info().weight;
+		let call_weight = call.get_dispatch_info().call_weight;
 		let encoded_call = call.encode();
 		let call_encoded_len = encoded_call.len() as u32;
 		let call_hash = <Test as frame_system::Config>::Hashing::hash(&encoded_call[..]);
@@ -153,7 +153,7 @@ fn test_whitelist_call_and_execute_failing_call() {
 			call_encoded_len: Default::default(),
 			call_weight_witness: Weight::zero(),
 		});
-		let call_weight = call.get_dispatch_info().weight;
+		let call_weight = call.get_dispatch_info().call_weight;
 		let encoded_call = call.encode();
 		let call_encoded_len = encoded_call.len() as u32;
 		let call_hash = <Test as frame_system::Config>::Hashing::hash(&encoded_call[..]);
@@ -200,7 +200,7 @@ fn test_whitelist_call_and_execute_without_note_preimage() {
 fn test_whitelist_call_and_execute_decode_consumes_all() {
 	new_test_ext().execute_with(|| {
 		let call = RuntimeCall::System(frame_system::Call::remark_with_event { remark: vec![1] });
-		let call_weight = call.get_dispatch_info().weight;
+		let call_weight = call.get_dispatch_info().call_weight;
 		let mut call = call.encode();
 		// Appending something does not make the encoded call invalid.
 		// This tests that the decode function consumes all data.
diff --git a/substrate/primitives/consensus/pow/Cargo.toml b/substrate/primitives/consensus/pow/Cargo.toml
index 8731015f7da..171137a1a04 100644
--- a/substrate/primitives/consensus/pow/Cargo.toml
+++ b/substrate/primitives/consensus/pow/Cargo.toml
@@ -23,9 +23,4 @@ sp-runtime = { workspace = true }
 
 [features]
 default = ["std"]
-std = [
-	"codec/std",
-	"sp-api/std",
-	"sp-core/std",
-	"sp-runtime/std",
-]
+std = ["codec/std", "sp-api/std", "sp-core/std", "sp-runtime/std"]
diff --git a/substrate/primitives/consensus/slots/Cargo.toml b/substrate/primitives/consensus/slots/Cargo.toml
index 43f8c5514f7..2f993d3167a 100644
--- a/substrate/primitives/consensus/slots/Cargo.toml
+++ b/substrate/primitives/consensus/slots/Cargo.toml
@@ -23,12 +23,7 @@ sp-timestamp = { workspace = true }
 
 [features]
 default = ["std"]
-std = [
-	"codec/std",
-	"scale-info/std",
-	"serde/std",
-	"sp-timestamp/std",
-]
+std = ["codec/std", "scale-info/std", "serde/std", "sp-timestamp/std"]
 
 # Serde support without relying on std features.
 serde = ["dep:serde", "scale-info/serde"]
diff --git a/substrate/primitives/inherents/src/lib.rs b/substrate/primitives/inherents/src/lib.rs
index 80787669856..0ddc12dde06 100644
--- a/substrate/primitives/inherents/src/lib.rs
+++ b/substrate/primitives/inherents/src/lib.rs
@@ -98,10 +98,10 @@
 //! and production.
 //!
 //! ```
-//! # use sp_runtime::testing::ExtrinsicWrapper;
+//! # use sp_runtime::testing::{MockCallU64, TestXt};
 //! # use sp_inherents::{InherentIdentifier, InherentData};
 //! # use futures::FutureExt;
-//! # type Block = sp_runtime::testing::Block<ExtrinsicWrapper<()>>;
+//! # type Block = sp_runtime::testing::Block<TestXt<MockCallU64, ()>>;
 //! # const INHERENT_IDENTIFIER: InherentIdentifier = *b"testinh0";
 //! # struct InherentDataProvider;
 //! # #[async_trait::async_trait]
diff --git a/substrate/primitives/metadata-ir/src/lib.rs b/substrate/primitives/metadata-ir/src/lib.rs
index 18b20f2ccaa..4bd13b935af 100644
--- a/substrate/primitives/metadata-ir/src/lib.rs
+++ b/substrate/primitives/metadata-ir/src/lib.rs
@@ -86,7 +86,7 @@ mod test {
 				call_ty: meta_type::<()>(),
 				signature_ty: meta_type::<()>(),
 				extra_ty: meta_type::<()>(),
-				signed_extensions: vec![],
+				extensions: vec![],
 			},
 			ty: meta_type::<()>(),
 			apis: vec![],
diff --git a/substrate/primitives/metadata-ir/src/types.rs b/substrate/primitives/metadata-ir/src/types.rs
index da4f5d7f371..199b692fbd8 100644
--- a/substrate/primitives/metadata-ir/src/types.rs
+++ b/substrate/primitives/metadata-ir/src/types.rs
@@ -178,10 +178,11 @@ pub struct ExtrinsicMetadataIR<T: Form = MetaForm> {
 	pub call_ty: T::Type,
 	/// The type of the extrinsic's signature.
 	pub signature_ty: T::Type,
-	/// The type of the outermost Extra enum.
+	/// The type of the outermost Extra/Extensions enum.
+	// TODO: metadata-v16: remove this, the `implicit` type can be found in `extensions::implicit`.
 	pub extra_ty: T::Type,
-	/// The signed extensions in the order they appear in the extrinsic.
-	pub signed_extensions: Vec<SignedExtensionMetadataIR<T>>,
+	/// The transaction extensions in the order they appear in the extrinsic.
+	pub extensions: Vec<TransactionExtensionMetadataIR<T>>,
 }
 
 impl IntoPortable for ExtrinsicMetadataIR {
@@ -195,7 +196,7 @@ impl IntoPortable for ExtrinsicMetadataIR {
 			call_ty: registry.register_type(&self.call_ty),
 			signature_ty: registry.register_type(&self.signature_ty),
 			extra_ty: registry.register_type(&self.extra_ty),
-			signed_extensions: registry.map_into_portable(self.signed_extensions),
+			extensions: registry.map_into_portable(self.extensions),
 		}
 	}
 }
@@ -225,23 +226,23 @@ impl IntoPortable for PalletAssociatedTypeMetadataIR {
 
 /// Metadata of an extrinsic's signed extension.
 #[derive(Clone, PartialEq, Eq, Encode, Debug)]
-pub struct SignedExtensionMetadataIR<T: Form = MetaForm> {
+pub struct TransactionExtensionMetadataIR<T: Form = MetaForm> {
 	/// The unique signed extension identifier, which may be different from the type name.
 	pub identifier: T::String,
 	/// The type of the signed extension, with the data to be included in the extrinsic.
 	pub ty: T::Type,
-	/// The type of the additional signed data, with the data to be included in the signed payload
-	pub additional_signed: T::Type,
+	/// The type of the implicit data, with the data to be included in the signed payload.
+	pub implicit: T::Type,
 }
 
-impl IntoPortable for SignedExtensionMetadataIR {
-	type Output = SignedExtensionMetadataIR<PortableForm>;
+impl IntoPortable for TransactionExtensionMetadataIR {
+	type Output = TransactionExtensionMetadataIR<PortableForm>;
 
 	fn into_portable(self, registry: &mut Registry) -> Self::Output {
-		SignedExtensionMetadataIR {
+		TransactionExtensionMetadataIR {
 			identifier: self.identifier.into_portable(registry),
 			ty: registry.register_type(&self.ty),
-			additional_signed: registry.register_type(&self.additional_signed),
+			implicit: registry.register_type(&self.implicit),
 		}
 	}
 }
diff --git a/substrate/primitives/metadata-ir/src/v14.rs b/substrate/primitives/metadata-ir/src/v14.rs
index e1b7a24f765..70e84532add 100644
--- a/substrate/primitives/metadata-ir/src/v14.rs
+++ b/substrate/primitives/metadata-ir/src/v14.rs
@@ -20,8 +20,8 @@
 use super::types::{
 	ExtrinsicMetadataIR, MetadataIR, PalletCallMetadataIR, PalletConstantMetadataIR,
 	PalletErrorMetadataIR, PalletEventMetadataIR, PalletMetadataIR, PalletStorageMetadataIR,
-	SignedExtensionMetadataIR, StorageEntryMetadataIR, StorageEntryModifierIR, StorageEntryTypeIR,
-	StorageHasherIR,
+	StorageEntryMetadataIR, StorageEntryModifierIR, StorageEntryTypeIR, StorageHasherIR,
+	TransactionExtensionMetadataIR,
 };
 
 use frame_metadata::v14::{
@@ -137,12 +137,12 @@ impl From<PalletErrorMetadataIR> for PalletErrorMetadata {
 	}
 }
 
-impl From<SignedExtensionMetadataIR> for SignedExtensionMetadata {
-	fn from(ir: SignedExtensionMetadataIR) -> Self {
+impl From<TransactionExtensionMetadataIR> for SignedExtensionMetadata {
+	fn from(ir: TransactionExtensionMetadataIR) -> Self {
 		SignedExtensionMetadata {
 			identifier: ir.identifier,
 			ty: ir.ty,
-			additional_signed: ir.additional_signed,
+			additional_signed: ir.implicit,
 		}
 	}
 }
@@ -152,7 +152,7 @@ impl From<ExtrinsicMetadataIR> for ExtrinsicMetadata {
 		ExtrinsicMetadata {
 			ty: ir.ty,
 			version: ir.version,
-			signed_extensions: ir.signed_extensions.into_iter().map(Into::into).collect(),
+			signed_extensions: ir.extensions.into_iter().map(Into::into).collect(),
 		}
 	}
 }
diff --git a/substrate/primitives/metadata-ir/src/v15.rs b/substrate/primitives/metadata-ir/src/v15.rs
index a942eb73223..4b3b6106d27 100644
--- a/substrate/primitives/metadata-ir/src/v15.rs
+++ b/substrate/primitives/metadata-ir/src/v15.rs
@@ -21,7 +21,7 @@ use crate::OuterEnumsIR;
 
 use super::types::{
 	ExtrinsicMetadataIR, MetadataIR, PalletMetadataIR, RuntimeApiMetadataIR,
-	RuntimeApiMethodMetadataIR, RuntimeApiMethodParamMetadataIR, SignedExtensionMetadataIR,
+	RuntimeApiMethodMetadataIR, RuntimeApiMethodParamMetadataIR, TransactionExtensionMetadataIR,
 };
 
 use frame_metadata::v15::{
@@ -87,12 +87,12 @@ impl From<PalletMetadataIR> for PalletMetadata {
 	}
 }
 
-impl From<SignedExtensionMetadataIR> for SignedExtensionMetadata {
-	fn from(ir: SignedExtensionMetadataIR) -> Self {
+impl From<TransactionExtensionMetadataIR> for SignedExtensionMetadata {
+	fn from(ir: TransactionExtensionMetadataIR) -> Self {
 		SignedExtensionMetadata {
 			identifier: ir.identifier,
 			ty: ir.ty,
-			additional_signed: ir.additional_signed,
+			additional_signed: ir.implicit,
 		}
 	}
 }
@@ -105,7 +105,7 @@ impl From<ExtrinsicMetadataIR> for ExtrinsicMetadata {
 			call_ty: ir.call_ty,
 			signature_ty: ir.signature_ty,
 			extra_ty: ir.extra_ty,
-			signed_extensions: ir.signed_extensions.into_iter().map(Into::into).collect(),
+			signed_extensions: ir.extensions.into_iter().map(Into::into).collect(),
 		}
 	}
 }
diff --git a/substrate/primitives/runtime/Cargo.toml b/substrate/primitives/runtime/Cargo.toml
index c3413775b1c..8a812c3a577 100644
--- a/substrate/primitives/runtime/Cargo.toml
+++ b/substrate/primitives/runtime/Cargo.toml
@@ -39,6 +39,7 @@ tracing = { workspace = true, features = ["log"], default-features = false }
 binary-merkle-tree = { workspace = true }
 
 simple-mermaid = { version = "0.1.1", optional = true }
+tuplex = { version = "0.1.2", default-features = false }
 
 [dev-dependencies]
 rand = { workspace = true, default-features = true }
@@ -75,6 +76,7 @@ std = [
 	"sp-trie/std",
 	"sp-weights/std",
 	"tracing/std",
+	"tuplex/std",
 ]
 
 # Serde support without relying on std features.
diff --git a/substrate/primitives/runtime/src/generic/block.rs b/substrate/primitives/runtime/src/generic/block.rs
index 8ed79c7c8dc..a084a3703f9 100644
--- a/substrate/primitives/runtime/src/generic/block.rs
+++ b/substrate/primitives/runtime/src/generic/block.rs
@@ -99,7 +99,7 @@ where
 impl<Header, Extrinsic: MaybeSerialize> traits::Block for Block<Header, Extrinsic>
 where
 	Header: HeaderT + MaybeSerializeDeserialize,
-	Extrinsic: Member + Codec + traits::Extrinsic,
+	Extrinsic: Member + Codec + traits::ExtrinsicLike,
 {
 	type Extrinsic = Extrinsic;
 	type Header = Header;
diff --git a/substrate/primitives/runtime/src/generic/checked_extrinsic.rs b/substrate/primitives/runtime/src/generic/checked_extrinsic.rs
index 44325920bee..e2ecd5ed6da 100644
--- a/substrate/primitives/runtime/src/generic/checked_extrinsic.rs
+++ b/substrate/primitives/runtime/src/generic/checked_extrinsic.rs
@@ -18,81 +18,117 @@
 //! Generic implementation of an extrinsic that has passed the verification
 //! stage.
 
+use codec::Encode;
+use sp_weights::Weight;
+
 use crate::{
 	traits::{
-		self, DispatchInfoOf, Dispatchable, MaybeDisplay, Member, PostDispatchInfoOf,
-		SignedExtension, ValidateUnsigned,
+		self, transaction_extension::TransactionExtension, AsTransactionAuthorizedOrigin,
+		DispatchInfoOf, DispatchTransaction, Dispatchable, MaybeDisplay, Member,
+		PostDispatchInfoOf, ValidateUnsigned,
 	},
 	transaction_validity::{TransactionSource, TransactionValidity},
 };
 
+/// The kind of extrinsic this is, including any fields required of that kind. This is basically
+/// the full extrinsic except the `Call`.
+#[derive(PartialEq, Eq, Clone, sp_core::RuntimeDebug)]
+pub enum ExtrinsicFormat<AccountId, Extension> {
+	/// Extrinsic is bare; it must pass either the bare forms of `TransactionExtension` or
+	/// `ValidateUnsigned`, both deprecated, or alternatively a `ProvideInherent`.
+	Bare,
+	/// Extrinsic has a default `Origin` of `Signed(AccountId)` and must pass all
+	/// `TransactionExtension`s regular checks and includes all extension data.
+	Signed(AccountId, Extension),
+	/// Extrinsic has a default `Origin` of `None` and must pass all `TransactionExtension`s.
+	/// regular checks and includes all extension data.
+	General(Extension),
+}
+
 /// Definition of something that the external world might want to say; its existence implies that it
 /// has been checked and is good, particularly with regards to the signature.
 ///
 /// This is typically passed into [`traits::Applyable::apply`], which should execute
 /// [`CheckedExtrinsic::function`], alongside all other bits and bobs.
 #[derive(PartialEq, Eq, Clone, sp_core::RuntimeDebug)]
-pub struct CheckedExtrinsic<AccountId, Call, Extra> {
+pub struct CheckedExtrinsic<AccountId, Call, Extension> {
 	/// Who this purports to be from and the number of extrinsics have come before
 	/// from the same signer, if anyone (note this is not a signature).
-	pub signed: Option<(AccountId, Extra)>,
+	pub format: ExtrinsicFormat<AccountId, Extension>,
 
 	/// The function that should be called.
 	pub function: Call,
 }
 
-impl<AccountId, Call, Extra, RuntimeOrigin> traits::Applyable
-	for CheckedExtrinsic<AccountId, Call, Extra>
+impl<AccountId, Call, Extension, RuntimeOrigin> traits::Applyable
+	for CheckedExtrinsic<AccountId, Call, Extension>
 where
 	AccountId: Member + MaybeDisplay,
-	Call: Member + Dispatchable<RuntimeOrigin = RuntimeOrigin>,
-	Extra: SignedExtension<AccountId = AccountId, Call = Call>,
-	RuntimeOrigin: From<Option<AccountId>>,
+	Call: Member + Dispatchable<RuntimeOrigin = RuntimeOrigin> + Encode,
+	Extension: TransactionExtension<Call>,
+	RuntimeOrigin: From<Option<AccountId>> + AsTransactionAuthorizedOrigin,
 {
 	type Call = Call;
 
-	fn validate<U: ValidateUnsigned<Call = Self::Call>>(
+	fn validate<I: ValidateUnsigned<Call = Self::Call>>(
 		&self,
-		// TODO [#5006;ToDr] should source be passed to `SignedExtension`s?
-		// Perhaps a change for 2.0 to avoid breaking too much APIs?
 		source: TransactionSource,
 		info: &DispatchInfoOf<Self::Call>,
 		len: usize,
 	) -> TransactionValidity {
-		if let Some((ref id, ref extra)) = self.signed {
-			Extra::validate(extra, id, &self.function, info, len)
-		} else {
-			let valid = Extra::validate_unsigned(&self.function, info, len)?;
-			let unsigned_validation = U::validate_unsigned(source, &self.function)?;
-			Ok(valid.combine_with(unsigned_validation))
+		match self.format {
+			ExtrinsicFormat::Bare => {
+				let inherent_validation = I::validate_unsigned(source, &self.function)?;
+				#[allow(deprecated)]
+				let legacy_validation = Extension::bare_validate(&self.function, info, len)?;
+				Ok(legacy_validation.combine_with(inherent_validation))
+			},
+			ExtrinsicFormat::Signed(ref signer, ref extension) => {
+				let origin = Some(signer.clone()).into();
+				extension.validate_only(origin, &self.function, info, len).map(|x| x.0)
+			},
+			ExtrinsicFormat::General(ref extension) =>
+				extension.validate_only(None.into(), &self.function, info, len).map(|x| x.0),
 		}
 	}
 
-	fn apply<U: ValidateUnsigned<Call = Self::Call>>(
+	fn apply<I: ValidateUnsigned<Call = Self::Call>>(
 		self,
 		info: &DispatchInfoOf<Self::Call>,
 		len: usize,
 	) -> crate::ApplyExtrinsicResultWithInfo<PostDispatchInfoOf<Self::Call>> {
-		let (maybe_who, maybe_pre) = if let Some((id, extra)) = self.signed {
-			let pre = Extra::pre_dispatch(extra, &id, &self.function, info, len)?;
-			(Some(id), Some(pre))
-		} else {
-			Extra::pre_dispatch_unsigned(&self.function, info, len)?;
-			U::pre_dispatch(&self.function)?;
-			(None, None)
-		};
-		let res = self.function.dispatch(RuntimeOrigin::from(maybe_who));
-		let post_info = match res {
-			Ok(info) => info,
-			Err(err) => err.post_info,
-		};
-		Extra::post_dispatch(
-			maybe_pre,
-			info,
-			&post_info,
-			len,
-			&res.map(|_| ()).map_err(|e| e.error),
-		)?;
-		Ok(res)
+		match self.format {
+			ExtrinsicFormat::Bare => {
+				I::pre_dispatch(&self.function)?;
+				// TODO: Separate logic from `TransactionExtension` into a new `InherentExtension`
+				// interface.
+				Extension::bare_validate_and_prepare(&self.function, info, len)?;
+				let res = self.function.dispatch(None.into());
+				let mut post_info = res.unwrap_or_else(|err| err.post_info);
+				let pd_res = res.map(|_| ()).map_err(|e| e.error);
+				// TODO: Separate logic from `TransactionExtension` into a new `InherentExtension`
+				// interface.
+				Extension::bare_post_dispatch(info, &mut post_info, len, &pd_res)?;
+				Ok(res)
+			},
+			ExtrinsicFormat::Signed(signer, extension) =>
+				extension.dispatch_transaction(Some(signer).into(), self.function, info, len),
+			ExtrinsicFormat::General(extension) =>
+				extension.dispatch_transaction(None.into(), self.function, info, len),
+		}
+	}
+}
+
+impl<AccountId, Call: Dispatchable, Extension: TransactionExtension<Call>>
+	CheckedExtrinsic<AccountId, Call, Extension>
+{
+	/// Returns the weight of the extension of this transaction, if present. If the transaction
+	/// doesn't use any extension, the weight returned is equal to zero.
+	pub fn extension_weight(&self) -> Weight {
+		match &self.format {
+			ExtrinsicFormat::Bare => Weight::zero(),
+			ExtrinsicFormat::Signed(_, ext) | ExtrinsicFormat::General(ext) =>
+				ext.weight(&self.function),
+		}
 	}
 }
diff --git a/substrate/primitives/runtime/src/generic/mod.rs b/substrate/primitives/runtime/src/generic/mod.rs
index 3687f7cdb3b..007dee2684b 100644
--- a/substrate/primitives/runtime/src/generic/mod.rs
+++ b/substrate/primitives/runtime/src/generic/mod.rs
@@ -16,7 +16,7 @@
 // limitations under the License.
 
 //! Generic implementations of [`crate::traits::Header`], [`crate::traits::Block`] and
-//! [`crate::traits::Extrinsic`].
+//! [`crate::traits::ExtrinsicLike`].
 
 mod block;
 mod checked_extrinsic;
@@ -29,9 +29,10 @@ mod unchecked_extrinsic;
 
 pub use self::{
 	block::{Block, BlockId, SignedBlock},
-	checked_extrinsic::CheckedExtrinsic,
+	checked_extrinsic::{CheckedExtrinsic, ExtrinsicFormat},
 	digest::{Digest, DigestItem, DigestItemRef, OpaqueDigestItemId},
 	era::{Era, Phase},
 	header::Header,
-	unchecked_extrinsic::{SignedPayload, UncheckedExtrinsic},
+	unchecked_extrinsic::{Preamble, SignedPayload, UncheckedExtrinsic, EXTRINSIC_FORMAT_VERSION},
 };
+pub use unchecked_extrinsic::UncheckedSignaturePayload;
diff --git a/substrate/primitives/runtime/src/generic/unchecked_extrinsic.rs b/substrate/primitives/runtime/src/generic/unchecked_extrinsic.rs
index 499b7c5f583..8c44e147f90 100644
--- a/substrate/primitives/runtime/src/generic/unchecked_extrinsic.rs
+++ b/substrate/primitives/runtime/src/generic/unchecked_extrinsic.rs
@@ -18,10 +18,10 @@
 //! Generic implementation of an unchecked (pre-verification) extrinsic.
 
 use crate::{
-	generic::CheckedExtrinsic,
+	generic::{CheckedExtrinsic, ExtrinsicFormat},
 	traits::{
-		self, Checkable, Extrinsic, ExtrinsicMetadata, IdentifyAccount, MaybeDisplay, Member,
-		SignaturePayload, SignedExtension,
+		self, transaction_extension::TransactionExtension, Checkable, Dispatchable, ExtrinsicLike,
+		ExtrinsicMetadata, IdentifyAccount, MaybeDisplay, Member, SignaturePayload,
 	},
 	transaction_validity::{InvalidTransaction, TransactionValidityError},
 	OpaqueExtrinsic,
@@ -33,16 +33,170 @@ use codec::{Compact, Decode, Encode, EncodeLike, Error, Input};
 use core::fmt;
 use scale_info::{build::Fields, meta_type, Path, StaticTypeInfo, Type, TypeInfo, TypeParameter};
 use sp_io::hashing::blake2_256;
+use sp_weights::Weight;
+
+/// Type to represent the version of the [Extension](TransactionExtension) used in this extrinsic.
+pub type ExtensionVersion = u8;
+/// Type to represent the extrinsic format version which defines an [UncheckedExtrinsic].
+pub type ExtrinsicVersion = u8;
 
 /// Current version of the [`UncheckedExtrinsic`] encoded format.
 ///
 /// This version needs to be bumped if the encoded representation changes.
 /// It ensures that if the representation is changed and the format is not known,
 /// the decoding fails.
-const EXTRINSIC_FORMAT_VERSION: u8 = 4;
+pub const EXTRINSIC_FORMAT_VERSION: ExtrinsicVersion = 5;
+/// Legacy version of the [`UncheckedExtrinsic`] encoded format.
+///
+/// This version was used in the signed/unsigned transaction model and is still supported for
+/// compatibility reasons. It will be deprecated in favor of v5 extrinsics and an inherent/general
+/// transaction model.
+pub const LEGACY_EXTRINSIC_FORMAT_VERSION: ExtrinsicVersion = 4;
+/// Current version of the [Extension](TransactionExtension) used in this
+/// [extrinsic](UncheckedExtrinsic).
+///
+/// This version needs to be bumped if there are breaking changes to the extension used in the
+/// [UncheckedExtrinsic] implementation.
+const EXTENSION_VERSION: ExtensionVersion = 0;
 
 /// The `SignaturePayload` of `UncheckedExtrinsic`.
-type UncheckedSignaturePayload<Address, Signature, Extra> = (Address, Signature, Extra);
+pub type UncheckedSignaturePayload<Address, Signature, Extension> = (Address, Signature, Extension);
+
+impl<Address: TypeInfo, Signature: TypeInfo, Extension: TypeInfo> SignaturePayload
+	for UncheckedSignaturePayload<Address, Signature, Extension>
+{
+	type SignatureAddress = Address;
+	type Signature = Signature;
+	type SignatureExtra = Extension;
+}
+
+/// A "header" for extrinsics leading up to the call itself. Determines the type of extrinsic and
+/// holds any necessary specialized data.
+#[derive(Eq, PartialEq, Clone)]
+pub enum Preamble<Address, Signature, Extension> {
+	/// An extrinsic without a signature or any extension. This means it's either an inherent or
+	/// an old-school "Unsigned" (we don't use that terminology any more since it's confusable with
+	/// the general transaction which is without a signature but does have an extension).
+	///
+	/// NOTE: In the future, once we remove `ValidateUnsigned`, this will only serve Inherent
+	/// extrinsics and thus can be renamed to `Inherent`.
+	Bare(ExtrinsicVersion),
+	/// An old-school transaction extrinsic which includes a signature of some hard-coded crypto.
+	/// Available only on extrinsic version 4.
+	Signed(Address, Signature, ExtensionVersion, Extension),
+	/// A new-school transaction extrinsic which does not include a signature by default. The
+	/// origin authorization, through signatures or other means, is performed by the transaction
+	/// extension in this extrinsic. Available starting with extrinsic version 5.
+	General(ExtensionVersion, Extension),
+}
+
+const VERSION_MASK: u8 = 0b0011_1111;
+const TYPE_MASK: u8 = 0b1100_0000;
+const BARE_EXTRINSIC: u8 = 0b0000_0000;
+const SIGNED_EXTRINSIC: u8 = 0b1000_0000;
+const GENERAL_EXTRINSIC: u8 = 0b0100_0000;
+
+impl<Address, Signature, Extension> Decode for Preamble<Address, Signature, Extension>
+where
+	Address: Decode,
+	Signature: Decode,
+	Extension: Decode,
+{
+	fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
+		let version_and_type = input.read_byte()?;
+
+		let version = version_and_type & VERSION_MASK;
+		let xt_type = version_and_type & TYPE_MASK;
+
+		let preamble = match (version, xt_type) {
+			(
+				extrinsic_version @ LEGACY_EXTRINSIC_FORMAT_VERSION..=EXTRINSIC_FORMAT_VERSION,
+				BARE_EXTRINSIC,
+			) => Self::Bare(extrinsic_version),
+			(LEGACY_EXTRINSIC_FORMAT_VERSION, SIGNED_EXTRINSIC) => {
+				let address = Address::decode(input)?;
+				let signature = Signature::decode(input)?;
+				let ext = Extension::decode(input)?;
+				Self::Signed(address, signature, 0, ext)
+			},
+			(EXTRINSIC_FORMAT_VERSION, GENERAL_EXTRINSIC) => {
+				let ext_version = ExtensionVersion::decode(input)?;
+				let ext = Extension::decode(input)?;
+				Self::General(ext_version, ext)
+			},
+			(_, _) => return Err("Invalid transaction version".into()),
+		};
+
+		Ok(preamble)
+	}
+}
+
+impl<Address, Signature, Extension> Encode for Preamble<Address, Signature, Extension>
+where
+	Address: Encode,
+	Signature: Encode,
+	Extension: Encode,
+{
+	fn size_hint(&self) -> usize {
+		match &self {
+			Preamble::Bare(_) => EXTRINSIC_FORMAT_VERSION.size_hint(),
+			Preamble::Signed(address, signature, _, ext) => LEGACY_EXTRINSIC_FORMAT_VERSION
+				.size_hint()
+				.saturating_add(address.size_hint())
+				.saturating_add(signature.size_hint())
+				.saturating_add(ext.size_hint()),
+			Preamble::General(ext_version, ext) => EXTRINSIC_FORMAT_VERSION
+				.size_hint()
+				.saturating_add(ext_version.size_hint())
+				.saturating_add(ext.size_hint()),
+		}
+	}
+
+	fn encode_to<T: codec::Output + ?Sized>(&self, dest: &mut T) {
+		match &self {
+			Preamble::Bare(extrinsic_version) => {
+				(extrinsic_version | BARE_EXTRINSIC).encode_to(dest);
+			},
+			Preamble::Signed(address, signature, _, ext) => {
+				(LEGACY_EXTRINSIC_FORMAT_VERSION | SIGNED_EXTRINSIC).encode_to(dest);
+				address.encode_to(dest);
+				signature.encode_to(dest);
+				ext.encode_to(dest);
+			},
+			Preamble::General(ext_version, ext) => {
+				(EXTRINSIC_FORMAT_VERSION | GENERAL_EXTRINSIC).encode_to(dest);
+				ext_version.encode_to(dest);
+				ext.encode_to(dest);
+			},
+		}
+	}
+}
+
+impl<Address, Signature, Extension> Preamble<Address, Signature, Extension> {
+	/// Returns `Some` if this is a signed extrinsic, together with the relevant inner fields.
+	pub fn to_signed(self) -> Option<(Address, Signature, Extension)> {
+		match self {
+			Self::Signed(a, s, _, e) => Some((a, s, e)),
+			_ => None,
+		}
+	}
+}
+
+impl<Address, Signature, Extension> fmt::Debug for Preamble<Address, Signature, Extension>
+where
+	Address: fmt::Debug,
+	Extension: fmt::Debug,
+{
+	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+		match self {
+			Self::Bare(_) => write!(f, "Bare"),
+			Self::Signed(address, _, ext_version, tx_ext) =>
+				write!(f, "Signed({:?}, {:?}, {:?})", address, ext_version, tx_ext),
+			Self::General(ext_version, tx_ext) =>
+				write!(f, "General({:?}, {:?})", ext_version, tx_ext),
+		}
+	}
+}
 
 /// An extrinsic right from the external world. This is unchecked and so can contain a signature.
 ///
@@ -66,41 +220,28 @@ type UncheckedSignaturePayload<Address, Signature, Extra> = (Address, Signature,
 /// This can be checked using [`Checkable`], yielding a [`CheckedExtrinsic`], which is the
 /// counterpart of this type after its signature (and other non-negotiable validity checks) have
 /// passed.
-#[derive(PartialEq, Eq, Clone)]
-pub struct UncheckedExtrinsic<Address, Call, Signature, Extra>
-where
-	Extra: SignedExtension,
-{
-	/// The signature, address, number of extrinsics have come before from the same signer and an
-	/// era describing the longevity of this transaction, if this is a signed extrinsic.
-	///
-	/// `None` if it is unsigned or an inherent.
-	pub signature: Option<UncheckedSignaturePayload<Address, Signature, Extra>>,
+#[derive(PartialEq, Eq, Clone, Debug)]
+pub struct UncheckedExtrinsic<Address, Call, Signature, Extension> {
+	/// Information regarding the type of extrinsic this is (inherent or transaction) as well as
+	/// associated extension (`Extension`) data if it's a transaction and a possible signature.
+	pub preamble: Preamble<Address, Signature, Extension>,
 	/// The function that should be called.
 	pub function: Call,
 }
 
-impl<Address: TypeInfo, Signature: TypeInfo, Extra: TypeInfo> SignaturePayload
-	for UncheckedSignaturePayload<Address, Signature, Extra>
-{
-	type SignatureAddress = Address;
-	type Signature = Signature;
-	type SignatureExtra = Extra;
-}
-
 /// Manual [`TypeInfo`] implementation because of custom encoding. The data is a valid encoded
 /// `Vec<u8>`, but requires some logic to extract the signature and payload.
 ///
 /// See [`UncheckedExtrinsic::encode`] and [`UncheckedExtrinsic::decode`].
-impl<Address, Call, Signature, Extra> TypeInfo
-	for UncheckedExtrinsic<Address, Call, Signature, Extra>
+impl<Address, Call, Signature, Extension> TypeInfo
+	for UncheckedExtrinsic<Address, Call, Signature, Extension>
 where
 	Address: StaticTypeInfo,
 	Call: StaticTypeInfo,
 	Signature: StaticTypeInfo,
-	Extra: SignedExtension + StaticTypeInfo,
+	Extension: StaticTypeInfo,
 {
-	type Identity = UncheckedExtrinsic<Address, Call, Signature, Extra>;
+	type Identity = UncheckedExtrinsic<Address, Call, Signature, Extension>;
 
 	fn type_info() -> Type {
 		Type::builder()
@@ -112,7 +253,7 @@ where
 				TypeParameter::new("Address", Some(meta_type::<Address>())),
 				TypeParameter::new("Call", Some(meta_type::<Call>())),
 				TypeParameter::new("Signature", Some(meta_type::<Signature>())),
-				TypeParameter::new("Extra", Some(meta_type::<Extra>())),
+				TypeParameter::new("Extra", Some(meta_type::<Extension>())),
 			])
 			.docs(&["UncheckedExtrinsic raw bytes, requires custom decoding routine"])
 			// Because of the custom encoding, we can only accurately describe the encoding as an
@@ -122,66 +263,104 @@ where
 	}
 }
 
-impl<Address, Call, Signature, Extra: SignedExtension>
-	UncheckedExtrinsic<Address, Call, Signature, Extra>
-{
-	/// New instance of a signed extrinsic aka "transaction".
-	pub fn new_signed(function: Call, signed: Address, signature: Signature, extra: Extra) -> Self {
-		Self { signature: Some((signed, signature, extra)), function }
+impl<Address, Call, Signature, Extension> UncheckedExtrinsic<Address, Call, Signature, Extension> {
+	/// New instance of a bare (ne unsigned) extrinsic. This could be used for an inherent or an
+	/// old-school "unsigned transaction" (which are new being deprecated in favour of general
+	/// transactions).
+	#[deprecated = "Use new_bare instead"]
+	pub fn new_unsigned(function: Call) -> Self {
+		Self::new_bare(function)
 	}
 
-	/// New instance of an unsigned extrinsic aka "inherent".
-	pub fn new_unsigned(function: Call) -> Self {
-		Self { signature: None, function }
+	/// Returns `true` if this extrinsic instance is an inherent, `false`` otherwise.
+	pub fn is_inherent(&self) -> bool {
+		matches!(self.preamble, Preamble::Bare(_))
 	}
-}
 
-impl<Address: TypeInfo, Call: TypeInfo, Signature: TypeInfo, Extra: SignedExtension + TypeInfo>
-	Extrinsic for UncheckedExtrinsic<Address, Call, Signature, Extra>
-{
-	type Call = Call;
+	/// Returns `true` if this extrinsic instance is an old-school signed transaction, `false`
+	/// otherwise.
+	pub fn is_signed(&self) -> bool {
+		matches!(self.preamble, Preamble::Signed(..))
+	}
 
-	type SignaturePayload = UncheckedSignaturePayload<Address, Signature, Extra>;
+	/// Create an `UncheckedExtrinsic` from a `Preamble` and the actual `Call`.
+	pub fn from_parts(function: Call, preamble: Preamble<Address, Signature, Extension>) -> Self {
+		Self { preamble, function }
+	}
 
-	fn is_signed(&self) -> Option<bool> {
-		Some(self.signature.is_some())
+	/// New instance of a bare (ne unsigned) extrinsic.
+	pub fn new_bare(function: Call) -> Self {
+		Self { preamble: Preamble::Bare(EXTRINSIC_FORMAT_VERSION), function }
 	}
 
-	fn new(function: Call, signed_data: Option<Self::SignaturePayload>) -> Option<Self> {
-		Some(if let Some((address, signature, extra)) = signed_data {
-			Self::new_signed(function, address, signature, extra)
-		} else {
-			Self::new_unsigned(function)
-		})
+	/// New instance of a bare (ne unsigned) extrinsic on extrinsic format version 4.
+	pub fn new_bare_legacy(function: Call) -> Self {
+		Self { preamble: Preamble::Bare(LEGACY_EXTRINSIC_FORMAT_VERSION), function }
+	}
+
+	/// New instance of an old-school signed transaction on extrinsic format version 4.
+	pub fn new_signed(
+		function: Call,
+		signed: Address,
+		signature: Signature,
+		tx_ext: Extension,
+	) -> Self {
+		Self { preamble: Preamble::Signed(signed, signature, 0, tx_ext), function }
+	}
+
+	/// New instance of an new-school unsigned transaction.
+	pub fn new_transaction(function: Call, tx_ext: Extension) -> Self {
+		Self { preamble: Preamble::General(EXTENSION_VERSION, tx_ext), function }
+	}
+}
+
+impl<Address: TypeInfo, Call: TypeInfo, Signature: TypeInfo, Extension: TypeInfo> ExtrinsicLike
+	for UncheckedExtrinsic<Address, Call, Signature, Extension>
+{
+	fn is_bare(&self) -> bool {
+		matches!(self.preamble, Preamble::Bare(_))
+	}
+
+	fn is_signed(&self) -> Option<bool> {
+		Some(matches!(self.preamble, Preamble::Signed(..)))
 	}
 }
 
-impl<LookupSource, AccountId, Call, Signature, Extra, Lookup> Checkable<Lookup>
-	for UncheckedExtrinsic<LookupSource, Call, Signature, Extra>
+// TODO: Migrate existing extension pipelines to support current `Signed` transactions as `General`
+// transactions by adding an extension to validate signatures, as they are currently validated in
+// the `Checkable` implementation for `Signed` transactions.
+
+impl<LookupSource, AccountId, Call, Signature, Extension, Lookup> Checkable<Lookup>
+	for UncheckedExtrinsic<LookupSource, Call, Signature, Extension>
 where
 	LookupSource: Member + MaybeDisplay,
-	Call: Encode + Member,
+	Call: Encode + Member + Dispatchable,
 	Signature: Member + traits::Verify,
 	<Signature as traits::Verify>::Signer: IdentifyAccount<AccountId = AccountId>,
-	Extra: SignedExtension<AccountId = AccountId>,
+	Extension: Encode + TransactionExtension<Call>,
 	AccountId: Member + MaybeDisplay,
 	Lookup: traits::Lookup<Source = LookupSource, Target = AccountId>,
 {
-	type Checked = CheckedExtrinsic<AccountId, Call, Extra>;
+	type Checked = CheckedExtrinsic<AccountId, Call, Extension>;
 
 	fn check(self, lookup: &Lookup) -> Result<Self::Checked, TransactionValidityError> {
-		Ok(match self.signature {
-			Some((signed, signature, extra)) => {
+		Ok(match self.preamble {
+			Preamble::Signed(signed, signature, _, tx_ext) => {
 				let signed = lookup.lookup(signed)?;
-				let raw_payload = SignedPayload::new(self.function, extra)?;
+				// The `Implicit` is "implicitly" included in the payload.
+				let raw_payload = SignedPayload::new(self.function, tx_ext)?;
 				if !raw_payload.using_encoded(|payload| signature.verify(payload, &signed)) {
 					return Err(InvalidTransaction::BadProof.into())
 				}
-
-				let (function, extra, _) = raw_payload.deconstruct();
-				CheckedExtrinsic { signed: Some((signed, extra)), function }
+				let (function, tx_ext, _) = raw_payload.deconstruct();
+				CheckedExtrinsic { format: ExtrinsicFormat::Signed(signed, tx_ext), function }
+			},
+			Preamble::General(_, tx_ext) => CheckedExtrinsic {
+				format: ExtrinsicFormat::General(tx_ext),
+				function: self.function,
 			},
-			None => CheckedExtrinsic { signed: None, function: self.function },
+			Preamble::Bare(_) =>
+				CheckedExtrinsic { format: ExtrinsicFormat::Bare, function: self.function },
 		})
 	}
 
@@ -190,91 +369,53 @@ where
 		self,
 		lookup: &Lookup,
 	) -> Result<Self::Checked, TransactionValidityError> {
-		Ok(match self.signature {
-			Some((signed, _, extra)) => {
+		Ok(match self.preamble {
+			Preamble::Signed(signed, _, _, extra) => {
 				let signed = lookup.lookup(signed)?;
-				let raw_payload = SignedPayload::new(self.function, extra)?;
-				let (function, extra, _) = raw_payload.deconstruct();
-				CheckedExtrinsic { signed: Some((signed, extra)), function }
+				CheckedExtrinsic {
+					format: ExtrinsicFormat::Signed(signed, extra),
+					function: self.function,
+				}
+			},
+			Preamble::General(_, extra) => CheckedExtrinsic {
+				format: ExtrinsicFormat::General(extra),
+				function: self.function,
 			},
-			None => CheckedExtrinsic { signed: None, function: self.function },
+			Preamble::Bare(_) =>
+				CheckedExtrinsic { format: ExtrinsicFormat::Bare, function: self.function },
 		})
 	}
 }
 
-impl<Address, Call, Signature, Extra> ExtrinsicMetadata
-	for UncheckedExtrinsic<Address, Call, Signature, Extra>
-where
-	Extra: SignedExtension,
+impl<Address, Call: Dispatchable, Signature, Extension: TransactionExtension<Call>>
+	ExtrinsicMetadata for UncheckedExtrinsic<Address, Call, Signature, Extension>
 {
-	const VERSION: u8 = EXTRINSIC_FORMAT_VERSION;
-	type SignedExtensions = Extra;
+	// TODO: Expose both version 4 and version 5 in metadata v16.
+	const VERSION: u8 = LEGACY_EXTRINSIC_FORMAT_VERSION;
+	type TransactionExtensions = Extension;
 }
 
-/// A payload that has been signed for an unchecked extrinsics.
-///
-/// Note that the payload that we sign to produce unchecked extrinsic signature
-/// is going to be different than the `SignaturePayload` - so the thing the extrinsic
-/// actually contains.
-pub struct SignedPayload<Call, Extra: SignedExtension>((Call, Extra, Extra::AdditionalSigned));
-
-impl<Call, Extra> SignedPayload<Call, Extra>
-where
-	Call: Encode,
-	Extra: SignedExtension,
+impl<Address, Call: Dispatchable, Signature, Extension: TransactionExtension<Call>>
+	UncheckedExtrinsic<Address, Call, Signature, Extension>
 {
-	/// Create new `SignedPayload`.
-	///
-	/// This function may fail if `additional_signed` of `Extra` is not available.
-	pub fn new(call: Call, extra: Extra) -> Result<Self, TransactionValidityError> {
-		let additional_signed = extra.additional_signed()?;
-		let raw_payload = (call, extra, additional_signed);
-		Ok(Self(raw_payload))
-	}
-
-	/// Create new `SignedPayload` from raw components.
-	pub fn from_raw(call: Call, extra: Extra, additional_signed: Extra::AdditionalSigned) -> Self {
-		Self((call, extra, additional_signed))
-	}
-
-	/// Deconstruct the payload into it's components.
-	pub fn deconstruct(self) -> (Call, Extra, Extra::AdditionalSigned) {
-		self.0
-	}
-}
-
-impl<Call, Extra> Encode for SignedPayload<Call, Extra>
-where
-	Call: Encode,
-	Extra: SignedExtension,
-{
-	/// Get an encoded version of this payload.
-	///
-	/// Payloads longer than 256 bytes are going to be `blake2_256`-hashed.
-	fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
-		self.0.using_encoded(|payload| {
-			if payload.len() > 256 {
-				f(&blake2_256(payload)[..])
-			} else {
-				f(payload)
-			}
-		})
+	/// Returns the weight of the extension of this transaction, if present. If the transaction
+	/// doesn't use any extension, the weight returned is equal to zero.
+	pub fn extension_weight(&self) -> Weight {
+		match &self.preamble {
+			Preamble::Bare(_) => Weight::zero(),
+			Preamble::Signed(_, _, _, ext) | Preamble::General(_, ext) =>
+				ext.weight(&self.function),
+		}
 	}
 }
 
-impl<Call, Extra> EncodeLike for SignedPayload<Call, Extra>
-where
-	Call: Encode,
-	Extra: SignedExtension,
-{
-}
-
-impl<Address, Call, Signature, Extra> Decode for UncheckedExtrinsic<Address, Call, Signature, Extra>
+impl<Address, Call, Signature, Extension> Decode
+	for UncheckedExtrinsic<Address, Call, Signature, Extension>
 where
 	Address: Decode,
 	Signature: Decode,
 	Call: Decode,
-	Extra: SignedExtension,
+	Extension: Decode,
 {
 	fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
 		// This is a little more complicated than usual since the binary format must be compatible
@@ -283,15 +424,7 @@ where
 		let expected_length: Compact<u32> = Decode::decode(input)?;
 		let before_length = input.remaining_len()?;
 
-		let version = input.read_byte()?;
-
-		let is_signed = version & 0b1000_0000 != 0;
-		let version = version & 0b0111_1111;
-		if version != EXTRINSIC_FORMAT_VERSION {
-			return Err("Invalid transaction version".into())
-		}
-
-		let signature = is_signed.then(|| Decode::decode(input)).transpose()?;
+		let preamble = Decode::decode(input)?;
 		let function = Decode::decode(input)?;
 
 		if let Some((before_length, after_length)) =
@@ -304,31 +437,20 @@ where
 			}
 		}
 
-		Ok(Self { signature, function })
+		Ok(Self { preamble, function })
 	}
 }
 
 #[docify::export(unchecked_extrinsic_encode_impl)]
-impl<Address, Call, Signature, Extra> Encode for UncheckedExtrinsic<Address, Call, Signature, Extra>
+impl<Address, Call, Signature, Extension> Encode
+	for UncheckedExtrinsic<Address, Call, Signature, Extension>
 where
-	Address: Encode,
-	Signature: Encode,
+	Preamble<Address, Signature, Extension>: Encode,
 	Call: Encode,
-	Extra: SignedExtension,
+	Extension: Encode,
 {
 	fn encode(&self) -> Vec<u8> {
-		let mut tmp = Vec::with_capacity(core::mem::size_of::<Self>());
-
-		// 1 byte version id.
-		match self.signature.as_ref() {
-			Some(s) => {
-				tmp.push(EXTRINSIC_FORMAT_VERSION | 0b1000_0000);
-				s.encode_to(&mut tmp);
-			},
-			None => {
-				tmp.push(EXTRINSIC_FORMAT_VERSION & 0b0111_1111);
-			},
-		}
+		let mut tmp = self.preamble.encode();
 		self.function.encode_to(&mut tmp);
 
 		let compact_len = codec::Compact::<u32>(tmp.len() as u32);
@@ -343,19 +465,19 @@ where
 	}
 }
 
-impl<Address, Call, Signature, Extra> EncodeLike
-	for UncheckedExtrinsic<Address, Call, Signature, Extra>
+impl<Address, Call, Signature, Extension> EncodeLike
+	for UncheckedExtrinsic<Address, Call, Signature, Extension>
 where
 	Address: Encode,
 	Signature: Encode,
-	Call: Encode,
-	Extra: SignedExtension,
+	Call: Encode + Dispatchable,
+	Extension: TransactionExtension<Call>,
 {
 }
 
 #[cfg(feature = "serde")]
-impl<Address: Encode, Signature: Encode, Call: Encode, Extra: SignedExtension> serde::Serialize
-	for UncheckedExtrinsic<Address, Call, Signature, Extra>
+impl<Address: Encode, Signature: Encode, Call: Encode, Extension: Encode> serde::Serialize
+	for UncheckedExtrinsic<Address, Call, Signature, Extension>
 {
 	fn serialize<S>(&self, seq: S) -> Result<S::Ok, S::Error>
 	where
@@ -366,45 +488,86 @@ impl<Address: Encode, Signature: Encode, Call: Encode, Extra: SignedExtension> s
 }
 
 #[cfg(feature = "serde")]
-impl<'a, Address: Decode, Signature: Decode, Call: Decode, Extra: SignedExtension>
-	serde::Deserialize<'a> for UncheckedExtrinsic<Address, Call, Signature, Extra>
+impl<'a, Address: Decode, Signature: Decode, Call: Decode, Extension: Decode> serde::Deserialize<'a>
+	for UncheckedExtrinsic<Address, Call, Signature, Extension>
 {
 	fn deserialize<D>(de: D) -> Result<Self, D::Error>
 	where
 		D: serde::Deserializer<'a>,
 	{
 		let r = sp_core::bytes::deserialize(de)?;
-		Decode::decode(&mut &r[..])
+		Self::decode(&mut &r[..])
 			.map_err(|e| serde::de::Error::custom(format!("Decode error: {}", e)))
 	}
 }
 
-impl<Address, Call, Signature, Extra> fmt::Debug
-	for UncheckedExtrinsic<Address, Call, Signature, Extra>
+/// A payload that has been signed for an unchecked extrinsics.
+///
+/// Note that the payload that we sign to produce unchecked extrinsic signature
+/// is going to be different than the `SignaturePayload` - so the thing the extrinsic
+/// actually contains.
+pub struct SignedPayload<Call: Dispatchable, Extension: TransactionExtension<Call>>(
+	(Call, Extension, Extension::Implicit),
+);
+
+impl<Call, Extension> SignedPayload<Call, Extension>
 where
-	Address: fmt::Debug,
-	Call: fmt::Debug,
-	Extra: SignedExtension,
+	Call: Encode + Dispatchable,
+	Extension: TransactionExtension<Call>,
 {
-	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-		write!(
-			f,
-			"UncheckedExtrinsic({:?}, {:?})",
-			self.signature.as_ref().map(|x| (&x.0, &x.2)),
-			self.function,
-		)
+	/// Create new `SignedPayload` for extrinsic format version 4.
+	///
+	/// This function may fail if `implicit` of `Extension` is not available.
+	pub fn new(call: Call, tx_ext: Extension) -> Result<Self, TransactionValidityError> {
+		let implicit = Extension::implicit(&tx_ext)?;
+		let raw_payload = (call, tx_ext, implicit);
+		Ok(Self(raw_payload))
+	}
+
+	/// Create new `SignedPayload` from raw components.
+	pub fn from_raw(call: Call, tx_ext: Extension, implicit: Extension::Implicit) -> Self {
+		Self((call, tx_ext, implicit))
+	}
+
+	/// Deconstruct the payload into it's components.
+	pub fn deconstruct(self) -> (Call, Extension, Extension::Implicit) {
+		self.0
+	}
+}
+
+impl<Call, Extension> Encode for SignedPayload<Call, Extension>
+where
+	Call: Encode + Dispatchable,
+	Extension: TransactionExtension<Call>,
+{
+	/// Get an encoded version of this `blake2_256`-hashed payload.
+	fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
+		self.0.using_encoded(|payload| {
+			if payload.len() > 256 {
+				f(&blake2_256(payload)[..])
+			} else {
+				f(payload)
+			}
+		})
 	}
 }
 
-impl<Address, Call, Signature, Extra> From<UncheckedExtrinsic<Address, Call, Signature, Extra>>
-	for OpaqueExtrinsic
+impl<Call, Extension> EncodeLike for SignedPayload<Call, Extension>
+where
+	Call: Encode + Dispatchable,
+	Extension: TransactionExtension<Call>,
+{
+}
+
+impl<Address, Call, Signature, Extension>
+	From<UncheckedExtrinsic<Address, Call, Signature, Extension>> for OpaqueExtrinsic
 where
 	Address: Encode,
 	Signature: Encode,
 	Call: Encode,
-	Extra: SignedExtension,
+	Extension: Encode,
 {
-	fn from(extrinsic: UncheckedExtrinsic<Address, Call, Signature, Extra>) -> Self {
+	fn from(extrinsic: UncheckedExtrinsic<Address, Call, Signature, Extension>) -> Self {
 		Self::from_bytes(extrinsic.encode().as_slice()).expect(
 			"both OpaqueExtrinsic and UncheckedExtrinsic have encoding that is compatible with \
 				raw Vec<u8> encoding; qed",
@@ -412,60 +575,196 @@ where
 	}
 }
 
+#[cfg(test)]
+mod legacy {
+	use codec::{Compact, Decode, Encode, EncodeLike, Error, Input};
+	use scale_info::{
+		build::Fields, meta_type, Path, StaticTypeInfo, Type, TypeInfo, TypeParameter,
+	};
+
+	pub type UncheckedSignaturePayloadV4<Address, Signature, Extra> = (Address, Signature, Extra);
+
+	#[derive(PartialEq, Eq, Clone, Debug)]
+	pub struct UncheckedExtrinsicV4<Address, Call, Signature, Extra> {
+		pub signature: Option<UncheckedSignaturePayloadV4<Address, Signature, Extra>>,
+		pub function: Call,
+	}
+
+	impl<Address, Call, Signature, Extra> TypeInfo
+		for UncheckedExtrinsicV4<Address, Call, Signature, Extra>
+	where
+		Address: StaticTypeInfo,
+		Call: StaticTypeInfo,
+		Signature: StaticTypeInfo,
+		Extra: StaticTypeInfo,
+	{
+		type Identity = UncheckedExtrinsicV4<Address, Call, Signature, Extra>;
+
+		fn type_info() -> Type {
+			Type::builder()
+				.path(Path::new("UncheckedExtrinsic", module_path!()))
+				// Include the type parameter types, even though they are not used directly in any
+				// of the described fields. These type definitions can be used by downstream
+				// consumers to help construct the custom decoding from the opaque bytes (see
+				// below).
+				.type_params(vec![
+					TypeParameter::new("Address", Some(meta_type::<Address>())),
+					TypeParameter::new("Call", Some(meta_type::<Call>())),
+					TypeParameter::new("Signature", Some(meta_type::<Signature>())),
+					TypeParameter::new("Extra", Some(meta_type::<Extra>())),
+				])
+				.docs(&["OldUncheckedExtrinsic raw bytes, requires custom decoding routine"])
+				// Because of the custom encoding, we can only accurately describe the encoding as
+				// an opaque `Vec<u8>`. Downstream consumers will need to manually implement the
+				// codec to encode/decode the `signature` and `function` fields.
+				.composite(Fields::unnamed().field(|f| f.ty::<Vec<u8>>()))
+		}
+	}
+
+	impl<Address, Call, Signature, Extra> UncheckedExtrinsicV4<Address, Call, Signature, Extra> {
+		pub fn new_signed(
+			function: Call,
+			signed: Address,
+			signature: Signature,
+			extra: Extra,
+		) -> Self {
+			Self { signature: Some((signed, signature, extra)), function }
+		}
+
+		pub fn new_unsigned(function: Call) -> Self {
+			Self { signature: None, function }
+		}
+	}
+
+	impl<Address, Call, Signature, Extra> Decode
+		for UncheckedExtrinsicV4<Address, Call, Signature, Extra>
+	where
+		Address: Decode,
+		Signature: Decode,
+		Call: Decode,
+		Extra: Decode,
+	{
+		fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
+			// This is a little more complicated than usual since the binary format must be
+			// compatible with SCALE's generic `Vec<u8>` type. Basically this just means accepting
+			// that there will be a prefix of vector length.
+			let expected_length: Compact<u32> = Decode::decode(input)?;
+			let before_length = input.remaining_len()?;
+
+			let version = input.read_byte()?;
+
+			let is_signed = version & 0b1000_0000 != 0;
+			let version = version & 0b0111_1111;
+			if version != 4u8 {
+				return Err("Invalid transaction version".into())
+			}
+
+			let signature = is_signed.then(|| Decode::decode(input)).transpose()?;
+			let function = Decode::decode(input)?;
+
+			if let Some((before_length, after_length)) =
+				input.remaining_len()?.and_then(|a| before_length.map(|b| (b, a)))
+			{
+				let length = before_length.saturating_sub(after_length);
+
+				if length != expected_length.0 as usize {
+					return Err("Invalid length prefix".into())
+				}
+			}
+
+			Ok(Self { signature, function })
+		}
+	}
+
+	#[docify::export(unchecked_extrinsic_encode_impl)]
+	impl<Address, Call, Signature, Extra> Encode
+		for UncheckedExtrinsicV4<Address, Call, Signature, Extra>
+	where
+		Address: Encode,
+		Signature: Encode,
+		Call: Encode,
+		Extra: Encode,
+	{
+		fn encode(&self) -> Vec<u8> {
+			let mut tmp = Vec::with_capacity(sp_std::mem::size_of::<Self>());
+
+			// 1 byte version id.
+			match self.signature.as_ref() {
+				Some(s) => {
+					tmp.push(4u8 | 0b1000_0000);
+					s.encode_to(&mut tmp);
+				},
+				None => {
+					tmp.push(4u8 & 0b0111_1111);
+				},
+			}
+			self.function.encode_to(&mut tmp);
+
+			let compact_len = codec::Compact::<u32>(tmp.len() as u32);
+
+			// Allocate the output buffer with the correct length
+			let mut output = Vec::with_capacity(compact_len.size_hint() + tmp.len());
+
+			compact_len.encode_to(&mut output);
+			output.extend(tmp);
+
+			output
+		}
+	}
+
+	impl<Address, Call, Signature, Extra> EncodeLike
+		for UncheckedExtrinsicV4<Address, Call, Signature, Extra>
+	where
+		Address: Encode,
+		Signature: Encode,
+		Call: Encode,
+		Extra: Encode,
+	{
+	}
+}
+
 #[cfg(test)]
 mod tests {
-	use super::*;
+	use super::{legacy::UncheckedExtrinsicV4, *};
 	use crate::{
 		codec::{Decode, Encode},
+		impl_tx_ext_default,
 		testing::TestSignature as TestSig,
-		traits::{DispatchInfoOf, IdentityLookup, SignedExtension},
+		traits::{FakeDispatchable, IdentityLookup, TransactionExtension},
 	};
 	use sp_io::hashing::blake2_256;
 
 	type TestContext = IdentityLookup<u64>;
 	type TestAccountId = u64;
-	type TestCall = Vec<u8>;
+	type TestCall = FakeDispatchable<Vec<u8>>;
 
 	const TEST_ACCOUNT: TestAccountId = 0;
 
 	// NOTE: this is demonstration. One can simply use `()` for testing.
 	#[derive(Debug, Encode, Decode, Clone, Eq, PartialEq, Ord, PartialOrd, TypeInfo)]
-	struct TestExtra;
-	impl SignedExtension for TestExtra {
-		const IDENTIFIER: &'static str = "TestExtra";
-		type AccountId = u64;
-		type Call = ();
-		type AdditionalSigned = ();
+	struct DummyExtension;
+	impl TransactionExtension<TestCall> for DummyExtension {
+		const IDENTIFIER: &'static str = "DummyExtension";
+		type Implicit = ();
+		type Val = ();
 		type Pre = ();
-
-		fn additional_signed(&self) -> core::result::Result<(), TransactionValidityError> {
-			Ok(())
-		}
-
-		fn pre_dispatch(
-			self,
-			who: &Self::AccountId,
-			call: &Self::Call,
-			info: &DispatchInfoOf<Self::Call>,
-			len: usize,
-		) -> Result<Self::Pre, TransactionValidityError> {
-			self.validate(who, call, info, len).map(|_| ())
-		}
+		impl_tx_ext_default!(TestCall; weight validate prepare);
 	}
 
-	type Ex = UncheckedExtrinsic<TestAccountId, TestCall, TestSig, TestExtra>;
-	type CEx = CheckedExtrinsic<TestAccountId, TestCall, TestExtra>;
+	type Ex = UncheckedExtrinsic<TestAccountId, TestCall, TestSig, DummyExtension>;
+	type CEx = CheckedExtrinsic<TestAccountId, TestCall, DummyExtension>;
 
 	#[test]
 	fn unsigned_codec_should_work() {
-		let ux = Ex::new_unsigned(vec![0u8; 0]);
+		let call: TestCall = vec![0u8; 0].into();
+		let ux = Ex::new_bare(call);
 		let encoded = ux.encode();
 		assert_eq!(Ex::decode(&mut &encoded[..]), Ok(ux));
 	}
 
 	#[test]
 	fn invalid_length_prefix_is_detected() {
-		let ux = Ex::new_unsigned(vec![0u8; 0]);
+		let ux = Ex::new_bare(vec![0u8; 0].into());
 		let mut encoded = ux.encode();
 
 		let length = Compact::<u32>::decode(&mut &encoded[..]).unwrap();
@@ -474,13 +773,20 @@ mod tests {
 		assert_eq!(Ex::decode(&mut &encoded[..]), Err("Invalid length prefix".into()));
 	}
 
+	#[test]
+	fn transaction_codec_should_work() {
+		let ux = Ex::new_transaction(vec![0u8; 0].into(), DummyExtension);
+		let encoded = ux.encode();
+		assert_eq!(Ex::decode(&mut &encoded[..]), Ok(ux));
+	}
+
 	#[test]
 	fn signed_codec_should_work() {
 		let ux = Ex::new_signed(
-			vec![0u8; 0],
+			vec![0u8; 0].into(),
 			TEST_ACCOUNT,
-			TestSig(TEST_ACCOUNT, (vec![0u8; 0], TestExtra).encode()),
-			TestExtra,
+			TestSig(TEST_ACCOUNT, (vec![0u8; 0], DummyExtension).encode()),
+			DummyExtension,
 		);
 		let encoded = ux.encode();
 		assert_eq!(Ex::decode(&mut &encoded[..]), Ok(ux));
@@ -489,13 +795,13 @@ mod tests {
 	#[test]
 	fn large_signed_codec_should_work() {
 		let ux = Ex::new_signed(
-			vec![0u8; 0],
+			vec![0u8; 0].into(),
 			TEST_ACCOUNT,
 			TestSig(
 				TEST_ACCOUNT,
-				(vec![0u8; 257], TestExtra).using_encoded(blake2_256)[..].to_owned(),
+				(vec![0u8; 257], DummyExtension).using_encoded(blake2_256)[..].to_owned(),
 			),
-			TestExtra,
+			DummyExtension,
 		);
 		let encoded = ux.encode();
 		assert_eq!(Ex::decode(&mut &encoded[..]), Ok(ux));
@@ -503,44 +809,68 @@ mod tests {
 
 	#[test]
 	fn unsigned_check_should_work() {
-		let ux = Ex::new_unsigned(vec![0u8; 0]);
-		assert!(!ux.is_signed().unwrap_or(false));
-		assert!(<Ex as Checkable<TestContext>>::check(ux, &Default::default()).is_ok());
+		let ux = Ex::new_bare(vec![0u8; 0].into());
+		assert!(ux.is_inherent());
+		assert_eq!(
+			<Ex as Checkable<TestContext>>::check(ux, &Default::default()),
+			Ok(CEx { format: ExtrinsicFormat::Bare, function: vec![0u8; 0].into() }),
+		);
 	}
 
 	#[test]
 	fn badly_signed_check_should_fail() {
 		let ux = Ex::new_signed(
-			vec![0u8; 0],
+			vec![0u8; 0].into(),
 			TEST_ACCOUNT,
-			TestSig(TEST_ACCOUNT, vec![0u8; 0]),
-			TestExtra,
+			TestSig(TEST_ACCOUNT, vec![0u8; 0].into()),
+			DummyExtension,
 		);
-		assert!(ux.is_signed().unwrap_or(false));
+		assert!(!ux.is_inherent());
 		assert_eq!(
 			<Ex as Checkable<TestContext>>::check(ux, &Default::default()),
 			Err(InvalidTransaction::BadProof.into()),
 		);
 	}
 
+	#[test]
+	fn transaction_check_should_work() {
+		let ux = Ex::new_transaction(vec![0u8; 0].into(), DummyExtension);
+		assert!(!ux.is_inherent());
+		assert_eq!(
+			<Ex as Checkable<TestContext>>::check(ux, &Default::default()),
+			Ok(CEx {
+				format: ExtrinsicFormat::General(DummyExtension),
+				function: vec![0u8; 0].into()
+			}),
+		);
+	}
+
 	#[test]
 	fn signed_check_should_work() {
+		let sig_payload = SignedPayload::from_raw(
+			FakeDispatchable::from(vec![0u8; 0]),
+			DummyExtension,
+			DummyExtension.implicit().unwrap(),
+		);
 		let ux = Ex::new_signed(
-			vec![0u8; 0],
+			vec![0u8; 0].into(),
 			TEST_ACCOUNT,
-			TestSig(TEST_ACCOUNT, (vec![0u8; 0], TestExtra).encode()),
-			TestExtra,
+			TestSig(TEST_ACCOUNT, sig_payload.encode()),
+			DummyExtension,
 		);
-		assert!(ux.is_signed().unwrap_or(false));
+		assert!(!ux.is_inherent());
 		assert_eq!(
 			<Ex as Checkable<TestContext>>::check(ux, &Default::default()),
-			Ok(CEx { signed: Some((TEST_ACCOUNT, TestExtra)), function: vec![0u8; 0] }),
+			Ok(CEx {
+				format: ExtrinsicFormat::Signed(TEST_ACCOUNT, DummyExtension),
+				function: vec![0u8; 0].into()
+			}),
 		);
 	}
 
 	#[test]
 	fn encoding_matches_vec() {
-		let ex = Ex::new_unsigned(vec![0u8; 0]);
+		let ex = Ex::new_bare(vec![0u8; 0].into());
 		let encoded = ex.encode();
 		let decoded = Ex::decode(&mut encoded.as_slice()).unwrap();
 		assert_eq!(decoded, ex);
@@ -550,7 +880,7 @@ mod tests {
 
 	#[test]
 	fn conversion_to_opaque() {
-		let ux = Ex::new_unsigned(vec![0u8; 0]);
+		let ux = Ex::new_bare(vec![0u8; 0].into());
 		let encoded = ux.encode();
 		let opaque: OpaqueExtrinsic = ux.into();
 		let opaque_encoded = opaque.encode();
@@ -559,10 +889,106 @@ mod tests {
 
 	#[test]
 	fn large_bad_prefix_should_work() {
-		let encoded = Compact::<u32>::from(u32::MAX).encode();
+		let encoded = (Compact::<u32>::from(u32::MAX), Preamble::<(), (), ()>::Bare(0)).encode();
+		assert!(Ex::decode(&mut &encoded[..]).is_err());
+	}
+
+	#[test]
+	fn legacy_short_signed_encode_decode() {
+		let call: TestCall = vec![0u8; 4].into();
+		let signed = TEST_ACCOUNT;
+		let extension = DummyExtension;
+		let implicit = extension.implicit().unwrap();
+		let legacy_signature = TestSig(TEST_ACCOUNT, (&call, &extension, &implicit).encode());
+
+		let old_ux =
+			UncheckedExtrinsicV4::<TestAccountId, TestCall, TestSig, DummyExtension>::new_signed(
+				call.clone(),
+				signed,
+				legacy_signature.clone(),
+				extension.clone(),
+			);
+
+		let encoded_old_ux = old_ux.encode();
+		let decoded_old_ux = Ex::decode(&mut &encoded_old_ux[..]).unwrap();
+
+		assert_eq!(decoded_old_ux.function, call);
 		assert_eq!(
-			Ex::decode(&mut &encoded[..]),
-			Err(Error::from("Not enough data to fill buffer"))
+			decoded_old_ux.preamble,
+			Preamble::Signed(signed, legacy_signature.clone(), 0, extension.clone())
 		);
+
+		let new_ux =
+			Ex::new_signed(call.clone(), signed, legacy_signature.clone(), extension.clone());
+
+		let new_checked = new_ux.check(&IdentityLookup::<TestAccountId>::default()).unwrap();
+		let old_checked =
+			decoded_old_ux.check(&IdentityLookup::<TestAccountId>::default()).unwrap();
+		assert_eq!(new_checked, old_checked);
+	}
+
+	#[test]
+	fn legacy_long_signed_encode_decode() {
+		let call: TestCall = vec![0u8; 257].into();
+		let signed = TEST_ACCOUNT;
+		let extension = DummyExtension;
+		let implicit = extension.implicit().unwrap();
+		let signature = TestSig(
+			TEST_ACCOUNT,
+			blake2_256(&(&call, DummyExtension, &implicit).encode()[..]).to_vec(),
+		);
+
+		let old_ux =
+			UncheckedExtrinsicV4::<TestAccountId, TestCall, TestSig, DummyExtension>::new_signed(
+				call.clone(),
+				signed,
+				signature.clone(),
+				extension.clone(),
+			);
+
+		let encoded_old_ux = old_ux.encode();
+		let decoded_old_ux = Ex::decode(&mut &encoded_old_ux[..]).unwrap();
+
+		assert_eq!(decoded_old_ux.function, call);
+		assert_eq!(
+			decoded_old_ux.preamble,
+			Preamble::Signed(signed, signature.clone(), 0, extension.clone())
+		);
+
+		let new_ux = Ex::new_signed(call.clone(), signed, signature.clone(), extension.clone());
+
+		let new_checked = new_ux.check(&IdentityLookup::<TestAccountId>::default()).unwrap();
+		let old_checked =
+			decoded_old_ux.check(&IdentityLookup::<TestAccountId>::default()).unwrap();
+		assert_eq!(new_checked, old_checked);
+	}
+
+	#[test]
+	fn legacy_unsigned_encode_decode() {
+		let call: TestCall = vec![0u8; 0].into();
+
+		let old_ux =
+			UncheckedExtrinsicV4::<TestAccountId, TestCall, TestSig, DummyExtension>::new_unsigned(
+				call.clone(),
+			);
+
+		let encoded_old_ux = old_ux.encode();
+		let decoded_old_ux = Ex::decode(&mut &encoded_old_ux[..]).unwrap();
+
+		assert_eq!(decoded_old_ux.function, call);
+		assert_eq!(decoded_old_ux.preamble, Preamble::Bare(LEGACY_EXTRINSIC_FORMAT_VERSION));
+
+		let new_legacy_ux = Ex::new_bare_legacy(call.clone());
+		assert_eq!(encoded_old_ux, new_legacy_ux.encode());
+
+		let new_ux = Ex::new_bare(call.clone());
+		let encoded_new_ux = new_ux.encode();
+		let decoded_new_ux = Ex::decode(&mut &encoded_new_ux[..]).unwrap();
+		assert_eq!(new_ux, decoded_new_ux);
+
+		let new_checked = new_ux.check(&IdentityLookup::<TestAccountId>::default()).unwrap();
+		let old_checked =
+			decoded_old_ux.check(&IdentityLookup::<TestAccountId>::default()).unwrap();
+		assert_eq!(new_checked, old_checked);
 	}
 }
diff --git a/substrate/primitives/runtime/src/lib.rs b/substrate/primitives/runtime/src/lib.rs
index 260c9a91855..6eed57656a6 100644
--- a/substrate/primitives/runtime/src/lib.rs
+++ b/substrate/primitives/runtime/src/lib.rs
@@ -26,7 +26,7 @@
 //! communication between the client and the runtime. This includes:
 //!
 //! - A set of traits to declare what any block/header/extrinsic type should provide.
-//! 	- [`traits::Block`], [`traits::Header`], [`traits::Extrinsic`]
+//! 	- [`traits::Block`], [`traits::Header`], [`traits::ExtrinsicLike`]
 //! - A set of types that implement these traits, whilst still providing a high degree of
 //!   configurability via generics.
 //! 	- [`generic::Block`], [`generic::Header`], [`generic::UncheckedExtrinsic`] and
@@ -131,6 +131,8 @@ pub use sp_arithmetic::{
 	FixedPointOperand, FixedU128, FixedU64, InnerOf, PerThing, PerU16, Perbill, Percent, Permill,
 	Perquintill, Rational128, Rounding, UpperOf,
 };
+/// Re-export this since it's part of the API of this crate.
+pub use sp_weights::Weight;
 
 pub use either::Either;
 
@@ -955,9 +957,10 @@ impl<'a> ::serde::Deserialize<'a> for OpaqueExtrinsic {
 	}
 }
 
-impl traits::Extrinsic for OpaqueExtrinsic {
-	type Call = ();
-	type SignaturePayload = ();
+impl traits::ExtrinsicLike for OpaqueExtrinsic {
+	fn is_bare(&self) -> bool {
+		false
+	}
 }
 
 /// Print something that implements `Printable` from the runtime.
diff --git a/substrate/primitives/runtime/src/testing.rs b/substrate/primitives/runtime/src/testing.rs
index a4ce4b5fc1a..1fc78cce670 100644
--- a/substrate/primitives/runtime/src/testing.rs
+++ b/substrate/primitives/runtime/src/testing.rs
@@ -19,23 +19,15 @@
 
 use crate::{
 	codec::{Codec, Decode, Encode, MaxEncodedLen},
-	generic,
+	generic::{self, UncheckedExtrinsic},
 	scale_info::TypeInfo,
-	traits::{
-		self, Applyable, BlakeTwo256, Checkable, DispatchInfoOf, Dispatchable, OpaqueKeys,
-		PostDispatchInfoOf, SignaturePayload, SignedExtension, ValidateUnsigned,
-	},
-	transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError},
-	ApplyExtrinsicResultWithInfo, KeyTypeId,
+	traits::{self, BlakeTwo256, Dispatchable, OpaqueKeys},
+	DispatchResultWithInfo, KeyTypeId,
 };
-use serde::{de::Error as DeError, Deserialize, Deserializer, Serialize, Serializer};
+use serde::{de::Error as DeError, Deserialize, Deserializer, Serialize};
 use sp_core::crypto::{key_types, ByteArray, CryptoType, Dummy};
 pub use sp_core::{sr25519, H256};
-use std::{
-	cell::RefCell,
-	fmt::{self, Debug},
-	ops::Deref,
-};
+use std::{cell::RefCell, fmt::Debug};
 
 /// A dummy type which can be used instead of regular cryptographic primitives.
 ///
@@ -80,6 +72,11 @@ impl UintAuthorityId {
 		bytes[0..8].copy_from_slice(&self.0.to_le_bytes());
 		T::from_slice(&bytes).unwrap()
 	}
+
+	/// Set the list of keys returned by the runtime call for all keys of that type.
+	pub fn set_all_keys<T: Into<UintAuthorityId>>(keys: impl IntoIterator<Item = T>) {
+		ALL_KEYS.with(|l| *l.borrow_mut() = keys.into_iter().map(Into::into).collect())
+	}
 }
 
 impl CryptoType for UintAuthorityId {
@@ -104,13 +101,6 @@ thread_local! {
 	static ALL_KEYS: RefCell<Vec<UintAuthorityId>> = RefCell::new(vec![]);
 }
 
-impl UintAuthorityId {
-	/// Set the list of keys returned by the runtime call for all keys of that type.
-	pub fn set_all_keys<T: Into<UintAuthorityId>>(keys: impl IntoIterator<Item = T>) {
-		ALL_KEYS.with(|l| *l.borrow_mut() = keys.into_iter().map(Into::into).collect())
-	}
-}
-
 impl sp_application_crypto::RuntimeAppPublic for UintAuthorityId {
 	const ID: KeyTypeId = key_types::DUMMY;
 
@@ -162,6 +152,18 @@ impl traits::IdentifyAccount for UintAuthorityId {
 	}
 }
 
+impl traits::Verify for UintAuthorityId {
+	type Signer = Self;
+
+	fn verify<L: traits::Lazy<[u8]>>(
+		&self,
+		_msg: L,
+		signer: &<Self::Signer as traits::IdentifyAccount>::AccountId,
+	) -> bool {
+		self.0 == *signer
+	}
+}
+
 /// A dummy signature type, to match `UintAuthorityId`.
 #[derive(Eq, PartialEq, Clone, Debug, Hash, Serialize, Deserialize, Encode, Decode, TypeInfo)]
 pub struct TestSignature(pub u64, pub Vec<u8>);
@@ -196,42 +198,6 @@ impl Header {
 	}
 }
 
-/// An opaque extrinsic wrapper type.
-#[derive(PartialEq, Eq, Clone, Debug, Encode, Decode)]
-pub struct ExtrinsicWrapper<Xt>(Xt);
-
-impl<Xt> traits::Extrinsic for ExtrinsicWrapper<Xt> {
-	type Call = ();
-	type SignaturePayload = ();
-
-	fn is_signed(&self) -> Option<bool> {
-		None
-	}
-}
-
-impl<Xt: Encode> serde::Serialize for ExtrinsicWrapper<Xt> {
-	fn serialize<S>(&self, seq: S) -> Result<S::Ok, S::Error>
-	where
-		S: ::serde::Serializer,
-	{
-		self.using_encoded(|bytes| seq.serialize_bytes(bytes))
-	}
-}
-
-impl<Xt> From<Xt> for ExtrinsicWrapper<Xt> {
-	fn from(xt: Xt) -> Self {
-		ExtrinsicWrapper(xt)
-	}
-}
-
-impl<Xt> Deref for ExtrinsicWrapper<Xt> {
-	type Target = Xt;
-
-	fn deref(&self) -> &Self::Target {
-		&self.0
-	}
-}
-
 /// Testing block
 #[derive(PartialEq, Eq, Clone, Serialize, Debug, Encode, Decode, TypeInfo)]
 pub struct Block<Xt> {
@@ -246,7 +212,16 @@ impl<Xt> traits::HeaderProvider for Block<Xt> {
 }
 
 impl<
-		Xt: 'static + Codec + Sized + Send + Sync + Serialize + Clone + Eq + Debug + traits::Extrinsic,
+		Xt: 'static
+			+ Codec
+			+ Sized
+			+ Send
+			+ Sync
+			+ Serialize
+			+ Clone
+			+ Eq
+			+ Debug
+			+ traits::ExtrinsicLike,
 	> traits::Block for Block<Xt>
 {
 	type Extrinsic = Xt;
@@ -281,139 +256,25 @@ where
 	}
 }
 
-/// The signature payload of a `TestXt`.
-type TxSignaturePayload<Extra> = (u64, Extra);
-
-impl<Extra: TypeInfo> SignaturePayload for TxSignaturePayload<Extra> {
-	type SignatureAddress = u64;
-	type Signature = ();
-	type SignatureExtra = Extra;
-}
-
-/// Test transaction, tuple of (sender, call, signed_extra)
-/// with index only used if sender is some.
-///
-/// If sender is some then the transaction is signed otherwise it is unsigned.
-#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo)]
-pub struct TestXt<Call, Extra> {
-	/// Signature of the extrinsic.
-	pub signature: Option<TxSignaturePayload<Extra>>,
-	/// Call of the extrinsic.
-	pub call: Call,
-}
-
-impl<Call, Extra> TestXt<Call, Extra> {
-	/// Create a new `TextXt`.
-	pub fn new(call: Call, signature: Option<(u64, Extra)>) -> Self {
-		Self { call, signature }
-	}
-}
-
-impl<Call, Extra> Serialize for TestXt<Call, Extra>
-where
-	TestXt<Call, Extra>: Encode,
-{
-	fn serialize<S>(&self, seq: S) -> Result<S::Ok, S::Error>
-	where
-		S: Serializer,
-	{
-		self.using_encoded(|bytes| seq.serialize_bytes(bytes))
-	}
-}
-
-impl<Call, Extra> Debug for TestXt<Call, Extra> {
-	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-		write!(f, "TestXt({:?}, ...)", self.signature.as_ref().map(|x| &x.0))
-	}
-}
-
-impl<Call: Codec + Sync + Send, Context, Extra> Checkable<Context> for TestXt<Call, Extra> {
-	type Checked = Self;
-	fn check(self, _: &Context) -> Result<Self::Checked, TransactionValidityError> {
-		Ok(self)
-	}
-
-	#[cfg(feature = "try-runtime")]
-	fn unchecked_into_checked_i_know_what_i_am_doing(
-		self,
-		_: &Context,
-	) -> Result<Self::Checked, TransactionValidityError> {
-		unreachable!()
-	}
-}
-
-impl<Call: Codec + Sync + Send + TypeInfo, Extra: TypeInfo> traits::Extrinsic
-	for TestXt<Call, Extra>
-{
-	type Call = Call;
-	type SignaturePayload = TxSignaturePayload<Extra>;
+/// Extrinsic type with `u64` accounts and mocked signatures, used in testing.
+pub type TestXt<Call, Extra> = UncheckedExtrinsic<u64, Call, (), Extra>;
 
-	fn is_signed(&self) -> Option<bool> {
-		Some(self.signature.is_some())
-	}
+/// Wrapper over a `u64` that can be used as a `RuntimeCall`.
+#[derive(PartialEq, Eq, Debug, Clone, Encode, Decode, TypeInfo)]
+pub struct MockCallU64(pub u64);
 
-	fn new(c: Call, sig: Option<Self::SignaturePayload>) -> Option<Self> {
-		Some(TestXt { signature: sig, call: c })
+impl Dispatchable for MockCallU64 {
+	type RuntimeOrigin = u64;
+	type Config = ();
+	type Info = ();
+	type PostInfo = ();
+	fn dispatch(self, _origin: Self::RuntimeOrigin) -> DispatchResultWithInfo<Self::PostInfo> {
+		Ok(())
 	}
 }
 
-impl<Call, Extra> traits::ExtrinsicMetadata for TestXt<Call, Extra>
-where
-	Call: Codec + Sync + Send,
-	Extra: SignedExtension<AccountId = u64, Call = Call>,
-{
-	type SignedExtensions = Extra;
-	const VERSION: u8 = 0u8;
-}
-
-impl<Origin, Call, Extra> Applyable for TestXt<Call, Extra>
-where
-	Call: 'static
-		+ Sized
-		+ Send
-		+ Sync
-		+ Clone
-		+ Eq
-		+ Codec
-		+ Debug
-		+ Dispatchable<RuntimeOrigin = Origin>,
-	Extra: SignedExtension<AccountId = u64, Call = Call>,
-	Origin: From<Option<u64>>,
-{
-	type Call = Call;
-
-	/// Checks to see if this is a valid *transaction*. It returns information on it if so.
-	fn validate<U: ValidateUnsigned<Call = Self::Call>>(
-		&self,
-		source: TransactionSource,
-		info: &DispatchInfoOf<Self::Call>,
-		len: usize,
-	) -> TransactionValidity {
-		if let Some((ref id, ref extra)) = self.signature {
-			Extra::validate(extra, id, &self.call, info, len)
-		} else {
-			let valid = Extra::validate_unsigned(&self.call, info, len)?;
-			let unsigned_validation = U::validate_unsigned(source, &self.call)?;
-			Ok(valid.combine_with(unsigned_validation))
-		}
-	}
-
-	/// Executes all necessary logic needed prior to dispatch and deconstructs into function call,
-	/// index and sender.
-	fn apply<U: ValidateUnsigned<Call = Self::Call>>(
-		self,
-		info: &DispatchInfoOf<Self::Call>,
-		len: usize,
-	) -> ApplyExtrinsicResultWithInfo<PostDispatchInfoOf<Self::Call>> {
-		let maybe_who = if let Some((who, extra)) = self.signature {
-			Extra::pre_dispatch(extra, &who, &self.call, info, len)?;
-			Some(who)
-		} else {
-			Extra::pre_dispatch_unsigned(&self.call, info, len)?;
-			U::pre_dispatch(&self.call)?;
-			None
-		};
-
-		Ok(self.call.dispatch(maybe_who.into()))
+impl From<u64> for MockCallU64 {
+	fn from(value: u64) -> Self {
+		Self(value)
 	}
 }
diff --git a/substrate/primitives/runtime/src/traits.rs b/substrate/primitives/runtime/src/traits/mod.rs
similarity index 91%
rename from substrate/primitives/runtime/src/traits.rs
rename to substrate/primitives/runtime/src/traits/mod.rs
index fc63bc76dec..e6906cdb387 100644
--- a/substrate/primitives/runtime/src/traits.rs
+++ b/substrate/primitives/runtime/src/traits/mod.rs
@@ -19,7 +19,7 @@
 
 use crate::{
 	generic::Digest,
-	scale_info::{MetaType, StaticTypeInfo, TypeInfo},
+	scale_info::{StaticTypeInfo, TypeInfo},
 	transaction_validity::{
 		TransactionSource, TransactionValidity, TransactionValidityError, UnknownTransaction,
 		ValidTransaction,
@@ -52,6 +52,11 @@ use std::fmt::Display;
 #[cfg(feature = "std")]
 use std::str::FromStr;
 
+pub mod transaction_extension;
+pub use transaction_extension::{
+	DispatchTransaction, TransactionExtension, TransactionExtensionMetadata, ValidateResult,
+};
+
 /// A lazy value.
 pub trait Lazy<T: ?Sized> {
 	/// Get a reference to the underlying value.
@@ -226,8 +231,14 @@ pub trait StaticLookup {
 }
 
 /// A lookup implementation returning the input value.
-#[derive(Default, Clone, Copy, PartialEq, Eq)]
+#[derive(Clone, Copy, PartialEq, Eq)]
 pub struct IdentityLookup<T>(PhantomData<T>);
+impl<T> Default for IdentityLookup<T> {
+	fn default() -> Self {
+		Self(PhantomData::<T>::default())
+	}
+}
+
 impl<T: Codec + Clone + PartialEq + Debug + TypeInfo> StaticLookup for IdentityLookup<T> {
 	type Source = T;
 	type Target = T;
@@ -1253,7 +1264,7 @@ pub trait Header:
 // that is then used to define `UncheckedExtrinsic`.
 // ```ignore
 // pub type UncheckedExtrinsic =
-// 	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+// 	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
 // ```
 // This `UncheckedExtrinsic` is supplied to the `Block`.
 // ```ignore
@@ -1286,7 +1297,7 @@ pub trait Block:
 	+ 'static
 {
 	/// Type for extrinsics.
-	type Extrinsic: Member + Codec + Extrinsic + MaybeSerialize;
+	type Extrinsic: Member + Codec + ExtrinsicLike + MaybeSerialize;
 	/// Header type.
 	type Header: Header<Hash = Self::Hash> + MaybeSerializeDeserialize;
 	/// Block hash type.
@@ -1310,6 +1321,7 @@ pub trait Block:
 }
 
 /// Something that acts like an `Extrinsic`.
+#[deprecated = "Use `ExtrinsicLike` along with the `CreateTransaction` trait family instead"]
 pub trait Extrinsic: Sized {
 	/// The function call.
 	type Call: TypeInfo;
@@ -1327,17 +1339,49 @@ pub trait Extrinsic: Sized {
 		None
 	}
 
-	/// Create new instance of the extrinsic.
-	///
-	/// Extrinsics can be split into:
-	/// 1. Inherents (no signature; created by validators during block production)
-	/// 2. Unsigned Transactions (no signature; represent "system calls" or other special kinds of
-	/// calls) 3. Signed Transactions (with signature; a regular transactions with known origin)
+	/// Returns `true` if this `Extrinsic` is bare.
+	fn is_bare(&self) -> bool {
+		!self.is_signed().unwrap_or(true)
+	}
+
+	/// Create a new old-school extrinsic, either a bare extrinsic if `_signed_data` is `None` or
+	/// a signed transaction is it is `Some`.
 	fn new(_call: Self::Call, _signed_data: Option<Self::SignaturePayload>) -> Option<Self> {
 		None
 	}
 }
 
+/// Something that acts like an `Extrinsic`.
+pub trait ExtrinsicLike: Sized {
+	/// Is this `Extrinsic` signed?
+	/// If no information are available about signed/unsigned, `None` should be returned.
+	#[deprecated = "Use and implement `!is_bare()` instead"]
+	fn is_signed(&self) -> Option<bool> {
+		None
+	}
+
+	/// Returns `true` if this `Extrinsic` is bare.
+	fn is_bare(&self) -> bool {
+		#[allow(deprecated)]
+		!self.is_signed().unwrap_or(true)
+	}
+}
+
+#[allow(deprecated)]
+impl<T> ExtrinsicLike for T
+where
+	T: Extrinsic,
+{
+	fn is_signed(&self) -> Option<bool> {
+		#[allow(deprecated)]
+		<Self as Extrinsic>::is_signed(&self)
+	}
+
+	fn is_bare(&self) -> bool {
+		<Self as Extrinsic>::is_bare(&self)
+	}
+}
+
 /// Something that acts like a [`SignaturePayload`](Extrinsic::SignaturePayload) of an
 /// [`Extrinsic`].
 pub trait SignaturePayload {
@@ -1370,8 +1414,8 @@ pub trait ExtrinsicMetadata {
 	/// By format is meant the encoded representation of the `Extrinsic`.
 	const VERSION: u8;
 
-	/// Signed extensions attached to this `Extrinsic`.
-	type SignedExtensions: SignedExtension;
+	/// Transaction extensions attached to this `Extrinsic`.
+	type TransactionExtensions;
 }
 
 /// Extract the hashing type for a block.
@@ -1435,6 +1479,27 @@ impl<T: BlindCheckable, Context> Checkable<Context> for T {
 	}
 }
 
+/// A type that can handle weight refunds.
+pub trait RefundWeight {
+	/// Refund some unspent weight.
+	fn refund(&mut self, weight: sp_weights::Weight);
+}
+
+/// A type that can handle weight refunds and incorporate extension weights into the call weight
+/// after dispatch.
+pub trait ExtensionPostDispatchWeightHandler<DispatchInfo>: RefundWeight {
+	/// Accrue some weight pertaining to the extension.
+	fn set_extension_weight(&mut self, info: &DispatchInfo);
+}
+
+impl RefundWeight for () {
+	fn refund(&mut self, _weight: sp_weights::Weight) {}
+}
+
+impl ExtensionPostDispatchWeightHandler<()> for () {
+	fn set_extension_weight(&mut self, _info: &()) {}
+}
+
 /// A lazy call (module function and argument values) that can be executed via its `dispatch`
 /// method.
 pub trait Dispatchable {
@@ -1450,12 +1515,21 @@ pub trait Dispatchable {
 	type Info;
 	/// Additional information that is returned by `dispatch`. Can be used to supply the caller
 	/// with information about a `Dispatchable` that is only known post dispatch.
-	type PostInfo: Eq + PartialEq + Clone + Copy + Encode + Decode + Printable;
+	type PostInfo: Eq
+		+ PartialEq
+		+ Clone
+		+ Copy
+		+ Encode
+		+ Decode
+		+ Printable
+		+ ExtensionPostDispatchWeightHandler<Self::Info>;
 	/// Actually dispatch this call and return the result of it.
 	fn dispatch(self, origin: Self::RuntimeOrigin)
 		-> crate::DispatchResultWithInfo<Self::PostInfo>;
 }
 
+/// Shortcut to reference the `RuntimeOrigin` type of a `Dispatchable`.
+pub type DispatchOriginOf<T> = <T as Dispatchable>::RuntimeOrigin;
 /// Shortcut to reference the `Info` type of a `Dispatchable`.
 pub type DispatchInfoOf<T> = <T as Dispatchable>::Info;
 /// Shortcut to reference the `PostInfo` type of a `Dispatchable`.
@@ -1474,8 +1548,75 @@ impl Dispatchable for () {
 	}
 }
 
+/// Dispatchable impl containing an arbitrary value which panics if it actually is dispatched.
+#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)]
+pub struct FakeDispatchable<Inner>(pub Inner);
+impl<Inner> From<Inner> for FakeDispatchable<Inner> {
+	fn from(inner: Inner) -> Self {
+		Self(inner)
+	}
+}
+impl<Inner> FakeDispatchable<Inner> {
+	/// Take `self` and return the underlying inner value.
+	pub fn deconstruct(self) -> Inner {
+		self.0
+	}
+}
+impl<Inner> AsRef<Inner> for FakeDispatchable<Inner> {
+	fn as_ref(&self) -> &Inner {
+		&self.0
+	}
+}
+
+impl<Inner> Dispatchable for FakeDispatchable<Inner> {
+	type RuntimeOrigin = ();
+	type Config = ();
+	type Info = ();
+	type PostInfo = ();
+	fn dispatch(
+		self,
+		_origin: Self::RuntimeOrigin,
+	) -> crate::DispatchResultWithInfo<Self::PostInfo> {
+		panic!("This implementation should not be used for actual dispatch.");
+	}
+}
+
+/// Runtime Origin which includes a System Origin variant whose `AccountId` is the parameter.
+pub trait AsSystemOriginSigner<AccountId> {
+	/// Extract a reference of the inner value of the System `Origin::Signed` variant, if self has
+	/// that variant.
+	fn as_system_origin_signer(&self) -> Option<&AccountId>;
+}
+
+/// Interface to differentiate between Runtime Origins authorized to include a transaction into the
+/// block and dispatch it, and those who aren't.
+///
+/// This trait targets transactions, by which we mean extrinsics which are validated through a
+/// [`TransactionExtension`]. This excludes bare extrinsics (i.e. inherents), which have their call,
+/// not their origin, validated and authorized.
+///
+/// Typically, upon validation or application of a transaction, the origin resulting from the
+/// transaction extension (see [`TransactionExtension`]) is checked for authorization. The
+/// transaction is then rejected or applied.
+///
+/// In FRAME, an authorized origin is either an `Origin::Signed` System origin or a custom origin
+/// authorized in a [`TransactionExtension`].
+pub trait AsTransactionAuthorizedOrigin {
+	/// Whether the origin is authorized to include a transaction in a block.
+	///
+	/// In typical FRAME chains, this function returns `false` if the origin is a System
+	/// `Origin::None` variant, `true` otherwise, meaning only signed or custom origin resulting
+	/// from the transaction extension pipeline are authorized.
+	///
+	/// NOTE: This function should not be used in the context of bare extrinsics (i.e. inherents),
+	/// as bare extrinsics do not authorize the origin but rather the call itself, and are not
+	/// validated through the [`TransactionExtension`] pipeline.
+	fn is_transaction_authorized(&self) -> bool;
+}
+
 /// Means by which a transaction may be extended. This type embodies both the data and the logic
 /// that should be additionally associated with the transaction. It should be plain old data.
+#[deprecated = "Use `TransactionExtension` instead."]
 pub trait SignedExtension:
 	Codec + Debug + Sync + Send + Clone + Eq + PartialEq + StaticTypeInfo
 {
@@ -1493,7 +1634,7 @@ pub trait SignedExtension:
 
 	/// Any additional data that will go into the signed payload. This may be created dynamically
 	/// from the transaction using the `additional_signed` function.
-	type AdditionalSigned: Encode + TypeInfo;
+	type AdditionalSigned: Codec + TypeInfo;
 
 	/// The type that encodes information that can be passed from pre_dispatch to post-dispatch.
 	type Pre;
@@ -1532,38 +1673,6 @@ pub trait SignedExtension:
 		len: usize,
 	) -> Result<Self::Pre, TransactionValidityError>;
 
-	/// Validate an unsigned transaction for the transaction queue.
-	///
-	/// This function can be called frequently by the transaction queue
-	/// to obtain transaction validity against current state.
-	/// It should perform all checks that determine a valid unsigned transaction,
-	/// and quickly eliminate ones that are stale or incorrect.
-	///
-	/// Make sure to perform the same checks in `pre_dispatch_unsigned` function.
-	fn validate_unsigned(
-		_call: &Self::Call,
-		_info: &DispatchInfoOf<Self::Call>,
-		_len: usize,
-	) -> TransactionValidity {
-		Ok(ValidTransaction::default())
-	}
-
-	/// Do any pre-flight stuff for a unsigned transaction.
-	///
-	/// Note this function by default delegates to `validate_unsigned`, so that
-	/// all checks performed for the transaction queue are also performed during
-	/// the dispatch phase (applying the extrinsic).
-	///
-	/// If you ever override this function, you need to make sure to always
-	/// perform the same validation as in `validate_unsigned`.
-	fn pre_dispatch_unsigned(
-		call: &Self::Call,
-		info: &DispatchInfoOf<Self::Call>,
-		len: usize,
-	) -> Result<(), TransactionValidityError> {
-		Self::validate_unsigned(call, info, len).map(|_| ()).map_err(Into::into)
-	}
-
 	/// Do any post-flight stuff for an extrinsic.
 	///
 	/// If the transaction is signed, then `_pre` will contain the output of `pre_dispatch`,
@@ -1594,125 +1703,46 @@ pub trait SignedExtension:
 	///
 	/// As a [`SignedExtension`] can be a tuple of [`SignedExtension`]s we need to return a `Vec`
 	/// that holds the metadata of each one. Each individual `SignedExtension` must return
-	/// *exactly* one [`SignedExtensionMetadata`].
+	/// *exactly* one [`TransactionExtensionMetadata`].
 	///
 	/// This method provides a default implementation that returns a vec containing a single
-	/// [`SignedExtensionMetadata`].
-	fn metadata() -> Vec<SignedExtensionMetadata> {
-		alloc::vec![SignedExtensionMetadata {
+	/// [`TransactionExtensionMetadata`].
+	fn metadata() -> Vec<TransactionExtensionMetadata> {
+		sp_std::vec![TransactionExtensionMetadata {
 			identifier: Self::IDENTIFIER,
 			ty: scale_info::meta_type::<Self>(),
-			additional_signed: scale_info::meta_type::<Self::AdditionalSigned>()
+			implicit: scale_info::meta_type::<Self::AdditionalSigned>()
 		}]
 	}
-}
-
-/// Information about a [`SignedExtension`] for the runtime metadata.
-pub struct SignedExtensionMetadata {
-	/// The unique identifier of the [`SignedExtension`].
-	pub identifier: &'static str,
-	/// The type of the [`SignedExtension`].
-	pub ty: MetaType,
-	/// The type of the [`SignedExtension`] additional signed data for the payload.
-	pub additional_signed: MetaType,
-}
-
-#[impl_for_tuples(1, 12)]
-impl<AccountId, Call: Dispatchable> SignedExtension for Tuple {
-	for_tuples!( where #( Tuple: SignedExtension<AccountId=AccountId, Call=Call,> )* );
-	type AccountId = AccountId;
-	type Call = Call;
-	const IDENTIFIER: &'static str = "You should call `identifier()`!";
-	for_tuples!( type AdditionalSigned = ( #( Tuple::AdditionalSigned ),* ); );
-	for_tuples!( type Pre = ( #( Tuple::Pre ),* ); );
-
-	fn additional_signed(&self) -> Result<Self::AdditionalSigned, TransactionValidityError> {
-		Ok(for_tuples!( ( #( Tuple.additional_signed()? ),* ) ))
-	}
-
-	fn validate(
-		&self,
-		who: &Self::AccountId,
-		call: &Self::Call,
-		info: &DispatchInfoOf<Self::Call>,
-		len: usize,
-	) -> TransactionValidity {
-		let valid = ValidTransaction::default();
-		for_tuples!( #( let valid = valid.combine_with(Tuple.validate(who, call, info, len)?); )* );
-		Ok(valid)
-	}
-
-	fn pre_dispatch(
-		self,
-		who: &Self::AccountId,
-		call: &Self::Call,
-		info: &DispatchInfoOf<Self::Call>,
-		len: usize,
-	) -> Result<Self::Pre, TransactionValidityError> {
-		Ok(for_tuples!( ( #( Tuple.pre_dispatch(who, call, info, len)? ),* ) ))
-	}
 
+	/// Validate an unsigned transaction for the transaction queue.
+	///
+	/// This function can be called frequently by the transaction queue
+	/// to obtain transaction validity against current state.
+	/// It should perform all checks that determine a valid unsigned transaction,
+	/// and quickly eliminate ones that are stale or incorrect.
 	fn validate_unsigned(
-		call: &Self::Call,
-		info: &DispatchInfoOf<Self::Call>,
-		len: usize,
+		_call: &Self::Call,
+		_info: &DispatchInfoOf<Self::Call>,
+		_len: usize,
 	) -> TransactionValidity {
-		let valid = ValidTransaction::default();
-		for_tuples!( #( let valid = valid.combine_with(Tuple::validate_unsigned(call, info, len)?); )* );
-		Ok(valid)
+		Ok(ValidTransaction::default())
 	}
 
+	/// Do any pre-flight stuff for an unsigned transaction.
+	///
+	/// Note this function by default delegates to `validate_unsigned`, so that
+	/// all checks performed for the transaction queue are also performed during
+	/// the dispatch phase (applying the extrinsic).
+	///
+	/// If you ever override this function, you need not perform the same validation as in
+	/// `validate_unsigned`.
 	fn pre_dispatch_unsigned(
 		call: &Self::Call,
 		info: &DispatchInfoOf<Self::Call>,
 		len: usize,
 	) -> Result<(), TransactionValidityError> {
-		for_tuples!( #( Tuple::pre_dispatch_unsigned(call, info, len)?; )* );
-		Ok(())
-	}
-
-	fn post_dispatch(
-		pre: Option<Self::Pre>,
-		info: &DispatchInfoOf<Self::Call>,
-		post_info: &PostDispatchInfoOf<Self::Call>,
-		len: usize,
-		result: &DispatchResult,
-	) -> Result<(), TransactionValidityError> {
-		match pre {
-			Some(x) => {
-				for_tuples!( #( Tuple::post_dispatch(Some(x.Tuple), info, post_info, len, result)?; )* );
-			},
-			None => {
-				for_tuples!( #( Tuple::post_dispatch(None, info, post_info, len, result)?; )* );
-			},
-		}
-		Ok(())
-	}
-
-	fn metadata() -> Vec<SignedExtensionMetadata> {
-		let mut ids = Vec::new();
-		for_tuples!( #( ids.extend(Tuple::metadata()); )* );
-		ids
-	}
-}
-
-impl SignedExtension for () {
-	type AccountId = u64;
-	type AdditionalSigned = ();
-	type Call = ();
-	type Pre = ();
-	const IDENTIFIER: &'static str = "UnitSignedExtension";
-	fn additional_signed(&self) -> core::result::Result<(), TransactionValidityError> {
-		Ok(())
-	}
-	fn pre_dispatch(
-		self,
-		who: &Self::AccountId,
-		call: &Self::Call,
-		info: &DispatchInfoOf<Self::Call>,
-		len: usize,
-	) -> Result<Self::Pre, TransactionValidityError> {
-		self.validate(who, call, info, len).map(|_| ())
+		Self::validate_unsigned(call, info, len).map(|_| ()).map_err(Into::into)
 	}
 }
 
@@ -1722,11 +1752,23 @@ impl SignedExtension for () {
 ///
 /// Also provides information on to whom this information is attributable and an index that allows
 /// each piece of attributable information to be disambiguated.
+///
+/// IMPORTANT: After validation, in both [validate](Applyable::validate) and
+/// [apply](Applyable::apply), all transactions should have *some* authorized origin, except for
+/// inherents. This is necessary in order to protect the chain against spam. If no extension in the
+/// transaction extension pipeline authorized the transaction with an origin, either a system signed
+/// origin or a custom origin, then the transaction must be rejected, as the extensions provided in
+/// substrate which protect the chain, such as `CheckNonce`, `ChargeTransactionPayment` etc., rely
+/// on the assumption that the system handles system signed transactions, and the pallets handle the
+/// custom origin that they authorized.
 pub trait Applyable: Sized + Send + Sync {
 	/// Type by which we can dispatch. Restricts the `UnsignedValidator` type.
 	type Call: Dispatchable;
 
 	/// Checks to see if this is a valid *transaction*. It returns information on it if so.
+	///
+	/// IMPORTANT: Ensure that *some* origin has been authorized after validating the transaction.
+	/// If no origin was authorized, the transaction must be rejected.
 	fn validate<V: ValidateUnsigned<Call = Self::Call>>(
 		&self,
 		source: TransactionSource,
@@ -1736,6 +1778,9 @@ pub trait Applyable: Sized + Send + Sync {
 
 	/// Executes all necessary logic needed prior to dispatch and deconstructs into function call,
 	/// index and sender.
+	///
+	/// IMPORTANT: Ensure that *some* origin has been authorized after validating the
+	/// transaction. If no origin was authorized, the transaction must be rejected.
 	fn apply<V: ValidateUnsigned<Call = Self::Call>>(
 		self,
 		info: &DispatchInfoOf<Self::Call>,
diff --git a/substrate/primitives/runtime/src/traits/transaction_extension/as_transaction_extension.rs b/substrate/primitives/runtime/src/traits/transaction_extension/as_transaction_extension.rs
new file mode 100644
index 00000000000..a5179748673
--- /dev/null
+++ b/substrate/primitives/runtime/src/traits/transaction_extension/as_transaction_extension.rs
@@ -0,0 +1,130 @@
+// This file is part of Substrate.
+
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! The [AsTransactionExtension] adapter struct for adapting [SignedExtension]s to
+//! [TransactionExtension]s.
+
+#![allow(deprecated)]
+
+use scale_info::TypeInfo;
+use sp_core::RuntimeDebug;
+
+use crate::{
+	traits::{AsSystemOriginSigner, SignedExtension, ValidateResult},
+	transaction_validity::InvalidTransaction,
+};
+
+use super::*;
+
+/// Adapter to use a `SignedExtension` in the place of a `TransactionExtension`.
+#[derive(TypeInfo, Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)]
+#[deprecated = "Convert your SignedExtension to a TransactionExtension."]
+pub struct AsTransactionExtension<SE: SignedExtension>(pub SE);
+
+impl<SE: SignedExtension + Default> Default for AsTransactionExtension<SE> {
+	fn default() -> Self {
+		Self(SE::default())
+	}
+}
+
+impl<SE: SignedExtension> From<SE> for AsTransactionExtension<SE> {
+	fn from(value: SE) -> Self {
+		Self(value)
+	}
+}
+
+impl<SE: SignedExtension> TransactionExtension<SE::Call> for AsTransactionExtension<SE>
+where
+	<SE::Call as Dispatchable>::RuntimeOrigin: AsSystemOriginSigner<SE::AccountId> + Clone,
+{
+	const IDENTIFIER: &'static str = SE::IDENTIFIER;
+	type Implicit = SE::AdditionalSigned;
+
+	fn implicit(&self) -> Result<Self::Implicit, TransactionValidityError> {
+		self.0.additional_signed()
+	}
+	fn metadata() -> Vec<TransactionExtensionMetadata> {
+		SE::metadata()
+	}
+	fn weight(&self, _call: &SE::Call) -> Weight {
+		Weight::zero()
+	}
+	type Val = ();
+	type Pre = SE::Pre;
+
+	fn validate(
+		&self,
+		origin: <SE::Call as Dispatchable>::RuntimeOrigin,
+		call: &SE::Call,
+		info: &DispatchInfoOf<SE::Call>,
+		len: usize,
+		_self_implicit: Self::Implicit,
+		_inherited_implication: &impl Encode,
+	) -> ValidateResult<Self::Val, SE::Call> {
+		let who = origin.as_system_origin_signer().ok_or(InvalidTransaction::BadSigner)?;
+		let r = self.0.validate(who, call, info, len)?;
+		Ok((r, (), origin))
+	}
+
+	fn prepare(
+		self,
+		_: (),
+		origin: &<SE::Call as Dispatchable>::RuntimeOrigin,
+		call: &SE::Call,
+		info: &DispatchInfoOf<SE::Call>,
+		len: usize,
+	) -> Result<Self::Pre, TransactionValidityError> {
+		let who = origin.as_system_origin_signer().ok_or(InvalidTransaction::BadSigner)?;
+		self.0.pre_dispatch(who, call, info, len)
+	}
+
+	fn post_dispatch_details(
+		pre: Self::Pre,
+		info: &DispatchInfoOf<SE::Call>,
+		post_info: &PostDispatchInfoOf<SE::Call>,
+		len: usize,
+		result: &DispatchResult,
+	) -> Result<Weight, TransactionValidityError> {
+		SE::post_dispatch(Some(pre), info, post_info, len, result)?;
+		Ok(Weight::zero())
+	}
+
+	fn bare_validate(
+		call: &SE::Call,
+		info: &DispatchInfoOf<SE::Call>,
+		len: usize,
+	) -> TransactionValidity {
+		SE::validate_unsigned(call, info, len)
+	}
+
+	fn bare_validate_and_prepare(
+		call: &SE::Call,
+		info: &DispatchInfoOf<SE::Call>,
+		len: usize,
+	) -> Result<(), TransactionValidityError> {
+		SE::pre_dispatch_unsigned(call, info, len)
+	}
+
+	fn bare_post_dispatch(
+		info: &DispatchInfoOf<SE::Call>,
+		post_info: &mut PostDispatchInfoOf<SE::Call>,
+		len: usize,
+		result: &DispatchResult,
+	) -> Result<(), TransactionValidityError> {
+		SE::post_dispatch(None, info, post_info, len, result)
+	}
+}
diff --git a/substrate/primitives/runtime/src/traits/transaction_extension/dispatch_transaction.rs b/substrate/primitives/runtime/src/traits/transaction_extension/dispatch_transaction.rs
new file mode 100644
index 00000000000..e2fb556bf9d
--- /dev/null
+++ b/substrate/primitives/runtime/src/traits/transaction_extension/dispatch_transaction.rs
@@ -0,0 +1,154 @@
+// This file is part of Substrate.
+
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! The [DispatchTransaction] trait.
+
+use crate::{traits::AsTransactionAuthorizedOrigin, transaction_validity::InvalidTransaction};
+
+use super::*;
+
+/// Single-function utility trait with a blanket impl over [`TransactionExtension`] in order to
+/// provide transaction dispatching functionality. We avoid implementing this directly on the trait
+/// since we never want it to be overriden by the trait implementation.
+pub trait DispatchTransaction<Call: Dispatchable> {
+	/// The origin type of the transaction.
+	type Origin;
+	/// The info type.
+	type Info;
+	/// The resultant type.
+	type Result;
+	/// The `Val` of the extension.
+	type Val;
+	/// The `Pre` of the extension.
+	type Pre;
+	/// Just validate a transaction.
+	///
+	/// The is basically the same as [validate](TransactionExtension::validate), except that there
+	/// is no need to supply the bond data.
+	fn validate_only(
+		&self,
+		origin: Self::Origin,
+		call: &Call,
+		info: &Self::Info,
+		len: usize,
+	) -> Result<(ValidTransaction, Self::Val, Self::Origin), TransactionValidityError>;
+	/// Validate and prepare a transaction, ready for dispatch.
+	fn validate_and_prepare(
+		self,
+		origin: Self::Origin,
+		call: &Call,
+		info: &Self::Info,
+		len: usize,
+	) -> Result<(Self::Pre, Self::Origin), TransactionValidityError>;
+	/// Dispatch a transaction with the given base origin and call.
+	fn dispatch_transaction(
+		self,
+		origin: Self::Origin,
+		call: Call,
+		info: &Self::Info,
+		len: usize,
+	) -> Self::Result;
+	/// Do everything which would be done in a [dispatch_transaction](Self::dispatch_transaction),
+	/// but instead of executing the call, execute `substitute` instead. Since this doesn't actually
+	/// dispatch the call, it doesn't need to consume it and so `call` can be passed as a reference.
+	fn test_run(
+		self,
+		origin: Self::Origin,
+		call: &Call,
+		info: &Self::Info,
+		len: usize,
+		substitute: impl FnOnce(
+			Self::Origin,
+		) -> crate::DispatchResultWithInfo<<Call as Dispatchable>::PostInfo>,
+	) -> Self::Result;
+}
+
+impl<T: TransactionExtension<Call>, Call: Dispatchable + Encode> DispatchTransaction<Call> for T
+where
+	<Call as Dispatchable>::RuntimeOrigin: AsTransactionAuthorizedOrigin,
+{
+	type Origin = <Call as Dispatchable>::RuntimeOrigin;
+	type Info = DispatchInfoOf<Call>;
+	type Result = crate::ApplyExtrinsicResultWithInfo<PostDispatchInfoOf<Call>>;
+	type Val = T::Val;
+	type Pre = T::Pre;
+
+	fn validate_only(
+		&self,
+		origin: Self::Origin,
+		call: &Call,
+		info: &DispatchInfoOf<Call>,
+		len: usize,
+	) -> Result<(ValidTransaction, T::Val, Self::Origin), TransactionValidityError> {
+		match self.validate(origin, call, info, len, self.implicit()?, call) {
+			// After validation, some origin must have been authorized.
+			Ok((_, _, origin)) if !origin.is_transaction_authorized() =>
+				Err(InvalidTransaction::UnknownOrigin.into()),
+			res => res,
+		}
+	}
+	fn validate_and_prepare(
+		self,
+		origin: Self::Origin,
+		call: &Call,
+		info: &DispatchInfoOf<Call>,
+		len: usize,
+	) -> Result<(T::Pre, Self::Origin), TransactionValidityError> {
+		let (_, val, origin) = self.validate_only(origin, call, info, len)?;
+		let pre = self.prepare(val, &origin, &call, info, len)?;
+		Ok((pre, origin))
+	}
+	fn dispatch_transaction(
+		self,
+		origin: <Call as Dispatchable>::RuntimeOrigin,
+		call: Call,
+		info: &DispatchInfoOf<Call>,
+		len: usize,
+	) -> Self::Result {
+		let (pre, origin) = self.validate_and_prepare(origin, &call, info, len)?;
+		let mut res = call.dispatch(origin);
+		let pd_res = res.map(|_| ()).map_err(|e| e.error);
+		let post_info = match &mut res {
+			Ok(info) => info,
+			Err(err) => &mut err.post_info,
+		};
+		post_info.set_extension_weight(info);
+		T::post_dispatch(pre, info, post_info, len, &pd_res)?;
+		Ok(res)
+	}
+	fn test_run(
+		self,
+		origin: Self::Origin,
+		call: &Call,
+		info: &Self::Info,
+		len: usize,
+		substitute: impl FnOnce(
+			Self::Origin,
+		) -> crate::DispatchResultWithInfo<<Call as Dispatchable>::PostInfo>,
+	) -> Self::Result {
+		let (pre, origin) = self.validate_and_prepare(origin, &call, info, len)?;
+		let mut res = substitute(origin);
+		let pd_res = res.map(|_| ()).map_err(|e| e.error);
+		let post_info = match &mut res {
+			Ok(info) => info,
+			Err(err) => &mut err.post_info,
+		};
+		post_info.set_extension_weight(info);
+		T::post_dispatch(pre, info, post_info, len, &pd_res)?;
+		Ok(res)
+	}
+}
diff --git a/substrate/primitives/runtime/src/traits/transaction_extension/mod.rs b/substrate/primitives/runtime/src/traits/transaction_extension/mod.rs
new file mode 100644
index 00000000000..58cd0974661
--- /dev/null
+++ b/substrate/primitives/runtime/src/traits/transaction_extension/mod.rs
@@ -0,0 +1,635 @@
+// This file is part of Substrate.
+
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! The transaction extension trait.
+
+use crate::{
+	scale_info::{MetaType, StaticTypeInfo},
+	transaction_validity::{TransactionValidity, TransactionValidityError, ValidTransaction},
+	DispatchResult,
+};
+use codec::{Codec, Decode, Encode};
+use impl_trait_for_tuples::impl_for_tuples;
+#[doc(hidden)]
+pub use sp_std::marker::PhantomData;
+use sp_std::{self, fmt::Debug, prelude::*};
+use sp_weights::Weight;
+use tuplex::{PopFront, PushBack};
+
+use super::{
+	DispatchInfoOf, DispatchOriginOf, Dispatchable, ExtensionPostDispatchWeightHandler,
+	PostDispatchInfoOf, RefundWeight,
+};
+
+mod as_transaction_extension;
+mod dispatch_transaction;
+#[allow(deprecated)]
+pub use as_transaction_extension::AsTransactionExtension;
+pub use dispatch_transaction::DispatchTransaction;
+
+/// Shortcut for the result value of the `validate` function.
+pub type ValidateResult<Val, Call> =
+	Result<(ValidTransaction, Val, DispatchOriginOf<Call>), TransactionValidityError>;
+
+/// Means by which a transaction may be extended. This type embodies both the data and the logic
+/// that should be additionally associated with the transaction. It should be plain old data.
+///
+/// The simplest transaction extension would be the Unit type (and empty pipeline) `()`. This
+/// executes no additional logic and implies a dispatch of the transaction's call using the
+/// inherited origin (either `None` or `Signed`, depending on whether this is a signed or general
+/// transaction).
+///
+/// Transaction extensions are capable of altering certain associated semantics:
+///
+/// - They may define the origin with which the transaction's call should be dispatched.
+/// - They may define various parameters used by the transaction queue to determine under what
+///   conditions the transaction should be retained and introduced on-chain.
+/// - They may define whether this transaction is acceptable for introduction on-chain at all.
+///
+/// Each of these semantics are defined by the `validate` function.
+///
+/// **NOTE: Transaction extensions cannot under any circumstances alter the call itself.**
+///
+/// Transaction extensions are capable of defining logic which is executed additionally to the
+/// dispatch of the call:
+///
+/// - They may define logic which must be executed prior to the dispatch of the call.
+/// - They may also define logic which must be executed after the dispatch of the call.
+///
+/// Each of these semantics are defined by the `prepare` and `post_dispatch_details` functions
+/// respectively.
+///
+/// Finally, transaction extensions may define additional data to help define the implications of
+/// the logic they introduce. This additional data may be explicitly defined by the transaction
+/// author (in which case it is included as part of the transaction body), or it may be implicitly
+/// defined by the transaction extension based around the on-chain state (which the transaction
+/// author is assumed to know). This data may be utilized by the above logic to alter how a node's
+/// transaction queue treats this transaction.
+///
+/// ## Default implementations
+///
+/// Of the 6 functions in this trait along with `TransactionExtension`, 2 of them must return a
+/// value of an associated type on success, with only `implicit` having a default implementation.
+/// This means that default implementations cannot be provided for `validate` and `prepare`.
+/// However, a macro is provided [impl_tx_ext_default](crate::impl_tx_ext_default) which is capable
+/// of generating default implementations for both of these functions. If you do not wish to
+/// introduce additional logic into the transaction pipeline, then it is recommended that you use
+/// this macro to implement these functions. Additionally, [weight](TransactionExtension::weight)
+/// can return a default value, which would mean the extension is weightless, but it is not
+/// implemented by default. Instead, implementers can explicitly choose to implement this default
+/// behavior through the same [impl_tx_ext_default](crate::impl_tx_ext_default) macro.
+///
+/// If your extension does any post-flight logic, then the functionality must be implemented in
+/// [post_dispatch_details](TransactionExtension::post_dispatch_details). This function can return
+/// the actual weight used by the extension during an entire dispatch cycle by wrapping said weight
+/// value in a `Some`. This is useful in computing fee refunds, similar to how post dispatch
+/// information is used to refund fees for calls. Alternatively, a `None` can be returned, which
+/// means that the worst case scenario weight, namely the value returned by
+/// [weight](TransactionExtension::weight), is the actual weight. This particular piece of logic
+/// is embedded in the default implementation of
+/// [post_dispatch](TransactionExtension::post_dispatch) so that the weight is assumed to be worst
+/// case scenario, but implementers of this trait can correct it with extra effort. Therefore, all
+/// users of an extension should use [post_dispatch](TransactionExtension::post_dispatch), with
+/// [post_dispatch_details](TransactionExtension::post_dispatch_details) considered an internal
+/// function.
+///
+/// ## Pipelines, Inherited Implications, and Authorized Origins
+///
+/// Requiring a single transaction extension to define all of the above semantics would be
+/// cumbersome and would lead to a lot of boilerplate. Instead, transaction extensions are
+/// aggregated into pipelines, which are tuples of transaction extensions. Each extension in the
+/// pipeline is executed in order, and the output of each extension is aggregated and/or relayed as
+/// the input to the next extension in the pipeline.
+///
+/// This ordered composition happens with all data types ([Val](TransactionExtension::Val),
+/// [Pre](TransactionExtension::Pre) and [Implicit](TransactionExtension::Implicit)) as well as
+/// all functions. There are important consequences stemming from how the composition affects the
+/// meaning of the `origin` and `implication` parameters as well as the results. Whereas the
+/// [prepare](TransactionExtension::prepare) and
+/// [post_dispatch](TransactionExtension::post_dispatch) functions are clear in their meaning, the
+/// [validate](TransactionExtension::validate) function is fairly sophisticated and warrants further
+/// explanation.
+///
+/// Firstly, the `origin` parameter. The `origin` passed into the first item in a pipeline is simply
+/// that passed into the tuple itself. It represents an authority who has authorized the implication
+/// of the transaction, as of the extension it has been passed into *and any further extensions it
+/// may pass though, all the way to, and including, the transaction's dispatch call itself. Each
+/// following item in the pipeline is passed the origin which the previous item returned. The origin
+/// returned from the final item in the pipeline is the origin which is returned by the tuple
+/// itself.
+///
+/// This means that if a constituent extension returns a different origin to the one it was called
+/// with, then (assuming no other extension changes it further) *this new origin will be used for
+/// all extensions following it in the pipeline, and will be returned from the pipeline to be used
+/// as the origin for the call's dispatch*. The call itself as well as all these extensions
+/// following may each imply consequence for this origin. We call this the *inherited implication*.
+///
+/// The *inherited implication* is the cumulated on-chain effects born by whatever origin is
+/// returned. It is expressed to the [validate](TransactionExtension::validate) function only as the
+/// `implication` argument which implements the [Encode] trait. A transaction extension may define
+/// its own implications through its own fields and the
+/// [implicit](TransactionExtension::implicit) function. This is only utilized by extensions
+/// which precede it in a pipeline or, if the transaction is an old-school signed transaction, the
+/// underlying transaction verification logic.
+///
+/// **The inherited implication passed as the `implication` parameter to
+/// [validate](TransactionExtension::validate) does not include the extension's inner data itself
+/// nor does it include the result of the extension's `implicit` function.** If you both provide an
+/// implication and rely on the implication, then you need to manually aggregate your extensions
+/// implication with the aggregated implication passed in.
+///
+/// In the post dispatch pipeline, the actual weight of each extension is accrued in the
+/// [PostDispatchInfo](PostDispatchInfoOf<Call>) of that transaction sequentially with each
+/// [post_dispatch](TransactionExtension::post_dispatch) call. This means that an extension handling
+/// transaction payment and refunds should be at the end of the pipeline in order to capture the
+/// correct amount of weight used during the call. This is because one cannot know the actual weight
+/// of an extension after post dispatch without running the post dispatch ahead of time.
+pub trait TransactionExtension<Call: Dispatchable>:
+	Codec + Debug + Sync + Send + Clone + Eq + PartialEq + StaticTypeInfo
+{
+	/// Unique identifier of this signed extension.
+	///
+	/// This will be exposed in the metadata to identify the signed extension used in an extrinsic.
+	const IDENTIFIER: &'static str;
+
+	/// Any additional data which was known at the time of transaction construction and can be
+	/// useful in authenticating the transaction. This is determined dynamically in part from the
+	/// on-chain environment using the `implicit` function and not directly contained in the
+	/// transaction itself and therefore is considered "implicit".
+	type Implicit: Codec + StaticTypeInfo;
+
+	/// Determine any additional data which was known at the time of transaction construction and
+	/// can be useful in authenticating the transaction. The expected usage of this is to include in
+	/// any data which is signed and verified as part of transaction validation. Also perform any
+	/// pre-signature-verification checks and return an error if needed.
+	fn implicit(&self) -> Result<Self::Implicit, TransactionValidityError> {
+		use crate::transaction_validity::InvalidTransaction::IndeterminateImplicit;
+		Ok(Self::Implicit::decode(&mut &[][..]).map_err(|_| IndeterminateImplicit)?)
+	}
+
+	/// Returns the metadata for this extension.
+	///
+	/// As a [`TransactionExtension`] can be a tuple of [`TransactionExtension`]s we need to return
+	/// a `Vec` that holds the metadata of each one. Each individual `TransactionExtension` must
+	/// return *exactly* one [`TransactionExtensionMetadata`].
+	///
+	/// This method provides a default implementation that returns a vec containing a single
+	/// [`TransactionExtensionMetadata`].
+	fn metadata() -> Vec<TransactionExtensionMetadata> {
+		sp_std::vec![TransactionExtensionMetadata {
+			identifier: Self::IDENTIFIER,
+			ty: scale_info::meta_type::<Self>(),
+			implicit: scale_info::meta_type::<Self::Implicit>()
+		}]
+	}
+
+	/// The type that encodes information that can be passed from `validate` to `prepare`.
+	type Val;
+
+	/// The type that encodes information that can be passed from `prepare` to `post_dispatch`.
+	type Pre;
+
+	/// The weight consumed by executing this extension instance fully during transaction dispatch.
+	fn weight(&self, call: &Call) -> Weight;
+
+	/// Validate a transaction for the transaction queue.
+	///
+	/// This function can be called frequently by the transaction queue to obtain transaction
+	/// validity against current state. It should perform all checks that determine a valid
+	/// transaction, that can pay for its execution and quickly eliminate ones that are stale or
+	/// incorrect.
+	///
+	/// Parameters:
+	/// - `origin`: The origin of the transaction which this extension inherited; coming from an
+	///   "old-school" *signed transaction*, this will be a system `RawOrigin::Signed` value. If the
+	///   transaction is a "new-school" *General Transaction*, then this will be a system
+	///   `RawOrigin::None` value. If this extension is an item in a composite, then it could be
+	///   anything which was previously returned as an `origin` value in the result of a `validate`
+	///   call.
+	/// - `call`: The `Call` wrapped by this extension.
+	/// - `info`: Information concerning, and inherent to, the transaction's call.
+	/// - `len`: The total length of the encoded transaction.
+	/// - `inherited_implication`: The *implication* which this extension inherits. This is a tuple
+	///   of the transaction's call and some additional opaque-but-encodable data. Coming directly
+	///   from a transaction, the latter is [()]. However, if this extension is expressed as part of
+	///   a composite type, then the latter component is equal to any further implications to which
+	///   the returned `origin` could potentially apply. See Pipelines, Inherited Implications, and
+	///   Authorized Origins for more information.
+	///
+	/// Returns a [ValidateResult], which is a [Result] whose success type is a tuple of
+	/// [ValidTransaction] (defining useful metadata for the transaction queue), the [Self::Val]
+	/// token of this transaction, which gets passed into [prepare](TransactionExtension::prepare),
+	/// and the origin of the transaction, which gets passed into
+	/// [prepare](TransactionExtension::prepare) and is ultimately used for dispatch.
+	fn validate(
+		&self,
+		origin: DispatchOriginOf<Call>,
+		call: &Call,
+		info: &DispatchInfoOf<Call>,
+		len: usize,
+		self_implicit: Self::Implicit,
+		inherited_implication: &impl Encode,
+	) -> ValidateResult<Self::Val, Call>;
+
+	/// Do any pre-flight stuff for a transaction after validation.
+	///
+	/// This is for actions which do not happen in the transaction queue but only immediately prior
+	/// to the point of dispatch on-chain. This should not return an error, since errors should
+	/// already have been identified during the [validate](TransactionExtension::validate) call. If
+	/// an error is returned, the transaction will be considered invalid but no state changes will
+	/// happen and therefore work done in [validate](TransactionExtension::validate) will not be
+	/// paid for.
+	///
+	/// Unlike `validate`, this function may consume `self`.
+	///
+	/// Parameters:
+	/// - `val`: `Self::Val` returned by the result of the `validate` call.
+	/// - `origin`: The origin returned by the result of the `validate` call.
+	/// - `call`: The `Call` wrapped by this extension.
+	/// - `info`: Information concerning, and inherent to, the transaction's call.
+	/// - `len`: The total length of the encoded transaction.
+	///
+	/// Returns a [Self::Pre] value on success, which gets passed into
+	/// [post_dispatch](TransactionExtension::post_dispatch) and after the call is dispatched.
+	///
+	/// IMPORTANT: **Checks made in validation need not be repeated here.**
+	fn prepare(
+		self,
+		val: Self::Val,
+		origin: &DispatchOriginOf<Call>,
+		call: &Call,
+		info: &DispatchInfoOf<Call>,
+		len: usize,
+	) -> Result<Self::Pre, TransactionValidityError>;
+
+	/// Do any post-flight stuff for an extrinsic.
+	///
+	/// `_pre` contains the output of `prepare`.
+	///
+	/// This gets given the `DispatchResult` `_result` from the extrinsic and can, if desired,
+	/// introduce a `TransactionValidityError`, causing the block to become invalid for including
+	/// it.
+	///
+	/// On success, the caller must return the amount of unspent weight left over by this extension
+	/// after dispatch. By default, this function returns no unspent weight, which means the entire
+	/// weight computed for the worst case scenario is consumed.
+	///
+	/// WARNING: This function does not automatically keep track of accumulated "actual" weight.
+	/// Unless this weight is handled at the call site, use
+	/// [post_dispatch](TransactionExtension::post_dispatch)
+	/// instead.
+	///
+	/// Parameters:
+	/// - `pre`: `Self::Pre` returned by the result of the `prepare` call prior to dispatch.
+	/// - `info`: Information concerning, and inherent to, the transaction's call.
+	/// - `post_info`: Information concerning the dispatch of the transaction's call.
+	/// - `len`: The total length of the encoded transaction.
+	/// - `result`: The result of the dispatch.
+	///
+	/// WARNING: It is dangerous to return an error here. To do so will fundamentally invalidate the
+	/// transaction and any block that it is included in, causing the block author to not be
+	/// compensated for their work in validating the transaction or producing the block so far. It
+	/// can only be used safely when you *know* that the transaction is one that would only be
+	/// introduced by the current block author.
+	fn post_dispatch_details(
+		_pre: Self::Pre,
+		_info: &DispatchInfoOf<Call>,
+		_post_info: &PostDispatchInfoOf<Call>,
+		_len: usize,
+		_result: &DispatchResult,
+	) -> Result<Weight, TransactionValidityError> {
+		Ok(Weight::zero())
+	}
+
+	/// A wrapper for [`post_dispatch_details`](TransactionExtension::post_dispatch_details) that
+	/// refunds the unspent weight consumed by this extension into the post dispatch information.
+	///
+	/// If `post_dispatch_details` returns a non-zero unspent weight, which, by definition, must be
+	/// less than the worst case weight provided by [weight](TransactionExtension::weight), that
+	/// is the value refunded in `post_info`.
+	///
+	/// If no unspent weight is reported by `post_dispatch_details`, this function assumes the worst
+	/// case weight and does not refund anything.
+	///
+	/// For more information, look into
+	/// [post_dispatch_details](TransactionExtension::post_dispatch_details).
+	fn post_dispatch(
+		pre: Self::Pre,
+		info: &DispatchInfoOf<Call>,
+		post_info: &mut PostDispatchInfoOf<Call>,
+		len: usize,
+		result: &DispatchResult,
+	) -> Result<(), TransactionValidityError> {
+		let unspent_weight = Self::post_dispatch_details(pre, info, &post_info, len, result)?;
+		post_info.refund(unspent_weight);
+
+		Ok(())
+	}
+
+	/// Validation logic for bare extrinsics.
+	///
+	/// NOTE: This function will be migrated to a separate `InherentExtension` interface.
+	fn bare_validate(
+		_call: &Call,
+		_info: &DispatchInfoOf<Call>,
+		_len: usize,
+	) -> TransactionValidity {
+		Ok(ValidTransaction::default())
+	}
+
+	/// All pre-flight logic run before dispatching bare extrinsics.
+	///
+	/// NOTE: This function will be migrated to a separate `InherentExtension` interface.
+	fn bare_validate_and_prepare(
+		_call: &Call,
+		_info: &DispatchInfoOf<Call>,
+		_len: usize,
+	) -> Result<(), TransactionValidityError> {
+		Ok(())
+	}
+
+	/// Post dispatch logic run after dispatching bare extrinsics.
+	///
+	/// NOTE: This function will be migrated to a separate `InherentExtension` interface.
+	fn bare_post_dispatch(
+		_info: &DispatchInfoOf<Call>,
+		_post_info: &mut PostDispatchInfoOf<Call>,
+		_len: usize,
+		_result: &DispatchResult,
+	) -> Result<(), TransactionValidityError> {
+		Ok(())
+	}
+}
+
+/// Helper macro to be used in a `impl TransactionExtension` block to add default implementations of
+/// `weight`, `validate`, `prepare` or any combinations of the them.
+///
+/// The macro is to be used with 2 parameters, separated by ";":
+/// - the `Call` type;
+/// - the functions for which a default implementation should be generated, separated by " ";
+///   available options are `weight`, `validate` and `prepare`.
+///
+/// Example usage:
+/// ```nocompile
+/// impl TransactionExtension<FirstCall> for EmptyExtension {
+/// 	type Val = ();
+/// 	type Pre = ();
+///
+/// 	impl_tx_ext_default!(FirstCall; weight validate prepare);
+/// }
+///
+/// impl TransactionExtension<SecondCall> for SimpleExtension {
+/// 	type Val = u32;
+/// 	type Pre = ();
+///
+/// 	fn weight(&self, _: &SecondCall) -> Weight {
+/// 		Weight::zero()
+/// 	}
+///
+/// 	fn validate(
+/// 			&self,
+/// 			_origin: <T as Config>::RuntimeOrigin,
+/// 			_call: &SecondCall,
+/// 			_info: &DispatchInfoOf<SecondCall>,
+/// 			_len: usize,
+/// 			_self_implicit: Self::Implicit,
+/// 			_inherited_implication: &impl Encode,
+/// 		) -> ValidateResult<Self::Val, SecondCall> {
+/// 		Ok((Default::default(), 42u32, origin))
+/// 	}
+///
+/// 	impl_tx_ext_default!(SecondCall; prepare);
+/// }
+/// ```
+#[macro_export]
+macro_rules! impl_tx_ext_default {
+	($call:ty ; , $( $rest:tt )*) => {
+		impl_tx_ext_default!{$call ; $( $rest )*}
+	};
+	($call:ty ; validate $( $rest:tt )*) => {
+		fn validate(
+			&self,
+			origin: $crate::traits::DispatchOriginOf<$call>,
+			_call: &$call,
+			_info: &$crate::traits::DispatchInfoOf<$call>,
+			_len: usize,
+			_self_implicit: Self::Implicit,
+			_inherited_implication: &impl $crate::codec::Encode,
+		) -> $crate::traits::ValidateResult<Self::Val, $call> {
+			Ok((Default::default(), Default::default(), origin))
+		}
+		impl_tx_ext_default!{$call ; $( $rest )*}
+	};
+	($call:ty ; prepare $( $rest:tt )*) => {
+		fn prepare(
+			self,
+			_val: Self::Val,
+			_origin: &$crate::traits::DispatchOriginOf<$call>,
+			_call: &$call,
+			_info: &$crate::traits::DispatchInfoOf<$call>,
+			_len: usize,
+		) -> Result<Self::Pre, $crate::transaction_validity::TransactionValidityError> {
+			Ok(Default::default())
+		}
+		impl_tx_ext_default!{$call ; $( $rest )*}
+	};
+	($call:ty ; weight $( $rest:tt )*) => {
+		fn weight(&self, _call: &$call) -> $crate::Weight {
+			$crate::Weight::zero()
+		}
+		impl_tx_ext_default!{$call ; $( $rest )*}
+	};
+	($call:ty ;) => {};
+}
+
+/// Information about a [`TransactionExtension`] for the runtime metadata.
+pub struct TransactionExtensionMetadata {
+	/// The unique identifier of the [`TransactionExtension`].
+	pub identifier: &'static str,
+	/// The type of the [`TransactionExtension`].
+	pub ty: MetaType,
+	/// The type of the [`TransactionExtension`] additional signed data for the payload.
+	pub implicit: MetaType,
+}
+
+#[impl_for_tuples(1, 12)]
+impl<Call: Dispatchable> TransactionExtension<Call> for Tuple {
+	const IDENTIFIER: &'static str = "Use `metadata()`!";
+	for_tuples!( type Implicit = ( #( Tuple::Implicit ),* ); );
+	fn implicit(&self) -> Result<Self::Implicit, TransactionValidityError> {
+		Ok(for_tuples!( ( #( Tuple.implicit()? ),* ) ))
+	}
+	fn metadata() -> Vec<TransactionExtensionMetadata> {
+		let mut ids = Vec::new();
+		for_tuples!( #( ids.extend(Tuple::metadata()); )* );
+		ids
+	}
+
+	for_tuples!( type Val = ( #( Tuple::Val ),* ); );
+	for_tuples!( type Pre = ( #( Tuple::Pre ),* ); );
+
+	fn weight(&self, call: &Call) -> Weight {
+		let mut weight = Weight::zero();
+		for_tuples!( #( weight = weight.saturating_add(Tuple.weight(call)); )* );
+		weight
+	}
+
+	fn validate(
+		&self,
+		origin: <Call as Dispatchable>::RuntimeOrigin,
+		call: &Call,
+		info: &DispatchInfoOf<Call>,
+		len: usize,
+		self_implicit: Self::Implicit,
+		inherited_implication: &impl Encode,
+	) -> Result<
+		(ValidTransaction, Self::Val, <Call as Dispatchable>::RuntimeOrigin),
+		TransactionValidityError,
+	> {
+		let valid = ValidTransaction::default();
+		let val = ();
+		let following_explicit_implications = for_tuples!( ( #( &self.Tuple ),* ) );
+		let following_implicit_implications = self_implicit;
+
+		for_tuples!(#(
+			// Implication of this pipeline element not relevant for later items, so we pop it.
+			let (_item, following_explicit_implications) = following_explicit_implications.pop_front();
+			let (item_implicit, following_implicit_implications) = following_implicit_implications.pop_front();
+			let (item_valid, item_val, origin) = {
+				let implications = (
+					// The first is the implications born of the fact we return the mutated
+					// origin.
+					inherited_implication,
+					// This is the explicitly made implication born of the fact the new origin is
+					// passed into the next items in this pipeline-tuple.
+					&following_explicit_implications,
+					// This is the implicitly made implication born of the fact the new origin is
+					// passed into the next items in this pipeline-tuple.
+					&following_implicit_implications,
+				);
+				Tuple.validate(origin, call, info, len, item_implicit, &implications)?
+			};
+			let valid = valid.combine_with(item_valid);
+			let val = val.push_back(item_val);
+		)* );
+		Ok((valid, val, origin))
+	}
+
+	fn prepare(
+		self,
+		val: Self::Val,
+		origin: &<Call as Dispatchable>::RuntimeOrigin,
+		call: &Call,
+		info: &DispatchInfoOf<Call>,
+		len: usize,
+	) -> Result<Self::Pre, TransactionValidityError> {
+		Ok(for_tuples!( ( #(
+			Tuple::prepare(self.Tuple, val.Tuple, origin, call, info, len)?
+		),* ) ))
+	}
+
+	fn post_dispatch_details(
+		pre: Self::Pre,
+		info: &DispatchInfoOf<Call>,
+		post_info: &PostDispatchInfoOf<Call>,
+		len: usize,
+		result: &DispatchResult,
+	) -> Result<Weight, TransactionValidityError> {
+		let mut total_unspent_weight = Weight::zero();
+		for_tuples!( #({
+			let unspent_weight = Tuple::post_dispatch_details(pre.Tuple, info, post_info, len, result)?;
+			total_unspent_weight = total_unspent_weight.saturating_add(unspent_weight);
+		})* );
+		Ok(total_unspent_weight)
+	}
+
+	fn post_dispatch(
+		pre: Self::Pre,
+		info: &DispatchInfoOf<Call>,
+		post_info: &mut PostDispatchInfoOf<Call>,
+		len: usize,
+		result: &DispatchResult,
+	) -> Result<(), TransactionValidityError> {
+		for_tuples!( #( Tuple::post_dispatch(pre.Tuple, info, post_info, len, result)?; )* );
+		Ok(())
+	}
+
+	fn bare_validate(call: &Call, info: &DispatchInfoOf<Call>, len: usize) -> TransactionValidity {
+		let valid = ValidTransaction::default();
+		for_tuples!(#(
+			let item_valid = Tuple::bare_validate(call, info, len)?;
+			let valid = valid.combine_with(item_valid);
+		)* );
+		Ok(valid)
+	}
+
+	fn bare_validate_and_prepare(
+		call: &Call,
+		info: &DispatchInfoOf<Call>,
+		len: usize,
+	) -> Result<(), TransactionValidityError> {
+		for_tuples!( #( Tuple::bare_validate_and_prepare(call, info, len)?; )* );
+		Ok(())
+	}
+
+	fn bare_post_dispatch(
+		info: &DispatchInfoOf<Call>,
+		post_info: &mut PostDispatchInfoOf<Call>,
+		len: usize,
+		result: &DispatchResult,
+	) -> Result<(), TransactionValidityError> {
+		for_tuples!( #( Tuple::bare_post_dispatch(info, post_info, len, result)?; )* );
+		Ok(())
+	}
+}
+
+impl<Call: Dispatchable> TransactionExtension<Call> for () {
+	const IDENTIFIER: &'static str = "UnitTransactionExtension";
+	type Implicit = ();
+	fn implicit(&self) -> sp_std::result::Result<Self::Implicit, TransactionValidityError> {
+		Ok(())
+	}
+	type Val = ();
+	type Pre = ();
+	fn weight(&self, _call: &Call) -> Weight {
+		Weight::zero()
+	}
+	fn validate(
+		&self,
+		origin: <Call as Dispatchable>::RuntimeOrigin,
+		_call: &Call,
+		_info: &DispatchInfoOf<Call>,
+		_len: usize,
+		_self_implicit: Self::Implicit,
+		_inherited_implication: &impl Encode,
+	) -> Result<
+		(ValidTransaction, (), <Call as Dispatchable>::RuntimeOrigin),
+		TransactionValidityError,
+	> {
+		Ok((ValidTransaction::default(), (), origin))
+	}
+	fn prepare(
+		self,
+		_val: (),
+		_origin: &<Call as Dispatchable>::RuntimeOrigin,
+		_call: &Call,
+		_info: &DispatchInfoOf<Call>,
+		_len: usize,
+	) -> Result<(), TransactionValidityError> {
+		Ok(())
+	}
+}
diff --git a/substrate/primitives/runtime/src/transaction_validity.rs b/substrate/primitives/runtime/src/transaction_validity.rs
index 2d800e29b8b..a48c8ee7ba8 100644
--- a/substrate/primitives/runtime/src/transaction_validity.rs
+++ b/substrate/primitives/runtime/src/transaction_validity.rs
@@ -82,6 +82,10 @@ pub enum InvalidTransaction {
 	MandatoryValidation,
 	/// The sending address is disabled or known to be invalid.
 	BadSigner,
+	/// The implicit data was unable to be calculated.
+	IndeterminateImplicit,
+	/// The transaction extension did not authorize any origin.
+	UnknownOrigin,
 }
 
 impl InvalidTransaction {
@@ -113,6 +117,10 @@ impl From<InvalidTransaction> for &'static str {
 				"Transaction dispatch is mandatory; transactions must not be validated.",
 			InvalidTransaction::Custom(_) => "InvalidTransaction custom error",
 			InvalidTransaction::BadSigner => "Invalid signing address",
+			InvalidTransaction::IndeterminateImplicit =>
+				"The implicit data was unable to be calculated",
+			InvalidTransaction::UnknownOrigin =>
+				"The transaction extension did not authorize any origin",
 		}
 	}
 }
@@ -338,7 +346,7 @@ pub struct ValidTransactionBuilder {
 impl ValidTransactionBuilder {
 	/// Set the priority of a transaction.
 	///
-	/// Note that the final priority for `FRAME` is combined from all `SignedExtension`s.
+	/// Note that the final priority for `FRAME` is combined from all `TransactionExtension`s.
 	/// Most likely for unsigned transactions you want the priority to be higher
 	/// than for regular transactions. We recommend exposing a base priority for unsigned
 	/// transactions as a runtime module parameter, so that the runtime can tune inter-module
diff --git a/substrate/primitives/storage/Cargo.toml b/substrate/primitives/storage/Cargo.toml
index 9341d7ac77e..e441ddae52e 100644
--- a/substrate/primitives/storage/Cargo.toml
+++ b/substrate/primitives/storage/Cargo.toml
@@ -25,12 +25,7 @@ sp-debug-derive = { workspace = true }
 
 [features]
 default = ["std"]
-std = [
-	"codec/std",
-	"impl-serde/std",
-	"serde/std",
-	"sp-debug-derive/std",
-]
+std = ["codec/std", "impl-serde/std", "serde/std", "sp-debug-derive/std"]
 
 # Serde support without relying on std features.
 serde = ["dep:serde", "impl-serde"]
diff --git a/substrate/primitives/test-primitives/src/lib.rs b/substrate/primitives/test-primitives/src/lib.rs
index 1e3b912eaf4..adc96d77369 100644
--- a/substrate/primitives/test-primitives/src/lib.rs
+++ b/substrate/primitives/test-primitives/src/lib.rs
@@ -28,7 +28,7 @@ use sp_application_crypto::sr25519;
 
 use alloc::vec::Vec;
 pub use sp_core::{hash::H256, RuntimeDebug};
-use sp_runtime::traits::{BlakeTwo256, Extrinsic as ExtrinsicT, Verify};
+use sp_runtime::traits::{BlakeTwo256, ExtrinsicLike, Verify};
 
 /// Extrinsic for test-runtime.
 #[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, scale_info::TypeInfo)]
@@ -47,10 +47,7 @@ impl serde::Serialize for Extrinsic {
 	}
 }
 
-impl ExtrinsicT for Extrinsic {
-	type Call = Extrinsic;
-	type SignaturePayload = ();
-
+impl ExtrinsicLike for Extrinsic {
 	fn is_signed(&self) -> Option<bool> {
 		if let Extrinsic::IncludeData(_) = *self {
 			Some(false)
@@ -59,8 +56,12 @@ impl ExtrinsicT for Extrinsic {
 		}
 	}
 
-	fn new(call: Self::Call, _signature_payload: Option<Self::SignaturePayload>) -> Option<Self> {
-		Some(call)
+	fn is_bare(&self) -> bool {
+		if let Extrinsic::IncludeData(_) = *self {
+			true
+		} else {
+			false
+		}
 	}
 }
 
diff --git a/substrate/primitives/weights/Cargo.toml b/substrate/primitives/weights/Cargo.toml
index 9b830403dbe..c4e1897dbb8 100644
--- a/substrate/primitives/weights/Cargo.toml
+++ b/substrate/primitives/weights/Cargo.toml
@@ -47,6 +47,4 @@ serde = [
 	"sp-arithmetic/serde",
 ]
 
-json-schema = [
-	"dep:schemars",
-]
+json-schema = ["dep:schemars"]
diff --git a/substrate/scripts/run_all_benchmarks.sh b/substrate/scripts/run_all_benchmarks.sh
index 6dd7cede319..fe5f89a5b56 100755
--- a/substrate/scripts/run_all_benchmarks.sh
+++ b/substrate/scripts/run_all_benchmarks.sh
@@ -107,6 +107,19 @@ for PALLET in "${PALLETS[@]}"; do
 
   FOLDER="$(echo "${PALLET#*_}" | tr '_' '-')";
   WEIGHT_FILE="./frame/${FOLDER}/src/weights.rs"
+
+  # Special handling of custom weight paths.
+  if [ "$PALLET" == "frame_system_extensions" ] || [ "$PALLET" == "frame-system-extensions" ]
+  then
+    WEIGHT_FILE="./frame/system/src/extensions/weights.rs"
+  elif [ "$PALLET" == "pallet_asset_conversion_tx_payment" ] || [ "$PALLET" == "pallet-asset-conversion-tx-payment" ]
+  then
+    WEIGHT_FILE="./frame/transaction-payment/asset-conversion-tx-payment/src/weights.rs"
+  elif [ "$PALLET" == "pallet_asset_tx_payment" ] || [ "$PALLET" == "pallet-asset-tx-payment" ]
+  then
+    WEIGHT_FILE="./frame/transaction-payment/asset-tx-payment/src/weights.rs"
+  fi
+
   echo "[+] Benchmarking $PALLET with weight file $WEIGHT_FILE";
 
   OUTPUT=$(
diff --git a/substrate/test-utils/runtime/src/extrinsic.rs b/substrate/test-utils/runtime/src/extrinsic.rs
index 5ae0d8f8f6e..8f94dd10a83 100644
--- a/substrate/test-utils/runtime/src/extrinsic.rs
+++ b/substrate/test-utils/runtime/src/extrinsic.rs
@@ -26,7 +26,10 @@ use frame_metadata_hash_extension::CheckMetadataHash;
 use frame_system::{CheckNonce, CheckWeight};
 use sp_core::crypto::Pair as TraitPair;
 use sp_keyring::AccountKeyring;
-use sp_runtime::{traits::SignedExtension, transaction_validity::TransactionPriority, Perbill};
+use sp_runtime::{
+	generic::Preamble, traits::TransactionExtension, transaction_validity::TransactionPriority,
+	Perbill,
+};
 
 /// Transfer used in test substrate pallet. Extrinsic is created and signed using this data.
 #[derive(Clone)]
@@ -66,11 +69,11 @@ impl TryFrom<&Extrinsic> for TransferData {
 		match uxt {
 			Extrinsic {
 				function: RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest, value }),
-				signature: Some((from, _, (CheckNonce(nonce), ..))),
+				preamble: Preamble::Signed(from, _, _, ((CheckNonce(nonce), ..), ..)),
 			} => Ok(TransferData { from: *from, to: *dest, amount: *value, nonce: *nonce }),
 			Extrinsic {
 				function: RuntimeCall::SubstrateTest(PalletCall::bench_call { transfer }),
-				signature: None,
+				preamble: Preamble::Bare(_),
 			} => Ok(transfer.clone()),
 			_ => Err(()),
 		}
@@ -203,9 +206,8 @@ impl ExtrinsicBuilder {
 	/// Build `Extrinsic` using embedded parameters
 	pub fn build(self) -> Extrinsic {
 		if let Some(signer) = self.signer {
-			let extra = (
-				CheckNonce::from(self.nonce.unwrap_or(0)),
-				CheckWeight::new(),
+			let tx_ext = (
+				(CheckNonce::from(self.nonce.unwrap_or(0)), CheckWeight::new()),
 				CheckSubstrateCall {},
 				self.metadata_hash
 					.map(CheckMetadataHash::new_with_custom_hash)
@@ -213,14 +215,14 @@ impl ExtrinsicBuilder {
 			);
 			let raw_payload = SignedPayload::from_raw(
 				self.function.clone(),
-				extra.clone(),
-				extra.additional_signed().unwrap(),
+				tx_ext.clone(),
+				tx_ext.implicit().unwrap(),
 			);
 			let signature = raw_payload.using_encoded(|e| signer.sign(e));
 
-			Extrinsic::new_signed(self.function, signer.public(), signature, extra)
+			Extrinsic::new_signed(self.function, signer.public(), signature, tx_ext)
 		} else {
-			Extrinsic::new_unsigned(self.function)
+			Extrinsic::new_bare(self.function)
 		}
 	}
 }
diff --git a/substrate/test-utils/runtime/src/lib.rs b/substrate/test-utils/runtime/src/lib.rs
index 74965264c03..a4a0d348a39 100644
--- a/substrate/test-utils/runtime/src/lib.rs
+++ b/substrate/test-utils/runtime/src/lib.rs
@@ -63,9 +63,11 @@ pub use sp_core::hash::H256;
 use sp_genesis_builder::PresetId;
 use sp_inherents::{CheckInherentsResult, InherentData};
 use sp_runtime::{
-	create_runtime_str, impl_opaque_keys,
-	traits::{BlakeTwo256, Block as BlockT, DispatchInfoOf, NumberFor, Verify},
-	transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError},
+	create_runtime_str, impl_opaque_keys, impl_tx_ext_default,
+	traits::{BlakeTwo256, Block as BlockT, DispatchInfoOf, Dispatchable, NumberFor, Verify},
+	transaction_validity::{
+		TransactionSource, TransactionValidity, TransactionValidityError, ValidTransaction,
+	},
 	ApplyExtrinsicResult, ExtrinsicInclusionMode, Perbill,
 };
 #[cfg(any(feature = "std", test))]
@@ -147,18 +149,18 @@ pub type Signature = sr25519::Signature;
 #[cfg(feature = "std")]
 pub type Pair = sp_core::sr25519::Pair;
 
-/// The SignedExtension to the basic transaction logic.
-pub type SignedExtra = (
-	CheckNonce<Runtime>,
-	CheckWeight<Runtime>,
+// TODO: Remove after the Checks are migrated to TxExtension.
+/// The extension to the basic transaction logic.
+pub type TxExtension = (
+	(CheckNonce<Runtime>, CheckWeight<Runtime>),
 	CheckSubstrateCall,
 	frame_metadata_hash_extension::CheckMetadataHash<Runtime>,
 );
 /// The payload being signed in transactions.
-pub type SignedPayload = sp_runtime::generic::SignedPayload<RuntimeCall, SignedExtra>;
+pub type SignedPayload = sp_runtime::generic::SignedPayload<RuntimeCall, TxExtension>;
 /// Unchecked extrinsic type as expected by this runtime.
 pub type Extrinsic =
-	sp_runtime::generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+	sp_runtime::generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
 
 /// An identifier for an account on this system.
 pub type AccountId = <Signature as Verify>::Signer;
@@ -252,8 +254,17 @@ impl sp_runtime::traits::Printable for CheckSubstrateCall {
 	}
 }
 
+impl sp_runtime::traits::RefundWeight for CheckSubstrateCall {
+	fn refund(&mut self, _weight: frame_support::weights::Weight) {}
+}
+impl sp_runtime::traits::ExtensionPostDispatchWeightHandler<CheckSubstrateCall>
+	for CheckSubstrateCall
+{
+	fn set_extension_weight(&mut self, _info: &CheckSubstrateCall) {}
+}
+
 impl sp_runtime::traits::Dispatchable for CheckSubstrateCall {
-	type RuntimeOrigin = CheckSubstrateCall;
+	type RuntimeOrigin = RuntimeOrigin;
 	type Config = CheckSubstrateCall;
 	type Info = CheckSubstrateCall;
 	type PostInfo = CheckSubstrateCall;
@@ -266,42 +277,32 @@ impl sp_runtime::traits::Dispatchable for CheckSubstrateCall {
 	}
 }
 
-impl sp_runtime::traits::SignedExtension for CheckSubstrateCall {
-	type AccountId = AccountId;
-	type Call = RuntimeCall;
-	type AdditionalSigned = ();
-	type Pre = ();
+impl sp_runtime::traits::TransactionExtension<RuntimeCall> for CheckSubstrateCall {
 	const IDENTIFIER: &'static str = "CheckSubstrateCall";
-
-	fn additional_signed(
-		&self,
-	) -> core::result::Result<Self::AdditionalSigned, TransactionValidityError> {
-		Ok(())
-	}
+	type Implicit = ();
+	type Pre = ();
+	type Val = ();
+	impl_tx_ext_default!(RuntimeCall; weight prepare);
 
 	fn validate(
 		&self,
-		_who: &Self::AccountId,
-		call: &Self::Call,
-		_info: &DispatchInfoOf<Self::Call>,
+		origin: <RuntimeCall as Dispatchable>::RuntimeOrigin,
+		call: &RuntimeCall,
+		_info: &DispatchInfoOf<RuntimeCall>,
 		_len: usize,
-	) -> TransactionValidity {
+		_self_implicit: Self::Implicit,
+		_inherited_implication: &impl Encode,
+	) -> Result<
+		(ValidTransaction, Self::Val, <RuntimeCall as Dispatchable>::RuntimeOrigin),
+		TransactionValidityError,
+	> {
 		log::trace!(target: LOG_TARGET, "validate");
-		match call {
+		let v = match call {
 			RuntimeCall::SubstrateTest(ref substrate_test_call) =>
-				substrate_test_pallet::validate_runtime_call(substrate_test_call),
-			_ => Ok(Default::default()),
-		}
-	}
-
-	fn pre_dispatch(
-		self,
-		who: &Self::AccountId,
-		call: &Self::Call,
-		info: &sp_runtime::traits::DispatchInfoOf<Self::Call>,
-		len: usize,
-	) -> Result<Self::Pre, TransactionValidityError> {
-		self.validate(who, call, info, len).map(drop)
+				substrate_test_pallet::validate_runtime_call(substrate_test_call)?,
+			_ => Default::default(),
+		};
+		Ok((v, (), origin))
 	}
 }
 
@@ -670,7 +671,7 @@ impl_runtime_apis! {
 
 	impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
 		fn offchain_worker(header: &<Block as BlockT>::Header) {
-			let ext = Extrinsic::new_unsigned(
+			let ext = Extrinsic::new_bare(
 				substrate_test_pallet::pallet::Call::storage_change{
 					key:b"some_key".encode(),
 					value:Some(header.number.encode())
@@ -1051,7 +1052,7 @@ mod tests {
 	use sp_consensus::BlockOrigin;
 	use sp_core::{storage::well_known_keys::HEAP_PAGES, traits::CallContext};
 	use sp_runtime::{
-		traits::{Hash as _, SignedExtension},
+		traits::{DispatchTransaction, Hash as _},
 		transaction_validity::{InvalidTransaction, ValidTransaction},
 	};
 	use substrate_test_runtime_client::{
@@ -1205,26 +1206,28 @@ mod tests {
 			let len = 0_usize;
 			assert_eq!(
 				CheckSubstrateCall {}
-					.validate(
-						&x,
+					.validate_only(
+						Some(x).into(),
 						&ExtrinsicBuilder::new_call_with_priority(16).build().function,
 						&info,
-						len
+						len,
 					)
 					.unwrap()
+					.0
 					.priority,
 				16
 			);
 
 			assert_eq!(
 				CheckSubstrateCall {}
-					.validate(
-						&x,
+					.validate_only(
+						Some(x).into(),
 						&ExtrinsicBuilder::new_call_do_not_propagate().build().function,
 						&info,
-						len
+						len,
 					)
 					.unwrap()
+					.0
 					.propagate,
 				false
 			);
diff --git a/substrate/utils/frame/benchmarking-cli/src/pallet/template.hbs b/substrate/utils/frame/benchmarking-cli/src/pallet/template.hbs
index 1e5e294acba..a044049a0d6 100644
--- a/substrate/utils/frame/benchmarking-cli/src/pallet/template.hbs
+++ b/substrate/utils/frame/benchmarking-cli/src/pallet/template.hbs
@@ -22,7 +22,11 @@ use core::marker::PhantomData;
 
 /// Weight functions for `{{pallet}}`.
 pub struct WeightInfo<T>(PhantomData<T>);
+{{#if (eq pallet "frame_system_extensions")}}
+impl<T: frame_system::Config> frame_system::ExtensionsWeightInfo for WeightInfo<T> {
+{{else}}
 impl<T: frame_system::Config> {{pallet}}::WeightInfo for WeightInfo<T> {
+{{/if}}
 	{{#each benchmarks as |benchmark|}}
 	{{#each benchmark.comments as |comment|}}
 	/// {{comment}}
diff --git a/substrate/utils/frame/remote-externalities/src/lib.rs b/substrate/utils/frame/remote-externalities/src/lib.rs
index 955e79008c8..75a2ac2aef4 100644
--- a/substrate/utils/frame/remote-externalities/src/lib.rs
+++ b/substrate/utils/frame/remote-externalities/src/lib.rs
@@ -1239,8 +1239,9 @@ where
 #[cfg(test)]
 mod test_prelude {
 	pub(crate) use super::*;
-	pub(crate) use sp_runtime::testing::{Block as RawBlock, ExtrinsicWrapper, H256 as Hash};
-	pub(crate) type Block = RawBlock<ExtrinsicWrapper<Hash>>;
+	pub(crate) use sp_runtime::testing::{Block as RawBlock, MockCallU64};
+	pub(crate) type UncheckedXt = sp_runtime::testing::TestXt<MockCallU64, ()>;
+	pub(crate) type Block = RawBlock<UncheckedXt>;
 
 	pub(crate) fn init_logger() {
 		sp_tracing::try_init_simple();
diff --git a/substrate/utils/frame/rpc/client/src/lib.rs b/substrate/utils/frame/rpc/client/src/lib.rs
index 221f260b156..0aecad55305 100644
--- a/substrate/utils/frame/rpc/client/src/lib.rs
+++ b/substrate/utils/frame/rpc/client/src/lib.rs
@@ -199,11 +199,12 @@ where
 #[cfg(test)]
 mod tests {
 	use super::*;
-	use sp_runtime::testing::{Block as TBlock, ExtrinsicWrapper, Header, H256};
+	use sp_runtime::testing::{Block as TBlock, Header, MockCallU64, TestXt, H256};
 	use std::sync::Arc;
 	use tokio::sync::Mutex;
 
-	type Block = TBlock<ExtrinsicWrapper<()>>;
+	type UncheckedXt = TestXt<MockCallU64, ()>;
+	type Block = TBlock<UncheckedXt>;
 	type BlockNumber = u64;
 	type Hash = H256;
 
diff --git a/templates/minimal/runtime/src/lib.rs b/templates/minimal/runtime/src/lib.rs
index 7379e33b6b3..464cad4e3da 100644
--- a/templates/minimal/runtime/src/lib.rs
+++ b/templates/minimal/runtime/src/lib.rs
@@ -103,8 +103,8 @@ pub fn native_version() -> NativeVersion {
 	NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
 }
 
-/// The signed extensions that are added to the runtime.
-type SignedExtra = (
+/// The transaction extensions that are added to the runtime.
+type TxExtension = (
 	// Checks that the sender is not the zero address.
 	frame_system::CheckNonZeroSender<Runtime>,
 	// Checks that the runtime version is correct.
@@ -207,7 +207,7 @@ impl pallet_transaction_payment::Config for Runtime {
 // Implements the types required for the template pallet.
 impl pallet_minimal_template::Config for Runtime {}
 
-type Block = frame::runtime::types_common::BlockOf<Runtime, SignedExtra>;
+type Block = frame::runtime::types_common::BlockOf<Runtime, TxExtension>;
 type Header = HeaderFor<Runtime>;
 
 type RuntimeExecutive =
diff --git a/templates/parachain/runtime/src/configs/mod.rs b/templates/parachain/runtime/src/configs/mod.rs
index 0cf6497fd95..ba4c71c7f21 100644
--- a/templates/parachain/runtime/src/configs/mod.rs
+++ b/templates/parachain/runtime/src/configs/mod.rs
@@ -177,6 +177,7 @@ impl pallet_transaction_payment::Config for Runtime {
 	type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
 	type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
 	type OperationalFeeMultiplier = ConstU8<5>;
+	type WeightInfo = ();
 }
 
 impl pallet_sudo::Config for Runtime {
diff --git a/templates/parachain/runtime/src/lib.rs b/templates/parachain/runtime/src/lib.rs
index cb30eb0e80d..78dc38ef427 100644
--- a/templates/parachain/runtime/src/lib.rs
+++ b/templates/parachain/runtime/src/lib.rs
@@ -72,9 +72,9 @@ pub type SignedBlock = generic::SignedBlock<Block>;
 /// BlockId type as expected by this runtime.
 pub type BlockId = generic::BlockId<Block>;
 
-/// The SignedExtension to the basic transaction logic.
+/// The extension to the basic transaction logic.
 #[docify::export(template_signed_extra)]
-pub type SignedExtra = (
+pub type TxExtension = (
 	frame_system::CheckNonZeroSender<Runtime>,
 	frame_system::CheckSpecVersion<Runtime>,
 	frame_system::CheckTxVersion<Runtime>,
@@ -89,7 +89,7 @@ pub type SignedExtra = (
 
 /// Unchecked extrinsic type as expected by this runtime.
 pub type UncheckedExtrinsic =
-	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
 
 /// All migrations of the runtime, aside from the ones declared in the pallets.
 ///
diff --git a/templates/solochain/node/Cargo.toml b/templates/solochain/node/Cargo.toml
index a0285e048d1..8a3c7d0ac78 100644
--- a/templates/solochain/node/Cargo.toml
+++ b/templates/solochain/node/Cargo.toml
@@ -72,6 +72,7 @@ std = ["solochain-template-runtime/std"]
 runtime-benchmarks = [
 	"frame-benchmarking-cli/runtime-benchmarks",
 	"frame-system/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"sc-service/runtime-benchmarks",
 	"solochain-template-runtime/runtime-benchmarks",
 	"sp-runtime/runtime-benchmarks",
diff --git a/templates/solochain/node/src/benchmarking.rs b/templates/solochain/node/src/benchmarking.rs
index 1bd3578af68..0d60230cd19 100644
--- a/templates/solochain/node/src/benchmarking.rs
+++ b/templates/solochain/node/src/benchmarking.rs
@@ -109,7 +109,7 @@ pub fn create_benchmark_extrinsic(
 		.checked_next_power_of_two()
 		.map(|c| c / 2)
 		.unwrap_or(2) as u64;
-	let extra: runtime::SignedExtra = (
+	let tx_ext: runtime::TxExtension = (
 		frame_system::CheckNonZeroSender::<runtime::Runtime>::new(),
 		frame_system::CheckSpecVersion::<runtime::Runtime>::new(),
 		frame_system::CheckTxVersion::<runtime::Runtime>::new(),
@@ -126,7 +126,7 @@ pub fn create_benchmark_extrinsic(
 
 	let raw_payload = runtime::SignedPayload::from_raw(
 		call.clone(),
-		extra.clone(),
+		tx_ext.clone(),
 		(
 			(),
 			runtime::VERSION.spec_version,
@@ -145,7 +145,7 @@ pub fn create_benchmark_extrinsic(
 		call,
 		sp_runtime::AccountId32::from(sender.public()).into(),
 		runtime::Signature::Sr25519(signature),
-		extra,
+		tx_ext,
 	)
 }
 
diff --git a/templates/solochain/runtime/Cargo.toml b/templates/solochain/runtime/Cargo.toml
index 8a7fa74a597..837849e844b 100644
--- a/templates/solochain/runtime/Cargo.toml
+++ b/templates/solochain/runtime/Cargo.toml
@@ -81,18 +81,14 @@ substrate-wasm-builder = { optional = true, workspace = true, default-features =
 default = ["std"]
 std = [
 	"codec/std",
-	"scale-info/std",
-
+	"frame-benchmarking?/std",
 	"frame-executive/std",
 	"frame-metadata-hash-extension/std",
 	"frame-support/std",
 	"frame-system-benchmarking?/std",
 	"frame-system-rpc-runtime-api/std",
 	"frame-system/std",
-
-	"frame-benchmarking?/std",
 	"frame-try-runtime?/std",
-
 	"pallet-aura/std",
 	"pallet-balances/std",
 	"pallet-grandpa/std",
@@ -101,7 +97,8 @@ std = [
 	"pallet-timestamp/std",
 	"pallet-transaction-payment-rpc-runtime-api/std",
 	"pallet-transaction-payment/std",
-
+	"scale-info/std",
+	"serde_json/std",
 	"sp-api/std",
 	"sp-block-builder/std",
 	"sp-consensus-aura/std",
@@ -109,15 +106,13 @@ std = [
 	"sp-core/std",
 	"sp-genesis-builder/std",
 	"sp-inherents/std",
+	"sp-keyring/std",
 	"sp-offchain/std",
 	"sp-runtime/std",
 	"sp-session/std",
 	"sp-storage/std",
 	"sp-transaction-pool/std",
 	"sp-version/std",
-
-	"serde_json/std",
-	"sp-keyring/std",
 	"substrate-wasm-builder",
 ]
 
@@ -131,6 +126,7 @@ runtime-benchmarks = [
 	"pallet-sudo/runtime-benchmarks",
 	"pallet-template/runtime-benchmarks",
 	"pallet-timestamp/runtime-benchmarks",
+	"pallet-transaction-payment/runtime-benchmarks",
 	"sp-runtime/runtime-benchmarks",
 ]
 
diff --git a/templates/solochain/runtime/src/apis.rs b/templates/solochain/runtime/src/apis.rs
index 87a09a5f7fe..f21eaa34443 100644
--- a/templates/solochain/runtime/src/apis.rs
+++ b/templates/solochain/runtime/src/apis.rs
@@ -223,6 +223,7 @@ impl_runtime_apis! {
 			use frame_benchmarking::{baseline, Benchmarking, BenchmarkList};
 			use frame_support::traits::StorageInfoTrait;
 			use frame_system_benchmarking::Pallet as SystemBench;
+			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
 			use baseline::Pallet as BaselineBench;
 			use super::*;
 
@@ -240,6 +241,7 @@ impl_runtime_apis! {
 			use frame_benchmarking::{baseline, Benchmarking, BenchmarkBatch};
 			use sp_storage::TrackedStorageKey;
 			use frame_system_benchmarking::Pallet as SystemBench;
+			use frame_system_benchmarking::extensions::Pallet as SystemExtensionsBench;
 			use baseline::Pallet as BaselineBench;
 			use super::*;
 
diff --git a/templates/solochain/runtime/src/benchmarks.rs b/templates/solochain/runtime/src/benchmarks.rs
index f39c2bd2959..59012e0b047 100644
--- a/templates/solochain/runtime/src/benchmarks.rs
+++ b/templates/solochain/runtime/src/benchmarks.rs
@@ -26,6 +26,7 @@
 frame_benchmarking::define_benchmarks!(
 	[frame_benchmarking, BaselineBench::<Runtime>]
 	[frame_system, SystemBench::<Runtime>]
+	[frame_system_extensions, SystemExtensionsBench::<Runtime>]
 	[pallet_balances, Balances]
 	[pallet_timestamp, Timestamp]
 	[pallet_sudo, Sudo]
diff --git a/templates/solochain/runtime/src/configs/mod.rs b/templates/solochain/runtime/src/configs/mod.rs
index 02d44967513..e34b3cb8215 100644
--- a/templates/solochain/runtime/src/configs/mod.rs
+++ b/templates/solochain/runtime/src/configs/mod.rs
@@ -148,6 +148,7 @@ impl pallet_transaction_payment::Config for Runtime {
 	type WeightToFee = IdentityFee<Balance>;
 	type LengthToFee = IdentityFee<Balance>;
 	type FeeMultiplierUpdate = ConstFeeMultiplier<FeeMultiplier>;
+	type WeightInfo = pallet_transaction_payment::weights::SubstrateWeight<Runtime>;
 }
 
 impl pallet_sudo::Config for Runtime {
diff --git a/templates/solochain/runtime/src/lib.rs b/templates/solochain/runtime/src/lib.rs
index bc47f3aeac8..42361a2ff36 100644
--- a/templates/solochain/runtime/src/lib.rs
+++ b/templates/solochain/runtime/src/lib.rs
@@ -146,8 +146,8 @@ pub type SignedBlock = generic::SignedBlock<Block>;
 /// BlockId type as expected by this runtime.
 pub type BlockId = generic::BlockId<Block>;
 
-/// The SignedExtension to the basic transaction logic.
-pub type SignedExtra = (
+/// The `TransactionExtension`` to the basic transaction logic.
+pub type TxExtension = (
 	frame_system::CheckNonZeroSender<Runtime>,
 	frame_system::CheckSpecVersion<Runtime>,
 	frame_system::CheckTxVersion<Runtime>,
@@ -161,10 +161,10 @@ pub type SignedExtra = (
 
 /// Unchecked extrinsic type as expected by this runtime.
 pub type UncheckedExtrinsic =
-	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
 
 /// The payload being signed in transactions.
-pub type SignedPayload = generic::SignedPayload<RuntimeCall, SignedExtra>;
+pub type SignedPayload = generic::SignedPayload<RuntimeCall, TxExtension>;
 
 /// All migrations of the runtime, aside from the ones declared in the pallets.
 ///
diff --git a/umbrella/Cargo.toml b/umbrella/Cargo.toml
index e05bf129bbd..7147a11fb9c 100644
--- a/umbrella/Cargo.toml
+++ b/umbrella/Cargo.toml
@@ -148,6 +148,7 @@ std = [
 	"pallet-tx-pause?/std",
 	"pallet-uniques?/std",
 	"pallet-utility?/std",
+	"pallet-verify-signature?/std",
 	"pallet-vesting?/std",
 	"pallet-whitelist?/std",
 	"pallet-xcm-benchmarks?/std",
@@ -251,6 +252,7 @@ runtime-benchmarks = [
 	"frame-system?/runtime-benchmarks",
 	"pallet-alliance?/runtime-benchmarks",
 	"pallet-asset-conversion-ops?/runtime-benchmarks",
+	"pallet-asset-conversion-tx-payment?/runtime-benchmarks",
 	"pallet-asset-conversion?/runtime-benchmarks",
 	"pallet-asset-rate?/runtime-benchmarks",
 	"pallet-asset-tx-payment?/runtime-benchmarks",
@@ -321,11 +323,13 @@ runtime-benchmarks = [
 	"pallet-sudo?/runtime-benchmarks",
 	"pallet-timestamp?/runtime-benchmarks",
 	"pallet-tips?/runtime-benchmarks",
+	"pallet-transaction-payment?/runtime-benchmarks",
 	"pallet-transaction-storage?/runtime-benchmarks",
 	"pallet-treasury?/runtime-benchmarks",
 	"pallet-tx-pause?/runtime-benchmarks",
 	"pallet-uniques?/runtime-benchmarks",
 	"pallet-utility?/runtime-benchmarks",
+	"pallet-verify-signature?/runtime-benchmarks",
 	"pallet-vesting?/runtime-benchmarks",
 	"pallet-whitelist?/runtime-benchmarks",
 	"pallet-xcm-benchmarks?/runtime-benchmarks",
@@ -460,6 +464,7 @@ try-runtime = [
 	"pallet-tx-pause?/try-runtime",
 	"pallet-uniques?/try-runtime",
 	"pallet-utility?/try-runtime",
+	"pallet-verify-signature?/try-runtime",
 	"pallet-vesting?/try-runtime",
 	"pallet-whitelist?/try-runtime",
 	"pallet-xcm-bridge-hub-router?/try-runtime",
@@ -536,7 +541,7 @@ with-tracing = [
 	"sp-tracing?/with-tracing",
 	"sp-tracing?/with-tracing",
 ]
-runtime-full = ["assets-common", "binary-merkle-tree", "bp-header-chain", "bp-messages", "bp-parachains", "bp-polkadot", "bp-polkadot-core", "bp-relayers", "bp-runtime", "bp-test-utils", "bp-xcm-bridge-hub", "bp-xcm-bridge-hub-router", "bridge-hub-common", "bridge-runtime-common", "cumulus-pallet-aura-ext", "cumulus-pallet-dmp-queue", "cumulus-pallet-parachain-system", "cumulus-pallet-parachain-system-proc-macro", "cumulus-pallet-session-benchmarking", "cumulus-pallet-solo-to-para", "cumulus-pallet-xcm", "cumulus-pallet-xcmp-queue", "cumulus-ping", "cumulus-primitives-aura", "cumulus-primitives-core", "cumulus-primitives-parachain-inherent", "cumulus-primitives-proof-size-hostfunction", "cumulus-primitives-storage-weight-reclaim", "cumulus-primitives-timestamp", "cumulus-primitives-utility", "frame-benchmarking", "frame-benchmarking-pallet-pov", "frame-election-provider-solution-type", "frame-election-provider-support", "frame-executive", "frame-metadata-hash-extension", "frame-support", "frame-support-procedural", "frame-support-procedural-tools-derive", "frame-system", "frame-system-benchmarking", "frame-system-rpc-runtime-api", "frame-try-runtime", "pallet-alliance", "pallet-asset-conversion", "pallet-asset-conversion-ops", "pallet-asset-conversion-tx-payment", "pallet-asset-rate", "pallet-asset-tx-payment", "pallet-assets", "pallet-assets-freezer", "pallet-atomic-swap", "pallet-aura", "pallet-authority-discovery", "pallet-authorship", "pallet-babe", "pallet-bags-list", "pallet-balances", "pallet-beefy", "pallet-beefy-mmr", "pallet-bounties", "pallet-bridge-grandpa", "pallet-bridge-messages", "pallet-bridge-parachains", "pallet-bridge-relayers", "pallet-broker", "pallet-child-bounties", "pallet-collator-selection", "pallet-collective", "pallet-collective-content", "pallet-contracts", "pallet-contracts-proc-macro", "pallet-contracts-uapi", "pallet-conviction-voting", "pallet-core-fellowship", "pallet-delegated-staking", "pallet-democracy", "pallet-dev-mode", "pallet-election-provider-multi-phase", "pallet-election-provider-support-benchmarking", "pallet-elections-phragmen", "pallet-fast-unstake", "pallet-glutton", "pallet-grandpa", "pallet-identity", "pallet-im-online", "pallet-indices", "pallet-insecure-randomness-collective-flip", "pallet-lottery", "pallet-membership", "pallet-message-queue", "pallet-migrations", "pallet-mixnet", "pallet-mmr", "pallet-multisig", "pallet-nft-fractionalization", "pallet-nfts", "pallet-nfts-runtime-api", "pallet-nis", "pallet-node-authorization", "pallet-nomination-pools", "pallet-nomination-pools-benchmarking", "pallet-nomination-pools-runtime-api", "pallet-offences", "pallet-offences-benchmarking", "pallet-paged-list", "pallet-parameters", "pallet-preimage", "pallet-proxy", "pallet-ranked-collective", "pallet-recovery", "pallet-referenda", "pallet-remark", "pallet-revive", "pallet-revive-fixtures", "pallet-revive-proc-macro", "pallet-revive-uapi", "pallet-root-offences", "pallet-root-testing", "pallet-safe-mode", "pallet-salary", "pallet-scheduler", "pallet-scored-pool", "pallet-session", "pallet-session-benchmarking", "pallet-skip-feeless-payment", "pallet-society", "pallet-staking", "pallet-staking-reward-curve", "pallet-staking-reward-fn", "pallet-staking-runtime-api", "pallet-state-trie-migration", "pallet-statement", "pallet-sudo", "pallet-timestamp", "pallet-tips", "pallet-transaction-payment", "pallet-transaction-payment-rpc-runtime-api", "pallet-transaction-storage", "pallet-treasury", "pallet-tx-pause", "pallet-uniques", "pallet-utility", "pallet-vesting", "pallet-whitelist", "pallet-xcm", "pallet-xcm-benchmarks", "pallet-xcm-bridge-hub", "pallet-xcm-bridge-hub-router", "parachains-common", "polkadot-core-primitives", "polkadot-parachain-primitives", "polkadot-primitives", "polkadot-runtime-common", "polkadot-runtime-metrics", "polkadot-runtime-parachains", "polkadot-sdk-frame", "sc-chain-spec-derive", "sc-tracing-proc-macro", "slot-range-helper", "snowbridge-beacon-primitives", "snowbridge-core", "snowbridge-ethereum", "snowbridge-outbound-queue-merkle-tree", "snowbridge-outbound-queue-runtime-api", "snowbridge-pallet-ethereum-client", "snowbridge-pallet-ethereum-client-fixtures", "snowbridge-pallet-inbound-queue", "snowbridge-pallet-inbound-queue-fixtures", "snowbridge-pallet-outbound-queue", "snowbridge-pallet-system", "snowbridge-router-primitives", "snowbridge-runtime-common", "snowbridge-system-runtime-api", "sp-api", "sp-api-proc-macro", "sp-application-crypto", "sp-arithmetic", "sp-authority-discovery", "sp-block-builder", "sp-consensus-aura", "sp-consensus-babe", "sp-consensus-beefy", "sp-consensus-grandpa", "sp-consensus-pow", "sp-consensus-slots", "sp-core", "sp-crypto-ec-utils", "sp-crypto-hashing", "sp-crypto-hashing-proc-macro", "sp-debug-derive", "sp-externalities", "sp-genesis-builder", "sp-inherents", "sp-io", "sp-keyring", "sp-keystore", "sp-metadata-ir", "sp-mixnet", "sp-mmr-primitives", "sp-npos-elections", "sp-offchain", "sp-runtime", "sp-runtime-interface", "sp-runtime-interface-proc-macro", "sp-session", "sp-staking", "sp-state-machine", "sp-statement-store", "sp-std", "sp-storage", "sp-timestamp", "sp-tracing", "sp-transaction-pool", "sp-transaction-storage-proof", "sp-trie", "sp-version", "sp-version-proc-macro", "sp-wasm-interface", "sp-weights", "staging-parachain-info", "staging-xcm", "staging-xcm-builder", "staging-xcm-executor", "substrate-bip39", "testnet-parachains-constants", "tracing-gum-proc-macro", "xcm-procedural", "xcm-runtime-apis"]
+runtime-full = ["assets-common", "binary-merkle-tree", "bp-header-chain", "bp-messages", "bp-parachains", "bp-polkadot", "bp-polkadot-core", "bp-relayers", "bp-runtime", "bp-test-utils", "bp-xcm-bridge-hub", "bp-xcm-bridge-hub-router", "bridge-hub-common", "bridge-runtime-common", "cumulus-pallet-aura-ext", "cumulus-pallet-dmp-queue", "cumulus-pallet-parachain-system", "cumulus-pallet-parachain-system-proc-macro", "cumulus-pallet-session-benchmarking", "cumulus-pallet-solo-to-para", "cumulus-pallet-xcm", "cumulus-pallet-xcmp-queue", "cumulus-ping", "cumulus-primitives-aura", "cumulus-primitives-core", "cumulus-primitives-parachain-inherent", "cumulus-primitives-proof-size-hostfunction", "cumulus-primitives-storage-weight-reclaim", "cumulus-primitives-timestamp", "cumulus-primitives-utility", "frame-benchmarking", "frame-benchmarking-pallet-pov", "frame-election-provider-solution-type", "frame-election-provider-support", "frame-executive", "frame-metadata-hash-extension", "frame-support", "frame-support-procedural", "frame-support-procedural-tools-derive", "frame-system", "frame-system-benchmarking", "frame-system-rpc-runtime-api", "frame-try-runtime", "pallet-alliance", "pallet-asset-conversion", "pallet-asset-conversion-ops", "pallet-asset-conversion-tx-payment", "pallet-asset-rate", "pallet-asset-tx-payment", "pallet-assets", "pallet-assets-freezer", "pallet-atomic-swap", "pallet-aura", "pallet-authority-discovery", "pallet-authorship", "pallet-babe", "pallet-bags-list", "pallet-balances", "pallet-beefy", "pallet-beefy-mmr", "pallet-bounties", "pallet-bridge-grandpa", "pallet-bridge-messages", "pallet-bridge-parachains", "pallet-bridge-relayers", "pallet-broker", "pallet-child-bounties", "pallet-collator-selection", "pallet-collective", "pallet-collective-content", "pallet-contracts", "pallet-contracts-proc-macro", "pallet-contracts-uapi", "pallet-conviction-voting", "pallet-core-fellowship", "pallet-delegated-staking", "pallet-democracy", "pallet-dev-mode", "pallet-election-provider-multi-phase", "pallet-election-provider-support-benchmarking", "pallet-elections-phragmen", "pallet-fast-unstake", "pallet-glutton", "pallet-grandpa", "pallet-identity", "pallet-im-online", "pallet-indices", "pallet-insecure-randomness-collective-flip", "pallet-lottery", "pallet-membership", "pallet-message-queue", "pallet-migrations", "pallet-mixnet", "pallet-mmr", "pallet-multisig", "pallet-nft-fractionalization", "pallet-nfts", "pallet-nfts-runtime-api", "pallet-nis", "pallet-node-authorization", "pallet-nomination-pools", "pallet-nomination-pools-benchmarking", "pallet-nomination-pools-runtime-api", "pallet-offences", "pallet-offences-benchmarking", "pallet-paged-list", "pallet-parameters", "pallet-preimage", "pallet-proxy", "pallet-ranked-collective", "pallet-recovery", "pallet-referenda", "pallet-remark", "pallet-revive", "pallet-revive-fixtures", "pallet-revive-proc-macro", "pallet-revive-uapi", "pallet-root-offences", "pallet-root-testing", "pallet-safe-mode", "pallet-salary", "pallet-scheduler", "pallet-scored-pool", "pallet-session", "pallet-session-benchmarking", "pallet-skip-feeless-payment", "pallet-society", "pallet-staking", "pallet-staking-reward-curve", "pallet-staking-reward-fn", "pallet-staking-runtime-api", "pallet-state-trie-migration", "pallet-statement", "pallet-sudo", "pallet-timestamp", "pallet-tips", "pallet-transaction-payment", "pallet-transaction-payment-rpc-runtime-api", "pallet-transaction-storage", "pallet-treasury", "pallet-tx-pause", "pallet-uniques", "pallet-utility", "pallet-verify-signature", "pallet-vesting", "pallet-whitelist", "pallet-xcm", "pallet-xcm-benchmarks", "pallet-xcm-bridge-hub", "pallet-xcm-bridge-hub-router", "parachains-common", "polkadot-core-primitives", "polkadot-parachain-primitives", "polkadot-primitives", "polkadot-runtime-common", "polkadot-runtime-metrics", "polkadot-runtime-parachains", "polkadot-sdk-frame", "sc-chain-spec-derive", "sc-tracing-proc-macro", "slot-range-helper", "snowbridge-beacon-primitives", "snowbridge-core", "snowbridge-ethereum", "snowbridge-outbound-queue-merkle-tree", "snowbridge-outbound-queue-runtime-api", "snowbridge-pallet-ethereum-client", "snowbridge-pallet-ethereum-client-fixtures", "snowbridge-pallet-inbound-queue", "snowbridge-pallet-inbound-queue-fixtures", "snowbridge-pallet-outbound-queue", "snowbridge-pallet-system", "snowbridge-router-primitives", "snowbridge-runtime-common", "snowbridge-system-runtime-api", "sp-api", "sp-api-proc-macro", "sp-application-crypto", "sp-arithmetic", "sp-authority-discovery", "sp-block-builder", "sp-consensus-aura", "sp-consensus-babe", "sp-consensus-beefy", "sp-consensus-grandpa", "sp-consensus-pow", "sp-consensus-slots", "sp-core", "sp-crypto-ec-utils", "sp-crypto-hashing", "sp-crypto-hashing-proc-macro", "sp-debug-derive", "sp-externalities", "sp-genesis-builder", "sp-inherents", "sp-io", "sp-keyring", "sp-keystore", "sp-metadata-ir", "sp-mixnet", "sp-mmr-primitives", "sp-npos-elections", "sp-offchain", "sp-runtime", "sp-runtime-interface", "sp-runtime-interface-proc-macro", "sp-session", "sp-staking", "sp-state-machine", "sp-statement-store", "sp-std", "sp-storage", "sp-timestamp", "sp-tracing", "sp-transaction-pool", "sp-transaction-storage-proof", "sp-trie", "sp-version", "sp-version-proc-macro", "sp-wasm-interface", "sp-weights", "staging-parachain-info", "staging-xcm", "staging-xcm-builder", "staging-xcm-executor", "substrate-bip39", "testnet-parachains-constants", "tracing-gum-proc-macro", "xcm-procedural", "xcm-runtime-apis"]
 runtime = [
 	"frame-benchmarking",
 	"frame-benchmarking-pallet-pov",
@@ -1332,6 +1337,11 @@ path = "../substrate/frame/utility"
 default-features = false
 optional = true
 
+[dependencies.pallet-verify-signature]
+path = "../substrate/frame/verify-signature"
+default-features = false
+optional = true
+
 [dependencies.pallet-vesting]
 path = "../substrate/frame/vesting"
 default-features = false
diff --git a/umbrella/src/lib.rs b/umbrella/src/lib.rs
index 7778706d515..f3fc949c66e 100644
--- a/umbrella/src/lib.rs
+++ b/umbrella/src/lib.rs
@@ -705,6 +705,10 @@ pub use pallet_uniques;
 #[cfg(feature = "pallet-utility")]
 pub use pallet_utility;
 
+/// FRAME verify signature pallet.
+#[cfg(feature = "pallet-verify-signature")]
+pub use pallet_verify_signature;
+
 /// FRAME pallet for manage vesting.
 #[cfg(feature = "pallet-vesting")]
 pub use pallet_vesting;
-- 
GitLab