paritytech / polkadot-sdk

The Parity Polkadot Blockchain SDK
https://polkadot.com/
1.91k stars 704 forks source link

Annoyance: Transaction extension tuple can't be more than 12 elements, and tuple of tuple changes order of inherited implication and is not discoverable with metadata #6569

Open gui1117 opened 1 day ago

gui1117 commented 1 day ago

TLDR: Transaction extension tuple can't be more than 12 elements, and tuple of tuple changes order of inherited implication, and the order is not discoverable with metadata because it only contains a vector of transaction extension.

Description:

The transaction extensions are define with a tuple of transaction extension, and is part of the extrinsic that is part of a block.

pub type TxExtension = (
    frame_system::CheckNonZeroSender<Runtime>,
    frame_system::CheckSpecVersion<Runtime>,
    frame_system::CheckTxVersion<Runtime>,
    frame_system::CheckGenesis<Runtime>,
    frame_system::CheckEra<Runtime>,
    frame_system::CheckNonce<Runtime>,
    frame_system::CheckWeight<Runtime>,
    pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
    cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim<Runtime>,
    frame_metadata_hash_extension::CheckMetadataHash<Runtime>,
);

/// Unchecked extrinsic type as expected by this runtime.
pub type UncheckedExtrinsic =
    generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;

The block requires among other traits: Eq, PartialEq, Debug.

Those specific traits are implemented on tuple of at most 12 elements: https://doc.rust-lang.org/core/primitive.tuple.html#trait-implementations-1

To fit into 12 elements we may want to group some into tuples like:

pub type TxExtension = (
    (
        frame_system::CheckNonZeroSender<Runtime>,
        frame_system::CheckSpecVersion<Runtime>,
        frame_system::CheckTxVersion<Runtime>,
        frame_system::CheckGenesis<Runtime>,
        frame_system::CheckEra<Runtime>,
    ),
    frame_system::CheckNonce<Runtime>,
    frame_system::CheckWeight<Runtime>,
    pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
    cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim<Runtime>,
    frame_metadata_hash_extension::CheckMetadataHash<Runtime>,
);

But this changes the inherited implication passed to the grouped transaction extensions: The code is here: https://github.com/paritytech/polkadot-sdk/blob/25691b8e945a6453fa65fd5ae6eb54b6a523f280/substrate/primitives/runtime/src/traits/transaction_extension/mod.rs#L510-L533

To be more precise:

Solution:

cc @georgepisaltu