Skip to content

Commit

Permalink
feat: add new config setting for beacon timeout
Browse files Browse the repository at this point in the history
  • Loading branch information
aimxhaisse committed Nov 21, 2023
1 parent 99c4837 commit b34425d
Show file tree
Hide file tree
Showing 18 changed files with 56 additions and 43 deletions.
2 changes: 1 addition & 1 deletion etc/config.local.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Example config file for the Ethereum watcher.

beacon_url: http://localhost:5051/
beacon_type: ~
beacon_type: other
execution_url: ~
web3signer_url: ~
default_fee_recipient: ~
Expand Down
32 changes: 15 additions & 17 deletions eth_validator_watcher/beacon.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Contains the Beacon class which is used to interact with the consensus layer node."""


import functools
from collections import defaultdict
from functools import lru_cache
Expand All @@ -26,11 +25,8 @@
ValidatorsLivenessResponse,
)

StatusEnum = Validators.DataItem.StatusEnum


# Hard-coded for now, will need to move this to a config.
TIMEOUT_BEACON_SEC = 90
StatusEnum = Validators.DataItem.StatusEnum


print = functools.partial(print, flush=True)
Expand All @@ -43,13 +39,15 @@ class NoBlockError(Exception):
class Beacon:
"""Beacon node abstraction."""

def __init__(self, url: str) -> None:
def __init__(self, url: str, timeout_sec: int) -> None:
"""Beacon
Parameters:
url: URL where the beacon can be reached
url : URL where the beacon can be reached
timeout_sec: timeout in seconds used to query the beacon
"""
self.__url = url
self.__timeout_sec = timeout_sec
self.__http_retry_not_found = Session()
self.__http = Session()
self.__first_liveness_call = True
Expand Down Expand Up @@ -114,7 +112,7 @@ def __post_retry_not_found(self, *args: Any, **kwargs: Any) -> Response:
def get_genesis(self) -> Genesis:
"""Get genesis data."""
response = self.__get_retry_not_found(
f"{self.__url}/eth/v1/beacon/genesis", timeout=TIMEOUT_BEACON_SEC
f"{self.__url}/eth/v1/beacon/genesis", timeout=self.__timeout_sec
)
response.raise_for_status()
genesis_dict = response.json()
Expand All @@ -129,7 +127,7 @@ def get_header(self, block_identifier: Union[BlockIdentierType, int]) -> Header:
"""
try:
response = self.__get(
f"{self.__url}/eth/v1/beacon/headers/{block_identifier}", timeout=TIMEOUT_BEACON_SEC
f"{self.__url}/eth/v1/beacon/headers/{block_identifier}", timeout=self.__timeout_sec
)

response.raise_for_status()
Expand All @@ -153,7 +151,7 @@ def get_block(self, slot: int) -> Block:
"""
try:
response = self.__get(
f"{self.__url}/eth/v2/beacon/blocks/{slot}", timeout=TIMEOUT_BEACON_SEC
f"{self.__url}/eth/v2/beacon/blocks/{slot}", timeout=self.__timeout_sec
)

response.raise_for_status()
Expand All @@ -176,7 +174,7 @@ def get_proposer_duties(self, epoch: int) -> ProposerDuties:
epoch: Epoch corresponding to the proposer duties to retrieve
"""
response = self.__get_retry_not_found(
f"{self.__url}/eth/v1/validator/duties/proposer/{epoch}", timeout=TIMEOUT_BEACON_SEC
f"{self.__url}/eth/v1/validator/duties/proposer/{epoch}", timeout=self.__timeout_sec
)

