Skip to content

Commit

Permalink
Testnet 3 (#168)
Browse files Browse the repository at this point in the history
* Add deadline for exit-sig-update (#144)

* Add deadline for exit-sig-update

* Upd IKeeper.json

* Add settings.exit_signature_deadline

* Fix utcnow

---------

Signed-off-by: cyc60 <[email protected]>
Co-authored-by: cyc60 <[email protected]>

* Update abis, contracts for goerli

* Move exit_signature_deadline to oracles config (#154)

Signed-off-by: cyc60 <[email protected]>

* Add validator registration deadline (#156)

* Add validator registration deadline

* Use signature_validity_period for validators deadline

* Review fix

* Add block number check (#160)

* Fix ApprovalRequest json (#162)

* Fix contract calls (#165)

* Replace timestamp with int for deadline

* Review fixes

---------

Signed-off-by: cyc60 <[email protected]>
Co-authored-by: Evgeny Gusarov <[email protected]>
Co-authored-by: Dmitri Tsumak <[email protected]>
  • Loading branch information
3 people authored Sep 18, 2023
1 parent d86f9d6 commit 3bc2d12
Show file tree
Hide file tree
Showing 17 changed files with 176 additions and 60 deletions.
92 changes: 83 additions & 9 deletions src/common/abi/IEthVault.json
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,31 @@
"name": "FeeRecipientUpdated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "receiver",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "shares",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "assets",
"type": "uint256"
}
],
"name": "FeeSharesMinted",
"type": "event"
},
{
"anonymous": false,
"inputs": [
Expand Down Expand Up @@ -425,13 +450,39 @@
"type": "function"
},
{
"inputs": [],
"name": "canUpdateExitQueue",
"inputs": [
{
"internalType": "address",
"name": "receiver",
"type": "address"
},
{
"internalType": "uint256",
"name": "positionTicket",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "exitQueueIndex",
"type": "uint256"
}
],
"name": "calculateExitedAssets",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
"internalType": "uint256",
"name": "leftShares",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "claimedShares",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "claimedAssets",
"type": "uint256"
}
],
"stateMutability": "view",
Expand Down Expand Up @@ -641,6 +692,19 @@
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "isStateUpdateRequired",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "keysManager",
Expand Down Expand Up @@ -705,7 +769,7 @@
},
{
"internalType": "uint256",
"name": "assets",
"name": "osTokenShares",
"type": "uint256"
},
{
Expand All @@ -718,7 +782,7 @@
"outputs": [
{
"internalType": "uint256",
"name": "shares",
"name": "assets",
"type": "uint256"
}
],
Expand Down Expand Up @@ -781,9 +845,9 @@
"name": "queuedShares",
"outputs": [
{
"internalType": "uint96",
"internalType": "uint128",
"name": "",
"type": "uint96"
"type": "uint128"
}
],
"stateMutability": "view",
Expand Down Expand Up @@ -858,6 +922,11 @@
"name": "validatorsRegistryRoot",
"type": "bytes32"
},
{
"internalType": "uint256",
"name": "deadline",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "validators",
Expand Down Expand Up @@ -898,6 +967,11 @@
"name": "validatorsRegistryRoot",
"type": "bytes32"
},
{
"internalType": "uint256",
"name": "deadline",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "validators",
Expand Down
16 changes: 10 additions & 6 deletions src/common/abi/IKeeper.json
Original file line number Diff line number Diff line change
Expand Up @@ -182,12 +182,6 @@
"internalType": "string",
"name": "exitSignaturesIpfsHash",
"type": "string"
},
{
"indexed": false,
"internalType": "uint256",
"name": "updateTimestamp",
"type": "uint256"
}
],
"name": "ValidatorsApproval",
Expand Down Expand Up @@ -228,6 +222,11 @@
"name": "validatorsRegistryRoot",
"type": "bytes32"
},
{
"internalType": "uint256",
"name": "deadline",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "validators",
Expand Down Expand Up @@ -649,6 +648,11 @@
"name": "vault",
"type": "address"
},
{
"internalType": "uint256",
"name": "deadline",
"type": "uint256"
},
{
"internalType": "string",
"name": "exitSignaturesIpfsHash",
Expand Down
4 changes: 4 additions & 0 deletions src/common/contracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import os
from functools import cached_property

from eth_typing import HexStr
from sw_utils.typings import Bytes32
from web3.contract import AsyncContract
from web3.contract.contract import ContractEvent
Expand Down Expand Up @@ -31,6 +32,9 @@ def contract(self) -> AsyncContract:
abi = json.load(f)
return execution_client.eth.contract(abi=abi, address=self.contract_address)

def encode_abi(self, fn_name: str, args: list | None = None) -> HexStr:
return self.contract.encodeABI(fn_name=fn_name, args=args)

def __getattr__(self, item):
return getattr(self.contract, item)

Expand Down
6 changes: 6 additions & 0 deletions src/common/execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ async def get_oracles() -> Oracles:
if exit_signature_recover_threshold > validators_threshold:
raise ValueError('Invalid exit signature threshold')

signature_validity_period = config['signature_validity_period']

if signature_validity_period < 0:
raise ValueError('Invalid signature validity period')

if len(public_keys) != len(set(public_keys)):
raise ValueError('Duplicate public keys in oracles config')

Expand All @@ -82,6 +87,7 @@ async def get_oracles() -> Oracles:
rewards_threshold=rewards_threshold,
validators_threshold=validators_threshold,
exit_signature_recover_threshold=exit_signature_recover_threshold,
signature_validity_period=signature_validity_period,
public_keys=public_keys,
endpoints=endpoints,
validators_approval_batch_limit=validators_approval_batch_limit,
Expand Down
10 changes: 9 additions & 1 deletion src/common/startup_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ async def wait_for_execution_node() -> None:
)
continue
block_number = await execution_client.eth.block_number
if block_number <= 0:
# There was a case when `block_number` equals to 0 although `syncing` is False.
logger.warning(
'Execution node %s. Current block number is %s',
execution_endpoint,
block_number,
)
continue
logger.info(
'Connected to execution node at %s. Current block number: %s',
execution_endpoint,
Expand All @@ -90,7 +98,7 @@ async def wait_for_execution_node() -> None:
)
if done:
return
logger.warning('Failed to connect to consensus nodes. Retrying in 10 seconds...')
logger.warning('Failed to connect to execution nodes. Retrying in 10 seconds...')
await asyncio.sleep(10)


Expand Down
9 changes: 9 additions & 0 deletions src/common/typings.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@


@dataclass
# pylint: disable-next=too-many-instance-attributes
class Oracles:
rewards_threshold: int
validators_threshold: int
exit_signature_recover_threshold: int
signature_validity_period: int
public_keys: list[HexStr]
endpoints: list[list[str]]

Expand Down Expand Up @@ -45,3 +47,10 @@ class HarvestParams:
class OracleApproval:
signature: bytes
ipfs_hash: str


@dataclass
class OraclesApproval:
signatures: bytes
ipfs_hash: str
deadline: int
7 changes: 6 additions & 1 deletion src/common/utils.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import asyncio
import logging
import time
from datetime import datetime, timezone
from pathlib import Path

from eth_typing import BlockNumber
from web3 import Web3
from web3.types import Wei
from web3.types import Timestamp, Wei

from src.common.clients import consensus_client, execution_client
from src.config.settings import settings
Expand Down Expand Up @@ -50,3 +51,7 @@ async def wait_block_finalization(block_number: BlockNumber | None = None):

elapsed = time.time() - start
sleep_time = float(settings.network_config.SECONDS_PER_BLOCK) - elapsed


def get_current_timestamp() -> Timestamp:
return Timestamp(int(datetime.now(timezone.utc).timestamp()))
4 changes: 2 additions & 2 deletions src/config/networks.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ class NetworkConfig:
),
VALIDATORS_REGISTRY_GENESIS_BLOCK=BlockNumber(4367321),
KEEPER_CONTRACT_ADDRESS=Web3.to_checksum_address(
'0xb39CEBd50642389ceE6C058C2134e53417ce053a'
'0x893ceb1cF23475defE3747670EbE4b40e629c6fD'
),
KEEPER_GENESIS_BLOCK=BlockNumber(9290253),
KEEPER_GENESIS_BLOCK=BlockNumber(9583358),
GENESIS_VALIDATORS_ROOT=Bytes32(
Web3.to_bytes(
hexstr=HexStr('0x043db0d9a83813551ee2f33450d23797757d430911a9320530ad8a0eabc43efb')
Expand Down
2 changes: 1 addition & 1 deletion src/config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

DATA_DIR = Path.home() / '.stakewise'

DEFAULT_MAX_FEE_PER_GAS_GWEI = 70
DEFAULT_MAX_FEE_PER_GAS_GWEI = 100
DEFAULT_METRICS_HOST = '127.0.0.1'
DEFAULT_METRICS_PORT = 9100

Expand Down
1 change: 1 addition & 0 deletions src/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ def mocked_oracles(
],
validators_approval_batch_limit=1,
validators_exit_rotation_batch_limit=1,
signature_validity_period=60,
)


Expand Down
3 changes: 2 additions & 1 deletion src/exits/execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

from src.common.clients import execution_client
from src.common.contracts import keeper_contract
from src.common.typings import OraclesApproval
from src.config.networks import ETH_NETWORKS
from src.config.settings import settings
from src.exits.typings import OraclesApproval

logger = logging.getLogger(__name__)

Expand All @@ -22,6 +22,7 @@ async def submit_exit_signatures(
logger.info('Submitting UpdateExitSignatures transaction')
tx = await keeper_contract.functions.updateExitSignatures(
settings.vault,
approval.deadline,
approval.ipfs_hash,
approval.signatures,
).transact()
Expand Down
10 changes: 6 additions & 4 deletions src/exits/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@
from src.common.contracts import keeper_contract
from src.common.execution import get_oracles
from src.common.metrics import metrics
from src.common.typings import Oracles
from src.common.utils import wait_block_finalization
from src.common.typings import Oracles, OraclesApproval
from src.common.utils import get_current_timestamp, wait_block_finalization
from src.config.settings import (
DEFAULT_RETRY_TIME,
OUTDATED_SIGNATURES_URL_PATH,
settings,
)
from src.exits.consensus import get_validator_public_keys
from src.exits.execution import submit_exit_signatures
from src.exits.typings import OraclesApproval, SignatureRotationRequest
from src.exits.typings import SignatureRotationRequest
from src.exits.utils import send_signature_rotation_requests
from src.validators.signing.local import get_exit_signature_shards
from src.validators.signing.remote import (
Expand Down Expand Up @@ -93,7 +93,7 @@ async def update_exit_signatures(
exit_rotation_batch_limit = oracles.validators_exit_rotation_batch_limit
outdated_indexes = outdated_indexes[:exit_rotation_batch_limit]

logger.info('Started exit signature rotation for %d validators', len(outdated_indexes))
logger.info('Starting exit signature rotation for %d validators', len(outdated_indexes))

# pylint: disable=duplicate-code
validators = await get_validator_public_keys(outdated_indexes)
Expand Down Expand Up @@ -157,6 +157,7 @@ async def get_oracles_approval(
public_keys=[],
public_key_shards=[],
exit_signature_shards=[],
deadline=get_current_timestamp() + oracles.signature_validity_period,
)
for validator_index, public_key in validators.items():
if len(keystores) > 0:
Expand Down Expand Up @@ -191,6 +192,7 @@ async def get_oracles_approval(
return OraclesApproval(
signatures=signatures,
ipfs_hash=ipfs_hash,
deadline=request.deadline,
)


Expand Down
Loading

0 comments on commit 3bc2d12

Please sign in to comment.