Skip to content

Commit dcad245

Browse files
authored
Merge pull request #12 from Tnmoxa/dev
fix: #8 return empty list
2 parents de1e980 + abf4625 commit dcad245

File tree

13 files changed

+105
-77
lines changed

13 files changed

+105
-77
lines changed

celestia/node_api/blob.py

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class BlobClient(Wrapper):
2828
""" Client for interacting with Celestia's Blob API."""
2929

3030
@handle_blob_error
31-
async def get(self, height: int, namespace: Namespace, commitment: Commitment,
31+
async def get(self, height: int, namespace: Namespace, commitment: Commitment, *,
3232
deserializer: Callable | None = None) -> Blob | None:
3333
""" Retrieves the blob by commitment under the given namespace and height.
3434
@@ -63,12 +63,14 @@ async def get_all(self, height: int, namespace: Namespace, *namespaces: Namespac
6363
deserializer (Callable | None): Custom deserializer. Defaults to None.
6464
6565
Returns:
66-
list[Blob] | None: The list, of blobs or None if not found.
66+
list[Blob]: The list of blobs or [] if not found.
6767
"""
6868

69-
def deserializer_(result):
69+
def deserializer_(result) -> list['Blob']:
7070
if result is not None:
7171
return [Blob(**kwargs) for kwargs in result]
72+
else:
73+
return []
7274

7375
deserializer = deserializer if deserializer is not None else deserializer_
7476
namespaces = tuple(Namespace(namespace) for namespace in (namespace, *namespaces))
@@ -100,7 +102,7 @@ def deserializer_(height):
100102
return await self._rpc.call("blob.Submit", (blobs, options), deserializer)
101103

102104
@handle_blob_error
103-
async def get_commitment_proof(self, height: int, namespace: Namespace, commitment: Commitment,
105+
async def get_commitment_proof(self, height: int, namespace: Namespace, commitment: Commitment, *,
104106
deserializer: Callable | None = None) -> CommitmentProof | None:
105107
""" Generates a commitment proof for a share commitment.
106108
@@ -119,25 +121,32 @@ async def get_commitment_proof(self, height: int, namespace: Namespace, commitme
119121
return await self._rpc.call("blob.GetCommitmentProof", (height, Namespace(namespace), Commitment(commitment)),
120122
deserializer)
121123

122-
@handle_blob_error
123-
async def get_proof(self, height: int, namespace: Namespace, commitment: Commitment,
124+
async def get_proof(self, height: int, namespace: Namespace, commitment: Commitment, *,
124125
deserializer: Callable | None = None) -> list[Proof] | None:
125126
""" Retrieves proofs in the given namespaces at the given height by commitment.
126127
127128
Args:
128129
height (int): The block height.
129130
namespace (Namespace): The namespace of the proof.
130131
commitment (Commitment): The commitment to generate the proof for.
131-
deserializer (Callable | None): Custom deserializer. Defaults to :meth:`~celestia.types.blob.Proof.deserializer`.
132+
deserializer (Callable | None): Custom deserializer. Defaults to None.
132133
133134
Returns:
134-
list[Proof] | None: A list of proofs, or None if not found.
135+
list[Proof]: A list of proofs or [] if not found.
135136
"""
136137

137-
deserializer = deserializer if deserializer is not None else Proof.deserializer
138+
def deserializer_(result) -> list['Proof']:
139+
if result is not None:
140+
return [Proof(**kwargs) for kwargs in result]
138141

139-
return await self._rpc.call("blob.GetProof", (height, Namespace(namespace), Commitment(commitment)),
140-
deserializer)
142+
deserializer = deserializer if deserializer is not None else deserializer_
143+
try:
144+
return await self._rpc.call("blob.GetProof", (height, Namespace(namespace), Commitment(commitment)),
145+
deserializer)
146+
except ConnectionError as e:
147+
if 'blob: not found' in e.args[1].body['message'].lower():
148+
return []
149+
raise
141150

142151
async def included(self, height: int, namespace: Namespace, proof: Proof, commitment: Commitment) -> bool:
143152
""" Checks whether a blob's given commitment(Merkle subtree root) is
@@ -155,7 +164,7 @@ async def included(self, height: int, namespace: Namespace, proof: Proof, commit
155164

156165
return await self._rpc.call("blob.Included", (height, Namespace(namespace), proof, Commitment(commitment)))
157166

158-
async def subscribe(self, namespace: Namespace,
167+
async def subscribe(self, namespace: Namespace, *,
159168
deserializer: Callable | None = None) -> AsyncIterator[SubscriptionBlobResult | None]:
160169
""" Subscribe to published blobs from the given namespace as they are included.
161170

celestia/node_api/das.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
class DasClient(Wrapper):
88
""" Client for interacting with Celestia's Das API."""
99

10-
async def sampling_stats(self, deserializer: Callable | None = None) -> SamplingStats:
10+
async def sampling_stats(self, *, deserializer: Callable | None = None) -> SamplingStats:
1111
""" Returns the current statistics over the DA sampling process.
1212
1313
Args:

celestia/node_api/header.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class HeaderClient(Wrapper):
2525
""" Client for interacting with Celestia's Header API."""
2626

2727
@handle_header_error
28-
async def get_by_hash(self, header_hash: str, deserializer: Callable | None = None) -> ExtendedHeader | None:
28+
async def get_by_hash(self, header_hash: str, *, deserializer: Callable | None = None) -> ExtendedHeader | None:
2929
""" Returns the header of the given hash from the node's header store.
3030
3131
Args:
@@ -40,7 +40,7 @@ async def get_by_hash(self, header_hash: str, deserializer: Callable | None = No
4040

4141
return await self._rpc.call("header.GetByHash", (header_hash,), deserializer)
4242

43-
async def get_by_height(self, height: int, deserializer: Callable | None = None) -> ExtendedHeader:
43+
async def get_by_height(self, height: int, *, deserializer: Callable | None = None) -> ExtendedHeader:
4444
""" Returns the ExtendedHeader at the given height if it is currently available.
4545
4646
Args:
@@ -55,7 +55,7 @@ async def get_by_height(self, height: int, deserializer: Callable | None = None)
5555

5656
return await self._rpc.call("header.GetByHeight", (int(height),), deserializer)
5757

58-
async def get_range_by_height(self, range_from: ExtendedHeader, range_to: int,
58+
async def get_range_by_height(self, range_from: ExtendedHeader, range_to: int, *,
5959
deserializer: Callable | None = None) -> list[ExtendedHeader]:
6060
""" Returns the given range (from:to) of ExtendedHeaders from the node's header store
6161
and verifies that the returned headers are adjacent to each other.
@@ -77,7 +77,7 @@ def deserializer_(result):
7777

7878
return await self._rpc.call("header.GetRangeByHeight", (range_from, int(range_to)), deserializer)
7979

80-
async def local_head(self, deserializer: Callable | None = None) -> ExtendedHeader:
80+
async def local_head(self, *, deserializer: Callable | None = None) -> ExtendedHeader:
8181
""" Returns the ExtendedHeader of the chain head.
8282
8383
Args:
@@ -91,7 +91,7 @@ async def local_head(self, deserializer: Callable | None = None) -> ExtendedHead
9191

9292
return await self._rpc.call("header.LocalHead", (), deserializer)
9393

94-
async def network_head(self, deserializer: Callable | None = None) -> ExtendedHeader:
94+
async def network_head(self, *, deserializer: Callable | None = None) -> ExtendedHeader:
9595
""" Provides the Syncer's view of the current network head.
9696
9797
Args:
@@ -105,7 +105,7 @@ async def network_head(self, deserializer: Callable | None = None) -> ExtendedHe
105105

106106
return await self._rpc.call("header.NetworkHead", (), deserializer)
107107

108-
async def subscribe(self, deserializer: Callable | None = None) -> AsyncIterator[ExtendedHeader | None]:
108+
async def subscribe(self, *, deserializer: Callable | None = None) -> AsyncIterator[ExtendedHeader | None]:
109109
""" Subscribes to recent ExtendedHeaders from the network.
110110
111111
Args:
@@ -121,7 +121,7 @@ async def subscribe(self, deserializer: Callable | None = None) -> AsyncIterator
121121
if subs_header_result is not None:
122122
yield subs_header_result
123123

124-
async def sync_state(self, deserializer: Callable | None = None) -> State:
124+
async def sync_state(self, *, deserializer: Callable | None = None) -> State:
125125
""" Returns the current state of the header Syncer.
126126
127127
Args:
@@ -143,7 +143,7 @@ async def sync_wait(self) -> None:
143143
"""
144144
return await self._rpc.call("header.SyncWait")
145145

146-
async def wait_for_height(self, height: int, deserializer: Callable | None = None) -> ExtendedHeader:
146+
async def wait_for_height(self, height: int, *, deserializer: Callable | None = None) -> ExtendedHeader:
147147
""" Blocks until the header at the given height has been processed
148148
by the store or context deadline is exceeded.
149149

celestia/node_api/p2p.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
class P2PClient(Wrapper):
88
""" Client for interacting with Celestia's P2P API."""
99

10-
async def bandwidth_for_peer(self, peer_id: str, deserializer: Callable | None = None) -> BandwidthStats:
10+
async def bandwidth_for_peer(self, peer_id: str, *, deserializer: Callable | None = None) -> BandwidthStats:
1111
""" Returns a Stats struct with bandwidth metrics associated with the given peer.ID.
1212
The metrics returned include all traffic sent / received for the peer, regardless of protocol.
1313
@@ -23,7 +23,7 @@ async def bandwidth_for_peer(self, peer_id: str, deserializer: Callable | None =
2323

2424
return await self._rpc.call("p2p.BandwidthForPeer", (peer_id,), deserializer)
2525

26-
async def bandwidth_for_protocol(self, protocol_id: str, deserializer: Callable | None = None) -> BandwidthStats:
26+
async def bandwidth_for_protocol(self, protocol_id: str, *, deserializer: Callable | None = None) -> BandwidthStats:
2727
""" Returns a Stats struct with bandwidth metrics associated with the given protocol.ID.
2828
2929
Args:
@@ -38,7 +38,7 @@ async def bandwidth_for_protocol(self, protocol_id: str, deserializer: Callable
3838

3939
return await self._rpc.call("p2p.BandwidthForProtocol", (protocol_id,), deserializer)
4040

41-
async def bandwidth_stats(self, deserializer: Callable | None = None) -> BandwidthStats:
41+
async def bandwidth_stats(self, *, deserializer: Callable | None = None) -> BandwidthStats:
4242
""" Returns a Stats struct with bandwidth metrics for all data sent/received by the local peer,
4343
regardless of protocol or remote peer IDs.
4444
@@ -88,7 +88,7 @@ async def connectedness(self, peer_id: str) -> Connectedness:
8888
"""
8989
return await self._rpc.call("p2p.Connectedness", (peer_id,))
9090

91-
async def info(self, deserializer: Callable | None = None) -> AddrInfo:
91+
async def info(self, *, deserializer: Callable | None = None) -> AddrInfo:
9292
""" Returns address information about the host.
9393
9494
Args:
@@ -130,7 +130,7 @@ async def nat_status(self) -> Reachability:
130130
"""
131131
return await self._rpc.call("p2p.NATStatus")
132132

133-
async def peer_info(self, peer_id: str, deserializer: Callable | None = None) -> AddrInfo:
133+
async def peer_info(self, peer_id: str, *, deserializer: Callable | None = None) -> AddrInfo:
134134
""" Returns a small slice of information Peerstore has on the given peer.
135135
136136
Args:
@@ -182,7 +182,7 @@ async def pub_sub_topics(self) -> list[str] | None:
182182
"""
183183
return await self._rpc.call("p2p.PubSubTopics")
184184

185-
async def resource_state(self, deserializer: Callable | None = None) -> ResourceManagerStat:
185+
async def resource_state(self, *, deserializer: Callable | None = None) -> ResourceManagerStat:
186186
""" Returns the state of the resource manager.
187187
188188
Args:

celestia/node_api/share.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Callable
22

3-
from celestia.types import Namespace, Base64
3+
from celestia.types import Namespace
44
from celestia.types.header import ExtendedHeader
55
from celestia.types.share import ExtendedDataSquare, NamespaceData, SampleCoords, GetRangeResult
66
from ._RPC import Wrapper
@@ -9,7 +9,7 @@
99
class ShareClient(Wrapper):
1010
""" Client for interacting with Celestia's Share API."""
1111

12-
async def get_eds(self, height: int, deserializer: Callable | None = None) -> ExtendedDataSquare:
12+
async def get_eds(self, height: int, *, deserializer: Callable | None = None) -> ExtendedDataSquare:
1313
""" Gets the full EDS identified by the given extended header.
1414
1515
Args:
@@ -24,7 +24,7 @@ async def get_eds(self, height: int, deserializer: Callable | None = None) -> Ex
2424

2525
return await self._rpc.call("share.GetEDS", (height,), deserializer)
2626

27-
async def get_namespace_data(self, height: int, namespace: Namespace,
27+
async def get_namespace_data(self, height: int, namespace: Namespace, *,
2828
deserializer: Callable | None = None) -> list[NamespaceData]:
2929
""" Gets all shares from an EDS within the given namespace. Shares are returned
3030
in a row-by-row order if the namespace spans multiple rows.
@@ -35,18 +35,20 @@ async def get_namespace_data(self, height: int, namespace: Namespace,
3535
deserializer (Callable | None): Custom deserializer. Defaults to None.
3636
3737
Returns:
38-
list[NamespaceData]: A list of NamespaceData objects.
38+
list[NamespaceData]: A list of NamespaceData objects or [] if not found.
3939
"""
4040

4141
def deserializer_(result):
4242
if result is not None:
4343
return [NamespaceData(**data) for data in result]
44+
else:
45+
return []
4446

4547
deserializer = deserializer if deserializer is not None else deserializer_
4648

4749
return await self._rpc.call("share.GetNamespaceData", (height, Namespace(namespace)), deserializer)
4850

49-
async def get_range(self, height: int, start: int, end: int,
51+
async def get_range(self, height: int, start: int, end: int, *,
5052
deserializer: Callable | None = None) -> GetRangeResult:
5153
""" Gets a list of shares and their corresponding proof.
5254
@@ -64,19 +66,20 @@ async def get_range(self, height: int, start: int, end: int,
6466

6567
return await self._rpc.call("share.GetRange", (height, start, end), deserializer)
6668

67-
async def get_samples(self, header: ExtendedHeader, indices: list[SampleCoords]) -> list[Base64]:
69+
async def get_samples(self, header: ExtendedHeader, indices: list[SampleCoords]) -> list[str]:
6870
""" Gets sample for given indices.
6971
7072
Args:
7173
header (ExtendedHeader): The extended header.
7274
indices (list[SampleCoords]): A list of sample coordinates.
7375
7476
Returns:
75-
list[Base64]: A list of retrieved samples.
77+
list[str]: A list of retrieved samples or [] if not found.
7678
"""
77-
return await self._rpc.call("share.GetSamples", (header, indices,))
79+
return await self._rpc.call("share.GetSamples", (header, indices,),
80+
lambda result: result if result is not None else [])
7881

79-
async def get_share(self, height: int, row: int, col: int) -> Base64:
82+
async def get_share(self, height: int, row: int, col: int) -> str:
8083
""" Gets a Share by coordinates in EDS.
8184
8285
Args:
@@ -85,7 +88,7 @@ async def get_share(self, height: int, row: int, col: int) -> Base64:
8588
col (int): The column index.
8689
8790
Returns:
88-
Base64: The retrieved share.
91+
str: The retrieved share.
8992
"""
9093
return await self._rpc.call("share.GetShare", (height, row, col,))
9194

0 commit comments

Comments
 (0)