diff --git a/archive/tests/shapella_upgrade_acceptance/test_accounting_oracle_negative.py b/archive/tests/shapella_upgrade_acceptance/test_accounting_oracle_negative.py index bd9107f3d..33f03bc27 100644 --- a/archive/tests/shapella_upgrade_acceptance/test_accounting_oracle_negative.py +++ b/archive/tests/shapella_upgrade_acceptance/test_accounting_oracle_negative.py @@ -822,6 +822,6 @@ def build_extra_data_item( module_id.to_bytes(FIELDS_WIDTH.MODULE_ID, **opts), len(nos_ids).to_bytes(FIELDS_WIDTH.NODE_OPS_COUNT, **opts), b"".join(i.to_bytes(FIELDS_WIDTH.NODE_OPERATOR_IDS, **opts) for i in nos_ids), - b"".join(i.to_bytes(FIELDS_WIDTH.STUCK_OR_EXITED_VALS_COUNT, **opts) for i in vals_count), + b"".join(i.to_bytes(FIELDS_WIDTH.EXITED_VALS_COUNT, **opts) for i in vals_count), ) ) diff --git a/tests/acceptance/test_accounting_oracle_negative.py b/tests/acceptance/test_accounting_oracle_negative.py index da2d379a4..2e65a9cbc 100644 --- a/tests/acceptance/test_accounting_oracle_negative.py +++ b/tests/acceptance/test_accounting_oracle_negative.py @@ -15,7 +15,6 @@ ZERO_BYTES32, AccountingReport, oracle_report, - EXTRA_DATA_FORMAT_EMPTY, EXTRA_DATA_FORMAT_LIST, ) @@ -209,10 +208,82 @@ def get_nor_operator_exited_keys(self, operator_id: int) -> int: (_, _, _, _, _, exited_keys, _, _) = nor.getNodeOperatorSummary(operator_id) return exited_keys - def get_nor_operator_stuck_keys(self, operator_id: int) -> int: - nor = contracts.node_operators_registry - (_, _, stuck_keys, _, _, _, _, _) = nor.getNodeOperatorSummary(operator_id) - return stuck_keys + def test_too_short_extra_data_item(self): + extra_data = self.build_extra_data( + [ + build_extra_data_item(0, ItemType.EXTRA_DATA_TYPE_EXITED_VALIDATORS, 2, [2], [2])[:36], + ] + ) + + (_, _, _, _, _, totalExitedValidators, _, _) = contracts.node_operators_registry.getNodeOperatorSummary(2) + with reverts(encode_error("InvalidExtraDataItem(uint256)", [0])): + self.report(extra_data) + + extra_data = self.build_extra_data( + [ + build_extra_data_item(0, ItemType.EXTRA_DATA_TYPE_EXITED_VALIDATORS, 1, [2, 3, 4, 5], [totalExitedValidators]), + build_extra_data_item(1, ItemType.EXTRA_DATA_TYPE_EXITED_VALIDATORS, 2, [2], [totalExitedValidators]), + ] + ) + + with reverts(encode_error("InvalidExtraDataItem(uint256)", [0])): + self.report(extra_data) + + def test_nos_count_zero(self): + extra_data = self.build_extra_data( + [ + build_extra_data_item(0, ItemType.EXTRA_DATA_TYPE_EXITED_VALIDATORS, 2, [], [1]), + ] + ) + + with reverts(encode_error("InvalidExtraDataItem(uint256)", [0])): + self.report(extra_data) + + def test_module_id_zero(self): + extra_data = self.build_extra_data( + [ + build_extra_data_item(0, ItemType.EXTRA_DATA_TYPE_EXITED_VALIDATORS, 0, [2], [1]), + build_extra_data_item(1, ItemType.EXTRA_DATA_TYPE_EXITED_VALIDATORS, 0, [2], [2]), + ] + ) + + with reverts(encode_error("InvalidExtraDataItem(uint256)", [0])): + self.report(extra_data) + + def test_unexpected_extra_data_index(self): + extra_data = self.build_extra_data( + [ + build_extra_data_item(1, ItemType.EXTRA_DATA_TYPE_EXITED_VALIDATORS, 1, [2], [1]), + build_extra_data_item(2, ItemType.EXTRA_DATA_TYPE_EXITED_VALIDATORS, 2, [2], [1]), + ] + ) + + with reverts(encode_error("UnexpectedExtraDataIndex(uint256,uint256)", [0, 1])): + self.report(extra_data) + + totalExitedValidators = self.get_nor_operator_exited_keys(2) + + extra_data = self.build_extra_data( + [ + build_extra_data_item(0, ItemType.EXTRA_DATA_TYPE_EXITED_VALIDATORS, 1, [2], [totalExitedValidators]), + build_extra_data_item(3, ItemType.EXTRA_DATA_TYPE_EXITED_VALIDATORS, 1, [2], [totalExitedValidators]), + ] + ) + + with reverts(encode_error("UnexpectedExtraDataIndex(uint256,uint256)", [1, 3])): + self.report(extra_data) + + totalExitedValidators = self.get_nor_operator_exited_keys(2) + + extra_data = self.build_extra_data( + [ + build_extra_data_item(0, ItemType.EXTRA_DATA_TYPE_EXITED_VALIDATORS, 1, [2], [totalExitedValidators]), + build_extra_data_item(0, ItemType.EXTRA_DATA_TYPE_EXITED_VALIDATORS, 1, [2], [totalExitedValidators]), + ] + ) + + with reverts(encode_error("UnexpectedExtraDataIndex(uint256,uint256)", [1, 0])): + self.report(extra_data) def test_unsupported_extra_data_type(self): extra_data = self.build_extra_data([build_extra_data_item(0, ItemType.UNSUPPORTED, 1, [1], [1])]) @@ -225,6 +296,24 @@ def test_unsupported_extra_data_type(self): ): self.report(extra_data, items_count=1) + def test_invalid_extra_data_sort_order_on_same_items(self): + module_id = 1 + operator_id = 2 + current_exited_keys = self.get_nor_operator_exited_keys(operator_id) + new_exited_keys = current_exited_keys + 1 + + extra_data = self.build_extra_data( + [ + build_extra_data_item(0, ItemType.EXTRA_DATA_TYPE_EXITED_VALIDATORS, module_id, [operator_id], + [new_exited_keys]), + build_extra_data_item(1, ItemType.EXTRA_DATA_TYPE_EXITED_VALIDATORS, module_id, [operator_id], + [new_exited_keys]), + ] + ) + + with reverts(encode_error("InvalidExtraDataSortOrder(uint256)", [1])): + self.report(extra_data) + def test_invalid_extra_data_sort_order_on_same_operator(self): module_id = 1 operator_id = 33 @@ -255,6 +344,37 @@ def test_invalid_extra_data_sort_order_on_exited(self): with reverts(encode_error("InvalidExtraDataSortOrder(uint256)", [0])): self.report(extra_data) + def test_unexpected_extra_data_item(self, extra_data_service: ExtraDataService) -> None: + extra_data = extra_data_service.collect( + { + (1, 2): self.get_nor_operator_exited_keys(2) + 1, + (1, 3): self.get_nor_operator_exited_keys(3) + 1, + (1, 4): self.get_nor_operator_exited_keys(4) + 1, + (1, 5): self.get_nor_operator_exited_keys(5) + 1, + (1, 6): self.get_nor_operator_exited_keys(6) + 1, + (1, 7): self.get_nor_operator_exited_keys(7) + 1, + (1, 8): self.get_nor_operator_exited_keys(8) + 1, + (1, 9): self.get_nor_operator_exited_keys(9) + 1, + (1, 10): self.get_nor_operator_exited_keys(10) + 1, + }, + MAX_ITEMS_PER_EXTRA_DATA_TRANSACTION, + 1, + ) + + with reverts( + encode_error( + "UnexpectedExtraDataItemsCount(uint256,uint256)", + [ + extra_data.items_count - 1, # expected count + extra_data.items_count - 1, # index of the item that makes the count mismatch + ], + ) + ): + self.report( + extra_data.extra_data_list[0], + items_count=extra_data.items_count - 1, + ) + def test_already_processed( self, accounting_oracle: Contract, @@ -263,6 +383,7 @@ def test_already_processed( ): module_id = 1 exited_keys_operator_id = 33 + current_exited_keys = self.get_nor_operator_exited_keys(exited_keys_operator_id) extra_data = extra_data_service.collect( @@ -619,6 +740,6 @@ def build_extra_data_item( module_id.to_bytes(FIELDS_WIDTH.MODULE_ID, **opts), len(nos_ids).to_bytes(FIELDS_WIDTH.NODE_OPS_COUNT, **opts), b"".join(i.to_bytes(FIELDS_WIDTH.NODE_OPERATOR_IDS, **opts) for i in nos_ids), - b"".join(i.to_bytes(FIELDS_WIDTH.STUCK_OR_EXITED_VALS_COUNT, **opts) for i in vals_count), + b"".join(i.to_bytes(FIELDS_WIDTH.EXITED_VALS_COUNT, **opts) for i in vals_count), ) ) diff --git a/tests/test_tw_csm2.py b/tests/test_tw_csm2.py index a0008ef3d..27713f75f 100644 --- a/tests/test_tw_csm2.py +++ b/tests/test_tw_csm2.py @@ -1941,4 +1941,4 @@ def test_vote(helpers, accounts, ldo_holder, vote_ids_from_env, stranger, dual_g # Step 1.70: Add new Kiln guardian assert dsm.isGuardian( NEW_KILN_ADDRESS) is True, "New Kiln address should be added to guardians" - assert dsm.getGuardianQuorum() == DSM_QUORUM_SIZE, "Guardians quorum should be 2" + assert dsm.getGuardianQuorum() == DSM_QUORUM_SIZE, "Guardians quorum should be 4" diff --git a/utils/test/extra_data.py b/utils/test/extra_data.py index ea7245784..5e26f8683 100644 --- a/utils/test/extra_data.py +++ b/utils/test/extra_data.py @@ -67,7 +67,7 @@ class ExtraDataLengths: MODULE_ID = 3 NODE_OPS_COUNT = 8 NODE_OPERATOR_IDS = 8 - STUCK_OR_EXITED_VALS_COUNT = 16 + EXITED_VALS_COUNT = 16 class ExtraDataService: @@ -162,7 +162,7 @@ def build_extra_transactions_data( for no_id in payload.node_operator_ids ) tx += b''.join( - count.to_bytes(ExtraDataLengths.STUCK_OR_EXITED_VALS_COUNT, byteorder='big') + count.to_bytes(ExtraDataLengths.EXITED_VALS_COUNT, byteorder='big') for count in payload.vals_counts )