Introduce TransactionExtensionPipeline to use instead of tuple for pipeline with more than 12 elements#6571
Introduce TransactionExtensionPipeline to use instead of tuple for pipeline with more than 12 elements#6571
TransactionExtensionPipeline to use instead of tuple for pipeline with more than 12 elements#6571Conversation
| #[derive(Debug, Clone, PartialEq, Eq, Encode, Decode, TypeInfo)] | ||
| pub struct TransactionExtensionPipeline< | ||
| $( $generic = (), )* | ||
| >( |
There was a problem hiding this comment.
another solution is to implement a wrapper of tuple, that manually implements Debug, PartialEq, Eq, and also implements TransactionExtension.
This way the type may look less like a hack.
There was a problem hiding this comment.
This would work, we just need to make sure we expose it properly in the metadata so that it's not transparent, right?
There was a problem hiding this comment.
I am not sure I understand, the metadata is anyway just a vec of TransactionExtensionMetadata.
What I am thinking is we can implement do either:
- like this PR currently, a type with 32 generics being
()by default. - or a type with only 1 generic, and do
impl<A> Debug for Pipeline<(A,)> ..,impl<A, B> Debug for Pipeline<(A, B)> ..etc...
Both implementation would be transparent
georgepisaltu
left a comment
There was a problem hiding this comment.
Looks good, can you also add extra tests with the new TransactionExtensionPipeline in substrate/frame/support/src/dispatch.rs in the extension_weight_tests module to make sure the weight calculation and refund is working properly?
| impl<Call: Dispatchable> TransactionExtension<Call> for () { | ||
| const IDENTIFIER: &'static str = "UnitTransactionExtension"; | ||
| type Implicit = (); | ||
| #[inline] |
There was a problem hiding this comment.
TransactionExtensionPipeline take 32 generics that defaults to (), so I inlined methods here so hopefully the code gets optimized by the compiler.
TransactionExtensionPipeline to use instead of tuple for pipeline with more than 12 elementsTransactionExtensionPipeline to use instead of tuple for pipeline with more than 12 elements
I added test for the refund of weights in EDIT: I will also do the test you suggest |
I added the test in b3e4503 |
|
All GitHub workflows were cancelled due to failure one of the required jobs. |
|
For the record another solution is to add a new fn validate_pipeline(
&self,
origin: <Call as Dispatchable>::RuntimeOrigin,
call: &Call,
info: &DispatchInfoOf<Call>,
len: usize,
self_implicit: Self::Implicit,
inherited_implicit_implication: &impl Encode,
inherited_explicit_implication: &impl Encode,
inherited_final_implication: &impl Encode,
source: TransactionSource,
) -> 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_final_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,
inherited_explicit_implication,
// 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,
inherited_implicit_implication,
);
Tuple.validate(origin, call, info, len, item_implicit, final, (following_explicit, inheritied_explicit), (following_implicit, inherited_implicit), source)?
};
let valid = valid.combine_with(item_valid);
let val = val.push_back(item_val);
)* );
Ok((valid, val, origin))
}
I mention this solution because I see in the doc people likes to have tuples of tuples, like here in the doc: polkadot-sdk/docs/sdk/packages/guides/first-runtime/src/lib.rs Lines 64 to 69 in 5abdc5c And also bridges stuff do it. EDIT: we can 2 functions or just one general function with all the 3 arguments and people will have to use it correctly. |
Fix #6569
Introduce a new type
TransactionExtensionPipelinethat has 32 generics that default to().This type accepts up to 32 transaction extensions which is better than the limit of 12 for a tuple.
As stated in the linked issue, the issue with tuple is that tuple of tuple is not the same as a single tuple. The inherited implication is changing. But it is impossible to find out the order in the metadata because the metadata is just a vec of transaction extension metadata.