65
65
from async_substrate_interface .utils .decoding import (
66
66
_determine_if_old_runtime_call ,
67
67
_bt_decode_to_dict_or_list ,
68
+ legacy_scale_decode ,
68
69
)
69
70
from async_substrate_interface .utils .storage import StorageKey
70
71
from async_substrate_interface .type_registry import _TYPE_REGISTRY
@@ -816,7 +817,7 @@ async def initialize(self):
816
817
)
817
818
818
819
if ss58_prefix_constant :
819
- self .ss58_format = ss58_prefix_constant
820
+ self .ss58_format = ss58_prefix_constant . value
820
821
self .initialized = True
821
822
self ._initializing = False
822
823
@@ -908,7 +909,7 @@ async def _get_current_block_hash(
908
909
909
910
async def _load_registry_at_block (
910
911
self , block_hash : Optional [str ]
911
- ) -> tuple [MetadataV15 , PortableRegistry ]:
912
+ ) -> tuple [Optional [ MetadataV15 ], Optional [ PortableRegistry ] ]:
912
913
# Should be called for any block that fails decoding.
913
914
# Possibly the metadata was different.
914
915
try :
@@ -922,7 +923,11 @@ async def _load_registry_at_block(
922
923
"Client error: Execution failed: Other: Exported method Metadata_metadata_at_version is not found"
923
924
in e .args
924
925
):
925
- raise MetadataAtVersionNotFound
926
+ logger .warning (
927
+ "Exported method Metadata_metadata_at_version is not found. This indicates the block is quite old, "
928
+ "decoding for this block will use legacy Python decoding."
929
+ )
930
+ return None , None
926
931
else :
927
932
raise e
928
933
metadata_option_hex_str = metadata_rpc_result ["result" ]
@@ -964,6 +969,7 @@ async def decode_scale(
964
969
return_scale_obj : bool = False ,
965
970
block_hash : Optional [str ] = None ,
966
971
runtime : Optional [Runtime ] = None ,
972
+ force_legacy : bool = False ,
967
973
) -> Union [ScaleObj , Any ]:
968
974
"""
969
975
Helper function to decode arbitrary SCALE-bytes (e.g. 0x02000000) according to given RUST type_string
@@ -979,6 +985,7 @@ async def decode_scale(
979
985
block_hash: Hash of the block where the desired runtime is located. Ignored if supplying `runtime`
980
986
runtime: Optional Runtime object whose registry to use for decoding. If not specified, runtime will be
981
987
loaded based on the block hash specified (or latest block if no block_hash is specified)
988
+ force_legacy: Whether to explicitly use legacy Python-only decoding (non bt-decode).
982
989
983
990
Returns:
984
991
Decoded object
@@ -991,10 +998,10 @@ async def decode_scale(
991
998
else :
992
999
if not runtime :
993
1000
runtime = await self .init_runtime (block_hash = block_hash )
994
- runtime_registry = runtime .registry
1001
+ if runtime .metadata_v15 is not None or force_legacy is True :
1002
+ obj = decode_by_type_string (type_string , runtime .registry , scale_bytes )
995
1003
else :
996
- runtime_registry = runtime .registry
997
- obj = decode_by_type_string (type_string , runtime_registry , scale_bytes )
1004
+ obj = legacy_scale_decode (type_string , scale_bytes , runtime )
998
1005
if return_scale_obj :
999
1006
return ScaleObj (obj )
1000
1007
else :
@@ -1933,7 +1940,12 @@ def convert_event_data(data):
1933
1940
)
1934
1941
if storage_obj :
1935
1942
for item in list (storage_obj ):
1936
- events .append (convert_event_data (item ))
1943
+ try :
1944
+ events .append (convert_event_data (item ))
1945
+ except (
1946
+ AttributeError
1947
+ ): # indicates this was legacy decoded with scalecodec
1948
+ events .append (item )
1937
1949
return events
1938
1950
1939
1951
async def get_metadata (self , block_hash = None ) -> MetadataV15 :
@@ -2909,7 +2921,7 @@ async def _do_runtime_call_old(
2909
2921
result_vec_u8_bytes = hex_to_bytes (result_data ["result" ])
2910
2922
result_bytes = await self .decode_scale (
2911
2923
"Vec<u8>" , result_vec_u8_bytes , runtime = runtime
2912
- )
2924
+ ) # TODO may need to force_legacy after testing.
2913
2925
2914
2926
# Decode result
2915
2927
# Get correct type
@@ -2945,22 +2957,32 @@ async def runtime_call(
2945
2957
params = {}
2946
2958
2947
2959
try :
2948
- metadata_v15_value = runtime .metadata_v15 .value ()
2960
+ if runtime .metadata_v15 is None :
2961
+ _ = self .runtime_config .type_registry ["runtime_api" ][api ]["methods" ][
2962
+ method
2963
+ ]
2964
+ runtime_api_types = self .runtime_config .type_registry ["runtime_api" ][
2965
+ api
2966
+ ].get ("types" , {})
2967
+ runtime .runtime_config .update_type_registry_types (runtime_api_types )
2968
+ return await self ._do_runtime_call_old (
2969
+ api , method , params , block_hash , runtime = runtime
2970
+ )
2949
2971
2950
- apis = {entry ["name" ]: entry for entry in metadata_v15_value ["apis" ]}
2951
- api_entry = apis [api ]
2952
- methods = {entry ["name" ]: entry for entry in api_entry ["methods" ]}
2953
- runtime_call_def = methods [method ]
2972
+ else :
2973
+ metadata_v15_value = runtime .metadata_v15 .value ()
2974
+
2975
+ apis = {entry ["name" ]: entry for entry in metadata_v15_value ["apis" ]}
2976
+ api_entry = apis [api ]
2977
+ methods = {entry ["name" ]: entry for entry in api_entry ["methods" ]}
2978
+ runtime_call_def = methods [method ]
2979
+ if _determine_if_old_runtime_call (runtime_call_def , metadata_v15_value ):
2980
+ return await self ._do_runtime_call_old (
2981
+ api , method , params , block_hash , runtime = runtime
2982
+ )
2954
2983
except KeyError :
2955
2984
raise ValueError (f"Runtime API Call '{ api } .{ method } ' not found in registry" )
2956
2985
2957
- if _determine_if_old_runtime_call (runtime_call_def , metadata_v15_value ):
2958
- result = await self ._do_runtime_call_old (
2959
- api , method , params , block_hash , runtime = runtime
2960
- )
2961
-
2962
- return result
2963
-
2964
2986
if isinstance (params , list ) and len (params ) != len (runtime_call_def ["inputs" ]):
2965
2987
raise ValueError (
2966
2988
f"Number of parameter provided ({ len (params )} ) does not "
0 commit comments