Conversation
| /// Returns the mode of transactional | ||
| pub fn get_transactional_mode() -> bool { | ||
| crate::storage::unhashed::get_or::<bool>(TRANSACTIONAL_MODE_KEY, true) | ||
| } | ||
|
|
||
| /// Set the value of transactional mode | ||
| pub fn set_transactional_mode(value: bool) { | ||
| crate::storage::unhashed::put::<bool>(TRANSACTIONAL_MODE_KEY, &value); | ||
| } |
There was a problem hiding this comment.
This is not the right thing to do.
The decision of whether we use transactional or not should be stateless, and happen at compile time.
You need to track the existence of without_transactional within the macro, and then simple use it to determine which arm of the code you want to compile
There was a problem hiding this comment.
match self {
#(
Self::#fn_name { #( #args_name_pattern, )* } => {
#frame_support::sp_tracing::enter_span!(
#frame_support::sp_tracing::trace_span!(stringify!(#fn_name))
);
if #without_transactional {
<#pallet_ident<#type_use_gen>>::#fn_name(origin, #( #args_name, )* )
.map(Into::into).map_err(Into::into)
} else {
// We execute all dispatchable in at least one storage layer, allowing them
// to return an error at any point, and undoing any storage changes.
#frame_support::storage::in_storage_layer(|| {
<#pallet_ident<#type_use_gen>>::#fn_name(origin, #( #args_name, )* )
.map(Into::into).map_err(Into::into)
})
}
},
)*
There was a problem hiding this comment.
Actually, even this can be done a bit better, by using the procedural macro to generate one of:
<#pallet_ident<#type_use_gen>>::#fn_name(origin, #( #args_name, )* )
.map(Into::into).map_err(Into::into)
or
// We execute all dispatchable in at least one storage layer, allowing them
// to return an error at any point, and undoing any storage changes.
#frame_support::storage::in_storage_layer(|| {
<#pallet_ident<#type_use_gen>>::#fn_name(origin, #( #args_name, )* )
.map(Into::into).map_err(Into::into)
})
And then this code is inserted into the same spot.
There was a problem hiding this comment.
@shawntabrizi Where should this be checked? It can't be inside the transactional macro, because it is now the default and you don't have to use it. What part of the code is currently getting executed by default to make use of transactional? Sorry if I didn't understand you right.
There was a problem hiding this comment.
If you take a look at the previous PR, you'll see that under frame/support/procedural/src/pallet/expand/call.rs, there is a new piece of code that unquestionably puts all extrinsic execution logic in a closure fed to in_storage_layer.
There was a problem hiding this comment.
@shawntabrizi To make the code you sent work we need access to the parsed definition of the pallet Def for the fn_name, args_name_pattern, pallet_ident and type_use_gen. Should I change the function parameters so it accepts def?
There was a problem hiding this comment.
@Szegoo It sounds like you're looking at the wrong place. frame/support/procedural/src/pallet/expand/call.rs should contain the code where you can decide whether or not there should be storage layer.
|
Hey, is anyone still working on this? Due to the inactivity this issue has been automatically marked as stale. It will be closed if no further activity occurs. Thank you for your contributions. |
|
Closed because of: #11533 (comment) |
Still in progress.
I have added a new attribute
modethat represents whether an extrinsic is gonna have a storage layer.When done this should fix #11533