1

We're writing a proxy extrinsic that dispatches a child call and consumes a 'free call'. We want to return the error of the child call to the user, but we want to consume a free call regardless.

Since I believe transactions are now transactional by default (ie rollback on error), what's the best way to return the results of the call to the user?

1 Answer 1

1

In general you cannot prevent the state from being rolled back on an error.

Did you have a look at the pallet-utility pallet?
The force_batch call has a similar semantic where errors are reported through events. It does not abort on an error but rather emits them as events. The respective event definitions look like this:

/// A single item within a Batch of dispatches has completed with no error.
ItemCompleted,

/// A single item within a Batch of dispatches has completed with error.
ItemFailed { error: DispatchError },

It then emits these events depending on the result of a previous dispatch:

if let Err(e) = result {
    Self::deposit_event(Event::ItemFailed { error: e.error });
} else {
    Self::deposit_event(Event::ItemCompleted);
}

So you could probably define similar events for FreeCallConsumed and ChildCallFailed.

2
  • 1
    Yeah, I was trying to avoid using Events as they are noisy and client has to manually find them (vs returning the result to them), but it looks like subxt's wait_for_finalized_success makes it easy to return the events associated with a transaction. Thanks! Oct 19, 2022 at 19:24
  • 1
    You kind of have to use events, since a CallConsumed could also happen through a different Extrinsic, eg utility::batch. So the only way to notice that is to use event and subscribe in the client. There was a similar Q here substrate.stackexchange.com/questions/5330/… Oct 19, 2022 at 20:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.