diff --git a/setup.py b/setup.py index 36a203a5..ba0e9502 100644 --- a/setup.py +++ b/setup.py @@ -33,7 +33,7 @@ setup( name='skale.py', - version='6.3', + version='6.4', description='SKALE client tools', long_description_markdown_filename='README.md', author='SKALE Labs', diff --git a/skale/contracts/manager/schains.py b/skale/contracts/manager/schains.py index 547992ec..f76783f2 100644 --- a/skale/contracts/manager/schains.py +++ b/skale/contracts/manager/schains.py @@ -53,6 +53,7 @@ class SchainStructure: originator: str chain_id: int options: SchainOptions + active: bool class SChains(BaseContract): @@ -72,20 +73,21 @@ def node_rotation(self): return self.skale.node_rotation @format_fields(FIELDS) - def get(self, id_, obj=False): + def get(self, id_, obj=True): res = self.schains_internal.get_raw(id_) hash_obj = keccak.new(data=res[0].encode("utf8"), digest_bits=256) hash_str = "0x" + hash_obj.hexdigest()[:13] res.append(hash_str) + active = self.schain_active(res) options = self.get_options(id_) if obj: # TODO: temporary solution for backwards compatibility - return SchainStructure(*res, options=options) + return SchainStructure(*res, active=active, options=options) else: res += asdict(options).values() return res @format_fields(FIELDS) - def get_by_name(self, name, obj=False): + def get_by_name(self, name, obj=True): id_ = self.name_to_id(name) return self.get(id_, obj=obj) @@ -104,7 +106,6 @@ def get_schains_for_node(self, node_id): schain_ids = self.schains_internal.get_schain_ids_for_node(node_id) for schain_id in schain_ids: schain = self.get(schain_id) - schain['active'] = True if self.schain_active(schain) else False schains.append(schain) return schains @@ -113,7 +114,6 @@ def get_active_schains_for_node(self, node_id): schain_ids = self.schains_internal.get_active_schain_ids_for_node(node_id) for schain_id in schain_ids: schain = self.get(schain_id) - schain['active'] = True schains.append(schain) return schains @@ -125,10 +125,9 @@ def get_last_rotation_id(self, schain_name): rotation_data = self.node_rotation.get_rotation(schain_name) return rotation_data['rotation_id'] - def schain_active(self, schain): - if schain['name'] != '' and \ - schain['mainnetOwner'] != '0x0000000000000000000000000000000000000000': - return True + @classmethod + def schain_active(cls, schain: list) -> bool: + return schain[0] != '' and schain[1] != '0x0000000000000000000000000000000000000000' # noqa def get_schain_price(self, index_of_type, lifetime): return self.contract.functions.getSchainPrice(index_of_type, diff --git a/skale/schain_config/ports_allocation.py b/skale/schain_config/ports_allocation.py index 90fa71e2..c7451c75 100644 --- a/skale/schain_config/ports_allocation.py +++ b/skale/schain_config/ports_allocation.py @@ -27,7 +27,7 @@ def calc_schain_base_port(node_base_port, schain_index): def get_schain_index_in_node(schain_name, node_schains): for index, schain in enumerate(node_schains): - if schain_name == schain['name']: + if schain_name == schain.name: return index raise SChainNotFoundException(f'sChain {schain_name} is not found in the list: {node_schains}') diff --git a/skale/utils/contracts_provision/main.py b/skale/utils/contracts_provision/main.py index 38542390..4155c5b6 100644 --- a/skale/utils/contracts_provision/main.py +++ b/skale/utils/contracts_provision/main.py @@ -166,7 +166,7 @@ def cleanup_nodes(skale, ids=()): def cleanup_schains(skale): for schain_id in skale.schains_internal.get_all_schains_ids(): - schain_data = skale.schains.get(schain_id) + schain_data = skale.schains.get(schain_id, obj=False) schain_name = schain_data.get('name', None) if schain_name is not None: skale.manager.delete_schain_by_root(schain_name, wait_for=True) diff --git a/skale/utils/web3_utils.py b/skale/utils/web3_utils.py index eae748ea..e2023395 100644 --- a/skale/utils/web3_utils.py +++ b/skale/utils/web3_utils.py @@ -108,11 +108,12 @@ def middleware(method, params): latest_block = web3.eth.get_block('latest') current_time = time.time() - ts_diff = current_time - latest_block['timestamp'] - if not is_test_env(): - ts_diff = abs(ts_diff) + if is_test_env(): + unsynced = current_time - latest_block['timestamp'] > allowed_ts_diff + else: + unsynced = abs(current_time - latest_block['timestamp']) > allowed_ts_diff - if ts_diff > allowed_ts_diff: + if unsynced: raise EthClientOutdatedError(outdated_client_time_msg( method, current_time, diff --git a/tests/manager/manager_test.py b/tests/manager/manager_test.py index 2c7349e9..39c6fc1a 100644 --- a/tests/manager/manager_test.py +++ b/tests/manager/manager_test.py @@ -69,7 +69,7 @@ def test_create_delete_schain(skale, nodes): schains_ids_after = skale.schains_internal.get_all_schains_ids() schains_names = [ - skale.schains.get(sid)['name'] + skale.schains.get(sid).name for sid in schains_ids_after ] assert name in schains_names @@ -81,7 +81,7 @@ def test_create_delete_schain(skale, nodes): schains_ids_after = skale.schains_internal.get_all_schains_ids() schains_names = [ - skale.schains.get(sid)['name'] + skale.schains.get(sid).name for sid in schains_ids_after ] assert name not in schains_names @@ -117,7 +117,7 @@ def test_create_delete_default_schain(skale, nodes): schains_ids_after = skale.schains_internal.get_all_schains_ids() schains_names = [ - skale.schains.get(sid)['name'] + skale.schains.get(sid).name for sid in schains_ids_after ] assert name in schains_names diff --git a/tests/manager/schains_internal_test.py b/tests/manager/schains_internal_test.py index 32f32f8b..9d0f6ada 100644 --- a/tests/manager/schains_internal_test.py +++ b/tests/manager/schains_internal_test.py @@ -36,7 +36,7 @@ def test_get_schain_id_by_index_for_owner(skale, schain): skale.wallet.address, 0 ) schain = skale.schains.get(schain_id) - assert schain['mainnetOwner'] == skale.wallet.address + assert schain.mainnet_owner == skale.wallet.address def test_get_node_ids_for_schain(skale, schain): diff --git a/tests/manager/schains_test.py b/tests/manager/schains_test.py index 20511bee..fec73964 100644 --- a/tests/manager/schains_test.py +++ b/tests/manager/schains_test.py @@ -24,32 +24,51 @@ ) -def test_get(skale): - schain = skale.schains.get(DEFAULT_SCHAIN_ID) +def test_schain_get_plain(skale): + schain = skale.schains.get(DEFAULT_SCHAIN_ID, obj=False) assert list(schain.keys()) == FIELDS - assert [k for k, v in schain.items() if v is None] == [] -def test_get_object(skale): - schain = skale.schains.get(DEFAULT_SCHAIN_ID, obj=True) - assert isinstance(schain, SchainStructure) - assert isinstance(schain.options, SchainOptions) - - -def test_get_by_name(skale): - schain = skale.schains.get(DEFAULT_SCHAIN_ID) - schain_name = schain["name"] - - schain_by_name = skale.schains.get_by_name(schain_name) - assert list(schain_by_name.keys()) == FIELDS - assert schain == schain_by_name +def test_schain_get_object(skale, schain): + schain_id = skale.schains.name_to_id(schain) + schain_struct = skale.schains.get(schain_id) + assert isinstance(schain_struct, SchainStructure) + assert isinstance(schain_struct.options, SchainOptions) + assert schain_struct.name == schain + assert schain_struct.index_in_owner_list == 0 + assert schain_struct.part_of_node == 1 + assert schain_struct.lifetime == 3600 + assert schain_struct.deposit == 0 + assert schain_struct.generation == 1 + assert schain_struct.options == SchainOptions( + multitransaction_mode=False, + threshold_encryption=False, + allocation_type=AllocationType.DEFAULT + ) + assert schain_struct.active + + +def test_get_by_name(skale, schain): + schain_by_name = skale.schains.get_by_name(schain) + assert isinstance(schain_by_name, SchainStructure) + assert schain_by_name.name == schain + assert schain_by_name.index_in_owner_list == 0 + assert schain_by_name.part_of_node == 1 + assert schain_by_name.lifetime == 3600 + assert schain_by_name.deposit == 0 + assert schain_by_name.generation == 1 + assert schain_by_name.options == SchainOptions( + multitransaction_mode=False, + threshold_encryption=False, + allocation_type=AllocationType.DEFAULT + ) + assert schain_by_name.active def test_get_schains_for_owner(skale, schain, empty_account): schains = skale.schains.get_schains_for_owner(skale.wallet.address) assert isinstance(schains, list) - assert len(schains) > 0 - assert set(schains[-1].keys()) == set(FIELDS) + assert schains[-1].mainnet_owner == skale.wallet.address schains = skale.schains.get_schains_for_owner(empty_account.address) assert schains == [] @@ -66,7 +85,7 @@ def test_get_schains_for_node(skale, schain): test_schain = schains_for_node[0] schain_node_ids = skale.schains_internal.get_node_ids_for_schain( - test_schain["name"] + test_schain.name ) assert node_id in schain_node_ids @@ -79,8 +98,19 @@ def test_name_to_id(skale): def test_get_all_schains_ids(skale, schain): schains_ids = skale.schains_internal.get_all_schains_ids() - schain = skale.schains.get(schains_ids[-1]) - assert list(schain.keys()) == FIELDS + schain_struct = skale.schains.get(schains_ids[-1]) + assert schain_struct.name == schain + assert schain_struct.index_in_owner_list == 0 + assert schain_struct.part_of_node == 1 + assert schain_struct.lifetime == 3600 + assert schain_struct.deposit == 0 + assert schain_struct.generation == 1 + assert schain_struct.options == SchainOptions( + multitransaction_mode=False, + threshold_encryption=False, + allocation_type=AllocationType.DEFAULT + ) + assert schain_struct.active def test_get_schain_price(skale): @@ -96,10 +126,10 @@ def test_add_schain_by_foundation(skale, nodes): try: skale.schains.add_schain_by_foundation(lifetime_seconds, type_of_nodes, 0, name) schains_ids_after = skale.schains_internal.get_all_schains_ids() - schains_names = [skale.schains.get(sid)["name"] for sid in schains_ids_after] + schains_names = [skale.schains.get(sid).name for sid in schains_ids_after] assert name in schains_names new_schain = skale.schains.get_by_name(name) - assert new_schain["mainnetOwner"] == skale.wallet.address + assert new_schain.mainnet_owner == skale.wallet.address schain = skale.schains.get_by_name(name, obj=True) assert schain.options.multitransaction_mode is False @@ -110,7 +140,7 @@ def test_add_schain_by_foundation(skale, nodes): schains_ids_after = skale.schains_internal.get_all_schains_ids() - schains_names = [skale.schains.get(sid)["name"] for sid in schains_ids_after] + schains_names = [skale.schains.get(sid).name for sid in schains_ids_after] assert name not in schains_names @@ -164,8 +194,8 @@ def test_add_schain_by_foundation_custom_owner(skale, nodes): ) new_schain = skale.schains.get_by_name(name) - assert new_schain["mainnetOwner"] != skale.wallet.address - assert new_schain["mainnetOwner"] == custom_wallet.address + assert new_schain.mainnet_owner != skale.wallet.address + assert new_schain.mainnet_owner == custom_wallet.address skale.wallet = custom_wallet finally: @@ -174,7 +204,7 @@ def test_add_schain_by_foundation_custom_owner(skale, nodes): schains_ids_after = skale.schains_internal.get_all_schains_ids() - schains_names = [skale.schains.get(sid)["name"] for sid in schains_ids_after] + schains_names = [skale.schains.get(sid).name for sid in schains_ids_after] assert name not in schains_names @@ -198,8 +228,8 @@ def test_add_schain_by_foundation_custom_originator(skale, nodes): ) new_schain = skale.schains.get_by_name(name) - assert new_schain["originator"] != skale.wallet.address - assert new_schain["originator"] == custom_originator.address + assert new_schain.originator != skale.wallet.address + assert new_schain.originator == custom_originator.address finally: if name: @@ -218,7 +248,7 @@ def test_get_active_schains_for_node(skale, nodes, schain): node_id = skale.nodes.node_name_to_index(DEFAULT_NODE_NAME) active_schains = skale.schains.get_active_schains_for_node(node_id) all_schains = skale.schains.get_schains_for_node(node_id) - all_active_schains = [schain for schain in all_schains if schain["active"]] + all_active_schains = [schain for schain in all_schains if schain.active] for active_schain in all_active_schains: assert active_schain in active_schains finally: diff --git a/tests/schain_config/generator_test.py b/tests/schain_config/generator_test.py index 4cfefb9b..d3b510a6 100644 --- a/tests/schain_config/generator_test.py +++ b/tests/schain_config/generator_test.py @@ -17,4 +17,4 @@ def test_get_schain_nodes_with_schains(skale, schain): schain_name = schain nodes_with_schains = get_schain_nodes_with_schains(skale, schain_name) assert isinstance(nodes_with_schains[0]['schains'], list) - assert isinstance(nodes_with_schains[0]['schains'][0]['mainnetOwner'], str) + assert nodes_with_schains[0]['schains'][0].mainnet_owner == skale.wallet.address