diff --git a/src/allora_sdk/worker/reputer.py b/src/allora_sdk/worker/reputer.py index e4472ad..51c8fb0 100644 --- a/src/allora_sdk/worker/reputer.py +++ b/src/allora_sdk/worker/reputer.py @@ -10,9 +10,9 @@ CanSubmitReputerPayloadRequest, EventReputerSubmissionWindowOpened, GetNetworkInferencesAtBlockRequest, + GetOpenReputerSubmissionWindowsRequest, GetStakeFromReputerInTopicInSelfRequest, GetTopicRequest, - GetUnfulfilledReputerNoncesRequest, IsReputerRegisteredInTopicIdRequest, NetworkInferenceBundle, LabeledValue, @@ -118,12 +118,14 @@ async def worker_is_whitelisted(self) -> bool: async def get_unfulfilled_nonces(self) -> set[int]: - # GetUnfulfilledReputerNonces gives all epochs in flight, which is not what we want here - # GetOpenReputerSubmissionWindows would be the more appropriate RPC call, but - # it doesn't seem to be implemented in the rpc client - # Returning [] here means we only react to EventReputerSubmissionWindowOpened - return set() + # So we use GetOpenReputerSubmissionWindows instead + resp = await self.client.emissions.query.get_open_reputer_submission_windows( + GetOpenReputerSubmissionWindowsRequest(topic_id=self.topic_id) + ) + if resp.nonces is None: + return set[int]() + return {x.reputer_nonce.block_height for x in resp.nonces.nonces} async def submit(self, nonce: int, account_seq: int) -> WorkerResult[InputValueBundle] | TxError | Exception: diff --git a/src/allora_sdk/worker/worker.py b/src/allora_sdk/worker/worker.py index 972401d..a64d83b 100644 --- a/src/allora_sdk/worker/worker.py +++ b/src/allora_sdk/worker/worker.py @@ -745,7 +745,12 @@ async def _maybe_submit_impl(self, ctx: Context, nonce: Optional[int] = None): self.stop() return - nonces = await self.use_case.get_unfulfilled_nonces() + # catch errors so that `nonce` is still processed if query fails + try: + nonces = await self.use_case.get_unfulfilled_nonces() + except Exception as err: + logger.warning(f" Failed querying unfulfilled nonces for topic {self.topic_id}: {err}") + nonces = set() new_nonces = { n for n in nonces if n not in self.submitted_nonces } if nonce is not None and nonce not in self.submitted_nonces: diff --git a/tests/test_reputer_submit.py b/tests/test_reputer_submit.py index 1d74b6d..c9c19ce 100644 --- a/tests/test_reputer_submit.py +++ b/tests/test_reputer_submit.py @@ -97,9 +97,9 @@ async def test_submit_returns_error_when_network_inferences_missing() -> None: @pytest.mark.asyncio -async def test_get_unfulfilled_nonces_uses_reputer_request_nonces() -> None: +async def test_get_unfulfilled_nonces_uses_open_submission_windows() -> None: client = _make_client() - client.emissions.query.get_unfulfilled_reputer_nonces = AsyncMock( + client.emissions.query.get_open_reputer_submission_windows = AsyncMock( return_value=Mock( nonces=Mock( nonces=[ @@ -112,4 +112,16 @@ async def test_get_unfulfilled_nonces_uses_reputer_request_nonces() -> None: reputer = _make_reputer(client) + assert await reputer.get_unfulfilled_nonces() == {101, 202} + + +@pytest.mark.asyncio +async def test_get_unfulfilled_nonces_empty_when_no_windows_open() -> None: + client = _make_client() + client.emissions.query.get_open_reputer_submission_windows = AsyncMock( + return_value=Mock(nonces=None) + ) + + reputer = _make_reputer(client) + assert await reputer.get_unfulfilled_nonces() == set()