12

I'm playing around with custom RPC endpoints exposed from my substrate node, but I'm encountering an issue when trying to call it with polkadotjs. Initially, my endpoint only accepted a single parameter of type Bytes. Invocation from the frontend worked with any problems. After modifying the endpoint to also accept parameters with type Vec and u32 (note: this is only a change in params, the implementation was not changed), polkadotjs has an error when calling createType (when the endpoint is invoked), seemingly requiring an expected size:

createType(Vec<u8>):: Bytes: required length less than remainder, expected at least 54, found 32

Is this an issue with using Vec as a parameter or an issue with my configuration?

In my frontend I've added the following RPC config to the api creation:

const api = await ApiPromise.create({
            provider,
            rpc: {
              iris: {
                retrieveBytes: {
                  description: 'retrieve bytes from iris',
                  params: [
                    {
                        name: 'signature',
                        type: 'Vec<u8>'
                    },
                    {
                        name: 'message',
                        type: 'Bytes'
                    },
                    {
                        name: 'signer',
                        type: 'Vec<u8>'
                    },
                    {
                      name: 'asset_id',
                      type: 'u32'
                    }
                  ],
                  type: 'Bytes'
                }
              }
            }
        });

Which I am calling using this:

    await api.rpc.iris.retrieveBytes(signature, message, accountId, assetId)
    .then(res => success_callback(res))
    .catch(err => error_callback(err));

My api implementation does nothing but return empty bytes.

pub fn retrieve_bytes(
        signature: Vec<u8>,
        message: Bytes,
        signer: Vec<u8>,
        asset_id: u32,
    ) -> Bytes {
        Bytes(Vec::new())
    }
1
  • it would be great if you can share the minimal code with which we can reproduce the issue. From the info given it's not clear
    – Arjun
    Apr 2, 2022 at 0:49

1 Answer 1

7

In general, issues like this are due to incorrectly encoding Vec in SCALE.

All Vecs are prepended with their length (section Vectors (lists, series, sets)).

A collection of same-typed values is encoded, prefixed with a compact encoding of the number of items, followed by each item's encoding concatenated in turn.

For example:

Vector of unsigned 16-bit integers:

[4, 8, 15, 16, 23, 42]

SCALE Bytes:

0x18040008000f00100017002a00

Where 0x18 is the hex representation of the number 24, which is the byte length of the vector: 6 digits that are each 4 bytes.

When an error like:

createType(Vec):: Bytes: required length less than remainder, expected at least 54, found 32

Shows up, it means that it is trying to read the first bytes as the length, and the length it is reading does not match the actual available bytes, implying something was encoded incorrectly.

In this case, the first bytes read as "the length of this vector is 54 bytes", and then the actual vector is only 32 bytes long, which is clearly an error.

Your Answer

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

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