diff --git a/src/sakia/app.py b/src/sakia/app.py index 41665a5d188b84a7928f3618aee0a2203bb052d3..6e4db32bb516de8a7bd3812feb42f656ab295516 100644 --- a/src/sakia/app.py +++ b/src/sakia/app.py @@ -153,7 +153,7 @@ class Application(QObject): TransactionsProcessor.instanciate(self).cleanup_connection(connection, connections_processor.pubkeys()) if not connections_processor.connections(): - NodesProcessor.instanciate(self).drop_all() + NodesProcessor.instanciate(self).drop_all(self.currency) self.db.commit() self.start_coroutines() diff --git a/src/sakia/data/graphs/base_graph.py b/src/sakia/data/graphs/base_graph.py index 0c4436d355687d20fa4c25ad4fd04d9c43214f14..b7e5f83565d166de3ad18461794e18085f7b5700 100644 --- a/src/sakia/data/graphs/base_graph.py +++ b/src/sakia/data/graphs/base_graph.py @@ -113,7 +113,7 @@ class BaseGraph(QObject): def add_certifier_node(self, certifier, identity, certification, node_status): metadata = { - 'text': certifier.uid, + 'text': certifier.uid if certifier.uid else certifier.pubkey[:12], 'tooltip': certifier.pubkey, 'identity': certifier, 'status': node_status @@ -136,7 +136,7 @@ class BaseGraph(QObject): def add_certified_node(self, identity, certified, certification, node_status): metadata = { - 'text': certified.uid, + 'text': certified.uid if certified.uid else certified.pubkey[:12], 'tooltip': certified.pubkey, 'identity': certified, 'status': node_status diff --git a/src/sakia/data/processors/certifications.py b/src/sakia/data/processors/certifications.py index c15910870fde4fdd14f9b4d3ca181f8b50ff132d..6185ce0e424bf3385d2bd78a020ba9a59d55e3ca 100644 --- a/src/sakia/data/processors/certifications.py +++ b/src/sakia/data/processors/certifications.py @@ -92,85 +92,6 @@ class CertificationsProcessor: except sqlite3.IntegrityError: self._certifications_repo.update(cert) - async def initialize_certifications(self, identity, log_stream): - """ - Initialize certifications to and from a given identity - :param sakia.data.entities.Identity identity: - :param function log_stream: - """ - log_stream("Requesting certifiers of data") - identities = list() - certifiers = list() - try: - data = await self._bma_connector.get(identity.currency, bma.wot.certifiers_of, - req_args={'search': identity.pubkey}) - - for certifier_data in data['certifications']: - certification = Certification(currency=identity.currency, - certified=identity.pubkey, - certifier=certifier_data['pubkey'], - block=certifier_data['cert_time']['block'], - timestamp=certifier_data['cert_time']['medianTime'], - signature=certifier_data['signature']) - other_identity = Identity(currency=identity.currency, - pubkey=certifier_data['pubkey'], - uid=certifier_data['uid'], - blockstamp=certifier_data['sigDate'], - member=certifier_data['isMember']) - if certifier_data['written']: - certification.written_on = certifier_data['written']['number'] - - certifiers.append(certification) - identities.append(other_identity) - except errors.DuniterError as e: - if e.ucode in (errors.NO_MATCHING_IDENTITY, errors.NO_MEMBER_MATCHING_PUB_OR_UID): - logging.debug("Certifiers of error : {0}".format(str(e))) - else: - raise - - log_stream("Requesting certified by data") - certified = list() - try: - data = await self._bma_connector.get(identity.currency, bma.wot.certified_by, - req_args={'search': identity.pubkey}) - for certified_data in data['certifications']: - certification = Certification(currency=identity.currency, - certifier=identity.pubkey, - certified=certified_data['pubkey'], - block=certified_data['cert_time']['block'], - timestamp=certified_data['cert_time']['medianTime'], - signature=certified_data['signature']) - other_identity = Identity(currency=identity.currency, - pubkey=certified_data['pubkey'], - uid=certified_data['uid'], - blockstamp=certified_data['sigDate'], - member=certified_data['isMember']) - if certified_data['written']: - certification.written_on = certified_data['written']['number'] - - certified.append(certification) - identities.append(other_identity) - except errors.DuniterError as e: - if e.ucode in (errors.NO_MATCHING_IDENTITY, errors.NO_MEMBER_MATCHING_PUB_OR_UID): - logging.debug("Certified by error : {0}".format(str(e))) - else: - raise - - log_stream('Commiting certifications...') - for i, cert in enumerate(certifiers + certified): - log_stream('Certification {0}/{1}'.format(i, len(certifiers + certified))) - self.insert_or_update_certification(cert) - await asyncio.sleep(0) - - log_stream('Commiting identities...') - for i, idty in enumerate(identities): - log_stream('Identity {0}/{1}'.format(i, len(identities))) - try: - self._identities_repo.insert(idty) - except sqlite3.IntegrityError: - self._identities_repo.update(idty) - await asyncio.sleep(0) - def cleanup_connection(self, connection, connections_pubkeys): """ Cleanup connections data after removal diff --git a/src/sakia/data/processors/identities.py b/src/sakia/data/processors/identities.py index 34fd2be02a1d29ac1e2f57c662d4888bf446d08f..1ed376057894ad634625db4a3043a6d633608b01 100644 --- a/src/sakia/data/processors/identities.py +++ b/src/sakia/data/processors/identities.py @@ -42,27 +42,23 @@ class IdentitiesProcessor: for idty in identities: if idty.blockstamp > found_identity.blockstamp: found_identity = idty - if not found_identity: - tries = 0 - while tries < 3: - try: - data = await self._bma_connector.get(currency, bma.wot.lookup, req_args={'search': pubkey}) - found_identity = None - for result in data['results']: - if result["pubkey"] == pubkey: - uids = result['uids'] - for uid_data in uids: - identity = Identity(currency, pubkey) - identity.uid = uid_data['uid'] - identity.blockstamp = block_uid(uid_data['meta']['timestamp']) - identity.signature = uid_data['self'] - if identity.blockstamp > found_identity.blockstamp: - found_identity = identity - except (errors.DuniterError, asyncio.TimeoutError, ClientError) as e: - tries += 1 - self._logger.debug(str(e)) - except NoPeerAvailable as e: - self._logger.debug(str(e)) + if not found_identity.uid: + try: + data = await self._bma_connector.get(currency, bma.wot.lookup, req_args={'search': pubkey}) + for result in data['results']: + if result["pubkey"] == pubkey: + uids = result['uids'] + for uid_data in uids: + identity = Identity(currency, pubkey) + identity.uid = uid_data['uid'] + identity.blockstamp = block_uid(uid_data['meta']['timestamp']) + identity.signature = uid_data['self'] + if identity.blockstamp >= found_identity.blockstamp: + found_identity = identity + except (errors.DuniterError, asyncio.TimeoutError, ClientError) as e: + self._logger.debug(str(e)) + except NoPeerAvailable as e: + self._logger.debug(str(e)) return found_identity async def lookup(self, currency, text): diff --git a/src/sakia/data/processors/nodes.py b/src/sakia/data/processors/nodes.py index c817f505e800118ce8b09d09f4204da2d4638e91..c8398543c99b05ad50724b837c1bbdafe8f93caa 100644 --- a/src/sakia/data/processors/nodes.py +++ b/src/sakia/data/processors/nodes.py @@ -141,7 +141,8 @@ class NodesProcessor: self._repo.update(node) return node - def drop_all(self): + def drop_all(self, currency): nodes = self._repo.get_all() for n in nodes: - self._repo.drop(n) \ No newline at end of file + if n.pubkey not in ROOT_SERVERS[currency].keys(): + self._repo.drop(n) \ No newline at end of file diff --git a/src/sakia/gui/dialogs/certification/model.py b/src/sakia/gui/dialogs/certification/model.py index c1ba9f6f6dcdb58fb77e1268f341010389a4cfcc..783798edb113a6e70fe1dec8c4f4292f5f218eb2 100644 --- a/src/sakia/gui/dialogs/certification/model.py +++ b/src/sakia/gui/dialogs/certification/model.py @@ -97,5 +97,4 @@ class CertificationModel(QObject): self.connection.uid) self.app.db.commit() self.app.identity_changed.emit(connection_identity) - self.app.identity_changed.emit(identity) return result diff --git a/src/sakia/gui/dialogs/connection_cfg/model.py b/src/sakia/gui/dialogs/connection_cfg/model.py index 2701ab3b25ca2a61dfbb4683d5f872c047544ee0..c1b4f760fb2a2a1040c46712f58538146402e339 100644 --- a/src/sakia/gui/dialogs/connection_cfg/model.py +++ b/src/sakia/gui/dialogs/connection_cfg/model.py @@ -1,12 +1,9 @@ import aiohttp from PyQt5.QtCore import QObject -from duniterpy.documents import BlockUID, BMAEndpoint, SecuredBMAEndpoint -from duniterpy.api import bma, errors from duniterpy.key import SigningKey -from sakia.data.entities import Connection, Identity, Node -from sakia.data.connectors import NodeConnector -from sakia.data.processors import ConnectionsProcessor, NodesProcessor, BlockchainProcessor, \ - SourcesProcessor, CertificationsProcessor, TransactionsProcessor, DividendsProcessor, IdentitiesProcessor +from sakia.data.entities import Connection +from sakia.data.processors import ConnectionsProcessor, BlockchainProcessor, \ + SourcesProcessor, TransactionsProcessor, DividendsProcessor, IdentitiesProcessor class ConnectionConfigModel(QObject): @@ -85,8 +82,7 @@ class ConnectionConfigModel(QObject): :param function log_stream: a method to log data in the screen :return: """ - certifications_processor = CertificationsProcessor.instanciate(self.app) - await certifications_processor.initialize_certifications(identity, log_stream) + await self.app.identities_service.initialize_certifications(identity, log_stream) async def initialize_transactions(self, identity, log_stream): """ diff --git a/src/sakia/services/identities.py b/src/sakia/services/identities.py index cff75417068cf0a3ece30871549c5fdd574c3bdf..f6790d9f86b736a68d401b04a50374e2e4c5345b 100644 --- a/src/sakia/services/identities.py +++ b/src/sakia/services/identities.py @@ -113,8 +113,8 @@ class IdentitiesService(QObject): async def load_certs_in_lookup(self, identity, certifiers, certified): """ :param sakia.data.entities.Identity identity: the identity - :param sakia.data.entities.Certification certifiers: the list of certifiers got in /wot/certifiers-of - :param sakia.data.entities.Certification certified: the list of certified got in /wot/certified-by + :param list[sakia.data.entities.Certification] certifiers: the list of certifiers got in /wot/certifiers-of + :param list[sakia.data.entities.Certification] certified: the list of certified got in /wot/certified-by """ try: lookup_data = await self._bma_connector.get(self.currency, bma.wot.lookup, @@ -230,6 +230,45 @@ class IdentitiesService(QObject): logging.debug(str(e)) return certifications + async def initialize_certifications(self, identity, log_stream): + """ + Initialize certifications to and from a given identity + :param sakia.data.entities.Identity identity: + :param function log_stream: + """ + log_stream("Requesting certifiers of data") + certifiers = await self.load_certifiers_of(identity) + + log_stream("Requesting certified by data") + certified = await self.load_certified_by(identity) + + log_stream("Requesting lookup data") + certifiers, certified = await self.load_certs_in_lookup(identity, certifiers, certified) + + log_stream("Requesting identities of certifications") + identities = [] + i = 0 + nb_certs = len(certified + certifiers) + for cert in certifiers: + log_stream("Requesting identity... {0}/{1}".format(i, nb_certs)) + i += 1 + certifier = self.get_identity(cert.certifier) + if not certifier: + certifier = await self.find_from_pubkey(cert.certifier) + identities.append(certifier) + + for cert in certified: + log_stream("Requesting identity... {0}/{1}".format(i, nb_certs)) + i += 1 + certified = self.get_identity(cert.certified) + if not certified: + certified = await self.find_from_pubkey(cert.certified) + identities.append(certified) + + log_stream("Commiting identities...") + for idty in identities: + self._identities_processor.insert_or_update_identity(idty) + def _parse_revocations(self, block): """ Parse revoked pubkeys found in a block and refresh local data diff --git a/tests/conftest.py b/tests/conftest.py index c81f172703141fefb5ee88d2684726454e36655b..e52361fbc9fbc7e7981f9fe6356d0f0375ee055a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -73,7 +73,6 @@ def application(event_loop, meta_repo, sakia_options, app_data, user_parameters) parameters=user_parameters, db=meta_repo, currency="test_currency") - app.documents_service = DocumentsService.instanciate(app) return app @@ -91,6 +90,7 @@ def fake_server(application, event_loop): state=Node.ONLINE, software="duniter", version="0.40.2")) + application.instanciate_services() return server @@ -203,7 +203,6 @@ def application_with_one_connection(application, simple_fake_server, bob): membership_type=bob_ms.type, membership_written_on=simple_fake_server.forge.blocks[bob_ms.written_on].number) application.db.identities_repo.insert(bob_identity) - application.instanciate_services() application.switch_language() return application