Skip to content

Commit 38ab21a

Browse files
committed
Fixes query_multiple. Adds tests
1 parent e32a62f commit 38ab21a

File tree

6 files changed

+60
-15
lines changed

6 files changed

+60
-15
lines changed

async_substrate_interface/async_substrate.py

Lines changed: 3 additions & 4 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()
@@ -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 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: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,29 @@ 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"]))
130-
assert event["attributes"] == (
131-
"5G1NjW9YhXLadMWajvTkfcJy6up3yH2q1YzMXDTi6ijanChe",
132-
30,
133-
"0xa6b4e5c8241d60ece0c25056b19f7d21ae845269fc771ad46bf3e011865129a5",
129+
assert (
130+
event["attributes"]
131+
== (
132+
"5G1NjW9YhXLadMWajvTkfcJy6up3yH2q1YzMXDTi6ijanChe", # TODO issue with decoding here
133+
30,
134+
"0xa6b4e5c8241d60ece0c25056b19f7d21ae845269fc771ad46bf3e011865129a5",
135+
)
136+
)
137+
138+
139+
@pytest.mark.asyncio
140+
async def test_query_multiple():
141+
block = 6153277
142+
cks = [
143+
"5FH9AQM4kqbkdC9jyV5FrdEWVYt41nkhFstop7Vhyfb9ZsXt",
144+
"5GQxLKxjZWNZDsghmYcw7P6ahC7XJCjx1WD94WGh92quSycx",
145+
"5EcaPiDT1cv951SkCFsvdHDs2yAEUWhJDuRP9mHb343WnaVn",
146+
]
147+
async with AsyncSubstrateInterface(ARCHIVE_ENTRYPOINT) as substrate:
148+
block_hash = await substrate.get_block_hash(block_id=block)
149+
assert await substrate.query_multiple(
150+
params=cks,
151+
module="SubtensorModule",
152+
storage_function="OwnedHotkeys",
153+
block_hash=block_hash,
134154
)

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)