Skip to content

Commit

Permalink
Updated runtime api calls handling logic
Browse files Browse the repository at this point in the history
  • Loading branch information
arjanz committed Oct 6, 2023
1 parent bd1990b commit a1b6cd8
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 43 deletions.
98 changes: 57 additions & 41 deletions scalecodec/type_registry/core.json
Original file line number Diff line number Diff line change
Expand Up @@ -1146,6 +1146,7 @@
"CustomValueMetadata15": "Bytes",
"RuntimeApiMetadataV15": {
"type": "struct",
"base_class": "GenericRuntimeApiMetadata",
"type_mapping": [
[
"name",
Expand All @@ -1163,6 +1164,7 @@
},
"RuntimeApiMethodMetadataV15": {
"type": "struct",
"base_class": "GenericRuntimeApiMethodMetadata",
"type_mapping": [
[
"name",
Expand Down Expand Up @@ -1195,6 +1197,59 @@
]
]
},
"RuntimeApiMetadataV14": {
"type": "struct",
"base_class": "LegacyRuntimeApiMetadata",
"type_mapping": [
[
"name",
"Text"
],
[
"methods",
"Vec<RuntimeApiMethodMetadataV14>"
],
[
"docs",
"Vec<Text>"
]
]
},
"RuntimeApiMethodMetadataV14": {
"type": "struct",
"base_class": "LegacyRuntimeApiMethodMetadata",
"type_mapping": [
[
"name",
"Text"
],
[
"inputs",
"Vec<RuntimeApiMethodParamMetadataV14>"
],
[
"output",
"String"
],
[
"docs",
"Vec<Text>"
]
]
},
"RuntimeApiMethodParamMetadataV14": {
"type": "struct",
"type_mapping": [
[
"name",
"Text"
],
[
"type",
"String"
]
]
},
"PalletMetadataV14": {
"type": "struct",
"base_class": "ScaleInfoPalletMetadata",
Expand Down Expand Up @@ -1909,46 +1964,7 @@
]
]
},
"ContractExecResult": "ContractExecResultTo267",
"RuntimeCallDefinition": {
"type": "struct",
"base_class": "GenericRuntimeCallDefinition",
"type_mapping": [
[
"api",
"String"
],
[
"method",
"String"
],
[
"description",
"String"
],
[
"params",
"Vec<RuntimeCallDefinitionParam>"
],
[
"type",
"String"
]
]
},
"RuntimeCallDefinitionParam": {
"type": "struct",
"type_mapping": [
[
"name",
"String"
],
[
"type",
"String"
]
]
}
"ContractExecResult": "ContractExecResultTo267"
},
"runtime_api": {
"AccountNonceApi": {
Expand Down Expand Up @@ -3008,8 +3024,8 @@
["nonce", "H64"]
]
},
"EthBloom": "H2048",
"H2048": "[u8; 256]",
"EthBloom": "H2048",
"H64": "[u8; 8]",
"Permill": "u32",
"TransactionV2": {
Expand Down
76 changes: 74 additions & 2 deletions scalecodec/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -2192,6 +2192,42 @@ def get_metadata_pallet(self, name: str) -> 'GenericPalletMetadata':
if pallet.value['name'] == name:
return pallet

def get_runtime_apis(self):
if self.index >= 15:
return self[1]['apis']
else:
return [self.get_runtime_api(name) for name in self.runtime_config.type_registry.get("runtime_api").keys()]

def get_runtime_api(self, name: str) -> Optional['GenericRuntimeApiMetadata']:

if self.index >= 15:
for runtime_api in self[1]['apis']:
if runtime_api.value['name'] == name:
return runtime_api
else:
# Legacy: Runtime APIs not included in metadata
runtime_api_data = self.runtime_config.type_registry.get("runtime_api", {}).get(name)

if runtime_api_data:
runtime_api = self.runtime_config.create_scale_object("RuntimeApiMetadataV14")

# Transform data
data = {
'name': name,
'methods': [{
'name': m_name, 'inputs': m_data['params'], 'output': m_data['type'],
'docs': [m_data['description']]
} for m_name, m_data in runtime_api_data['methods'].items()],
'docs': []
}

runtime_api.encode(data)

# Add embedded types to type registry
self.runtime_config.update_type_registry_types(runtime_api_data.get("types", {}))

return runtime_api

def process(self):
value = super().process()

Expand Down Expand Up @@ -2326,6 +2362,12 @@ def get_signed_extensions(self):

return signed_extensions

def get_runtime_api(self, name: str):
return self.get_metadata().get_runtime_api(name)

def get_runtime_apis(self):
return self.get_metadata().get_runtime_apis()


class GenericStringType(String):
@property
Expand Down Expand Up @@ -2755,7 +2797,28 @@ def get_param_info(self, max_recursion: int = TYPE_DECOMP_MAX_RECURSIVE) -> list
return param_info


class GenericRuntimeCallDefinition(Struct):
class GenericRuntimeApiMetadata(Struct):

def get_methods(self):
return list(self.value_object['methods'])

def get_method(self, name: str) -> Optional['GenericRuntimeApiMethodMetadata']:
for method in self.value_object['methods']:
if name == method.value['name']:
return method


class LegacyRuntimeApiMetadata(GenericRuntimeApiMetadata):
pass


class GenericRuntimeApiMethodMetadata(Struct):

def get_params(self):
return [{'name': p['name'], 'type': f'scale_info::{p["type"]}'} for p in self.value['inputs']]

def get_return_type_string(self):
return f"scale_info::{self.value['output']}"

def get_param_info(self, max_recursion: int = TYPE_DECOMP_MAX_RECURSIVE) -> list:
"""
Expand All @@ -2766,13 +2829,22 @@ def get_param_info(self, max_recursion: int = TYPE_DECOMP_MAX_RECURSIVE) -> list
list
"""
param_info = []
for param in self.value['params']:
for param in self.get_params():
scale_type = self.runtime_config.create_scale_object(param['type'])
param_info.append(scale_type.generate_type_decomposition(max_recursion=max_recursion))

return param_info


class LegacyRuntimeApiMethodMetadata(GenericRuntimeApiMethodMetadata):

def get_params(self):
return [{'name': p['name'], 'type': p["type"]} for p in self.value['inputs']]

def get_return_type_string(self):
return self.value['output']


class GenericEventMetadata(Struct):

@property
Expand Down
8 changes: 8 additions & 0 deletions test/test_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ def test_metadata_registry_decode_v14(self):

self.assertGreater(len(metadata_obj.get_signed_extensions().items()), 0)

# Test runtime api
self.assertIsNotNone(metadata_obj.get_runtime_api('Core'))

def test_metadata_registry_decode_v15(self):
metadata_obj = self.runtime_config.create_scale_object(
"MetadataVersioned", data=ScaleBytes(self.metadata_fixture_dict['V15'])
Expand All @@ -125,6 +128,11 @@ def test_metadata_registry_decode_v15(self):

self.assertGreater(len(metadata_obj.get_signed_extensions().items()), 0)

self.assertIsNotNone(metadata_obj.get_runtime_api('Core'))

method = metadata_obj.get_runtime_api('AccountNonceApi').get_method('account_nonce')


# def test_pickle_test(self):
# metadata_obj = self.runtime_config.create_scale_object(
# "MetadataVersioned", data=ScaleBytes(self.metadata_fixture_dict['V14'])
Expand Down

0 comments on commit a1b6cd8

Please sign in to comment.