response.raise_for_status()
Expand All @@ -193,7 +191,7 @@ def get_status_to_index_to_validator(
inner value : Validator
"""
response = self.__get_retry_not_found(
f"{self.__url}/eth/v1/beacon/states/head/validators", timeout=TIMEOUT_BEACON_SEC
f"{self.__url}/eth/v1/beacon/states/head/validators", timeout=self.__timeout_sec
)

response.raise_for_status()
Expand Down Expand Up @@ -226,7 +224,7 @@ def get_duty_slot_to_committee_index_to_validators_index(
response = self.__get_retry_not_found(
f"{self.__url}/eth/v1/beacon/states/head/committees",
params=dict(epoch=epoch),
timeout=TIMEOUT_BEACON_SEC,
timeout=self.__timeout_sec,
)

response.raise_for_status()
Expand Down Expand Up @@ -289,7 +287,7 @@ def get_rewards(
if validators_index is not None
else []
),
timeout=TIMEOUT_BEACON_SEC,
timeout=self.__timeout_sec,
)

response.raise_for_status()
Expand Down Expand Up @@ -390,7 +388,7 @@ def __get_validators_liveness_lighthouse(
json=ValidatorsLivenessRequestLighthouse(
epoch=epoch, indices=sorted(list(validators_index))
).model_dump(),
timeout=TIMEOUT_BEACON_SEC,
timeout=self.__timeout_sec,
)

def __get_validators_liveness_old_teku(
Expand All @@ -410,7 +408,7 @@ def __get_validators_liveness_old_teku(
json=ValidatorsLivenessRequestTeku(
indices=sorted(list(validators_index))
).model_dump(),
timeout=TIMEOUT_BEACON_SEC,
timeout=self.__timeout_sec,
)

def __get_validators_liveness_beacon_api(
Expand All @@ -431,5 +429,5 @@ def __get_validators_liveness_beacon_api(
str(validator_index)
for validator_index in sorted(list(validators_index))
],
timeout=TIMEOUT_BEACON_SEC,
timeout=self.__timeout_sec,
)
1 change: 1 addition & 0 deletions eth_validator_watcher/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class Config(BaseSettings):

beacon_url: Optional[str] = None
beacon_type: BeaconType = BeaconType.OTHER
beacon_timeout_sec: int = 90
execution_url: Optional[str] = None
web3signer_url: Optional[str] = None
default_fee_recipient: Optional[str] = None
Expand Down
4 changes: 3 additions & 1 deletion eth_validator_watcher/entrypoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ def handler(
try: # pragma: no cover
_handler(
cfg.beacon_url,
cfg.beacon_timeout_sec,
cfg.execution_url,
cfg.watched_keys,
cfg.web3signer_url,
Expand All @@ -161,6 +162,7 @@ def handler(

def _handler(
beacon_url: str,
beacon_timeout_sec: int,
execution_url: str | None,
watched_keys: List[WatchedKeyConfig] | None,
web3signer_url: str | None,
Expand Down Expand Up @@ -195,7 +197,7 @@ def _handler(
else None
)

beacon = Beacon(beacon_url)
beacon = Beacon(beacon_url, beacon_timeout_sec)
execution = Execution(execution_url) if execution_url is not None else None
coinbase = Coinbase()
web3signer = Web3Signer(web3signer_url) if web3signer_url is not None else None
Expand Down
2 changes: 1 addition & 1 deletion eth_validator_watcher/execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@


class Execution:
"""Beacon node abstraction."""
"""Execution node abstraction."""

def __init__(self, url: str) -> None:
"""Execution node
Expand Down
6 changes: 3 additions & 3 deletions tests/beacon/test_get_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def test_get_block_exists() -> None:
with block_path.open() as file_descriptor:
block_dict = json.load(file_descriptor)

beacon = Beacon("http://beacon-node:5052")
beacon = Beacon("http://beacon-node:5052", 90)

with Mocker() as mock:
mock.get(
Expand All @@ -33,7 +33,7 @@ def get(url: str, **_) -> Response:

raise HTTPError(response=response)

beacon = Beacon("http://beacon-node:5052")
beacon = Beacon("http://beacon-node:5052", 90)
beacon._Beacon__http.get = get # type: ignore

with raises(NoBlockError):
Expand All @@ -48,7 +48,7 @@ def get(url: str, **_) -> Response:

raise HTTPError(response=response)

beacon = Beacon("http://beacon-node:5052")
beacon = Beacon("http://beacon-node:5052", 90)
beacon._Beacon__http.get = get # type: ignore

with raises(exceptions.RequestException):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def test_get_duty_slot_to_committee_index_to_validators_index():
json=committees,
)

beacon = Beacon(beacon_url)
beacon = Beacon(beacon_url, 90)

assert (
beacon.get_duty_slot_to_committee_index_to_validators_index(epoch)
Expand Down
2 changes: 1 addition & 1 deletion tests/beacon/test_get_genesis.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ def test_get_genesis():
f"{beacon_url}/eth/v1/beacon/genesis",
json=genesis,
)
beacon = Beacon(beacon_url)
beacon = Beacon(beacon_url, 90)

assert beacon.get_genesis() == expected
6 changes: 3 additions & 3 deletions tests/beacon/test_get_header.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def test_get_header_exists() -> None:
with block_path.open() as file_descriptor:
header_dict = json.load(file_descriptor)

beacon = Beacon("http://beacon-node:5052")
beacon = Beacon("http://beacon-node:5052", 90)

for identifier, value in {
"head": BlockIdentierType.HEAD,
Expand All @@ -42,7 +42,7 @@ def get(url: str, **_) -> Response:

raise HTTPError(response=response)

beacon = Beacon("http://beacon-node:5052")
beacon = Beacon("http://beacon-node:5052", 90)
beacon._Beacon__http.get = get # type: ignore

with raises(NoBlockError):
Expand All @@ -57,7 +57,7 @@ def get(url: str, **_) -> Response:

raise HTTPError(response=response)

beacon = Beacon("http://beacon-node:5052")
beacon = Beacon("http://beacon-node:5052", 90)
beacon._Beacon__http.get = get # type: ignore

with raises(exceptions.RequestException):
Expand Down
2 changes: 1 addition & 1 deletion tests/beacon/test_get_proposer_duties.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,6 @@ def test_():
f"{beacon_url}/eth/v1/validator/duties/proposer/6542", json=proposer_duties
)

beacon = Beacon(beacon_url)
beacon = Beacon(beacon_url, 90)

assert beacon.get_proposer_duties(6542) == expected
4 changes: 2 additions & 2 deletions tests/beacon/test_get_rewards.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@


def test_get_rewards_not_supported() -> None:
beacon = Beacon("http://beacon-node:5052")
beacon = Beacon("http://beacon-node:5052", 90)

expected = Rewards(data=Rewards.Data(ideal_rewards=[], total_rewards=[]))

Expand All @@ -26,7 +26,7 @@ def test_get_rewards() -> None:
with rewards_path.open() as file_descriptor:
rewards_dict = json.load(file_descriptor)

beacon = Beacon("http://beacon-node:5052")
beacon = Beacon("http://beacon-node:5052", 90)

def match_request(request) -> bool:
return request.json() == ["8499", "8500"]
Expand Down
2 changes: 1 addition & 1 deletion tests/beacon/test_get_status_to_index_to_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def test_get_status_to_index_to_validator() -> None:
with asset_path.open() as file_descriptor:
validators = json.load(file_descriptor)

beacon = Beacon("http://localhost:5052")
beacon = Beacon("http://localhost:5052", 90)
expected = {
StatusEnum.activeOngoing: {
0: Validator(
Expand Down
12 changes: 6 additions & 6 deletions tests/beacon/test_get_validators_liveness.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def match_request(request) -> bool:
additional_matcher=match_request,
json=liveness_response,
)
beacon = Beacon(beacon_url)
beacon = Beacon(beacon_url, 90)
expected = {42: True, 44: False, 46: True}

assert (
Expand All @@ -48,7 +48,7 @@ def match_request(request) -> bool:

def test_get_validators_liveness_nimbus():
beacon_url = "http://beacon:5052"
beacon = Beacon(beacon_url)
beacon = Beacon(beacon_url, 90)

assert beacon.get_validators_liveness(
beacon_type=BeaconType.NIMBUS, epoch=1664, validators_index={42, 44, 46}
Expand Down Expand Up @@ -76,7 +76,7 @@ def match_request(request) -> bool:
additional_matcher=match_request,
json=liveness_response,
)
beacon = Beacon(beacon_url)
beacon = Beacon(beacon_url, 90)
expected = {42: True, 44: False, 46: True}

assert (
Expand Down Expand Up @@ -113,7 +113,7 @@ def match_request(request) -> bool:
additional_matcher=match_request,
json=liveness_response,
)
beacon = Beacon(beacon_url)
beacon = Beacon(beacon_url, 90)
expected = {42: True, 44: False, 46: True}

assert (
Expand All @@ -134,7 +134,7 @@ def post(url: str, **_) -> Response:

return response

beacon = Beacon(beacon_url)
beacon = Beacon(beacon_url, 90)
beacon._Beacon__http_retry_not_found.post = post # type: ignore

expected = {42: True, 44: True, 46: True}
Expand All @@ -154,7 +154,7 @@ def post(url: str, **_) -> Response:

return response

beacon = Beacon(beacon_url)
beacon = Beacon(beacon_url, 90)
beacon._Beacon__http_retry_not_found.post = post # type: ignore

with raises(HTTPError):
Expand Down
4 changes: 2 additions & 2 deletions tests/beacon/test_potential_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def get_block(slot: int) -> Block:
assert slot == 42
return "a fake block" # type: ignore

beacon = Beacon("http://beacon-node:5052")
beacon = Beacon("http://beacon-node:5052", 90)
beacon.get_block = get_block # type: ignore

assert beacon.get_potential_block(42) == "a fake block"
Expand All @@ -18,7 +18,7 @@ def get_block(slot: int) -> Block:
assert slot == 42
raise NoBlockError

beacon = Beacon("http://beacon-node:5052")
beacon = Beacon("http://beacon-node:5052", 90)
beacon.get_block = get_block # type: ignore

assert beacon.get_potential_block(42) is None
1 change: 0 additions & 1 deletion tests/config/assets/config.null.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
beacon_url: ~
beacon_type: other
execution_url: ~
web3signer_url: ~
default_fee_recipient: ~
Expand Down
1 change: 1 addition & 0 deletions tests/config/assets/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

beacon_url: http://localhost:5051/
beacon_type: other
beacon_timeout_sec: 90
execution_url: http://localhost:8545/
web3signer_url: http://web3signer:9000/
default_fee_recipient: '0x41bF25fC8C52d292bD66D3BCEcd8a919ecB9EF88'
Expand Down
Loading

0 comments on commit b34425d

Please sign in to comment.