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

Decode of assetId hex string fails for signed payload because of Option #6074

Closed
Chralt98 opened this issue Jan 23, 2025 · 7 comments
Closed

Comments

@Chralt98
Copy link

Error: Struct: failed on assetId: Option<MultiLocationV3>:: decodeU8aStruct: failed at 0x010300a10f043205e514… on interior (index 2/2): {"_enum":{"Here":"Null","X1":"JunctionV3","X2":"(JunctionV3,JunctionV3)","X3":"(JunctionV3,JunctionV3,JunctionV3)","X4":"(JunctionV3,JunctionV3,JunctionV3,JunctionV3)","X5":"(JunctionV3,JunctionV3,JunctionV3,JunctionV3,JunctionV3)","X6":"(JunctionV3,JunctionV3,JunctionV3,JunctionV3,JunctionV3,JunctionV3)","X7":"(JunctionV3,JunctionV3,JunctionV3,JunctionV3,JunctionV3,JunctionV3,JunctionV3)","X8":"(JunctionV3,JunctionV3,JunctionV3,JunctionV3,JunctionV3,JunctionV3,JunctionV3,JunctionV3)"}}:: decodeU8aStruct: failed at 0xa10f043205e514… on key (index 2/2): [u8;20]:: Expected input with 20 bytes (160 bits), found 7 bytes

In the above error it expects AccountKey20 (derived from [u8;20]). The index of this is 3 in JunctionV3. The assetId hex string always starts with 0x0103, in which 0x01 is used for parent: 1 and 0x03 should be used for X3 of JunctionsV3. However, the 0x03 occurs to be used not only for JunctionsV3 but also for the first entry into the tuple of X3, which is JunctionV3. So, it seems to be like a mistaken overlap for the decode functionality.

Image

I want to use the following assetId (which is USDC on AssetHub for our Zeitgeist Parachain):

let parentsNumber = api.registry.createType('u8', 1);
let parachainCompactNumber = api.registry.createType('Compact<u32>', 1000);
// let parachain = api.registry.createType('JunctionV3', { Parachain: parachainCompactNumber });
let palletInstanceNumber = api.registry.createType('u8', 50);
// let palletInstance = api.registry.createType('JunctionV3', { PalletInstance: palletInstanceNumber });
let generalIndexNumber = api.registry.createType('Compact<u128>', 1337);
// let generalIndex = api.registry.createType('JunctionV3', { GeneralIndex: generalIndexNumber });
let assetId = api.registry.createType('TAssetConversion', {
  // eslint-disable-next-line sort-keys
  // 0x010300a10f043205e514 (parachain, palletInstance, generalIndex) [1,1,3,0,161,15,4,50,5,229,20]
  // 0x010305e51400a10f0432 (generalIndex, parachain, palletInstance) [1,1,3,5,229,20,0,161,15,4,50]
  // 0x010300a10f05e5140432 (parachain, generalindex, palletInstance) [1,1,3,0,161,15,5,229,20,4,50]
  // 0x0103043200a10f05e514 (palletInstance, parachain, generalIndex) [1,1,3,4,50,0,161,15,5,229,20]
  // 0x0103043205e51400a10f (palletInstance, generalIndex, parachain) [1,1,3,4,50,5,229,20,0,161,15]
  // 0x010305e514043200a10f (generalindex, palletInstance, parachain) [1,1,3,5,229,20,4,50,0,161,15]
  // parents: 0x01 or [1,1]
  // interior x3: 0x03 or [3]
  // generalIndex: 0x05e514 or [5,229,20]; the 5 is the index of JunctionV3 enum
  // palletInstance: 0x0432 or [4,50]; the 4 is the index of JunctionV3 enum; 50 is the palletInstance number
  // parachain: 0x0a10f or [0,161,15]; the 0 is the index of JunctionV3 enum
  parents: parentsNumber,
  interior: {
    x3: [
      { parachain: parachainCompactNumber },
      { palletInstance: palletInstanceNumber },
      { generalIndex: generalIndexNumber },
    ],
  },
});

Here is some useful debug output of @polkadot/types-codec:

Image

Btw. I used a local fork of @polkadot/api and @polkadot/known-types to override the TAssetConversion for zeitgeist to be Option<MultiLocationV3>.

@Chralt98
Copy link
Author

I'll move this to @polkadot/extension-dapp, because as soon as I sign with the extension, it wouldn't work. The asset id input for the polkadot api however is fine.

@Chralt98
Copy link
Author

Chralt98 commented Jan 24, 2025

@TarikGul

Unfortunately, #5968 adds the Option to the hex asset id payload. This results in the asset id to include the option in the string through toPayload() for the signature here. So instead of asset id hex 0x010300a10f043205e514 it is then 0x01010300a10f043205e514, which then results in a decoding error somewhere down the line.

Also see #5967.

Maybe it's what you have been talking about here.

@Chralt98 Chralt98 changed the title Decode overlaps "X3" with enum variant number of "JunctionV3" Decode of assetId hex string fails for signed payload because of Option Jan 24, 2025
@TarikGul
Copy link
Member

I want to use the following assetId (which is USDC on AssetHub for our Zeitgeist Parachain)

Little tip: When you are constructing a value like above, you shouldn't be using createType. But instead just have the value as an object, and let the API do all the encoding based on what the type is. (This could very well be your problem)>

Example:

const main = async () => {
    const api = await ApiPromise.create({
        provider: new WsProvider('wss://kusama-asset-hub-rpc.polkadot.io'),
        typesBundle: {
            spec: {
                'statemine': {
                    types: [
                        {
                            minmax: [0, undefined],
                            TAssetConversion: 'Option<MultiLocationV3>'
                        }
                    ]
                }
            }
        }
    });

    // Encoding here just to show it works.
    const asset = api.registry.createType('TAssetConversion', {
        parents: 1,
        interior: {
            X3: [
                { Parachain: 1000 },
                { PalletInstance: 50 },
                { GeneralIndex: 1337 }
            ]
        }
    })

    console.log(asset.unwrap().toJSON());
};

When you actually plug in the value lets say to the SignerPayload. You can just give it the Object of the Multilocation and let the API handle the encoding and decoding.

@Chralt98
Copy link
Author

Chralt98 commented Jan 30, 2025

@TarikGul

It's interesting, I am using the Substrate front end template right now. As soon as I use the Polkadot extension, I get the following error:

Image

Before the failure it correctly shows the assetId in the extension:

Image

If I use the normal account selector for Alice, the transaction goes through and uses USDC as fee payment asset:

Image

Btw. I don't use createType anymore:

Image

@TarikGul
Copy link
Member

Mmm, try and use master of the api. I just merged in #6083 which fixes how the assetId is decoded when a value is passed in from the signer. This was related to apps but it could also be related here.

I have it working on live Kusama, and Polkadot - but haven't checked the front end template yet.

@Chralt98
Copy link
Author

Yes, perfect! This PR fixed it. Thanks!

@polkadot-js-bot
Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue if you think you have a related problem or query.

@polkadot-js polkadot-js locked as resolved and limited conversation to collaborators Feb 6, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants