tjjfvi/subshape

Non-contiguous indices vs. union decoder selection

harrysolovay opened this issue · 0 comments

I came across an interesting Union type in the frame metadata of Westend:

{
  i: 17,
  path: [ "westend_runtime", "Event" ],
  params: [],
  _tag: "Union",
  members: [
    { name: "System", fields: [ [Object] ], i: 0, docs: [] },
    { name: "Indices", fields: [ [Object] ], i: 3, docs: [] },
    { name: "Balances", fields: [ [Object] ], i: 4, docs: [] },
    { name: "Staking", fields: [ [Object] ], i: 6, docs: [] },
    { name: "Offences", fields: [ [Object] ], i: 7, docs: [] },
    { name: "Session", fields: [ [Object] ], i: 8, docs: [] },
    { name: "Grandpa", fields: [ [Object] ], i: 10, docs: [] },
    { name: "ImOnline", fields: [ [Object] ], i: 11, docs: [] },
    { name: "Utility", fields: [ [Object] ], i: 16, docs: [] },
    { name: "Identity", fields: [ [Object] ], i: 17, docs: [] },
    { name: "Recovery", fields: [ [Object] ], i: 18, docs: [] },
    { name: "Vesting", fields: [ [Object] ], i: 19, docs: [] },
    { name: "Scheduler", fields: [ [Object] ], i: 20, docs: [] },
    { name: "Preimage", fields: [ [Object] ], i: 28, docs: [] },
    { name: "Sudo", fields: [ [Object] ], i: 21, docs: [] },
    { name: "Proxy", fields: [ [Object] ], i: 22, docs: [] },
    { name: "Multisig", fields: [ [Object] ], i: 23, docs: [] },
    { name: "ElectionProviderMultiPhase", fields: [ [Object] ], i: 24, docs: [] },
    { name: "BagsList", fields: [ [Object] ], i: 25, docs: [] },
    { name: "NominationPools", fields: [ [Object] ], i: 29, docs: [] },
    { name: "ParaInclusion", fields: [ [Object] ], i: 44, docs: [] },
    { name: "Paras", fields: [ [Object] ], i: 47, docs: [] },
    { name: "Ump", fields: [ [Object] ], i: 50, docs: [] },
    { name: "Hrmp", fields: [ [Object] ], i: 51, docs: [] },
    { name: "ParasDisputes", fields: [ [Object] ], i: 53, docs: [] },
    { name: "Registrar", fields: [ [Object] ], i: 60, docs: [] },
    { name: "Slots", fields: [ [Object] ], i: 61, docs: [] },
    { name: "Auctions", fields: [ [Object] ], i: 63, docs: [] },
    { name: "Crowdloan", fields: [ [Object] ], i: 64, docs: [] },
    { name: "AssignedSlots", fields: [ [Object] ], i: 65, docs: [] },
    { name: "XcmPallet", fields: [ [Object] ], i: 99, docs: [] }
  ],
  docs: []
}

Here, the discriminants of each member do not necessarily correspond to their position in the members list. To correct decoding, I needed to modify the union codec with a getIndexOfDiscriminant, which maps the discriminant to a codec in the $union-supplied $members arg list. Not sure if this is the best approach.