joystream icon indicating copy to clipboard operation
joystream copied to clipboard

POC for extracting call parameters corresponding to specific event

Open zeeshanakram3 opened this issue 2 years ago • 1 comments

For an event E that we are processing in mappings, we want to find the call e that emitted the said event provided that the given call can be indefinitely wrapped in top-level extrinsics such as sudo, sudoAs, batch, batchAll. Following, I have described different scenarios in which we may find the extrinsic payload of the event.

Scenario 1

Call e is wrapped in sudo/sudoAs by unknown times, say

orignalCall = sudoAs(sudoAs(sudoAs(e)))

Solution

A recursive solution for finding the call e would work, i.e. keep on unwrapping the originalCall until we find the e

Scenario 2

Call e is part of some batch call. And other calls in the batch can be of the same or different types, say e1, e2, c, d

orignalCall = batch(e1, e2, e, c, d)

Solution

  1. Get the list of all the events in the block
  2. Filter all events of type E in the events list and return the filtered events, say filteredEvents
  3. Find index i of event E we are processing in the filteredEvents
  4. Filter all calls of type e in the batch list and return the filtered batch list, say filteredCalls
  5. A call at index i in filteredCalls list would correspond to the event call

Scenario 3

Call e is part of some batch call. And all other calls in the batch are of the same type as e, say e1, e2, e3, e4

orignalCall = batch(e1, e2, e3, e, e4)

Solution

Scenario 2 solution would work

Scenario 4

Call e is part of some batch call. And other calls in the batch can themselves be the batch of other calls, say

orignalCall =  batch(e1, batch(e, c, batch(e2)), d)

Solution

The scenario 2 solution would work; the trick is that the execution order of calls in the nested batches would look as if all calls were part of only one batch. e.g. For batch(e1, batch(e, c, batch(e2)), d), the execution order would be e1, e, c, e2, d, So we can convert nested batches as one flattened batch containing all calls using depth first search.


P.S:

Solution for all the batch scenarios would only work if we guaranteed that every batch call would succeed. Otherwise, there would be some missing events in the events array, and we will not able to correctly find the index of the call. However, batchAll is transactional extrinsic, so it would ensure that either all calls succeed or none, So we can safely say that batchAll would work for the above scenarios. And for this solution, we still need to disable batch extrinsic from the utility pallet.

┆Issue is synchronized with this Asana task by Unito

zeeshanakram3 avatar Aug 21 '22 19:08 zeeshanakram3

So seems like there are more scenarios for the batch calls, and the solution proposed here does not encompass those scenarios. e.g., there could have been consecutive batch calls in the block (batch(e1, e2)), batch(e3, e, e4), and the proposed solution only assumes that there would be only one batch call in blick

zeeshanakram3 avatar Aug 22 '22 08:08 zeeshanakram3