Skip to content

Commit

Permalink
Add logging for submit_exit_signatures error (#211)
Browse files Browse the repository at this point in the history
  • Loading branch information
evgeny-stakewise authored Oct 24, 2023
1 parent c2c013c commit 6cecf70
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 46 deletions.
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

0 comments on commit 6cecf70

Please sign in to comment.