Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 24 additions & 11 deletions async_substrate_interface/substrate_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -1089,6 +1089,8 @@ def __init__(
else:
self.query_map_result_cls = QueryMapResult
self.extrinsic_receipt_cls = AsyncExtrinsicReceipt
self.reload_type_registry()
self._initializing = False

async def __aenter__(self):
await self.initialize()
Expand All @@ -1099,13 +1101,14 @@ async def initialize(self):
Initialize the connection to the chain.
"""
async with self._lock:
self._initializing = True
if not self.initialized:
if not self.__chain:
chain = await self.rpc_request("system_chain", [])
self.__chain = chain.get("result")
self.reload_type_registry()
await asyncio.gather(self.load_registry(), self._init_init_runtime())
self.initialized = True
self._initializing = False

async def __aexit__(self, exc_type, exc_val, exc_tb):
pass
Expand Down Expand Up @@ -1248,19 +1251,28 @@ async def _wait_for_registry():
if scale_bytes == b"\x00":
obj = None
else:
if not self.registry:
await asyncio.wait_for(_wait_for_registry(), timeout=10)
try:
if not self.registry:
await asyncio.wait_for(_wait_for_registry(), timeout=10)
obj = decode_by_type_string(type_string, self.registry, scale_bytes)
except TimeoutError:
# indicates that registry was never loaded
if _attempt < _retries:
if not self._initializing:
raise AttributeError(
"Registry was never loaded. This did not occur during initialization, which usually indicates "
"you must first initialize the AsyncSubstrateInterface object, either with "
"`await AsyncSubstrateInterface.initialize()` or running with `async with`"
)
elif _attempt < _retries:
await self.load_registry()
return await self.decode_scale(
type_string, scale_bytes, _attempt + 1
)
else:
raise ValueError("Registry was never loaded.")
raise AttributeError(
"Registry was never loaded. This occurred during initialization, which usually indicates a "
"connection or node error."
)
if return_scale_obj:
return ScaleObj(obj)
else:
Expand Down Expand Up @@ -2471,7 +2483,7 @@ async def get_block_runtime_version(self, block_hash: str) -> dict:

async def get_block_metadata(
self, block_hash: Optional[str] = None, decode: bool = True
) -> Union[dict, ScaleType]:
) -> Optional[Union[dict, ScaleType]]:
"""
A pass-though to existing JSONRPC method `state_getMetadata`.

Expand All @@ -2480,7 +2492,8 @@ async def get_block_metadata(
decode: Whether to decode the metadata or present it raw

Returns:
metadata, either as a dict (not decoded) or ScaleType (decoded)
metadata, either as a dict (not decoded) or ScaleType (decoded); None if there was no response
from the server
"""
params = None
if decode and not self.runtime_config:
Expand All @@ -2495,15 +2508,15 @@ async def get_block_metadata(
if "error" in response:
raise SubstrateRequestException(response["error"]["message"])

if response.get("result") and decode:
if (result := response.get("result")) and decode:
metadata_decoder = self.runtime_config.create_scale_object(
"MetadataVersioned", data=ScaleBytes(response.get("result"))
"MetadataVersioned", data=ScaleBytes(result)
)
metadata_decoder.decode()

return metadata_decoder

return response
else:
return result

async def _preprocess(
self,
Expand Down