Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pallet-utility: if_else #6321

Open
wants to merge 17 commits into
base: master
Choose a base branch
from

Conversation

rainbow-promise
Copy link

@rainbow-promise rainbow-promise commented Oct 31, 2024

Utility Call Fallback

This introduces a new extrinsic: if_else

Which first attempts to dispatch the main call(s). If the main call(s) fail, the fallback call(s) is dispatched instead. Both calls are executed with the same origin.

In the event of a fallback failure the whole call fails with the weights returned.

Use Case

Some use cases might involve submitting a batch type call in either main, fallback or both.

Resolves #6000

Polkadot Address: 1HbdqutFR8M535LpbLFT41w3j7v9ptEYGEJKmc6PKpqthZ8

@cla-bot-2021
Copy link

cla-bot-2021 bot commented Oct 31, 2024

User @rainbow-promise, please sign the CLA here.

Copy link
Contributor

@xlc xlc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you understand the requirements clearly because you have implemented batch, not if-else.
the fallback is only executed if and only if the main call failed. if main call successes, do not call fallback

substrate/frame/utility/src/lib.rs Outdated Show resolved Hide resolved
@rainbow-promise
Copy link
Author

rainbow-promise commented Nov 1, 2024

Need to take a closer look at the extrinsic executions, even with the revisions it Is not quit there yet.

@rainbow-promise rainbow-promise marked this pull request as ready for review November 6, 2024 16:48
@rainbow-promise rainbow-promise requested a review from a team as a code owner November 6, 2024 16:48
@rainbow-promise
Copy link
Author

please review @xlc @ggwpez

@xlc
Copy link
Contributor

xlc commented Nov 6, 2024

looks fine now. need proper weights

@rainbow-promise
Copy link
Author

I am guessing the weight signature below the pallet index will have some form of condition as well?

@xlc
Copy link
Contributor

xlc commented Nov 7, 2024

use the worst case (i.e. main + fallback). extra weight will be refunded as the actual weight is returned in the call

@rainbow-promise
Copy link
Author

use the worst case (i.e. main + fallback). extra weight will be refunded as the actual weight is returned in the call

this also applies to dispatch class?

@gui1117
Copy link
Contributor

gui1117 commented Nov 7, 2024

use the worst case (i.e. main + fallback). extra weight will be refunded as the actual weight is returned in the call

this also applies to dispatch class?

I would say dispatch class is the lowest class of the 2. if both are operational then it is operational. if one is normal then it is normal. etc.

@rainbow-promise
Copy link
Author

I would say dispatch class is the lowest class of the 2. if both are operational then it is operational. if one is normal then it is normal. etc.

how can one determine the class of a RuntimeCall? if Operational or Normal?

@gui1117
Copy link
Contributor

gui1117 commented Nov 7, 2024

I would say dispatch class is the lowest class of the 2. if both are operational then it is operational. if one is normal then it is normal. etc.

how can one determine the class of a RuntimeCall? if Operational or Normal?

take a look at batch, they do similar operation. You can use get_dispatch_info on the call.

@rainbow-promise
Copy link
Author

Also the kitchensink-runtime has no genesis_config_presets.rs file, using frame-omni-bencher errors out for that runtime because of that.

@rainbow-promise
Copy link
Author

i have added weights to all runtimes containing pallet-utility please review @ggwpez @xlc @gui1117

@rainbow-promise
Copy link
Author

Also the kitchensink-runtime has no genesis_config_presets.rs file, using frame-omni-bencher errors out for that runtime because of that.

Should I raise an issue for this? @xlc @gui1117

let caller = whitelisted_caller();

#[extrinsic_call]
_(RawOrigin::Signed(caller), main_call, fallback_call);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The err branch should be slightly more costly, but difference should be negligible so it is ok.

Copy link
Author

@rainbow-promise rainbow-promise Nov 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok.

Thanks for the review

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use a root call, it will be failing, like set_heap_page.
This would benchmark for the failing case, which is more costly

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...
        #[benchmark]
	fn if_else() {
		let main_call = Box::new(frame_system::Call::set_heap_pages { pages: 0u64 }.into());
		let fallback_call = Box::new(frame_system::Call::remark { remark: vec![1] }.into());
		let caller = whitelisted_caller();

		#[extrinsic_call]
		_(RawOrigin::Signed(caller), main_call, fallback_call);

		assert_last_event::<T>(Event::IfElseFallbackCalled { main_error: sp_runtime::DispatchError::Module(sp_runtime::ModuleError { index: 0, error: [5, 0, 0, 0], message: None }) }.into());
	}

substrate/frame/utility/src/lib.rs Outdated Show resolved Hide resolved
substrate/frame/utility/src/lib.rs Outdated Show resolved Hide resolved
substrate/frame/utility/src/tests.rs Show resolved Hide resolved
Copy link
Member

@ggwpez ggwpez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty good now, thanks!

I just put some comments.

prdoc/pr_6321.prdoc Outdated Show resolved Hide resolved
prdoc/pr_6321.prdoc Outdated Show resolved Hide resolved
substrate/frame/utility/src/lib.rs Outdated Show resolved Hide resolved
substrate/frame/utility/src/lib.rs Show resolved Hide resolved
substrate/frame/utility/src/lib.rs Outdated Show resolved Hide resolved
@ggwpez ggwpez added the T2-pallets This PR/Issue is related to a particular pallet. label Nov 13, 2024
@paritytech-review-bot paritytech-review-bot bot requested a review from a team November 13, 2024 14:21
@rainbow-promise
Copy link
Author

Need the CI to run some checks @ggwpez 🙏

gui1117
gui1117 previously approved these changes Nov 13, 2024
substrate/frame/utility/src/lib.rs Outdated Show resolved Hide resolved
@gui1117 gui1117 self-requested a review November 14, 2024 00:18
@paritytech-review-bot paritytech-review-bot bot requested a review from a team November 14, 2024 00:19
@rainbow-promise
Copy link
Author

Ready for review! @gui1117 @ggwpez
Hope the CI agrees.

assert_eq!(Balances::free_balance(1), 10);
assert_eq!(Balances::free_balance(2), 10);

System::assert_last_event(utility::Event::IfElseBothFailure { main_error: TokenError::FundsUnavailable.into(), fallback_error: TokenError::FundsUnavailable.into()}.into());
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems this event is not firing as expected.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks to me that Err is executed first in this block leaving out the Event completely?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah indeed, the error will revert the storage, so we can't deposit event.

Copy link

Review required! Latest push from author must always be reviewed

@rainbow-promise
Copy link
Author

Should be ready for final review now @gui1117 @ggwpez @xlc

the all failed case should just result the whole call to be failed. ie no extra event. so we only really two event: main success, and fallback called

Decided this was the way to go, the last event made it cumbersome.

- name: westend-runtime
bump: major
- name: pallet-utility
bump: major
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not a breaking change so should be a minor bump?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changes the call enum

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but the change is not in a breaking way? i.e. existing enum encode/decode as it was

Copy link
Author

@rainbow-promise rainbow-promise Nov 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ggwpez noted it here

if let Err(_fallback_error) = fallback_result {
// Both calls have faild.
return Err(sp_runtime::DispatchErrorWithPostInfo {
error: Error::<T>::IfElseBothFailure.into(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not 100% sure about this as it mask the underlying error and makes debugging harder

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can alternatively return the fallback error here

return Err(sp_runtime::DispatchErrorWithPostInfo {
        error: _fallback_error.error,
	post_info: Some(weight).into(),
})

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah that will be better than not having anything

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T2-pallets This PR/Issue is related to a particular pallet.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Utility if_else call
4 participants