Skip to content

Commit 5284a61

Browse files
tsudmicyc60
andauthored
Merge stage into master (#82)
* Add tests for controllers Signed-off-by: cyc60 <[email protected]> * Move pagination to gql query funcs Signed-off-by: cyc60 <[email protected]> * Fix a nested bug in tests for clients Signed-off-by: cyc60 <[email protected]> * Implement batch deposits (#79) * Implement batch deposits * Update packages to latest * Fix type * Fix tests * Fix validator selection * Updaate pyproject version * Add faker for test data Signed-off-by: cyc60 <[email protected]> * Increase batch param (#81) Co-authored-by: cyc60 <[email protected]>
1 parent dce3cf8 commit 5284a61

27 files changed

+1149
-480
lines changed

.github/workflows/ci.yaml

+32
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,38 @@ jobs:
2020
- uses: actions/checkout@v2
2121
- uses: actions/setup-python@v2
2222
- uses: pre-commit/[email protected]
23+
test:
24+
name: Testing
25+
runs-on: ubuntu-latest
26+
steps:
27+
- name: Checkout code
28+
uses: actions/checkout@v2
29+
30+
- name: Set up python
31+
uses: actions/setup-python@v2
32+
with:
33+
python-version: 3.8.12
34+
35+
# Install poetry
36+
- name: Load cached Poetry installation
37+
uses: actions/cache@v2
38+
with:
39+
path: ~/.local
40+
key: poetry-0
41+
- name: Install Poetry
42+
uses: snok/install-poetry@v1
43+
with:
44+
virtualenvs-create: true
45+
virtualenvs-in-project: true
46+
installer-parallel: true
47+
48+
# Install dependencies
49+
- name: Install dependencies
50+
run: poetry install --no-interaction --no-root
51+
52+
# Run tests
53+
- name: Run tests
54+
run: poetry run pytest -s oracle/
2355
docker:
2456
name: Build Docker Image
2557
runs-on: ubuntu-latest

.pre-commit-config.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
repos:
22
- repo: https://github.com/psf/black
3-
rev: 22.1.0
3+
rev: 22.3.0
44
hooks:
55
- id: black
66

oracle/keeper/contracts.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -167,14 +167,14 @@ def get_oracles_contract(web3_client: Web3, network: str) -> Contract:
167167
"type": "bytes",
168168
},
169169
],
170-
"internalType": "struct IPoolValidators.DepositData",
170+
"internalType": "struct IPoolValidators.DepositData[]",
171171
"name": "depositData",
172-
"type": "tuple",
172+
"type": "tuple[]",
173173
},
174174
{
175-
"internalType": "bytes32[]",
176-
"name": "merkleProof",
177-
"type": "bytes32[]",
175+
"internalType": "bytes32[][]",
176+
"name": "merkleProofs",
177+
"type": "bytes32[][]",
178178
},
179179
{
180180
"internalType": "bytes32",
@@ -187,7 +187,7 @@ def get_oracles_contract(web3_client: Web3, network: str) -> Contract:
187187
"type": "bytes[]",
188188
},
189189
],
190-
"name": "registerValidator",
190+
"name": "registerValidators",
191191
"outputs": [],
192192
"stateMutability": "nonpayable",
193193
"type": "function",

oracle/keeper/typings.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from oracle.oracle.distributor.types import DistributorVote
66
from oracle.oracle.rewards.types import RewardVote
7-
from oracle.oracle.validators.types import ValidatorVote
7+
from oracle.oracle.validators.types import ValidatorsVote
88

99

1010
class Parameters(NamedTuple):
@@ -17,4 +17,4 @@ class Parameters(NamedTuple):
1717
class OraclesVotes(NamedTuple):
1818
rewards: List[RewardVote]
1919
distributor: List[DistributorVote]
20-
validator: List[ValidatorVote]
20+
validators: List[ValidatorsVote]

oracle/keeper/utils.py

