py-substrate-interface: Verification Error: Execution(ApiError("Could not convert parameter `tx` ...

error message:

sending from: 5HmubXCdmtEvKmvqjJ7fXkxhPXcg6JTS62kMMphqxpEE6zcG
Failed to send: <class 'substrateinterface.exceptions.SubstrateRequestException'> with args:
{'code': 1002,
 'data': 'RuntimeApi("Execution(ApiError(\\"Could not convert parameter `tx` '
         'between node and runtime: No such variant in enum '
         'MultiSignature\\"))")',
 'message': 'Verification Error: Execution(ApiError("Could not convert '
            'parameter `tx` between node and runtime: No such variant in enum '
            'MultiSignature"))'}

when using the same 2.0.0-rc2 substrate dev chain node-template as in https://github.com/polkascan/py-substrate-interface/issues/13

node-template purge-chain -y --dev
node-template --dev

2020-06-10 23:39:38 Substrate Node
2020-06-10 23:39:38 ✌️  version 2.0.0-rc2-83d7157-x86_64-linux-gnu
2020-06-10 23:39:38 📋 Chain specification: Development

this python code is almost identical to your README.md example

from substrateinterface import SubstrateInterface, Keypair, SubstrateRequestException
from pprint import pformat
substrate = SubstrateInterface( url="ws://127.0.0.1:9944" )
keypair = Keypair.create_from_mnemonic('episode together nose spoon dose oil faculty zoo ankle evoke admit walnut')
print ("sending from:", keypair.ss58_address)
BOB_ADDRESS = '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty'
call = substrate.compose_call(
    call_module='Balances', call_function='transfer',
    call_params={
        'dest': BOB_ADDRESS,
        'value': 1 * 10**12})
try:
    extrinsic = substrate.create_signed_extrinsic(call=call, keypair=keypair)
    result = substrate.send_extrinsic(extrinsic, wait_for_inclusion=True)
    print("Extrinsic '{}' sent and included in block '{}'".format(result['extrinsic_hash'], result['block_hash']))
except (SubstrateRequestException, ValueError) as e:
    print("Failed to send: {} with args:".format(type(e)))
    print("{}".format(pformat(e.args[0])))

What am I doing wrong?

Thanks a lot!

P.S.: In subkey, we can access also the predefined accounts (Alice, Bob, Charlie, etc) by their aliases. It would be nice to be able to do something like this:

keypair = Keypair.create_from_private_key('//Alice')
keypair = Keypair.create_from_mnemonic('//Alice')
keypair = Keypair.create_from_alias('Alice')

Thanks!

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 35 (11 by maintainers)

Commits related to this issue

Most upvoted comments

Thanks, @arjanz . Are the changes to the types published somewhere ahead of time or do you just have to dig around in the substrate code to find them?

Basically I skim the updates in https://github.com/paritytech/substrate pallets and look for type changes and put those types in default.json. For example the PreimageStatus enum in the democracy pallet (https://github.com/paritytech/substrate/blob/master/frame/democracy/src/lib.rs#L309).

Then when a runtime is pinned and scheduled for release for Polkadot, Kusama, etc. I make an entry with runtime id and changes necessary for versioning in polkadot.json, kusama.json etc.

I agree this is a bit cumbersome but the only way to let the library know how to decode certain types that are not primitives.

Note that the upgrade runtime WASM is provided on-chain and will be auto-enacted on your node even if you don’t update your node. I believe the runtime that is provided by the node natively is faster than if your node will run the synced on-chain runtime WASM, so it is advised to update frequently, but you will always be up to date with the latest runtime. For more info see https://wiki.polkadot.network/docs/en/build-node-management and https://wiki.polkadot.network/docs/en/learn-wasm#forkless-upgrades

@arjanz Thank you for your work maintaining this library and making sure it continues to work across new releases of substrate, polkadot etc. After having multiple issues connecting to various different versions of various different substrate nodes, I was able to get your example code working. However, I really don’t understand how it is sustainable to rely on you personally updating all the .json type registry files in the scalecodec library (https://github.com/polkascan/py-scale-codec/tree/master/scalecodec/type_registry). Do you have a plan for the future to make this process automatic or somehow have the py-substrate-interface library query the node itself rather than pull types from github.com? How do you discover the necessary changes to the type registries anyway? How will you handle support for older versions? Sorry I’m not sure where else to ask this question.

Still, I am trying your code, but get this:

substrateinterface.exceptions.ConfigurationError:
Result handlers only available for websockets (ws://) connections

so changing to

    substrate = SubstrateInterface(url="ws://127.0.0.1:9944",
                                   address_type=42,
                                   type_registry_preset='default',
                                   type_registry=custom_type_registry)

right?

Yes, or leave out the wait_for_inclusion=True keyword arg, this will work for http. The wait_for_inclusion and wait_for_finalization subscribes to the `submitExtrinsic’ and will also return the block hash. Without these keyword args, there is no confirmation the extrinsic is successfully included =, but the extrinsic hash can still be used to for example create a link to Polkascan

sending from: 5HmubXCdmtEvKmvqjJ7fXkxhPXcg6JTS62kMMphqxpEE6zcG Failed to send: <class ‘substrateinterface.exceptions.SubstrateRequestException’> with args: {‘code’: 1002, ‘data’: ‘RuntimeApi(“Execution(ApiError(\“Could not convert parameter tx ’ 'between node and runtime: No such variant in enum ’ 'MultiSignature\”))”)’, ‘message’: ‘Verification Error: Execution(ApiError(“Could not convert ’ 'parameter tx between node and runtime: No such variant in enum ’ 'MultiSignature”))’}

I reproduced this error, the Address format in the ‘default’ type registry is still in an outdated format, can you try the following:

custom_type_registry = {
  "runtime_id": 1,
  "types": {
    "Address": "AccountIdAddress",
    "ExtrinsicPayloadValue": {
      "type": "struct",
      "type_mapping": [
        ["call", "CallBytes"],
        ["era", "Era"],
        ["nonce", "Compact<Index>"],
        ["tip", "Compact<Balance>"],
        ["specVersion", "u32"],
        ["genesisHash", "Hash"],
        ["blockHash", "Hash"]
      ]
    }
  },
  "versioning": [
  ]
}

After we figure out to work with current substrate-node-template, we will make a dedicated type_registry_preset and pin the version of substrate-node-template to make it easier to get started.

Then I suspect you have a slightly older version of Substrate, recently the signing payload added the field ‘transactionVersion’. (You can check this by inspecting the ‘chain_getRuntimeVersion’ RPC call, recently ‘transactionVersion’ is added there)

What you can try is the following:

custom_type_registry = {
  "runtime_id": 1,
  "types": {
    "ExtrinsicPayloadValue": {
      "type": "struct",
      "type_mapping": [
        ["call", "CallBytes"],
        ["era", "Era"],
        ["nonce", "Compact<Index>"],
        ["tip", "Compact<Balance>"],
        ["specVersion", "u32"],
        ["genesisHash", "Hash"],
        ["blockHash", "Hash"]
      ]
    }
  },
  "versioning": [
  ]
}

substrate = SubstrateInterface(
    url="http://127.0.0.1:9933",
    address_type=42,
    type_registry_preset='default',
    type_registry=custom_type_registry
)

This uses the older version of the signing payload. Alternatively you can place this together with all your custom types in a separate JSON file and use:

custom_type_registry = load_type_registry_file("custom_type_registry.json")

On our todo list is to support backwards compatibility for this kind of changes, but this isn’t trivial to realize for now.