|
2 | 2 |
|
3 | 3 | from unittest.mock import Mock
|
4 | 4 |
|
| 5 | +from faker import Faker |
| 6 | + |
5 | 7 | from src.constants import FAR_FUTURE_EPOCH
|
6 | 8 | from src.providers.consensus.types import Validator, ValidatorStatus, ValidatorState
|
7 | 9 | from src.services.bunker_cases.abnormal_cl_rebase import AbnormalClRebase
|
8 | 10 | from src.services.bunker_cases.types import BunkerConfig
|
| 11 | +from src.types import Gwei |
| 12 | +from src.web3py.extensions import LidoValidatorsProvider |
| 13 | +from src.web3py.types import Web3 |
| 14 | +from tests.factory.blockstamp import ReferenceBlockStampFactory |
| 15 | +from tests.factory.configs import ChainConfigFactory, BunkerConfigFactory |
| 16 | +from tests.factory.no_registry import LidoValidatorFactory |
9 | 17 | from tests.modules.accounting.bunker.conftest import simple_ref_blockstamp, simple_key, simple_blockstamp
|
10 | 18 |
|
| 19 | +faker = Faker() |
| 20 | + |
11 | 21 |
|
12 | 22 | def simple_validators(
|
13 | 23 | from_index: int,
|
@@ -198,41 +208,175 @@ def test_get_nearest_and_distant_blockstamps(
|
198 | 208 |
|
199 | 209 | @pytest.mark.unit
|
200 | 210 | @pytest.mark.parametrize(
|
201 |
| - ("prev_blockstamp", "blockstamp", "expected_rebase"), |
| 211 | + ( |
| 212 | + "prev_lido_validators", |
| 213 | + "curr_lido_validators", |
| 214 | + "prev_withdrawals_vault_balance", # wei |
| 215 | + "curr_withdrawals_vault_balance", # wei |
| 216 | + "withdrawn_from_vault", # Gwei |
| 217 | + "expected_rebase", # Gwei |
| 218 | + ), |
202 | 219 | [
|
203 |
| - # the same count of validators, 1 ETH used to finalize requests, new val balance is more than previous |
204 |
| - (simple_ref_blockstamp(0), simple_ref_blockstamp(10), 195), |
205 |
| - # the same count of validators, 1 ETH used to finalize requests, new val balance is less than previous |
206 |
| - (simple_ref_blockstamp(0), simple_ref_blockstamp(20), -(32 * 10**9) - 100700), |
207 |
| - # new count of validators, no ETH used to finalize requests, new val balance is more than previous |
208 |
| - (simple_ref_blockstamp(30), simple_ref_blockstamp(40), 1157445), |
209 |
| - # new validators count is less than previous, should be exception |
210 | 220 | (
|
211 |
| - simple_ref_blockstamp(20), |
212 |
| - simple_ref_blockstamp(30), |
213 |
| - "Validators count diff should be positive or 0. Something went wrong with CL API", |
| 221 | + # The same count of validators, |
| 222 | + LidoValidatorFactory.batch(10, balance=32 * 10**9), |
| 223 | + # but current validators have more balance (has non-withdrawn rewards). |
| 224 | + LidoValidatorFactory.batch(10, balance=(32 * 10**9) + Gwei(100_000)), |
| 225 | + # Previous withdrawals vault balance the same as current |
| 226 | + 15 * 10**18, |
| 227 | + 15 * 10**18, |
| 228 | + # and nothing was withdrawn from the vault. |
| 229 | + Gwei(0), |
| 230 | + # Rebase is equal non-withdrawn rewards from vals above. |
| 231 | + Gwei(10 * 100_000), |
| 232 | + ), |
| 233 | + ( |
| 234 | + # The same count of validators, |
| 235 | + LidoValidatorFactory.batch(10, balance=32 * 10**9), |
| 236 | + # and the same balance. |
| 237 | + LidoValidatorFactory.batch(10, balance=32 * 10**9), |
| 238 | + # Previous withdrawals vault balance the same as current |
| 239 | + 15 * 10**18, |
| 240 | + 15 * 10**18, |
| 241 | + # and rewards was withdrawn from the vault. |
| 242 | + Gwei(10 * 100_000), |
| 243 | + # Rebase is equal withdrawn rewards. |
| 244 | + Gwei(10 * 100_000), |
| 245 | + ), |
| 246 | + ( |
| 247 | + # New vals count is more than previous, |
| 248 | + LidoValidatorFactory.batch(9, balance=32 * 10**9), |
| 249 | + # and have the same balance. |
| 250 | + LidoValidatorFactory.batch(10, balance=32 * 10**9), |
| 251 | + # Previous withdrawals vault balance the same as current |
| 252 | + 15 * 10**18, |
| 253 | + 15 * 10**18, |
| 254 | + # and nothing was withdrawn from the vault. |
| 255 | + Gwei(0), |
| 256 | + # Rebase should be equal to 0 because validators diff has been accounted. |
| 257 | + Gwei(0), |
| 258 | + ), |
| 259 | + ( |
| 260 | + # The same count of validators, |
| 261 | + LidoValidatorFactory.batch(10, balance=32 * 10**9), |
| 262 | + # but some validators have less balance (has penalties). |
| 263 | + [ |
| 264 | + *LidoValidatorFactory.batch(5, balance=(32 * 10**9) - Gwei(100_000)), |
| 265 | + *LidoValidatorFactory.batch(5, balance=32 * 10**9), |
| 266 | + ], |
| 267 | + # Previous withdrawals vault balance the same as current. |
| 268 | + 15 * 10**18, |
| 269 | + 15 * 10**18, |
| 270 | + # rewards was withdrawn from the vault. |
| 271 | + Gwei(10 * 100_000), |
| 272 | + # Rebase is equal to rewards minus penalties. |
| 273 | + Gwei(5 * 100_000), |
| 274 | + ), |
| 275 | + ( |
| 276 | + # The same count of validators, |
| 277 | + LidoValidatorFactory.batch(10, balance=32 * 10**9), |
| 278 | + # but some validators have less balance (has penalties). |
| 279 | + [ |
| 280 | + *LidoValidatorFactory.batch(5, balance=(32 * 10**9) - Gwei(100_000)), |
| 281 | + *LidoValidatorFactory.batch(5, balance=32 * 10**9), |
| 282 | + ], |
| 283 | + # Current withdrawals vault balance is more than previous because some rewards were withdrawn |
| 284 | + 15 * 10**18, |
| 285 | + 15 * 10**18 + Web3.to_wei(10 * 100_000, 'gwei'), |
| 286 | + # but wasn't withdrawn from the vault. |
| 287 | + Gwei(0), |
| 288 | + # Rebase is equal to rewards on vault minus penalties |
| 289 | + Gwei(5 * 100_000), |
| 290 | + ), |
| 291 | + ( |
| 292 | + # New vals count is more than previous, |
| 293 | + LidoValidatorFactory.batch(9, balance=32 * 10**9), |
| 294 | + # but some validators have less balance (has penalties). |
| 295 | + # and another part has non-withdrawn rewards. |
| 296 | + [ |
| 297 | + *LidoValidatorFactory.batch(5, balance=(32 * 10**9) - Gwei(100_000)), |
| 298 | + *LidoValidatorFactory.batch(5, balance=(32 * 10**9) + Gwei(100_000)), |
| 299 | + ], |
| 300 | + # Current withdrawals vault balance is more than previous |
| 301 | + # because some were got between withdrawal event and ref block, |
| 302 | + 15 * 10**18, |
| 303 | + 15 * 10**18 + Web3.to_wei(100_000, 'gwei'), |
| 304 | + # and some were withdrawn from the vault. |
| 305 | + Gwei(10 * 100_000), |
| 306 | + # Rebase is equal to rewards withdrawn from vault plus diff between vaults balances |
| 307 | + Gwei(10 * 100_000 + 100_000), |
| 308 | + ), |
| 309 | + ( |
| 310 | + # New vals count is more than previous, |
| 311 | + LidoValidatorFactory.batch(9, balance=32 * 10**9), |
| 312 | + # but some validators have less balance (has penalties). |
| 313 | + [ |
| 314 | + *LidoValidatorFactory.batch(5, balance=(32 * 10**9) - Gwei(100_000)), |
| 315 | + *LidoValidatorFactory.batch(5, balance=32 * 10**9), |
| 316 | + ], |
| 317 | + # Current withdrawals vault balance is less than previous |
| 318 | + 15 * 10**18, |
| 319 | + 15 * 10**18 - Web3.to_wei(10 * 100_000, 'gwei'), |
| 320 | + # because were withdrawn from the vault. |
| 321 | + Gwei(10 * 100_000), |
| 322 | + # Rebase is equal to rewards withdrawn from vault minus penalties. Validators diff has been accounted |
| 323 | + Gwei(-5 * 100_000), |
| 324 | + ), |
| 325 | + ( |
| 326 | + # The same count of validators, |
| 327 | + LidoValidatorFactory.batch(10, balance=32 * 10**9), |
| 328 | + # but current validators have less balance (has penalties). |
| 329 | + LidoValidatorFactory.batch(10, balance=(32 * 10**9) - Gwei(100_000)), |
| 330 | + # Previous withdrawals vault balance the same as current |
| 331 | + 15 * 10**18, |
| 332 | + 15 * 10**18, |
| 333 | + # nothing was withdrawn from the vault. |
| 334 | + Gwei(0), |
| 335 | + # Rebase is equal to penalties. |
| 336 | + Gwei(-10 * 100_000), |
| 337 | + ), |
| 338 | + ( |
| 339 | + # New vals count is less than previous, |
| 340 | + LidoValidatorFactory.batch(10, balance=32 * 10**9), |
| 341 | + # and have the same balance |
| 342 | + LidoValidatorFactory.batch(9, balance=32 * 10**9), |
| 343 | + faker.pyint(), |
| 344 | + faker.pyint(), |
| 345 | + faker.pyint(), |
| 346 | + # It is exception because new vals count can't be less that previous |
| 347 | + ValueError("Validators count diff should be positive or 0. Something went wrong with CL API"), |
214 | 348 | ),
|
215 | 349 | ],
|
216 | 350 | )
|
217 | 351 | def test_calculate_cl_rebase_between_blocks(
|
218 |
| - abnormal_case, |
219 |
| - mock_get_eth_distributed_events, |
220 |
| - mock_get_withdrawal_vault_balance, |
221 |
| - mock_get_blockstamp, |
222 |
| - prev_blockstamp, |
223 |
| - blockstamp, |
| 352 | + web3, |
| 353 | + prev_lido_validators, |
| 354 | + curr_lido_validators, |
| 355 | + prev_withdrawals_vault_balance, |
| 356 | + curr_withdrawals_vault_balance, |
| 357 | + withdrawn_from_vault, |
224 | 358 | expected_rebase,
|
225 | 359 | ):
|
226 |
| - abnormal_case.lido_keys = [ |
227 |
| - simple_key(v.validator.pubkey) for v in abnormal_case.w3.cc.get_validators(simple_ref_blockstamp(0)) |
228 |
| - ] |
229 |
| - abnormal_case.lido_validators = abnormal_case.w3.cc.get_validators(blockstamp) |
230 |
| - abnormal_case.w3.lido_contracts.accounting_oracle.get_consensus_version = Mock(return_value=2) |
231 |
| - if isinstance(expected_rebase, str): |
232 |
| - with pytest.raises(ValueError, match=expected_rebase): |
233 |
| - abnormal_case._calculate_cl_rebase_between_blocks(prev_blockstamp, blockstamp) |
| 360 | + prev_blockstamp = ReferenceBlockStampFactory.build(block_number=8) |
| 361 | + ref_blockstamp = ReferenceBlockStampFactory.build(block_number=88) |
| 362 | + abnormal_case = AbnormalClRebase(web3, ChainConfigFactory.build(), BunkerConfigFactory.build()) |
| 363 | + abnormal_case.lido_keys = Mock() |
| 364 | + abnormal_case.w3.cc = Mock() |
| 365 | + abnormal_case.w3.lido_contracts = Mock() |
| 366 | + abnormal_case.w3.cc.get_validators_no_cache = Mock() |
| 367 | + |
| 368 | + LidoValidatorsProvider.merge_validators_with_keys = Mock(return_value=prev_lido_validators) |
| 369 | + abnormal_case.lido_validators = curr_lido_validators |
| 370 | + abnormal_case.w3.lido_contracts.get_withdrawal_balance_no_cache = Mock( |
| 371 | + side_effect=[curr_withdrawals_vault_balance, prev_withdrawals_vault_balance] |
| 372 | + ) |
| 373 | + abnormal_case._get_withdrawn_from_vault_between_blocks = Mock(return_value=withdrawn_from_vault) |
| 374 | + |
| 375 | + if isinstance(expected_rebase, Exception): |
| 376 | + with pytest.raises(ValueError, match=expected_rebase.args[0]): |
| 377 | + abnormal_case._calculate_cl_rebase_between_blocks(prev_blockstamp, ref_blockstamp) |
234 | 378 | else:
|
235 |
| - result = abnormal_case._calculate_cl_rebase_between_blocks(prev_blockstamp, blockstamp) |
| 379 | + result = abnormal_case._calculate_cl_rebase_between_blocks(prev_blockstamp, ref_blockstamp) |
236 | 380 | assert result == expected_rebase
|
237 | 381 |
|
238 | 382 |
|
|
0 commit comments