py-substrate-interface
py-substrate-interface copied to clipboard
get_block_metadata function returns a dictionary and scalecodec __init__ raises error
Hey Arjan,
There is a little issue happening when I'm running a python simulation and sending transactions to the substrate node. At some point I get the traceback below, do you think there is a workaround here to re-try getting the correct metadata result?
The error: https://github.com/polkascan/py-scale-codec/blob/master/scalecodec/base.py#L243
The function where this error drags from: https://github.com/polkascan/py-substrate-interface/blob/master/substrateinterface/base.py#L744
The traceback:
track_trade_event: {5c7f2e} [origin: H2 PV -> H1 Storage2] [IAA House 2 -> IAA House 1] 0.011199999999999998 kWh @ 0.176 15.71428571 888af532-09f7-4114-9ebe-6b5613052896 [fee: 0.0 cts.]
data: {'apis': [['0xdf6acb689907609b', 3], ['0x37e397fc7c91f5e4', 1], ['0x40fe3ad401f8959a', 4], ['0xd2bc9897eed08f15', 2], ['0xf78b278be53f454c', 2], ['0xdd718d5cc53262d4', 1], ['0xab3c0572291feb8b', 1], ['0xed99c5acb25eedf5', 2], ['0xbc9d89904f5b923f', 1], ['0x37c8bb1350a9a2a8', 1], ['0x68b66ba122c93fa7', 1]], 'authoringVersion': 1, 'implName': 'canvas', 'implVersion': 0, 'specName': 'canvas', 'specVersion': 8, 'transactionVersion': 1}
Traceback (most recent call last):
File "/Users/admin/Envs/d3a/bin/d3a", line 33, in <module>
sys.exit(load_entry_point('d3a', 'console_scripts', 'd3a')())
File "/Users/admin/Envs/d3a/lib/python3.8/site-packages/click/core.py", line 829, in __call__
return self.main(*args, **kwargs)
File "/Users/admin/Envs/d3a/lib/python3.8/site-packages/click/core.py", line 782, in main
rv = self.invoke(ctx)
File "/Users/admin/Envs/d3a/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/Users/admin/Envs/d3a/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/Users/admin/Envs/d3a/lib/python3.8/site-packages/click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "/Users/admin/github/d3a/src/d3a/d3a_core/cli.py", line 151, in run
run_simulation(setup_module_name, simulation_config, None, None, None,
File "/Users/admin/github/d3a/src/d3a/d3a_core/simulation.py", line 618, in run_simulation
simulation.run()
File "/Users/admin/github/d3a/src/d3a/d3a_core/simulation.py", line 234, in run
self._run_cli_execute_cycle(initial_slot, tick_resume) \
File "/Users/admin/github/d3a/src/d3a/d3a_core/simulation.py", line 246, in _run_cli_execute_cycle
self._execute_simulation(slot_resume, tick_resume, console)
File "/Users/admin/github/d3a/src/d3a/d3a_core/simulation.py", line 363, in _execute_simulation
self.area.tick_and_dispatch()
File "/Users/admin/github/d3a/src/d3a/models/area/__init__.py", line 400, in tick_and_dispatch
self.dispatcher.broadcast_tick()
File "/Users/admin/github/d3a/src/d3a/models/area/event_dispatcher.py", line 63, in broadcast_tick
return self._broadcast_notification(AreaEvent.TICK, **kwargs)
File "/Users/admin/github/d3a/src/d3a/models/area/event_dispatcher.py", line 81, in _broadcast_notification
child.dispatcher.event_listener(event_type, **kwargs)
File "/Users/admin/github/d3a/src/d3a/models/area/event_dispatcher.py", line 113, in event_listener
self.area.tick_and_dispatch()
File "/Users/admin/github/d3a/src/d3a/models/area/__init__.py", line 400, in tick_and_dispatch
self.dispatcher.broadcast_tick()
File "/Users/admin/github/d3a/src/d3a/models/area/event_dispatcher.py", line 63, in broadcast_tick
return self._broadcast_notification(AreaEvent.TICK, **kwargs)
File "/Users/admin/github/d3a/src/d3a/models/area/event_dispatcher.py", line 91, in _broadcast_notification
agents[area_name].event_listener(event_type, **kwargs)
File "/Users/admin/github/d3a/src/d3a/models/strategy/__init__.py", line 402, in event_listener
super().event_listener(event_type, **kwargs)
File "/Users/admin/github/d3a/src/d3a/events/__init__.py", line 58, in event_listener
self._event_mapping(event_type)(**kwargs)
File "/Users/admin/github/d3a/src/d3a/models/strategy/area_agents/one_sided_agent.py", line 59, in event_tick
engine.tick(area=area)
File "/Users/admin/github/d3a/src/d3a/models/strategy/area_agents/one_sided_engine.py", line 97, in tick
self.propagate_offer(area.current_tick)
File "/Users/admin/github/d3a/src/d3a/models/strategy/area_agents/one_sided_engine.py", line 132, in propagate_offer
forwarded_offer = self._forward_offer(offer)
File "/Users/admin/github/d3a/src/d3a/models/strategy/area_agents/one_sided_engine.py", line 86, in _forward_offer
self.markets.target.dispatch_market_offer_event(forwarded_offer)
File "/Users/admin/github/d3a/src/d3a/models/market/one_sided.py", line 107, in dispatch_market_offer_event
self._notify_listeners(MarketEvent.OFFER, offer=offer)
File "/Users/admin/github/d3a/src/d3a/models/market/__init__.py", line 145, in _notify_listeners
listener(event, market_id=self.id, **kwargs)
File "/Users/admin/github/d3a/src/d3a/models/area/event_dispatcher.py", line 81, in _broadcast_notification
child.dispatcher.event_listener(event_type, **kwargs)
File "/Users/admin/github/d3a/src/d3a/models/area/event_dispatcher.py", line 120, in event_listener
self.area.strategy.event_listener(event_type, **kwargs)
File "/Users/admin/github/d3a/src/d3a/models/strategy/__init__.py", line 402, in event_listener
super().event_listener(event_type, **kwargs)
File "/Users/admin/github/d3a/src/d3a/events/__init__.py", line 58, in event_listener
self._event_mapping(event_type)(**kwargs)
File "/Users/admin/github/d3a/src/d3a/models/strategy/storage.py", line 598, in event_offer
self.buy_energy(market, offer)
File "/Users/admin/github/d3a/src/d3a/models/strategy/storage.py", line 517, in buy_energy
self._try_to_buy_offer(offer, market, max_affordable_offer_rate)
File "/Users/admin/github/d3a/src/d3a/models/strategy/storage.py", line 498, in _try_to_buy_offer
self.accept_offer(market, offer, energy=max_energy,
File "/Users/admin/github/d3a/src/d3a/models/strategy/__init__.py", line 314, in accept_offer
trade = self._accept_offer(market_or_id, offer, buyer, energy, trade_rate, already_tracked,
File "/Users/admin/github/d3a/src/d3a/models/strategy/__init__.py", line 341, in _accept_offer
return market_or_id.accept_offer(offer_or_id=offer, buyer=buyer, energy=energy,
File "/Users/admin/github/d3a/src/d3a/models/market/__init__.py", line 57, in wrapper
return function(self, *args, **kwargs)
File "/Users/admin/github/d3a/src/d3a/models/market/one_sided.py", line 277, in accept_offer
self._notify_listeners(MarketEvent.TRADE, trade=trade)
File "/Users/admin/github/d3a/src/d3a/models/market/__init__.py", line 145, in _notify_listeners
listener(event, market_id=self.id, **kwargs)
File "/Users/admin/github/d3a/src/d3a/models/area/event_dispatcher.py", line 91, in _broadcast_notification
agents[area_name].event_listener(event_type, **kwargs)
File "/Users/admin/github/d3a/src/d3a/models/strategy/__init__.py", line 402, in event_listener
super().event_listener(event_type, **kwargs)
File "/Users/admin/github/d3a/src/d3a/events/__init__.py", line 58, in event_listener
self._event_mapping(event_type)(**kwargs)
File "/Users/admin/github/d3a/src/d3a/models/strategy/area_agents/one_sided_agent.py", line 63, in event_trade
engine.event_trade(trade=trade)
File "/Users/admin/github/d3a/src/d3a/models/strategy/area_agents/one_sided_engine.py", line 162, in event_trade
trade_source = self.owner.accept_offer(
File "/Users/admin/github/d3a/src/d3a/models/strategy/__init__.py", line 314, in accept_offer
trade = self._accept_offer(market_or_id, offer, buyer, energy, trade_rate, already_tracked,
File "/Users/admin/github/d3a/src/d3a/models/strategy/__init__.py", line 341, in _accept_offer
return market_or_id.accept_offer(offer_or_id=offer, buyer=buyer, energy=energy,
File "/Users/admin/github/d3a/src/d3a/models/market/__init__.py", line 57, in wrapper
return function(self, *args, **kwargs)
File "/Users/admin/github/d3a/src/d3a/models/market/one_sided.py", line 268, in accept_offer
self.bc_interface.track_trade_event(self.simulation_id, self.market_id,
File "/Users/admin/github/d3a/src/d3a/d3a_core/util.py", line 382, in wrapped
return recursive_retry(f, 0, max_retries, *args, **kwargs)
File "/Users/admin/github/d3a/src/d3a/d3a_core/util.py", line 389, in recursive_retry
return functor(*args, **kwargs)
File "/Users/admin/github/d3a/src/d3a/models/market/blockchain_interface.py", line 113, in track_trade_event
call = self.substrate.compose_call(
File "/Users/admin/Envs/d3a/lib/python3.8/site-packages/substrateinterface/base.py", line 1349, in compose_call
self.init_runtime(block_hash=block_hash)
File "/Users/admin/Envs/d3a/lib/python3.8/site-packages/substrateinterface/base.py", line 1089, in init_runtime
self.metadata_decoder = self.get_block_metadata(block_hash=runtime_block_hash, decode=True)
File "/Users/admin/Envs/d3a/lib/python3.8/site-packages/substrateinterface/base.py", line 785, in get_block_metadata
metadata_decoder = MetadataDecoder(ScaleBytes(response.get('result')))
File "/Users/admin/Envs/d3a/lib/python3.8/site-packages/scalecodec/base.py", line 225, in __init__
raise ValueError("Provided data is not in supported format: provided '{}'".format(type(data)))
ValueError: Provided data is not in supported format: provided '<class 'dict'>'
The get_block_metadata
function depends on the state_getMetadata
RPC call and that the results directly contains the hex-bytes (0x...). It seems for some reason that is not the case (apparently a dict
), is that something that has changed in the runtime? What exactly does state_getMetadata
return in your case?.
Also, are you using the latest version? It could also be an error is present in the RPC call result and at some point I added better error handling:
https://github.com/polkascan/py-substrate-interface/blob/7da12f022947d59d34b89b14b944e5d6796119fe/substrateinterface/base.py#L766
The
get_block_metadata
function depends on thestate_getMetadata
RPC call and that the results directly contains the hex-bytes (0x...). It seems for some reason that is not the case (apparently adict
), is that something that has changed in the runtime? What exactly doesstate_getMetadata
return in your case?.Also, are you using the latest version? It could also be an error is present in the RPC call result and at some point I added better error handling:
https://github.com/polkascan/py-substrate-interface/blob/7da12f022947d59d34b89b14b944e5d6796119fe/substrateinterface/base.py#L766
so the dictionary I get looks like so:
data: {'apis': [['0xdf6acb689907609b', 3], ['0x37e397fc7c91f5e4', 1], ['0x40fe3ad401f8959a', 4], ['0xd2bc9897eed08f15', 2], ['0xf78b278be53f454c', 2], ['0xdd718d5cc53262d4', 1], ['0xab3c0572291feb8b', 1], ['0xed99c5acb25eedf5', 2], ['0xbc9d89904f5b923f', 1], ['0x37c8bb1350a9a2a8', 1], ['0x68b66ba122c93fa7', 1]], 'authoringVersion': 1, 'implName': 'canvas', 'implVersion': 0, 'specName': 'canvas', 'specVersion': 8, 'transactionVersion': 1}
The substrate interface version in 0.11.15 - the latest I think :)
@arjanz do you think adding a check to the type of the data variable would help? It tries to get the block hash, so maybe adding a re-try would help? E.g. somewhere around here? https://github.com/polkascan/py-substrate-interface/blob/7da12f022947d59d34b89b14b944e5d6796119fe/substrateinterface/base.py#L748
Do you have a way for me to reproduce this error you are getting? Otherwise it will be very difficult for me to analyse this or give you pointers in the right direction..
Do you have a way for me to reproduce this error you are getting? Otherwise it will be very difficult for me to analyse this or give you pointers in the right direction..
I'm getting this error when running our d3a simulation with a node. The process is described in our wiki https://gridsingularity.github.io/d3a/blockchain/
It sends transactions to a substrate node we have in the cluster. It fails about mid-way through the 96 transactions in the basic test scenario (I posted the traceback above). Somehow at some point it returns the result of {"id":1, "jsonrpc":"2.0", "method": "state_getRuntimeVersion"}
instead of {"id":1, "jsonrpc":"2.0", "method": "state_getMetadata"}
and I can't figure out in the interface, where this could happen. The RPC call is here https://github.com/polkascan/py-substrate-interface/blob/7da12f022947d59d34b89b14b944e5d6796119fe/substrateinterface/base.py#L764