Skip to content

Commit 9b68fbb

Browse files
authored
Merge pull request #168 from opentensor/fix/thewhaleking/query-multiple-fix
query multiple/decoding fix
2 parents e32a62f + 62b70cb commit 9b68fbb

File tree

6 files changed

+54
-12
lines changed

6 files changed

+54
-12
lines changed

async_substrate_interface/async_substrate.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -784,9 +784,9 @@ async def retrieve(self, item_id: str) -> Optional[dict]:
784784
if item is not None:
785785
if item.done():
786786
self.max_subscriptions.release()
787+
res = item.result()
787788
del self._received[item_id]
788-
789-
return item.result()
789+
return res
790790
else:
791791
try:
792792
return self._received_subscriptions[item_id].get_nowait()
@@ -1165,7 +1165,7 @@ async def get_runtime_for_version(
11651165
async def _get_runtime_for_version(
11661166
self, runtime_version: int, block_hash: Optional[str] = None
11671167
) -> Runtime:
1168-
runtime_config = RuntimeConfigurationObject()
1168+
runtime_config = RuntimeConfigurationObject(ss58_format=self.ss58_format)
11691169
runtime_config.clear_type_registry()
11701170
runtime_config.update_type_registry(load_type_registry_preset(name="core"))
11711171

@@ -2337,7 +2337,7 @@ async def _make_rpc_request(
23372337
request_manager.add_request(item_id, payload["id"])
23382338

23392339
while True:
2340-
for item_id in list(request_manager.response_map.keys()):
2340+
for item_id in request_manager.unresponded():
23412341
if (
23422342
item_id not in request_manager.responses
23432343
or asyncio.iscoroutinefunction(result_handler)
@@ -2368,7 +2368,6 @@ async def _make_rpc_request(
23682368
runtime=runtime,
23692369
force_legacy_decode=force_legacy_decode,
23702370
)
2371-
23722371
request_manager.add_response(
23732372
item_id, decoded_response, complete
23742373
)

async_substrate_interface/sync_substrate.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1924,7 +1924,7 @@ def _make_rpc_request(
19241924
_received[response["params"]["subscription"]] = response
19251925
else:
19261926
raise SubstrateRequestException(response)
1927-
for item_id in list(request_manager.response_map.keys()):
1927+
for item_id in request_manager.unresponded():
19281928
if item_id not in request_manager.responses or isinstance(
19291929
result_handler, Callable
19301930
):

async_substrate_interface/types.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,15 @@ def get_results(self) -> RequestResults:
418418
request_id: info["results"] for request_id, info in self.responses.items()
419419
}
420420

421+
def unresponded(self):
422+
"""
423+
Yields items from response_map whose corresponding response is missing or incomplete.
424+
"""
425+
for item_id, request_id in list(self.response_map.items()):
426+
response_info = self.responses.get(request_id)
427+
if response_info is None or not response_info["complete"]:
428+
yield item_id
429+
421430

422431
@dataclass
423432
class Preprocessed:

tests/integration_tests/test_async_substrate_interface.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,26 @@ async def test_get_events_proper_decoding():
126126
async with AsyncSubstrateInterface(ARCHIVE_ENTRYPOINT) as substrate:
127127
all_events = await substrate.get_events(block_hash=block_hash)
128128
event = all_events[1]
129-
print(type(event["attributes"]))
130129
assert event["attributes"] == (
131130
"5G1NjW9YhXLadMWajvTkfcJy6up3yH2q1YzMXDTi6ijanChe",
132131
30,
133132
"0xa6b4e5c8241d60ece0c25056b19f7d21ae845269fc771ad46bf3e011865129a5",
134133
)
134+
135+
136+
@pytest.mark.asyncio
137+
async def test_query_multiple():
138+
block = 6153277
139+
cks = [
140+
"5FH9AQM4kqbkdC9jyV5FrdEWVYt41nkhFstop7Vhyfb9ZsXt",
141+
"5GQxLKxjZWNZDsghmYcw7P6ahC7XJCjx1WD94WGh92quSycx",
142+
"5EcaPiDT1cv951SkCFsvdHDs2yAEUWhJDuRP9mHb343WnaVn",
143+
]
144+
async with AsyncSubstrateInterface(ARCHIVE_ENTRYPOINT) as substrate:
145+
block_hash = await substrate.get_block_hash(block_id=block)
146+
assert await substrate.query_multiple(
147+
params=cks,
148+
module="SubtensorModule",
149+
storage_function="OwnedHotkeys",
150+
block_hash=block_hash,
151+
)

tests/integration_tests/test_substrate_interface.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,25 @@ def test_get_events_proper_decoding():
7878
with SubstrateInterface(ARCHIVE_ENTRYPOINT) as substrate:
7979
all_events = substrate.get_events(block_hash=block_hash)
8080
event = all_events[1]
81-
print(type(event["attributes"]))
8281
assert event["attributes"] == (
8382
"5G1NjW9YhXLadMWajvTkfcJy6up3yH2q1YzMXDTi6ijanChe",
8483
30,
8584
"0xa6b4e5c8241d60ece0c25056b19f7d21ae845269fc771ad46bf3e011865129a5",
8685
)
86+
87+
88+
def test_query_multiple():
89+
block = 6153277
90+
cks = [
91+
"5FH9AQM4kqbkdC9jyV5FrdEWVYt41nkhFstop7Vhyfb9ZsXt",
92+
"5GQxLKxjZWNZDsghmYcw7P6ahC7XJCjx1WD94WGh92quSycx",
93+
"5EcaPiDT1cv951SkCFsvdHDs2yAEUWhJDuRP9mHb343WnaVn",
94+
]
95+
with SubstrateInterface(ARCHIVE_ENTRYPOINT) as substrate:
96+
block_hash = substrate.get_block_hash(block_id=block)
97+
assert substrate.query_multiple(
98+
params=cks,
99+
module="SubtensorModule",
100+
storage_function="OwnedHotkeys",
101+
block_hash=block_hash,
102+
)

tests/unit_tests/asyncio_/test_substrate_interface.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import pytest
55
from websockets.exceptions import InvalidURI
6+
from websockets.protocol import State
67

78
from async_substrate_interface.async_substrate import AsyncSubstrateInterface
89
from async_substrate_interface.types import ScaleObj
@@ -103,17 +104,17 @@ async def test_websocket_shutdown_timer():
103104
async with AsyncSubstrateInterface("wss://lite.sub.latent.to:443") as substrate:
104105
await substrate.get_chain_head()
105106
await asyncio.sleep(6)
106-
assert (
107-
substrate.ws._initialized is False
108-
) # connection should have closed automatically
107+
assert (
108+
substrate.ws.state is State.CLOSED
109+
) # connection should have closed automatically
109110

110111
# using custom ws shutdown timer of 10.0 seconds
111112
async with AsyncSubstrateInterface(
112113
"wss://lite.sub.latent.to:443", ws_shutdown_timer=10.0
113114
) as substrate:
114115
await substrate.get_chain_head()
115116
await asyncio.sleep(6) # same sleep time as before
116-
assert substrate.ws._initialized is True # connection should still be open
117+
assert substrate.ws.state is State.OPEN # connection should still be open
117118

118119

119120
@pytest.mark.asyncio

0 commit comments

Comments
 (0)