polkascan / py-substrate-interface

Python Substrate Interface
https://polkascan.github.io/py-substrate-interface/
Apache License 2.0
240 stars 116 forks source link

Encoding `BoundedBTreeMap` type error #230

Closed dastanbeksamatov closed 2 years ago

dastanbeksamatov commented 2 years ago

Hey there,

I have been experiencing some strange behaviour while encoding a custom struct with field of BoundedBTreeMap type. It fails with this error message:

ValueError: value should be a list of tuples e.g.: [('1', 2), ('23', 24), ('28', 30), ('45', 80)]

Here is the struct and types definition

// Types
#[derive(Clone, Encode, Decode, Eq, PartialEq, TypeInfo, SmartDefault, MaxEncodedLen)]
#[scale_info(skip_type_params(T))]
#[codec(mel_bound(T: Config))]
pub struct SomeStruct<T: Config> {
    pub some_field: Option<BoundedVec<u32, T::SomeType>>,
    pub some_other_field: Option<BoundedVec<u64, T::SomeOtherType>>,
}

pub MapType<T> = BoundedBTreeMap<u32, SomeStruct<T as Config>, T::MaxSomeStructs>;

pub struct SomeDescriptorStruct<MapType> {
        pub name: [u8, 8],
        pub some_structs: MapType,
}

// Extrinsic definition
pub fn create_some_struct(
    origin: OriginFor<T>,
    descriptor: SomeDescriptorStruct<T>,
) -> DispatchResult {}

How I am calling it:

params = {
    "descriptor": {
        "name": "test1234".encode("utf-8"),
        "some_structs": [
            (
                1,
                {
                     some_field: [],
                     some_other_field: [],
                },
            )
        ],
    },
};

# self.connection is `SubstrateInterface` type
call = self.connection.compose_call(
    call_module="some_pallet", call_function="create_some_struct", call_params=params
)

extrinsic = self.connection.create_signed_extrinsic(call=call, keypair=keypair)

receipt = self.connection.submit_extrinsic(extrinsic, wait_for_inclusion=True)

Would really appreciate if you could point out what I am doing wrong or if it is an unexpected behaviour from the codec library?

arjanz commented 2 years ago

I would like to debug this type for you, could you provide the metadata hex-bytes? (result of substrate.rpc_request("state_getMetadata", [])).

dastanbeksamatov commented 2 years ago

hey @arjanz, thanks for the response.

here is the link to our testnet's rpc calls, just query state -> get_metadata

arjanz commented 2 years ago

@dastanbeksamatov Is the call you want to compose already available on the testnet you provided? That would help me a lot to debug

arjanz commented 2 years ago

Fix released in https://github.com/polkascan/py-scale-codec/releases/tag/v1.0.48