Comments (35)
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.
from py-substrate-interface.
sending from: 5HmubXCdmtEvKmvqjJ7fXkxhPXcg6JTS62kMMphqxpEE6zcG
Failed to send: <class 'substrateinterface.exceptions.SubstrateRequestException'> with args:
{'code': 1002,
'data': 'RuntimeApi("Execution(ApiError(\"Could not convert parametertx
'
'between node and runtime: No such variant in enum '
'MultiSignature\"))")',
'message': 'Verification Error: Execution(ApiError("Could not convert '
'parametertx
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.
from py-substrate-interface.
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
from py-substrate-interface.
@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.
from py-substrate-interface.
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
from py-substrate-interface.
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?
from py-substrate-interface.
updated to scalecodec-0.9.54. Now the error has changed:
ValueError: Element "transactionVersion" of struct is missing in given value
and it happens already in substrate.create_signed_extrinsic()
from py-substrate-interface.
Ah, thanks a lot. Much appreciated.
So the
version 2.0.0-rc2-83d7157-x86_64-linux-gnu
is outdated now, I suppose?
If I drop that rc2, and compile rc3 instead ... that problem will be gone too, right?
I really don't cling to any specific version, I just don't want to upgrade every 3 weeks, if possible. Looks like rc2 had a lifetime of 15 days lol --> https://github.com/substrate-developer-hub/substrate-node-template/tags
Will that rc3 and its tool support last me for a while then?
from py-substrate-interface.
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?
from py-substrate-interface.
getting this error:
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"))'}
using these versions
scalecodec==0.9.54
substrate-interface==0.9.14
node-template --dev ✌️ version 2.0.0-rc2-83d7157-x86_64-linux-gnu
but no worries, I will simply compile rc3
now, hoping that it will last a while then.
from py-substrate-interface.
You can check this by inspecting the 'chain_getRuntimeVersion' RPC call, recently 'transactionVersion' is added there
Just tried that. It's not part of your interface yet
grv = substrate.chain_getRuntimeVersion()
AttributeError: 'SubstrateInterface' object has no attribute 'chain_getRuntimeVersion'
but I could call it this way:
pprint(substrate.rpc_request(method="chain_getRuntimeVersion", params=[]))
and got this:
chain_getRuntimeVersion():
{'id': 1,
'jsonrpc': '2.0',
'result': {'apis': [['0xdf6acb689907609b', 3],
['0x37e397fc7c91f5e4', 1],
['0x40fe3ad401f8959a', 4],
['0xd2bc9897eed08f15', 2],
['0xf78b278be53f454c', 2],
['0xdd718d5cc53262d4', 1],
['0xab3c0572291feb8b', 1],
['0xed99c5acb25eedf5', 2]],
'authoringVersion': 1,
'implName': 'node-template',
'implVersion': 1,
'specName': 'node-template',
'specVersion': 1,
'transactionVersion': 1}}
that ^ was for rc2. Compiling rc3 is half ready.
from py-substrate-interface.
Suggestion for your README.md - mention the version for which you can guarantee that it works:
this is tested with this version of substrate or node-template:
substrate --version; node-template --version;
substrate 2.0.0-rc2-45b9f0a9c-x86_64-linux-gnu
node-template 2.0.0-rc2-83d7157-x86_64-linux-gnu
from py-substrate-interface.
compiling rc3
... done. This is the version answer when talking to it:
get_version() = 2.0.0-rc3-f5acce1-x86_64-linux-gnu
chain_getRuntimeVersion():
{'id': 1,
'jsonrpc': '2.0',
'result': {'apis': [['0xdf6acb689907609b', 3],
['0x37e397fc7c91f5e4', 1],
['0x40fe3ad401f8959a', 4],
['0xd2bc9897eed08f15', 2],
['0xf78b278be53f454c', 2],
['0xdd718d5cc53262d4', 1],
['0xab3c0572291feb8b', 1],
['0xed99c5acb25eedf5', 2]],
'authoringVersion': 1,
'implName': 'node-template',
'implVersion': 1,
'specName': 'node-template',
'specVersion': 1,
'transactionVersion': 1}}
The 'transactionVersion': 1
is the same as above for the rc2
.
from py-substrate-interface.
Same error remains. Here's the code to try - thanks a lot!
https://gist.github.com/drandreaskrueger/053bfe0c8ddfaeeb50134a977708f999
from py-substrate-interface.
can you try the following:
YESSS ... that new custom_type_registry
made a difference = now the error messages are different:
Default SubstrateInterface:
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"))'}
SubstrateInterface with custom type registry:
sending from: 5HmubXCdmtEvKmvqjJ7fXkxhPXcg6JTS62kMMphqxpEE6zcG
Failed to send: <class 'substrateinterface.exceptions.SubstrateRequestException'> with args:
{'code': 1010, 'data': 'BadProof', 'message': 'Invalid Transaction'}
from py-substrate-interface.
Yes, or leave out the wait_for_inclusion=True keyword arg
Ah yes, that makes sense. Thanks.
subscribes to the `submitExtrinsic' and will also return the block hash. Without these keyword args, there is no confirmation the extrinsic is successfully included ...
Without the block_hash returned, perhaps a slight change to result.get('block_hash', None))
:
# result = substrate.submit_extrinsic(extrinsic, wait_for_inclusion=True) # works only with ws not http
result = substrate.submit_extrinsic(extrinsic) # works with http AND ws
print("Extrinsic '{}' sent and included in block '{}'".format(result['extrinsic_hash'], result.get('block_hash', None)))
from py-substrate-interface.
can you try the following:
YESSS ... that new
custom_type_registry
made a difference = now the error messages are different:Default SubstrateInterface: 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"))'} SubstrateInterface with custom type registry: sending from: 5HmubXCdmtEvKmvqjJ7fXkxhPXcg6JTS62kMMphqxpEE6zcG Failed to send: <class 'substrateinterface.exceptions.SubstrateRequestException'> with args: {'code': 1010, 'data': 'BadProof', 'message': 'Invalid Transaction'}
Since the upgrade to rc3 you probably need to include transactionVersion
again in the ExtrinsicPayloadValue
? (so remove that type from the custom_type_registry
)
Error BadProof
means the signature is not accepted
from py-substrate-interface.
Thx a lot. I have updated the gist:
https://gist.github.com/drandreaskrueger/053bfe0c8ddfaeeb50134a977708f999/revisions
(substrate
rc3 is still compiling)
from py-substrate-interface.
Since the upgrade to rc3 you probably need to include transactionVersion again in the ExtrinsicPayloadValue? (so remove that type from the custom_type_registry)
Remove ExtrinsicPayloadValue completely, like this?
custom_type_registry = { "runtime_id": 1,
"types": {
"Address": "AccountIdAddress",
},
"versioning": [
]
}
that doesn't solve it. I misunderstood you, right?
please you try again:
now both results (bottom) are done with rc3
https://gist.github.com/drandreaskrueger/053bfe0c8ddfaeeb50134a977708f999
Thanks!
from py-substrate-interface.
OMG ... every substrate chain color needs a different type_registry
?
I have just found this folder: scalecodec/type_registry That is ... complicated. Ouch.
Shouldn't the "chain maker" at least make sure to PUBLISH such a type_registry/<MYCHAINNAME>.json
file?
Or better: Provide an RPC answer on some TCP IP port that results in exactly that information?
As I understand it now from your code examples, you already need that information when you initiate the connection with SubstrateInterface(url=URL, address_type=42, type_registry_preset='default', type_registry=custom_type_registry)
, right? If there was such a port xyz RPC answer, that class initiation could call the node, get the full type_registry from the node, and configure itself. Would that work? Just an idea, how to make your and everyone's life easier. One can dream, right? :-) But back to the harsh reality:
I suppose the substrate
default chain (rc3
? ) uses default.json
?
Please you run your example README.md code, as it is now part of this https://gist.github.com/drandreaskrueger/053bfe0c8ddfaeeb50134a977708f999 .
As you already have a should-be-working type_registry
ready for the default substrate
(before we look into node-template
) let's first get substrate
running. Both rc3
.
Thanks a lot. Much appreciate your help!
from py-substrate-interface.
Actually ...
Shouldn't the "chain maker" ... provide an RPC answer on some TCP IP port that results in exactly that information?
isn't that what get_metadata_call_functions()
or get_metadata_storage_functions()
does?
Or what is your type_registry
?
from py-substrate-interface.
I have added a "quickstart" to the gist, for anyone else trying to help:
Thanks
from py-substrate-interface.
Made simplifications, clarifications; reran with newest scalecodec version, updating the output RESULTS - but ~same outcome. Anyways, slightly newer code, same place: https://gist.github.com/drandreaskrueger/053bfe0c8ddfaeeb50134a977708f999
from py-substrate-interface.
https://riot.im/app/#/room/!HzySYSaIhtyWrwiwEV:matrix.org/$159308184511859xHcjX:matrix.org
EDIT: scrolled through that whole chat on 29/6/2020 - no answer yet.
from py-substrate-interface.
I am develop Himalia ,
so use py-substrate-interface for contracts,
i use this to success commit extrinsic to canvas-node :
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"],
["transactionVersion", "u32"],
["genesisHash", "Hash"],
["blockHash", "Hash"]
]
}
},
"versioning": [
]
}
substrate = SubstrateInterface(
url="ws://localhost:9944",
type_registry_preset='default',
type_registry=custom_type_registry
)
keypair = Keypair.create_from_uri('//Alice')
# Upload WASM code
code = ContractCode.create_from_contract_files(
metadata_file=os.path.join(os.path.dirname(__file__), 'erc20.json'),
wasm_file=os.path.join(os.path.dirname(__file__), 'erc20.wasm'),
substrate=substrate
)
receipt = code.upload_wasm(keypair)
Note : the current payload struct has a params:
["transactionVersion", "u32"],
@drandreaskrueger can try by this.
Note the substract : keyring.rs
...
let payload = (xt.function, extra.clone(), spec_version, tx_version, genesis_hash, genesis_hash);
let key = AccountKeyring::from_account_id(&signed).unwrap();
...
from py-substrate-interface.
Hi @polkadev, thanks for your feedback. Did you also try to use type_registry_preset='canvas'
? There I already put AccountIdAddress
as Address
. The ExtrinsicPayloadValue
seems the same as in default.json
, am I missing something?
Anyway cool you are using the contract interface, note this is very recent work and needs some more testing, so I would appreciate further feedback from you!
from py-substrate-interface.
@polkadev latest release should add compatibility with latest substrate 2.0.0 and canvas-node
from py-substrate-interface.
@alexspurling This is a very legitimate question and I can only agree with you that putting the responsibility of type compatibility of numerous chains on the maintainers of the libraries (Polkadot-JS for example also manually administer this) is not a sustainable solution. But unfortunately at this moment there is no way to query the Substrate node how their runtime types are decomposed.
I have been lobbying for this feature just like it is possible to query the metadata in order to get feature discovery with all calls, events etc, but as far as I know automatic type decomposition is not on the planning yet.
I have seen though that automatic type decomposition all the way down to primitive types is realized for the Ink! contract pallet, so I hope this feature will come to Substrate runtime wide any time soon.
from py-substrate-interface.
I think the best way to lobby for this feature is to make yourself heard and state this once again in the Substrate Github issue tracker.
Regarding your question about type versioning, I do keep a versioning trail of changed types per runtime and this will be automatically applied when querying historic state.
from py-substrate-interface.
Could you explain exactly how you extract type information if it is not available as part of any of the metadata APIs?
Also, how exactly do you track changes between versions? In the scalecodec repo, there is only a single json file for each chain. I can see the repo has versioned tags I don't think a single version number can track changes across multiple chains.
For example, let's say I am running a polkadot node based on v0.8.2 and used your py-substrate-interface in my client code in order to create and sign transactions. At some point in the future polkadot release a new version of their node which includes some type changes. Let's say that I choose not to update my node, however if at any point my client code runs substrate.update_type_registry_presets()
then it will update to the latest type registry for polkadot and stop working with my old node. Is there any way that I can "fix" the version that I want to use for my type registry?
from py-substrate-interface.
Problem when I using canvas local dev node to deploy ink! contract
from py-substrate-interface.
Problem when I using canvas local dev node to deploy ink! contract
I think you're experiencing an issue not with this library but with Polkadot-JS (https://github.com/polkadot-js/). Have you tried updating to latest version? At a glance it seems to be type registry related.
from py-substrate-interface.
Problem when I using canvas local dev node to deploy ink! contractI think you're experiencing an issue not with this library but with Polkadot-JS (https://github.com/polkadot-js/). Have you tried updating to latest version? At a glance it seems to be type registry related.
I used the canvas-ui online and it seems updated just five days ago.
https://github.com/paritytech/canvas-ui/deployments
from py-substrate-interface.
@leeduckgo then I advise you to post an issue at https://github.com/paritytech/canvas-ui
from py-substrate-interface.
@leeduckgo then I advise you to post an issue at https://github.com/paritytech/canvas-ui
thx, i have already post issue there
from py-substrate-interface.
Related Issues (20)
- Is there a way to apply custom signedExtensions HOT 2
- Unable to parse contract events HOT 9
- pip install --no-binary not working HOT 3
- Async interface HOT 6
- Decoding problem - parity struct change HOT 5
- Decoder class for "Compact<u32>" not found HOT 4
- Make websocket timeout configurable HOT 2
- How to create an Hex that can be used in JS UI with Extrinsic / Decode? HOT 2
- AttributeError: 'NoneType' object has no attribute 'get_type_string' HOT 1
- Failing tests? HOT 16
- ContractExecutionReceipt.process_events() crashes on events from other contracts. HOT 5
- Wrong number of parameters for storage function HOT 1
- Unhandled WebSocketConnectionClosedException HOT 3
- Wrong authority set used while determining block author HOT 1
- [feat] Keyring batch export and importable for polkadot.js frontend or polkadot js wallet.
- transaction object is not refreshed giving random errors HOT 1
- support for ImOnline module HOT 4
- Add CheckMetadataHash signed extension support HOT 1
- Unsupported Metadata Version in substrate-interface HOT 1
- KSM Proxy Extrinsic not working HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from py-substrate-interface.