From e80e60606d1b6cfac6dfce986222fd4bdc9bc8a8 Mon Sep 17 00:00:00 2001 From: Michal Baranowski Date: Tue, 20 May 2025 18:08:48 +0700 Subject: [PATCH] feat: support new pectra endpoitns --- tests/test_async_beacon.py | 32 ++++++++++++++++++++++++++++++++ web3_utils/async_beacon.py | 21 +++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/tests/test_async_beacon.py b/tests/test_async_beacon.py index 5f8376e..75d5f7f 100644 --- a/tests/test_async_beacon.py +++ b/tests/test_async_beacon.py @@ -129,3 +129,35 @@ async def test_get_validator_balances(mocker: MockerFixture): mocked_fn.assert_called_with( f"http://127.0.0.1:8545/eth/v1/beacon/states/{state_id}/validator_balances", timeout=10.0, params={"id": ["0", "1"]} ) + + +@pytest.mark.asyncio() +async def test_get_pending_consolidations(mocker: MockerFixture): + response_json = {"data": ["consolidation1", "consolidation2"]} + mocked_response = mocker.patch("web3_utils.async_beacon.AsyncBeacon._get_pending_consolidations", return_value=response_json) + async_beacon = AsyncBeacon("http://127.0.0.1:8545", logger=logging.getLogger(), retry_stop=None) + response = await async_beacon.get_pending_consolidations() + assert response == response_json + mocked_response.assert_called_once_with("head") + + +@pytest.mark.asyncio() +async def test_get_pending_deposits(mocker: MockerFixture): + response_json = {"data": ["deposit1", "deposit2"]} + mocked_response = mocker.patch("web3_utils.async_beacon.AsyncBeacon._get_pending_deposits", return_value=response_json) + async_beacon = AsyncBeacon("http://127.0.0.1:8545", logger=logging.getLogger(), retry_stop=None) + response = await async_beacon.get_pending_deposits() + assert response == response_json + mocked_response.assert_called_once_with("head") + + +@pytest.mark.asyncio() +async def test_get_pending_partial_withdrawals(mocker: MockerFixture): + response_json = {"data": ["withdrawal1", "withdrawal2"]} + mocked_response = mocker.patch( + "web3_utils.async_beacon.AsyncBeacon._get_pending_partial_withdrawals", return_value=response_json + ) + async_beacon = AsyncBeacon("http://127.0.0.1:8545", logger=logging.getLogger(), retry_stop=None) + response = await async_beacon.get_pending_partial_withdrawals() + assert response == response_json + mocked_response.assert_called_once_with("head") diff --git a/web3_utils/async_beacon.py b/web3_utils/async_beacon.py index 3344eac..4885998 100644 --- a/web3_utils/async_beacon.py +++ b/web3_utils/async_beacon.py @@ -59,6 +59,15 @@ async def get_validators(self, state_id: str = "head", ids: List[str] = None, st async def get_validator_balances(self, state_id: str = "head", indexes: List[str] = None) -> Dict[str, Any]: return await self._run_as_async(self._get_validator_balances, state_id, indexes) + async def get_pending_consolidations(self, state_id: str = "head"): + return await self._run_as_async(self._get_pending_consolidations, state_id) + + async def get_pending_deposits(self, state_id: str = "head"): + return await self._run_as_async(self._get_pending_deposits, state_id) + + async def get_pending_partial_withdrawals(self, state_id: str = "head"): + return await self._run_as_async(self._get_pending_partial_withdrawals, state_id) + def _get_validator(self, pubkey: str, state_id: str = "head"): try: return super().get_validator(pubkey, state_id) @@ -86,6 +95,18 @@ def _get_validator_balances(self, state_id: str = "head", indexes: List[str] = N return self._make_get_request_with_params(endpoint, params) + def _get_pending_consolidations(self, state_id: str = "head"): + endpoint = f"/eth/v1/beacon/states/{state_id}/pending_consolidations" + return self._make_get_request_with_params(endpoint, params=None) + + def _get_pending_deposits(self, state_id: str = "head"): + endpoint = f"/eth/v1/beacon/states/{state_id}/pending_deposits" + return self._make_get_request_with_params(endpoint, params=None) + + def _get_pending_partial_withdrawals(self, state_id: str = "head"): + endpoint = f"/eth/v1/beacon/states/{state_id}/pending_partial_withdrawals" + return self._make_get_request_with_params(endpoint, params=None) + def _make_get_request_with_params(self, endpoint: str, params: Any) -> Dict[str, Any]: uri = URI(self.base_url + endpoint) return json_make_get_request(uri, timeout=self.request_timeout, params=params)