|
16 | 16 | from src.providers.ipfs import CIDv0, CID
|
17 | 17 | from src.types import EpochNumber, NodeOperatorId, SlotNumber, StakingModuleId, ValidatorIndex
|
18 | 18 | from src.web3py.extensions.csm import CSM
|
19 |
| -from tests.factory.blockstamp import ReferenceBlockStampFactory |
| 19 | +from tests.factory.blockstamp import BlockStampFactory, ReferenceBlockStampFactory |
20 | 20 | from tests.factory.configs import ChainConfigFactory, FrameConfigFactory
|
21 | 21 |
|
22 | 22 |
|
@@ -83,6 +83,55 @@ def test_stuck_operators(module: CSOracle, csm: CSM):
|
83 | 83 | assert stuck == {NodeOperatorId(2), NodeOperatorId(4), NodeOperatorId(5), NodeOperatorId(6), NodeOperatorId(1337)}
|
84 | 84 |
|
85 | 85 |
|
| 86 | +def test_stuck_operators_left_border_before_enact(module: CSOracle, csm: CSM, caplog: pytest.LogCaptureFixture): |
| 87 | + module.module = Mock() # type: ignore |
| 88 | + module.module_id = StakingModuleId(3) |
| 89 | + module.w3.cc = Mock() |
| 90 | + module.w3.lido_validators = Mock() |
| 91 | + module.w3.lido_contracts = Mock() |
| 92 | + module.w3.lido_validators.get_lido_node_operators_by_modules = Mock( |
| 93 | + return_value={ |
| 94 | + 1: { |
| 95 | + type('NodeOperator', (object,), {'id': 0, 'stuck_validators_count': 0})(), |
| 96 | + type('NodeOperator', (object,), {'id': 1, 'stuck_validators_count': 0})(), |
| 97 | + type('NodeOperator', (object,), {'id': 2, 'stuck_validators_count': 1})(), |
| 98 | + type('NodeOperator', (object,), {'id': 3, 'stuck_validators_count': 0})(), |
| 99 | + type('NodeOperator', (object,), {'id': 4, 'stuck_validators_count': 100500})(), |
| 100 | + type('NodeOperator', (object,), {'id': 5, 'stuck_validators_count': 100})(), |
| 101 | + type('NodeOperator', (object,), {'id': 6, 'stuck_validators_count': 0})(), |
| 102 | + }, |
| 103 | + 2: {}, |
| 104 | + } |
| 105 | + ) |
| 106 | + |
| 107 | + module.w3.csm.get_operators_with_stucks_in_range = Mock( |
| 108 | + return_value=[ |
| 109 | + NodeOperatorId(2), |
| 110 | + NodeOperatorId(4), |
| 111 | + NodeOperatorId(6), |
| 112 | + ] |
| 113 | + ) |
| 114 | + |
| 115 | + module.current_frame_range = Mock(return_value=(69, 100)) |
| 116 | + module.converter = Mock() |
| 117 | + module.converter.get_epoch_first_slot = Mock(return_value=lambda epoch: epoch * 32) |
| 118 | + |
| 119 | + l_blockstamp = BlockStampFactory.build() |
| 120 | + blockstamp = BlockStampFactory.build() |
| 121 | + |
| 122 | + with patch('src.modules.csm.csm.build_blockstamp', return_value=l_blockstamp): |
| 123 | + with patch('src.modules.csm.csm.get_next_non_missed_slot', return_value=Mock()): |
| 124 | + stuck = module.stuck_operators(blockstamp=blockstamp) |
| 125 | + |
| 126 | + assert stuck == { |
| 127 | + NodeOperatorId(2), |
| 128 | + NodeOperatorId(4), |
| 129 | + NodeOperatorId(6), |
| 130 | + } |
| 131 | + |
| 132 | + assert caplog.messages[0].startswith("No CSM digest at blockstamp") |
| 133 | + |
| 134 | + |
86 | 135 | def test_calculate_distribution(module: CSOracle, csm: CSM):
|
87 | 136 | csm.fee_distributor.shares_to_distribute = Mock(return_value=10_000)
|
88 | 137 | csm.oracle.perf_leeway_bp = Mock(return_value=500)
|
|
0 commit comments