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

Contract.DecodingFailed when using Enum with non-unit-like variants in chain extension inputs #1829

Open
2 tasks done
SailorSnoW opened this issue Jun 29, 2023 · 0 comments
Open
2 tasks done

Comments

@SailorSnoW
Copy link

Is there an existing issue?

  • I have searched the existing issues

Experiencing problems? Have you tried our Stack Exchange first?

  • This is not a support question.

Description of bug

We are currently developing a chain extension to be able to use the NFTs pallet from the contract side on-chain.

Because it fit better with our needs, we use the second method as described in this video (Chain Extension Builder):
https://www.youtube.com/watch?v=-T-HKy_vFCo&t=2427s

The problem:

The implementation went good but we are actually stuck on the following problem:
Using an enum containing a non-unit-like variant (for example Some(T) in the enum Option<T>) make it impossible to decode the input on the substrate side with env.read_as() ONLY if a unit-like variant of the Enum is selected by the user (for example None).
This return a Contract.DecodingFailed error.

You can find the chain extension code of this demo at the following repo and branch (don't mind the rest of the code as it's in a really WIP state): to-fix/extension-decodingfailed
The repo is divided in 4 parts:

  • Root crate: The Ink side of the chain extension with the chain extension builder implementation.
  • impls_runtime crate: The substrate side of the chain extension with the ChainExtension trait implemented on the struct for the runtime.
  • types crate: The shared types between the substrate and ink side to avoid some conflicts between ink and runtime dependencies.
  • test_contracts create: Contain the code of the testing contract used above (basically a simple wrapper of the developed extensions fn).

What have been tested:

  • Destructuring field parameters (one parameter for each type)
  • Not using env.read_as() in substrate side => work ✔
  • Not using any Option and custom Enum tuple-variant => work ✔

My guess:

Something that mess with the total size of what env.read_as() expect, as using an unit-like variant of an Enum decrease the dynamic size of the object ? Maybe something with the MaxEncodedLen derivation ?

Steps to reproduce

  1. Clone the following node repo: [email protected]:Allfeat/Allfeat.git
  2. Checkout the tofix/extension-decodefailed branch
  3. Start a dev node with $ cargo run --release -- --dev --tmp
  4. Access the dev node through Polkadot/Substrate Portal - Local Node - Contracts UI
  5. Upload and instantiate the linked test contract (with the .contract)
    test-contract.zip
  6. Then try to interact with the create() message of the contract. You should have the DecodingFailed error if you use a None in one of the Option<T> fields and if you don't use the HolderOf(CollectionId) variant.
    Putting a Some value in each of the Option<T> fields with using the HolderOf(CollectionId) variant don't cause a DecodingFailed error.
@bkchr bkchr transferred this issue from paritytech/substrate Jun 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant