2323 SubstrateRequestException ,
2424 BlockNotFound ,
2525 MaxRetriesExceeded ,
26- MetadataAtVersionNotFound ,
2726 StateDiscardedError ,
2827)
2928from async_substrate_interface .protocols import Keypair
4544 _determine_if_old_runtime_call ,
4645 _bt_decode_to_dict_or_list ,
4746 decode_query_map ,
47+ legacy_scale_decode ,
4848)
4949from async_substrate_interface .utils .storage import StorageKey
5050from async_substrate_interface .type_registry import _TYPE_REGISTRY
@@ -576,17 +576,6 @@ def metadata(self):
576576 else :
577577 return self .runtime .metadata
578578
579- @property
580- def implements_scaleinfo (self ) -> Optional [bool ]:
581- """
582- Returns True if current runtime implements a `PortableRegistry` (`MetadataV14` and higher). Returns `None` if
583- no currently loaded runtime.
584- """
585- if self .runtime and self .runtime .metadata :
586- return self .runtime .metadata .portable_registry is not None
587- else :
588- return None
589-
590579 @property
591580 def properties (self ):
592581 if self ._properties is None :
@@ -669,7 +658,7 @@ def _load_registry_at_block(self, block_hash: Optional[str]) -> MetadataV15:
669658 "Client error: Execution failed: Other: Exported method Metadata_metadata_at_version is not found"
670659 in e .args
671660 ):
672- raise MetadataAtVersionNotFound
661+ return None , None
673662 else :
674663 raise e
675664 metadata_option_hex_str = metadata_rpc_result ["result" ]
@@ -701,7 +690,12 @@ def decode_scale(
701690 # Decode AccountId bytes to SS58 address
702691 return ss58_encode (scale_bytes , SS58_FORMAT )
703692 else :
704- obj = decode_by_type_string (type_string , self .runtime .registry , scale_bytes )
693+ if self .runtime .metadata_v15 is not None :
694+ obj = decode_by_type_string (
695+ type_string , self .runtime .registry , scale_bytes
696+ )
697+ else :
698+ obj = legacy_scale_decode (type_string , scale_bytes , self .runtime )
705699 if return_scale_obj :
706700 return ScaleObj (obj )
707701 else :
@@ -714,7 +708,7 @@ def load_runtime(self, runtime):
714708 self .runtime .reload_type_registry (use_remote_preset = False , auto_discover = True )
715709
716710 self .runtime_config .set_active_spec_version_id (runtime .runtime_version )
717- if self .implements_scaleinfo :
711+ if self .runtime . implements_scaleinfo :
718712 logger .debug ("Add PortableRegistry from metadata to type registry" )
719713 self .runtime_config .add_portable_registry (runtime .metadata )
720714 # Set runtime compatibility flags
@@ -754,7 +748,8 @@ def init_runtime(
754748 if runtime := self .runtime_cache .retrieve (block = block_id ):
755749 self .runtime = runtime
756750 self .runtime .load_runtime ()
757- self .runtime .load_registry_type_map ()
751+ if self .runtime .registry :
752+ self .runtime .load_registry_type_map ()
758753 return self .runtime
759754 block_hash = self .get_block_hash (block_id )
760755
@@ -765,7 +760,8 @@ def init_runtime(
765760 if runtime := self .runtime_cache .retrieve (block_hash = block_hash ):
766761 self .runtime = runtime
767762 self .runtime .load_runtime ()
768- self .runtime .load_registry_type_map ()
763+ if self .runtime .registry :
764+ self .runtime .load_registry_type_map ()
769765 return self .runtime
770766
771767 runtime_version = self .get_block_runtime_version_for (block_hash )
@@ -780,12 +776,14 @@ def init_runtime(
780776 if runtime := self .runtime_cache .retrieve (runtime_version = runtime_version ):
781777 self .runtime = runtime
782778 self .runtime .load_runtime ()
783- self .runtime .load_registry_type_map ()
779+ if self .runtime .registry :
780+ self .runtime .load_registry_type_map ()
784781 return runtime
785782 else :
786783 self .runtime = self .get_runtime_for_version (runtime_version , block_hash )
787784 self .runtime .load_runtime ()
788- self .runtime .load_registry_type_map ()
785+ if self .runtime .registry :
786+ self .runtime .load_registry_type_map ()
789787 return self .runtime
790788
791789 def get_runtime_for_version (
@@ -819,9 +817,15 @@ def get_runtime_for_version(
819817 metadata_v15 , registry = self ._load_registry_at_block (
820818 block_hash = runtime_block_hash
821819 )
822- logger .debug (
823- f"Retrieved metadata v15 for { runtime_version } from Substrate node"
824- )
820+ if metadata_v15 is not None :
821+ logger .debug (
822+ f"Retrieved metadata and metadata v15 for { runtime_version } from Substrate node"
823+ )
824+ else :
825+ logger .debug (
826+ f"Exported method Metadata_metadata_at_version is not found for { runtime_version } . This indicates the "
827+ f"block is quite old, decoding for this block will use legacy Python decoding."
828+ )
825829
826830 runtime = Runtime (
827831 chain = self .chain ,
@@ -1204,7 +1208,7 @@ def decode_block(block_data, block_data_hash=None) -> dict[str, Any]:
12041208 block_data ["header" ]["digest" ]["logs" ][idx ] = log_digest
12051209
12061210 if include_author and "PreRuntime" in log_digest .value :
1207- if self .implements_scaleinfo :
1211+ if self .runtime . implements_scaleinfo :
12081212 engine = bytes (log_digest [1 ][0 ])
12091213 # Retrieve validator set
12101214 parent_hash = block_data ["header" ]["parentHash" ]
@@ -1609,7 +1613,12 @@ def convert_event_data(data):
16091613 )
16101614 if storage_obj :
16111615 for item in list (storage_obj ):
1612- events .append (convert_event_data (item ))
1616+ try :
1617+ events .append (convert_event_data (item ))
1618+ except (
1619+ AttributeError
1620+ ): # indicates this was legacy decoded with scalecodec
1621+ events .append (item )
16131622 return events
16141623
16151624 def get_metadata (self , block_hash = None ) -> MetadataV15 :
@@ -2530,20 +2539,28 @@ def runtime_call(
25302539 params = {}
25312540
25322541 try :
2533- metadata_v15_value = runtime .metadata_v15 .value ()
2542+ if runtime .metadata_v15 is None :
2543+ _ = self .runtime_config .type_registry ["runtime_api" ][api ]["methods" ][
2544+ method
2545+ ]
2546+ runtime_api_types = self .runtime_config .type_registry ["runtime_api" ][
2547+ api
2548+ ].get ("types" , {})
2549+ runtime .runtime_config .update_type_registry_types (runtime_api_types )
2550+ return self ._do_runtime_call_old (api , method , params , block_hash )
2551+ else :
2552+ metadata_v15_value = runtime .metadata_v15 .value ()
2553+
2554+ apis = {entry ["name" ]: entry for entry in metadata_v15_value ["apis" ]}
2555+ api_entry = apis [api ]
2556+ methods = {entry ["name" ]: entry for entry in api_entry ["methods" ]}
2557+ runtime_call_def = methods [method ]
2558+ if _determine_if_old_runtime_call (runtime_call_def , metadata_v15_value ):
2559+ return self ._do_runtime_call_old (api , method , params , block_hash )
25342560
2535- apis = {entry ["name" ]: entry for entry in metadata_v15_value ["apis" ]}
2536- api_entry = apis [api ]
2537- methods = {entry ["name" ]: entry for entry in api_entry ["methods" ]}
2538- runtime_call_def = methods [method ]
25392561 except KeyError :
25402562 raise ValueError (f"Runtime API Call '{ api } .{ method } ' not found in registry" )
25412563
2542- if _determine_if_old_runtime_call (runtime_call_def , metadata_v15_value ):
2543- result = self ._do_runtime_call_old (api , method , params , block_hash )
2544-
2545- return result
2546-
25472564 if isinstance (params , list ) and len (params ) != len (runtime_call_def ["inputs" ]):
25482565 raise ValueError (
25492566 f"Number of parameter provided ({ len (params )} ) does not "
@@ -2745,7 +2762,7 @@ def get_type_registry(self, block_hash: str = None, max_recursion: int = 4) -> d
27452762 """
27462763 self .init_runtime (block_hash = block_hash )
27472764
2748- if not self .implements_scaleinfo :
2765+ if not self .runtime . implements_scaleinfo :
27492766 raise NotImplementedError ("MetadataV14 or higher runtimes is required" )
27502767
27512768 type_registry = {}
0 commit comments