Skip to content

Commit f9776bc

Browse files
committed
Ensure runtime_call is the same in both async and sync versions. Fix sync test
1 parent 831c1c0 commit f9776bc

File tree

2 files changed

+55
-35
lines changed

2 files changed

+55
-35
lines changed

async_substrate_interface/sync_substrate.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2497,13 +2497,13 @@ def runtime_call(
24972497
Returns:
24982498
ScaleType from the runtime call
24992499
"""
2500-
self.init_runtime(block_hash=block_hash)
2500+
runtime = self.init_runtime(block_hash=block_hash)
25012501

25022502
if params is None:
25032503
params = {}
25042504

25052505
try:
2506-
metadata_v15_value = self.runtime.metadata_v15.value()
2506+
metadata_v15_value = runtime.metadata_v15.value()
25072507

25082508
apis = {entry["name"]: entry for entry in metadata_v15_value["apis"]}
25092509
api_entry = apis[api]
Lines changed: 53 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,74 @@
1-
import unittest.mock
1+
from unittest.mock import MagicMock
22

33
from async_substrate_interface.sync_substrate import SubstrateInterface
44
from async_substrate_interface.types import ScaleObj
55

66

77
def test_runtime_call(monkeypatch):
8-
monkeypatch.setattr(
9-
"async_substrate_interface.sync_substrate.connect", unittest.mock.MagicMock()
10-
)
11-
12-
substrate = SubstrateInterface(
13-
"ws://localhost",
14-
_mock=True,
15-
)
16-
substrate._metadata = unittest.mock.Mock()
17-
substrate.metadata_v15 = unittest.mock.Mock(
18-
**{
19-
"value.return_value": {
20-
"apis": [
8+
substrate = SubstrateInterface("ws://localhost", _mock=True)
9+
fake_runtime = MagicMock()
10+
fake_metadata_v15 = MagicMock()
11+
fake_metadata_v15.value.return_value = {
12+
"apis": [
13+
{
14+
"name": "SubstrateApi",
15+
"methods": [
2116
{
22-
"name": "SubstrateApi",
23-
"methods": [
24-
{
25-
"name": "SubstrateMethod",
26-
"inputs": [],
27-
"output": "1",
28-
},
29-
],
17+
"name": "SubstrateMethod",
18+
"inputs": [],
19+
"output": "1",
3020
},
3121
],
3222
},
33-
}
34-
)
35-
substrate.rpc_request = unittest.mock.Mock(
36-
return_value={
37-
"result": "0x00",
23+
],
24+
"types": {
25+
"types": [
26+
{
27+
"id": "1",
28+
"type": {
29+
"path": ["Vec"],
30+
"def": {"sequence": {"type": "4"}},
31+
},
32+
},
33+
]
3834
},
35+
}
36+
fake_runtime.metadata_v15 = fake_metadata_v15
37+
substrate.init_runtime = MagicMock(return_value=fake_runtime)
38+
39+
# Patch encode_scale (should not be called in this test since no inputs)
40+
substrate.encode_scale = MagicMock()
41+
42+
# Patch decode_scale to produce a dummy value
43+
substrate.decode_scale = MagicMock(return_value="decoded_result")
44+
45+
# Patch RPC request with correct behavior
46+
substrate.rpc_request = MagicMock(
47+
side_effect=lambda method, params: {
48+
"result": "0x00" if method == "state_call" else {"parentHash": "0xDEADBEEF"}
49+
}
3950
)
40-
substrate.decode_scale = unittest.mock.Mock()
4151

52+
# Patch get_block_runtime_info
53+
substrate.get_block_runtime_info = MagicMock(return_value={"specVersion": "1"})
54+
55+
# Run the call
4256
result = substrate.runtime_call(
4357
"SubstrateApi",
4458
"SubstrateMethod",
4559
)
4660

61+
# Validate the result is wrapped in ScaleObj
4762
assert isinstance(result, ScaleObj)
48-
assert result.value is substrate.decode_scale.return_value
63+
assert result.value == "decoded_result"
4964

50-
substrate.rpc_request.assert_called_once_with(
51-
"state_call",
52-
["SubstrateApi_SubstrateMethod", "", None],
53-
)
65+
# Check decode_scale called correctly
5466
substrate.decode_scale.assert_called_once_with("scale_info::1", b"\x00")
67+
68+
# encode_scale should not be called since no inputs
69+
substrate.encode_scale.assert_not_called()
70+
71+
# Check RPC request called for the state_call
72+
substrate.rpc_request.assert_any_call(
73+
"state_call", ["SubstrateApi_SubstrateMethod", "", None]
74+
)

0 commit comments

Comments
 (0)