Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add logging for submit_exit_signatures error #211

Merged
merged 1 commit into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ exclude_dirs = ["*/tests/*", "src/config/networks.py", "conftest.py"]
skips = ["B608"]

[tool.pylint."pre-commit-hook"]
disable = ["C0103", "C0114", "C0115", "C0116", "W0511", "W0703"]
disable = ["C0103", "C0114", "C0115", "C0116", "W0511", "W0703", "R0801"]
ignore-paths=["src/.*/tests/.*", "src/test_fixtures/.*"]
ignore=["conftest.py"]

Expand Down
5 changes: 5 additions & 0 deletions src/common/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import tenacity
from eth_typing import BlockNumber, ChecksumAddress
from web3 import Web3
from web3.exceptions import Web3Exception
from web3.types import Timestamp, Wei

from src.common.clients import consensus_client
Expand Down Expand Up @@ -59,6 +60,10 @@ def format_error(e: Exception) -> str:
# str(e) returns empty string
return repr(e)

if isinstance(e, Web3Exception):
# str(e) gives hex output. Not user-friendly.
return e.__class__.__name__

return str(e)


Expand Down
23 changes: 16 additions & 7 deletions src/exits/execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from src.common.clients import execution_client
from src.common.contracts import keeper_contract
from src.common.typings import OraclesApproval
from src.common.utils import format_error
from src.config.networks import ETH_NETWORKS
from src.config.settings import settings

Expand All @@ -14,18 +15,26 @@

async def submit_exit_signatures(
approval: OraclesApproval,
) -> HexStr:
) -> HexStr | None:
"""Sends updateExitSignatures transaction to keeper contract"""
if settings.network not in ETH_NETWORKS:
raise NotImplementedError('networks other than Ethereum not supported')

logger.info('Submitting UpdateExitSignatures transaction')
tx = await keeper_contract.functions.updateExitSignatures(
settings.vault,
approval.deadline,
approval.ipfs_hash,
approval.signatures,
).transact()
try:
tx = await keeper_contract.functions.updateExitSignatures(
settings.vault,
approval.deadline,
approval.ipfs_hash,
approval.signatures,
).transact()
except Exception as e:
logger.error('Failed to update exit signatures: %s', format_error(e))

if settings.verbose:
logger.exception(e)
return None

logger.info('Waiting for transaction %s confirmation', Web3.to_hex(tx))
await execution_client.eth.wait_for_transaction_receipt(tx, timeout=300)
return Web3.to_hex(tx)
3 changes: 3 additions & 0 deletions src/exits/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ async def _update_exit_signatures(
log_verbose(e)

tx_hash = await submit_exit_signatures(oracles_approval)
if not tx_hash:
return

logger.info(
'Successfully rotated exit signatures for validators with indexes %s, tx hash: %s',
', '.join([str(index) for index in outdated_indexes]),
Expand Down
31 changes: 21 additions & 10 deletions src/harvest/execution.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,39 @@
import logging

from eth_typing import HexStr
from web3 import Web3

from src.common.clients import execution_client
from src.common.contracts import vault_contract
from src.common.typings import HarvestParams
from src.common.utils import format_error
from src.config.networks import ETH_NETWORKS
from src.config.settings import settings

logger = logging.getLogger(__name__)


async def submit_harvest_transaction(harvest_params: HarvestParams) -> None:
async def submit_harvest_transaction(harvest_params: HarvestParams) -> HexStr | None:
if settings.network not in ETH_NETWORKS:
raise NotImplementedError('networks other than Ethereum not supported')

logger.info('Submitting harvest transaction...')
tx = await vault_contract.functions.updateState(
(
harvest_params.rewards_root,
harvest_params.reward,
harvest_params.unlocked_mev_reward,
harvest_params.proof,
)
).transact()
logger.info('Waiting for transaction %s confirmation', Web3.to_hex(tx))
try:
tx = await vault_contract.functions.updateState(
(
harvest_params.rewards_root,
harvest_params.reward,
harvest_params.unlocked_mev_reward,
harvest_params.proof,
)
).transact()
except Exception as e:
logger.error('Failed to harvest: %s', format_error(e))
if settings.verbose:
logger.exception(e)
return None

tx_hash = Web3.to_hex(tx)
logger.info('Waiting for transaction %s confirmation', tx_hash)
await execution_client.eth.wait_for_transaction_receipt(tx, timeout=300)
return tx_hash
4 changes: 3 additions & 1 deletion src/harvest/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,7 @@ async def harvest_vault() -> None:
return

logger.info('Starting vault harvest')
await submit_harvest_transaction(harvest_params)
tx_hash = await submit_harvest_transaction(harvest_params)
if not tx_hash:
return
logger.info('Successfully harvested vault')
65 changes: 43 additions & 22 deletions src/validators/execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from src.common.ipfs import fetch_harvest_params
from src.common.metrics import metrics
from src.common.typings import OraclesApproval
from src.common.utils import format_error
from src.config.networks import ETH_NETWORKS
from src.config.settings import DEPOSIT_AMOUNT, settings
from src.validators.database import NetworkValidatorCrud
Expand Down Expand Up @@ -253,7 +254,7 @@ async def register_single_validator(
tx_validators: list[bytes],
update_state_call: HexStr | None,
validators_registry_root: Bytes32,
) -> None:
) -> HexStr | None:
"""Registers single validator."""
if settings.network not in ETH_NETWORKS:
raise NotImplementedError('networks other than Ethereum not supported')
Expand All @@ -269,17 +270,27 @@ async def register_single_validator(
),
multi_proof.proof,
]
if update_state_call is not None:
register_call = vault_contract.encode_abi(
fn_name='registerValidator',
args=register_call_args,
)
tx = await vault_contract.functions.multicall([update_state_call, register_call]).transact()
else:
tx = await vault_contract.functions.registerValidator(*register_call_args).transact()

