23
23
)
24
24
25
25
from bt_decode import MetadataV15 , PortableRegistry , decode as decode_by_type_string
26
- from scalecodec .base import ScaleBytes , ScaleType , RuntimeConfigurationObject
26
+ from scalecodec .base import ScaleBytes , ScaleType
27
27
from scalecodec .types import (
28
28
GenericCall ,
29
29
GenericExtrinsic ,
@@ -787,15 +787,9 @@ def __init__(
787
787
self .type_registry = type_registry
788
788
self .type_registry_preset = type_registry_preset
789
789
self .runtime_cache = RuntimeCache ()
790
- self .runtime_config = RuntimeConfigurationObject (
791
- ss58_format = self .ss58_format , implements_scale_info = True
792
- )
793
790
self ._nonces = {}
794
791
self .metadata_version_hex = "0x0f000000" # v15
795
- self .reload_type_registry ()
796
792
self ._initializing = False
797
- self .registry_type_map = {}
798
- self .type_id_to_name = {}
799
793
self ._mock = _mock
800
794
801
795
async def __aenter__ (self ):
@@ -896,52 +890,31 @@ async def _load_registry_at_block(
896
890
metadata_option_bytes = bytes .fromhex (metadata_option_hex_str [2 :])
897
891
metadata = MetadataV15 .decode_from_metadata_option (metadata_option_bytes )
898
892
registry = PortableRegistry .from_metadata_v15 (metadata )
899
- self ._load_registry_type_map (registry )
900
893
return metadata , registry
901
894
902
- async def _wait_for_registry (self , _attempt : int = 1 , _retries : int = 3 ) -> None :
903
- async def _waiter ():
904
- while self .runtime .registry is None :
905
- await asyncio .sleep (0.1 )
906
- return
907
-
908
- try :
909
- if not self .runtime .registry :
910
- await asyncio .wait_for (_waiter (), timeout = 10 )
911
- except TimeoutError :
912
- # indicates that registry was never loaded
913
- if not self ._initializing :
914
- raise AttributeError (
915
- "Registry was never loaded. This did not occur during initialization, which usually indicates "
916
- "you must first initialize the AsyncSubstrateInterface object, either with "
917
- "`await AsyncSubstrateInterface.initialize()` or running with `async with`"
918
- )
919
- elif _attempt < _retries :
920
- await self ._load_registry_at_block (None )
921
- return await self ._wait_for_registry (_attempt + 1 , _retries )
922
- else :
923
- raise AttributeError (
924
- "Registry was never loaded. This occurred during initialization, which usually indicates a "
925
- "connection or node error."
926
- )
927
-
928
895
async def encode_scale (
929
- self , type_string , value : Any , _attempt : int = 1 , _retries : int = 3
896
+ self ,
897
+ type_string ,
898
+ value : Any ,
899
+ block_hash : Optional [str ] = None ,
900
+ runtime : Optional [Runtime ] = None ,
930
901
) -> bytes :
931
902
"""
932
- Helper function to encode arbitrary data into SCALE-bytes for given RUST type_string
903
+ Helper function to encode arbitrary data into SCALE-bytes for given RUST type_string. If neither `block_hash`
904
+ nor `runtime` are supplied, the runtime of the current block will be used.
933
905
934
906
Args:
935
907
type_string: the type string of the SCALE object for decoding
936
908
value: value to encode
937
- _attempt: the current number of attempts to load the registry needed to encode the value
938
- _retries : the maximum number of attempts to load the registry needed to encode the value
909
+ block_hash: hash of the block where the desired runtime is located. Ignored if supplying `runtime`
910
+ runtime : the runtime to use for the scale encoding. If supplied, `block_hash` is ignored
939
911
940
912
Returns:
941
913
encoded bytes
942
914
"""
943
- await self ._wait_for_registry (_attempt , _retries )
944
- return self ._encode_scale (type_string , value )
915
+ if runtime is None :
916
+ runtime = await self .init_runtime (block_hash = block_hash )
917
+ return self ._encode_scale (type_string , value , runtime = runtime )
945
918
946
919
async def decode_scale (
947
920
self ,
@@ -987,25 +960,26 @@ async def decode_scale(
987
960
return obj
988
961
989
962
def load_runtime (self , runtime ):
990
- self .runtime = runtime
991
-
992
963
# Update type registry
993
- self .reload_type_registry (use_remote_preset = False , auto_discover = True )
964
+ runtime .reload_type_registry (use_remote_preset = False , auto_discover = True )
994
965
995
- self .runtime_config .set_active_spec_version_id (runtime .runtime_version )
996
- if self .implements_scaleinfo :
997
- logger .debug ("Add PortableRegistry from metadata to type registry" )
998
- self .runtime_config .add_portable_registry (runtime .metadata )
966
+ runtime .runtime_config .set_active_spec_version_id (runtime .runtime_version )
967
+ runtime .runtime_config .set_active_spec_version_id (runtime .runtime_version )
968
+ if runtime .implements_scaleinfo :
969
+ logger .debug ("Adding PortableRegistry from metadata to type registry" )
970
+ runtime .runtime_config .add_portable_registry (runtime .metadata )
999
971
# Set runtime compatibility flags
1000
972
try :
1001
- _ = self .runtime_config .create_scale_object ("sp_weights::weight_v2::Weight" )
1002
- self .config ["is_weight_v2" ] = True
1003
- self .runtime_config .update_type_registry_types (
973
+ _ = runtime .runtime_config .create_scale_object (
974
+ "sp_weights::weight_v2::Weight"
975
+ )
976
+ runtime .config ["is_weight_v2" ] = True
977
+ runtime .runtime_config .update_type_registry_types (
1004
978
{"Weight" : "sp_weights::weight_v2::Weight" }
1005
979
)
1006
980
except NotImplementedError :
1007
- self .config ["is_weight_v2" ] = False
1008
- self .runtime_config .update_type_registry_types ({"Weight" : "WeightV1" })
981
+ runtime .config ["is_weight_v2" ] = False
982
+ runtime .runtime_config .update_type_registry_types ({"Weight" : "WeightV1" })
1009
983
1010
984
async def init_runtime (
1011
985
self , block_hash : Optional [str ] = None , block_id : Optional [int ] = None
@@ -1288,6 +1262,7 @@ async def get_metadata_storage_functions(
1288
1262
storage_item = storage ,
1289
1263
module = module ,
1290
1264
spec_version_id = runtime .runtime_version ,
1265
+ runtime = runtime ,
1291
1266
)
1292
1267
)
1293
1268
@@ -1407,21 +1382,21 @@ async def get_metadata_runtime_call_function(
1407
1382
self ,
1408
1383
api : str ,
1409
1384
method : str ,
1410
- block_hash : str = None ,
1385
+ block_hash : Optional [ str ] = None ,
1411
1386
runtime : Optional [Runtime ] = None ,
1412
1387
) -> GenericRuntimeCallDefinition :
1413
1388
"""
1414
- Get details of a runtime API call
1389
+ Get details of a runtime API call. If not supplying `block_hash` or `runtime`, the runtime of the current block
1390
+ will be used.
1415
1391
1416
1392
Args:
1417
1393
api: Name of the runtime API e.g. 'TransactionPaymentApi'
1418
1394
method: Name of the method e.g. 'query_fee_details'
1419
- block_hash: Hash of the block to query, unused if specifying `runtime`
1420
- runtime: Optional `Runtime` whose call functions to retrieve. If not specified, will fall back to the
1421
- runtime at the block hash specified. If that is not specified, will fall back to the current block.
1395
+ block_hash: Hash of the block whose runtime to use, if not specifying `runtime`
1396
+ runtime: The `Runtime` object whose metadata to use.
1422
1397
1423
1398
Returns:
1424
- runtime call function
1399
+ GenericRuntimeCallDefinition
1425
1400
"""
1426
1401
if not runtime :
1427
1402
runtime = await self .init_runtime (block_hash = block_hash )
@@ -1439,7 +1414,7 @@ async def get_metadata_runtime_call_function(
1439
1414
raise ValueError (f"Runtime API Call '{ api } .{ method } ' not found in registry" )
1440
1415
1441
1416
# Add runtime API types to registry
1442
- self .runtime_config .update_type_registry_types (runtime_api_types )
1417
+ runtime .runtime_config .update_type_registry_types (runtime_api_types )
1443
1418
1444
1419
runtime_call_def_obj = await self .create_scale_object (
1445
1420
"RuntimeCallDefinition" , runtime = runtime
@@ -1448,41 +1423,6 @@ async def get_metadata_runtime_call_function(
1448
1423
1449
1424
return runtime_call_def_obj
1450
1425
1451
- async def get_metadata_runtime_call_function (
1452
- self , api : str , method : str
1453
- ) -> GenericRuntimeCallDefinition :
1454
- """
1455
- Get details of a runtime API call
1456
-
1457
- Args:
1458
- api: Name of the runtime API e.g. 'TransactionPaymentApi'
1459
- method: Name of the method e.g. 'query_fee_details'
1460
-
1461
- Returns:
1462
- GenericRuntimeCallDefinition
1463
- """
1464
- await self .init_runtime (block_hash = block_hash )
1465
-
1466
- try :
1467
- runtime_call_def = self .runtime_config .type_registry ["runtime_api" ][api ][
1468
- "methods"
1469
- ][method ]
1470
- runtime_call_def ["api" ] = api
1471
- runtime_call_def ["method" ] = method
1472
- runtime_api_types = self .runtime_config .type_registry ["runtime_api" ][
1473
- api
1474
- ].get ("types" , {})
1475
- except KeyError :
1476
- raise ValueError (f"Runtime API Call '{ api } .{ method } ' not found in registry" )
1477
-
1478
- # Add runtime API types to registry
1479
- self .runtime_config .update_type_registry_types (runtime_api_types )
1480
-
1481
- runtime_call_def_obj = await self .create_scale_object ("RuntimeCallDefinition" )
1482
- runtime_call_def_obj .encode (runtime_call_def )
1483
-
1484
- return runtime_call_def_obj
1485
-
1486
1426
async def _get_block_handler (
1487
1427
self ,
1488
1428
block_hash : str ,
@@ -2897,6 +2837,7 @@ async def _do_runtime_call_old(
2897
2837
method : str ,
2898
2838
params : Optional [Union [list , dict ]] = None ,
2899
2839
block_hash : Optional [str ] = None ,
2840
+ runtime : Optional [Runtime ] = None ,
2900
2841
) -> ScaleType :
2901
2842
logger .debug (
2902
2843
f"Decoding old runtime call: { api } .{ method } with params: { params } at block hash: { block_hash } "
@@ -2927,10 +2868,14 @@ async def _do_runtime_call_old(
2927
2868
2928
2869
# RPC request
2929
2870
result_data = await self .rpc_request (
2930
- "state_call" , [f"{ api } _{ method } " , param_data .hex (), block_hash ]
2871
+ "state_call" ,
2872
+ [f"{ api } _{ method } " , param_data .hex (), block_hash ],
2873
+ runtime = runtime ,
2931
2874
)
2932
2875
result_vec_u8_bytes = hex_to_bytes (result_data ["result" ])
2933
- result_bytes = await self .decode_scale ("Vec<u8>" , result_vec_u8_bytes )
2876
+ result_bytes = await self .decode_scale (
2877
+ "Vec<u8>" , result_vec_u8_bytes , runtime = runtime
2878
+ )
2934
2879
2935
2880
# Decode result
2936
2881
# Get correct type
@@ -2976,7 +2921,9 @@ async def runtime_call(
2976
2921
raise ValueError (f"Runtime API Call '{ api } .{ method } ' not found in registry" )
2977
2922
2978
2923
if _determine_if_old_runtime_call (runtime_call_def , metadata_v15_value ):
2979
- result = await self ._do_runtime_call_old (api , method , params , block_hash )
2924
+ result = await self ._do_runtime_call_old (
2925
+ api , method , params , block_hash , runtime = runtime
2926
+ )
2980
2927
2981
2928
return result
2982
2929
0 commit comments