Skip to content

Commit 1982955

Browse files
committed
fix: update time retrieval method and enhance depositable node operator logic
1 parent b78c0d6 commit 1982955

File tree

2 files changed

+61
-33
lines changed

2 files changed

+61
-33
lines changed

tests/regression/test_csm.py

Lines changed: 60 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -88,27 +88,43 @@ def ejector():
8888
def strikes():
8989
return contracts.cs_strikes
9090

91+
@pytest.fixture(params=[pytest.param(1, id="1 key")])
92+
def keys_count(request):
93+
return request.param
9194

9295
@pytest.fixture
93-
def depositable_node_operator(csm, accounting, permissionless_gate, stranger):
96+
def depositable_node_operator(keys_count, csm, accounting, permissionless_gate, stranger):
97+
return _depositable_node_operator(keys_count, csm, accounting, permissionless_gate, stranger)
98+
99+
100+
def _depositable_node_operator(keys_count, csm, accounting, permissionless_gate, stranger):
94101
increase_staking_module_share(module_id=CSM_MODULE_ID, share_multiplier=2)
95102
csm.cleanDepositQueue(2 * csm.getNonce(), {"from": stranger.address})
103+
keys_to_deposit = 0
96104
for queue_priority in range(0, 6):
97105
deposit_batch = csm.depositQueueItem(queue_priority, csm.depositQueuePointers(queue_priority)["head"])
98106
if deposit_batch:
99107
node_operator_id = (deposit_batch >> 192) & ((1 << 64) - 1)
100-
keys_count = (deposit_batch >> 128) & ((1 << 64) - 1)
101-
break
108+
batch_keys_count = (deposit_batch >> 128) & ((1 << 64) - 1)
109+
keys_to_deposit += batch_keys_count
110+
if batch_keys_count >= keys_count:
111+
break
102112
else:
103113
address = accounts[7].address
104-
keys_count = 5
105114
node_operator_id = csm_add_node_operator(csm, permissionless_gate, accounting, address, keys_count=keys_count)
106-
return node_operator_id, keys_count
115+
return node_operator_id, keys_to_deposit
107116

108117