logger.info('Waiting for transaction %s confirmation', Web3.to_hex(tx))
try:
if update_state_call is not None:
register_call = vault_contract.encode_abi(
fn_name='registerValidator',
args=register_call_args,
)
tx = await vault_contract.functions.multicall(
[update_state_call, register_call]
).transact()
else:
tx = await vault_contract.functions.registerValidator(*register_call_args).transact()
except Exception as e:
logger.error('Failed to register validator: %s', format_error(e))
if settings.verbose:
logger.exception(e)
return None

tx_hash = Web3.to_hex(tx)
logger.info('Waiting for transaction %s confirmation', tx_hash)
await execution_client.eth.wait_for_transaction_receipt(tx, timeout=300)
return tx_hash


async def register_multiple_validator(
Expand All @@ -288,7 +299,7 @@ async def register_multiple_validator(
approval: OraclesApproval,
update_state_call: HexStr | None,
validators_registry_root: Bytes32,
) -> None:
) -> HexStr | None:
"""Registers multiple validators."""
if settings.network not in ETH_NETWORKS:
raise NotImplementedError('networks other than Ethereum not supported')
Expand All @@ -309,14 +320,24 @@ async def register_multiple_validator(
multi_proof.proof_flags,
multi_proof.proof,
]
if update_state_call is not None:
register_call = vault_contract.encode_abi(
fn_name='registerValidators',
args=register_call_args,
)
tx = await vault_contract.functions.multicall([update_state_call, register_call]).transact()
else:
tx = await vault_contract.functions.registerValidators(*register_call_args).transact()

logger.info('Waiting for transaction %s confirmation', Web3.to_hex(tx))
try:
if update_state_call is not None:
register_call = vault_contract.encode_abi(
fn_name='registerValidators',
args=register_call_args,
)
tx = await vault_contract.functions.multicall(
[update_state_call, register_call]
).transact()
else:
tx = await vault_contract.functions.registerValidators(*register_call_args).transact()
except Exception as e:
logger.error('Failed to register validators: %s', format_error(e))
if settings.verbose:
logger.exception(e)
return None

tx_hash = Web3.to_hex(tx)
logger.info('Waiting for transaction %s confirmation', tx_hash)
await execution_client.eth.wait_for_transaction_receipt(tx, timeout=300)
return tx_hash
14 changes: 9 additions & 5 deletions src/validators/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,25 +134,29 @@ async def register_validators(

if len(validators) == 1:
validator = validators[0]
await register_single_validator(
tx_hash = await register_single_validator(
approval=oracles_approval,
multi_proof=multi_proof,
tx_validators=tx_validators,
update_state_call=update_state_call,
validators_registry_root=registry_root,
)
logger.info('Successfully registered validator with public key %s', validator.public_key)
if tx_hash:
logger.info(
'Successfully registered validator with public key %s', validator.public_key
)

if len(validators) > 1:
await register_multiple_validator(
tx_hash = await register_multiple_validator(
approval=oracles_approval,
multi_proof=multi_proof,
tx_validators=tx_validators,
update_state_call=update_state_call,
validators_registry_root=registry_root,
)
pub_keys = ', '.join([val.public_key for val in validators])
logger.info('Successfully registered validators with public keys %s', pub_keys)
if tx_hash:
pub_keys = ', '.join([val.public_key for val in validators])
logger.info('Successfully registered validators with public keys %s', pub_keys)


# pylint: disable-next=too-many-arguments
Expand Down