+54-33
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import json
12
import logging
23
import time
34
from collections import Counter
@@ -16,7 +17,7 @@
1617
from oracle.networks import NETWORKS
1718
from oracle.oracle.distributor.types import DistributorVote
1819
from oracle.oracle.rewards.types import RewardVote
19-
from oracle.oracle.validators.types import ValidatorVote
20+
from oracle.oracle.validators.types import ValidatorsVote
2021
from oracle.settings import (
2122
CONFIRMATION_BLOCKS,
2223
DISTRIBUTOR_VOTE_FILENAME,
@@ -140,16 +141,26 @@ def check_distributor_vote(
140141

141142

142143
def check_validator_vote(
143-
web3_client: Web3, vote: ValidatorVote, oracle: ChecksumAddress
144+
web3_client: Web3, vote: ValidatorsVote, oracle: ChecksumAddress
144145
) -> bool:
145146
"""Checks whether oracle's validator vote is correct."""
146147
try:
148+
deposit_data_payloads = []
149+
for deposit_data in vote["deposit_data"]:
150+
deposit_data_payloads.append(
151+
(
152+
deposit_data["operator"],
153+
deposit_data["withdrawal_credentials"],
154+
deposit_data["deposit_data_root"],
155+
deposit_data["public_key"],
156+
deposit_data["deposit_data_signature"],
157+
)
158+
)
147159
encoded_data: bytes = web3_client.codec.encode_abi(
148-
["uint256", "bytes", "address", "bytes32"],
160+
["uint256", "(address,bytes32,bytes32,bytes,bytes)[]", "bytes32"],
149161
[
150162
int(vote["nonce"]),
151-
vote["public_key"],
152-
vote["operator"],
163+
deposit_data_payloads,
153164
vote["validators_deposit_root"],
154165
],
155166
)
@@ -168,7 +179,7 @@ def get_oracles_votes(
168179
oracles: List[ChecksumAddress],
169180
) -> OraclesVotes:
170181
"""Fetches oracle votes that match current nonces."""
171-
votes = OraclesVotes(rewards=[], distributor=[], validator=[])
182+
votes = OraclesVotes(rewards=[], distributor=[], validators=[])
172183
network_config = NETWORKS[network]
173184
aws_bucket_name = network_config["AWS_BUCKET_NAME"]
174185
aws_region = network_config["AWS_REGION"]
@@ -183,7 +194,7 @@ def get_oracles_votes(
183194
check_distributor_vote,
184195
),
185196
(
186-
votes.validator,
197+
votes.validators,
187198
VALIDATOR_VOTE_FILENAME,
188199
validators_nonce,
189200
check_validator_vote,
@@ -349,57 +360,67 @@ def submit_votes(
349360

350361
counter = Counter(
351362
[
352-
(vote["public_key"], vote["operator"], vote["validators_deposit_root"])
353-
for vote in votes.validator
363+
(
364+
json.dumps(vote["deposit_data"], sort_keys=True),
365+
vote["validators_deposit_root"],
366+
)
367+
for vote in votes.validators
354368
]
355369
)
356370
most_voted = counter.most_common(1)
357371
if most_voted and can_submit(most_voted[0][1], total_oracles):
358-
public_key, operator, validators_deposit_root = most_voted[0][0]
372+
deposit_data, validators_deposit_root = most_voted[0][0]
373+
deposit_data = json.loads(deposit_data)
374+
359375
signatures = []
360376
i = 0
361377
while not can_submit(len(signatures), total_oracles):
362-
vote = votes.validator[i]
363-
if (public_key, operator, validators_deposit_root) == (
364-
vote["public_key"],
365-
vote["operator"],
378+
vote = votes.validators[i]
379+
if (deposit_data, validators_deposit_root) == (
380+
vote["deposit_data"],
366381
vote["validators_deposit_root"],
367382
):
368383
signatures.append(vote["signature"])
369384
i += 1
370385

371-
validator_vote: ValidatorVote = next(
386+
validators_vote: ValidatorsVote = next(
372387
vote
373-
for vote in votes.validator
374-
if (public_key, operator, validators_deposit_root)
388+
for vote in votes.validators
389+
if (deposit_data, validators_deposit_root)
375390
== (
376-
vote["public_key"],
377-
vote["operator"],
391+
vote["deposit_data"],
378392
vote["validators_deposit_root"],
379393
)
380394
)
381395
logger.info(
382-
f"[{network}] Submitting validator registration: "
383-
f"operator={operator}, "
384-
f"public key={public_key}, "
385-
f"validator deposit root={validators_deposit_root}"
396+
f"[{network}] Submitting validator(s) registration: "
397+
f"count={len(validators_vote['deposit_data'])}, "
398+
f"deposit root={validators_deposit_root}"
386399
)
400+
submit_deposit_data = []
401+
submit_merkle_proofs = []
402+
for deposit in deposit_data:
403+
submit_deposit_data.append(
404+
dict(
405+
operator=deposit["operator"],
406+
withdrawalCredentials=deposit["withdrawal_credentials"],
407+
depositDataRoot=deposit["deposit_data_root"],
408+
publicKey=deposit["public_key"],
409+
signature=deposit["deposit_data_signature"],
410+
)
411+
)
412+
submit_merkle_proofs.append(deposit["proof"])
413+
387414
submit_update(
388415
network,
389416
web3_client,
390-
oracles_contract.functions.registerValidator(
391-
dict(
392-
operator=validator_vote["operator"],
393-
withdrawalCredentials=validator_vote["withdrawal_credentials"],
394-
depositDataRoot=validator_vote["deposit_data_root"],
395-
publicKey=validator_vote["public_key"],
396-
signature=validator_vote["deposit_data_signature"],
397-
),
398-
validator_vote["proof"],
417+
oracles_contract.functions.registerValidators(
418+
submit_deposit_data,
419+
submit_merkle_proofs,
399420
validators_deposit_root,
400421
signatures,
401422
),
402423
)
403424
logger.info(
404-
f"[{network}] Validator registration has been successfully submitted"
425+
f"[{network}] Validator(s) registration has been successfully submitted"
405426
)

oracle/networks.py

+40
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@
2929
default="https://api.thegraph.com/subgraphs/name/stakewise/uniswap-v3-mainnet",
3030
),
3131
ETH2_ENDPOINT=config(f"{MAINNET_UPPER}_ETH2_ENDPOINT", default=""),
32+
VALIDATORS_FETCH_CHUNK_SIZE=config(
33+
f"{MAINNET_UPPER}_VALIDATORS_FETCH_CHUNK_SIZE",
34+
default=100,
35+
cast=int,
36+
),
37+
VALIDATORS_BATCH_SIZE=config(
38+
f"{MAINNET_UPPER}_VALIDATORS_BATCH_SIZE",
39+
default=10,
40+
cast=int,
41+
),
3242
SLOTS_PER_EPOCH=32,
3343
SECONDS_PER_SLOT=12,
3444
ORACLES_CONTRACT_ADDRESS=Web3.toChecksumAddress(
@@ -92,6 +102,16 @@
92102
default="https://api.thegraph.com/subgraphs/name/stakewise/uniswap-v3-goerli",
93103
),
94104
ETH2_ENDPOINT=config(f"{GOERLI_UPPER}_ETH2_ENDPOINT", default=""),
105+
VALIDATORS_FETCH_CHUNK_SIZE=config(
106+
f"{GOERLI_UPPER}_VALIDATORS_FETCH_CHUNK_SIZE",
107+
default=100,
108+
cast=int,
109+
),
110+
VALIDATORS_BATCH_SIZE=config(
111+
f"{GOERLI_UPPER}_VALIDATORS_BATCH_SIZE",
112+
default=10,
113+
cast=int,
114+
),
95115
SLOTS_PER_EPOCH=32,
96116
SECONDS_PER_SLOT=12,
97117
ORACLES_CONTRACT_ADDRESS=Web3.toChecksumAddress(
@@ -153,6 +173,16 @@
153173
default="",
154174
),
155175
ETH2_ENDPOINT=config(f"{PERM_GOERLI_UPPER}_ETH2_ENDPOINT", default=""),
176+
VALIDATORS_FETCH_CHUNK_SIZE=config(
177+
f"{PERM_GOERLI_UPPER}_VALIDATORS_FETCH_CHUNK_SIZE",
178+
default=100,
179+
cast=int,
180+
),
181+
VALIDATORS_BATCH_SIZE=config(
182+
f"{PERM_GOERLI_UPPER}_VALIDATORS_BATCH_SIZE",
183+
default=10,
184+
cast=int,
185+
),
156186
SLOTS_PER_EPOCH=32,
157187
SECONDS_PER_SLOT=12,
158188
ORACLES_CONTRACT_ADDRESS=Web3.toChecksumAddress(
@@ -217,6 +247,16 @@
217247
f"{GNOSIS_CHAIN_UPPER}_UNISWAP_V3_SUBGRAPH_URL", default=""
218248
),
219249
ETH2_ENDPOINT=config(f"{GNOSIS_CHAIN_UPPER}_ETH2_ENDPOINT", default=""),
250+
VALIDATORS_FETCH_CHUNK_SIZE=config(
251+
f"{GNOSIS_CHAIN_UPPER}_VALIDATORS_FETCH_CHUNK_SIZE",
252+
default=100,
253+
cast=int,
254+
),
255+
VALIDATORS_BATCH_SIZE=config(
256+
f"{GNOSIS_CHAIN_UPPER}_VALIDATORS_BATCH_SIZE",
257+
default=10,
258+
cast=int,
259+
),
220260
SLOTS_PER_EPOCH=16,
221261
SECONDS_PER_SLOT=5,
222262
ORACLES_CONTRACT_ADDRESS=Web3.toChecksumAddress(

0 commit comments

Comments
 (0)