py-substrate-interface icon indicating copy to clipboard operation
py-substrate-interface copied to clipboard

RemainingScaleBytesNotEmptyException for Kilt Spiritnet

Open Maharacha opened this issue 8 months ago • 5 comments

Reproduce:

substrate-interface==1.7.11 scalecodec==1.2.11

    substrate = SubstrateInterface(url=server_address_ws)
    call = substrate.compose_call(
        'Session', 'set_keys', {
            'keys': keys,
            'proof': '0x00',
        }
    )

    keypair = Keypair.create_from_mnemonic(mnemonic)
    extrinsic = substrate.create_signed_extrinsic(call=call, keypair=keypair)

Error:

scalecodec.exceptions.RemainingScaleBytesNotEmptyException: Decoding <U32> - Current offset: 4 / length: 8

Some trace in my application:

substrateinterface/base.py", line 1593, in create_signed_extrinsic
    nonce = self.get_account_nonce(keypair.ss58_address) or 0
substrateinterface/base.py", line 1428, in get_account_nonce
    nonce_obj = self.runtime_call("AccountNonceApi", "account_nonce", [account_address])
substrateinterface/base.py", line 1283, in runtime_call
    result_obj.decode(ScaleBytes(result_data['result']), check_remaining=self.config.get('strict_scale_decode'))
scalecodec/base.py", line 888, in decode
    raise RemainingScaleBytesNotEmptyException(
scalecodec.exceptions.RemainingScaleBytesNotEmptyException: Decoding <U32> - Current offset: 4 / length: 8

Maharacha avatar Mar 13 '25 14:03 Maharacha

Is this repo still maintained? @arjanz ?

Maharacha avatar Apr 01 '25 08:04 Maharacha

Hello @Maharacha This week JAMdotTechnologies has announced to take up stewardship of Polkascan's Python libraries for the Polkadot ecosystem. Our current focus is on delivering our Python implementation of JAM Protocol. However as we expect major delivery milestones for JAM later this year, we will be shifting our attention more towards user/developer facing libraries, such as this library (PyPolkadotSDK).

We will schedule some timeboxed resources this week to check if we can help you with this issue. Thank you for understanding.

emielsebastiaan avatar Apr 02 '25 10:04 emielsebastiaan

@Maharacha It seems it is a type registry related issue. To determine the account nonce, the Runtime API AccountNonceApi.account_nonce() is being called. Runtime API calls are still manually administered in the library atm, type definition updates are not automatically applied (yet).

After some debugging I found out Index is not a u32 but a u64 for Kilt.

As a workaround until runtime APIs are included in the metadata (It was under development in Substrate but didn't check progress of this for a while to be honest), you can add the following:

substrate = SubstrateInterface(url=server_address_ws)
# Manually update type definition
substrate.runtime_config.update_type_registry_types({'Index': 'U64'})

 call = substrate.compose_call(
    'Session', 'set_keys', {
        'keys': {
            'aura': '0x0000000000000000000000000000000000000000000000000000000000000000'
        },
        'proof': '0x00'
    }
)

keypair = Keypair.create_from_mnemonic(mnemonic)
extrinsic = substrate.create_signed_extrinsic(call=call, keypair=keypair)

arjanz avatar Apr 07 '25 13:04 arjanz

@Maharacha It seems it is a type registry related issue. To determine the account nonce, the Runtime API AccountNonceApi.account_nonce() is being called. Runtime API calls are still manually administered in the library atm, type definition updates are not automatically applied (yet).

After some debugging I found out Index is not a u32 but a u64 for Kilt.

As a workaround until runtime APIs are included in the metadata (It was under development in Substrate but didn't check progress of this for a while to be honest), you can add the following:

substrate = SubstrateInterface(url=server_address_ws)
# Manually update type definition
substrate.runtime_config.update_type_registry_types({'Index': 'U64'})

 call = substrate.compose_call(
    'Session', 'set_keys', {
        'keys': {
            'aura': '0x0000000000000000000000000000000000000000000000000000000000000000'
        },
        'proof': '0x00'
    }
)

keypair = Keypair.create_from_mnemonic(mnemonic)
extrinsic = substrate.create_signed_extrinsic(call=call, keypair=keypair)

Thanks, I will try this!

Maharacha avatar Apr 09 '25 11:04 Maharacha

@arjanz I just tried the work around and it works well! You want to keep the issue open for the actual fix?

Maharacha avatar Apr 14 '25 10:04 Maharacha