109-
@pytest.fixture
110-
def node_operator(depositable_node_operator, csm, accounting) -> int:
111-
node_operator, keys_count = depositable_node_operator
118+
@pytest.fixture()
119+
def node_operator(keys_count, csm, accounting, permissionless_gate, stranger) -> int:
120+
total_node_operators = contracts.csm.getNodeOperatorsCount()
121+
for no_id in range(0, total_node_operators):
122+
no = csm.getNodeOperator(no_id)
123+
if no["totalDepositedKeys"] - no["totalWithdrawnKeys"] >= keys_count:
124+
return no_id
125+
126+
# Fallback: use _depositable_node_operator
127+
node_operator, keys_count = _depositable_node_operator(keys_count, csm, accounting, permissionless_gate, stranger)
112128
fill_deposit_buffer(keys_count)
113129
contracts.lido.deposit(keys_count, CSM_MODULE_ID, "0x", {"from": contracts.deposit_security_module})
114130
return node_operator
@@ -195,13 +211,15 @@ def test_add_node_operator_permissionless(csm, permissionless_gate, accounting,
195211

196212
@pytest.mark.usefixtures("pause_modules")
197213
def test_deposit(depositable_node_operator, csm, remove_stake_limit):
198-
(node_operator, keys_count) = depositable_node_operator
199-
fill_deposit_buffer(keys_count)
214+
(node_operator, keys_to_deposit) = depositable_node_operator
215+
no = csm.getNodeOperator(node_operator)
216+
depositable_keys = no["depositableValidatorsCount"] - no["totalWithdrawnKeys"]
217+
fill_deposit_buffer(keys_to_deposit)
200218
total_deposited_before = csm.getNodeOperator(node_operator)["totalDepositedKeys"]
201-
contracts.lido.deposit(keys_count, CSM_MODULE_ID, "0x", {"from": contracts.deposit_security_module})
219+
contracts.lido.deposit(keys_to_deposit, CSM_MODULE_ID, "0x", {"from": contracts.deposit_security_module})
202220

203221
no = csm.getNodeOperator(node_operator)
204-
assert no["totalDepositedKeys"] == total_deposited_before + keys_count
222+
assert no["totalDepositedKeys"] == total_deposited_before + depositable_keys
205223

206224

207225
def test_mint_rewards_happy_path(csm, fee_distributor):
@@ -229,7 +247,8 @@ def test_csm_target_limits(csm, node_operator):
229247

230248
def test_csm_report_exited(csm, node_operator, extra_data_service):
231249
total_exited = csm.getStakingModuleSummary()["totalExitedValidators"]
232-
exited_keys = 5
250+
no = csm.getNodeOperator(node_operator)
251+
exited_keys = no["totalExitedKeys"] + 1
233252
extra_data = extra_data_service.collect({(CSM_MODULE_ID, node_operator): exited_keys}, exited_keys, exited_keys)
234253
oracle_report(
235254
extraDataFormat=1,
@@ -244,13 +263,14 @@ def test_csm_report_exited(csm, node_operator, extra_data_service):
244263
assert no["totalExitedKeys"] == exited_keys
245264

246265

247-
def test_csm_get_staking_module_summary(csm, accounting, node_operator, extra_data_service, remove_stake_limit):
266+
def test_csm_get_staking_module_summary(csm, accounting, node_operator, extra_data_service, remove_stake_limit, permissionless_gate, stranger):
248267
(exited_before, deposited_before, depositable_before) = contracts.staking_router.getStakingModuleSummary(
249268
CSM_MODULE_ID
250269
)
251270

252271
# Assure there are new exited keys
253-
exited_keys = 5
272+
no = csm.getNodeOperator(node_operator)
273+
exited_keys = no["totalExitedKeys"] + 1
254274
extra_data = extra_data_service.collect({(CSM_MODULE_ID, node_operator): exited_keys}, exited_keys, exited_keys)
255275
oracle_report(
256276
extraDataFormat=1,
@@ -262,21 +282,20 @@ def test_csm_get_staking_module_summary(csm, accounting, node_operator, extra_da
262282
)
263283

264284
# Assure there are new deposited keys
265-
266-
deposits_count = 3
267-
new_keys = 5
268-
new_depositable = new_keys - deposits_count
269-
csm_upload_keys(csm, accounting, node_operator, new_keys)
270-
increase_staking_module_share(module_id=CSM_MODULE_ID, share_multiplier=2)
285+
keys_to_deposit = 2
286+
depositable_no, deposits_count = _depositable_node_operator(keys_to_deposit, csm, accounting, permissionless_gate, stranger)
271287

272288
fill_deposit_buffer(deposits_count)
273289
contracts.lido.deposit(deposits_count, CSM_MODULE_ID, "0x", {"from": contracts.deposit_security_module})
274290

291+
new_depositable = 5
292+
csm_upload_keys(csm, accounting, node_operator, new_depositable)
293+
275294
(exited_after, deposited_after, depositable_after) = contracts.staking_router.getStakingModuleSummary(CSM_MODULE_ID)
276295

277296
assert exited_after == exited_before + exited_keys
278297
assert deposited_after == deposited_before + deposits_count
279-
assert depositable_after == depositable_before + new_depositable
298+
assert depositable_after == depositable_before - deposits_count + new_depositable
280299

281300

282301
def test_csm_get_node_operator_summary(csm, node_operator, extra_data_service):
@@ -309,7 +328,9 @@ def test_csm_get_node_operator_summary(csm, node_operator, extra_data_service):
309328

310329

311330
def test_csm_decrease_vetted_keys(csm, depositable_node_operator, stranger):
312-
(node_operator, keys_count) = depositable_node_operator
331+
(node_operator, _) = depositable_node_operator
332+
no = csm.getNodeOperator(node_operator)
333+
depositable_keys = no["depositableValidatorsCount"] - no["totalWithdrawnKeys"]
313334
total_added_keys = csm.getNodeOperator(node_operator)["totalAddedKeys"]
314335
block_number = web3.eth.get_block_number()
315336
block = web3.eth.get_block(block_number)
@@ -320,15 +341,15 @@ def test_csm_decrease_vetted_keys(csm, depositable_node_operator, stranger):
320341
staking_module_id=CSM_MODULE_ID,
321342
nonce=staking_module_nonce,
322343
node_operator_ids=to_bytes(node_operator, 16),
323-
vetted_signing_keys_counts=to_bytes(total_added_keys - keys_count, 32),
344+
vetted_signing_keys_counts=to_bytes(total_added_keys - depositable_keys, 32),
324345
)
325346

326347
set_single_guardian(contracts.deposit_security_module, contracts.agent, stranger)
327348

328349
contracts.deposit_security_module.unvetSigningKeys(*unvet_args.to_tuple(), (0, 0), {"from": stranger.address})
329350

330351
no = csm.getNodeOperator(node_operator)
331-
assert no["totalVettedKeys"] == total_added_keys - keys_count
352+
assert no["totalVettedKeys"] == total_added_keys - depositable_keys
332353

333354

334355
def test_csm_penalize_node_operator(csm, accounting, node_operator, helpers):
@@ -439,8 +460,10 @@ def test_csm_remove_key(csm, parameters_registry, accounting, node_operator):
439460
assert no["totalAddedKeys"] == keys_before - 1
440461

441462

442-
def test_eject_bad_performer(csm, accounting, ejector, strikes, node_operator, stranger):
443-
index_to_eject = 0
463+
@pytest.mark.parametrize("keys_count", [pytest.param(2, id="2 keys")], indirect=True)
464+
def test_eject_bad_performer(csm, accounting, ejector, strikes, node_operator, stranger, keys_count):
465+
no = csm.getNodeOperator(node_operator)
466+
index_to_eject = no["totalDepositedKeys"] - 2
444467
pubkey_to_eject = csm.getSigningKeys(node_operator, index_to_eject, 1)
445468
leaf_to_eject = (node_operator, pubkey_to_eject, [1, 1, 1, 1, 1, 1])
446469
another_pubkey = csm.getSigningKeys(node_operator, index_to_eject + 1, 1)
@@ -484,18 +507,22 @@ def test_eject_bad_performer(csm, accounting, ejector, strikes, node_operator, s
484507
def test_voluntary_eject(csm, ejector, node_operator):
485508
eject_payment_value = get_sys_fee_to_eject()
486509
operator_address = csm.getNodeOperatorOwner(node_operator)
510+
no = csm.getNodeOperator(node_operator)
511+
index_to_eject = no["totalDepositedKeys"] - 1
487512

488513
tx = ejector.voluntaryEject(
489-
node_operator, 0, 1, ZERO_ADDRESS, {"value": eject_payment_value, "from": operator_address}
514+
node_operator, index_to_eject, 1, ZERO_ADDRESS, {"value": eject_payment_value, "from": operator_address}
490515
)
491516
assert "TriggeredExitFeeRecorded" not in tx.events
492517

493518

494519
def test_report_validator_exit_delay(csm, accounting, parameters_registry, node_operator):
495-
pubkey = csm.getSigningKeys(node_operator, 0, 1)
496520
day_in_seconds = 60 * 60 * 24
521+
no = csm.getNodeOperator(node_operator)
522+
index_to_report = no["totalDepositedKeys"] - 1
523+
pubkey = csm.getSigningKeys(node_operator, index_to_report, 1)
497524

498-
tx = csm.reportValidatorExitDelay(node_operator, 0, pubkey, 7 * day_in_seconds, {"from": contracts.staking_router})
525+
tx = csm.reportValidatorExitDelay(node_operator, index_to_report, pubkey, 7 * day_in_seconds, {"from": contracts.staking_router})
499526
assert "ValidatorExitDelayProcessed" in tx.events
500527
assert tx.events["ValidatorExitDelayProcessed"]["nodeOperatorId"] == node_operator
501528
assert tx.events["ValidatorExitDelayProcessed"]["pubkey"] == pubkey
@@ -507,7 +534,9 @@ def test_report_validator_exit_delay(csm, accounting, parameters_registry, node_
507534

508535
def test_on_validator_exit_triggered(csm, node_operator):
509536
eject_payment_value = 1
510-
pubkey = csm.getSigningKeys(node_operator, 0, 1)
537+
no = csm.getNodeOperator(node_operator)
538+
index_to_report = no["totalDepositedKeys"] - 1
539+
pubkey = csm.getSigningKeys(node_operator, index_to_report, 1)
511540
exit_type = 3
512541

513542
tx = csm.onValidatorExitTriggered(node_operator, pubkey, 1, exit_type, {"from": contracts.staking_router})

utils/test/oracle_report_helpers.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -351,8 +351,7 @@ def wait_to_next_available_report_time(consensus_contract):
351351
else:
352352
raise
353353

354-
# Use chain.time() instead of block timestamp for consistency
355-
time = chain.time()
354+
time = web3.eth.get_block("latest").timestamp
356355
(_, EPOCHS_PER_FRAME, _) = consensus_contract.getFrameConfig()
357356
frame_start_with_offset = GENESIS_TIME + (refSlot + SLOTS_PER_EPOCH * EPOCHS_PER_FRAME + 1) * SECONDS_PER_SLOT
358357
chain.sleep(frame_start_with_offset - time)

0 commit comments

Comments
 (0)