diff --git a/src/cutecoin/core/account.py b/src/cutecoin/core/account.py index 77fed99695ecdd3944b5c2537b6b5fa89874ed7d..b25b56fccf4764c0d3ae45393c245e72b97f67ec 100644 --- a/src/cutecoin/core/account.py +++ b/src/cutecoin/core/account.py @@ -44,7 +44,10 @@ def relative(units, community): :param cutecoin.core.community.Community community: Community instance :return: float """ - return units / float(community.dividend) + if community.dividend > 0: + return units / float(community.dividend) + else: + return 0 def quantitative_zerosum(units, community): diff --git a/src/cutecoin/core/net/api/bma/__init__.py b/src/cutecoin/core/net/api/bma/__init__.py index 1b6b94bcd252ff8a5c49a1a71636f956eeee2adb..adaa1dcaa36d8087e5b1a3e3e4a4f1ff6bbf0104 100644 --- a/src/cutecoin/core/net/api/bma/__init__.py +++ b/src/cutecoin/core/net/api/bma/__init__.py @@ -2,8 +2,8 @@ __all__ = ['api'] -from PyQt5.QtNetwork import QNetworkRequest -from PyQt5.QtCore import QUrl, QUrlQuery +from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply +from PyQt5.QtCore import QUrl, QUrlQuery, QTimer import logging logger = logging.getLogger("ucoin") @@ -97,8 +97,21 @@ class API(object): url.setQuery(query) request = QNetworkRequest(url) logging.debug(url.toString()) + reply = self.conn_handler.network_manager.get(request) + def onTimeout(reply): + logging.debug("Timeout error on reply") + reply.setError(QNetworkReply.TimeoutError, "Timeout error") + reply.abort() + + timer = QTimer() + timer.setInterval(100) + timer.timeout.connect(lambda: onTimeout(reply)) + timer.start() + #reply.downloadProgress.connect(lambda: timer.start(10000)) + reply.finished.connect(timer.stop) + return reply def requests_post(self, path, **kwargs): @@ -124,6 +137,12 @@ class API(object): reply = self.conn_handler.network_manager.post(request, post_data.toString(QUrl.FullyEncoded).encode('utf-8')) logging.debug(url.toString(QUrl.FullyEncoded)) + timer = QTimer() + timer.setInterval(15000) + timer.timeout.connect(reply.abort) + reply.downloadProgress.connect(lambda: timer.start(15000)) + reply.finished.connect(timer.stop) + return reply from . import network, blockchain, tx, wot, ud, node \ No newline at end of file diff --git a/src/cutecoin/core/net/node.py b/src/cutecoin/core/net/node.py index 80ff1a3aad56f693030a9cdbc822e084aa875f57..7ff7d37d9e91ce51af19dceb987d58e2cd3d71cf 100644 --- a/src/cutecoin/core/net/node.py +++ b/src/cutecoin/core/net/node.py @@ -89,7 +89,8 @@ class Node(QObject): if peer.currency != currency: raise InvalidNodeCurrency(peer.currency, currency) - node = cls(network_manager, peer.currency, peer.endpoints, + node = cls(network_manager, peer.currency, + [Endpoint.from_inline(e.inline()) for e in peer.endpoints], "", peer.pubkey, 0, Node.ONLINE, time.time(), {'root': "", 'leaves': []}, "", "") logging.debug("Node from address : {:}".format(str(node))) @@ -110,7 +111,9 @@ class Node(QObject): if peer.currency != currency: raise InvalidNodeCurrency(peer.currency, currency) - node = cls(network_manager, peer.currency, peer.endpoints, "", pubkey, 0, + node = cls(network_manager, peer.currency, + [Endpoint.from_inline(e.inline()) for e in peer.endpoints], + "", pubkey, 0, Node.ONLINE, time.time(), {'root': "", 'leaves': []}, "", "") @@ -268,13 +271,13 @@ class Node(QObject): self.state = Node.ONLINE def check_noerror(self, error_code, status_code): - if error_code != QNetworkReply.NoError: - if self.state == Node.OFFLINE: - self.state = Node.ONLINE - return False - if status_code == 503: - return False - return True + if error_code == QNetworkReply.NoError: + if status_code in (200, 404): + if self.state == Node.OFFLINE: + self.state = Node.ONLINE + return True + self.state = Node.OFFLINE + return False @pyqtSlot() def refresh(self): @@ -294,7 +297,6 @@ class Node(QObject): logging.debug("Requesting {0}".format(conn_handler)) reply = qtbma.blockchain.Current(conn_handler).get() - reply.finished.connect(self.handle_block_reply) @pyqtSlot() @@ -437,10 +439,10 @@ class Node(QObject): if self.check_noerror(reply.error(), status_code): strdata = bytes(reply.readAll()).decode('utf-8') leaf_data = json.loads(strdata) - doc = Peer.from_signed_raw("{0}{1}\n".format(leaf_data['leaf']['value']['raw'], + peer_doc = Peer.from_signed_raw("{0}{1}\n".format(leaf_data['leaf']['value']['raw'], leaf_data['leaf']['value']['signature'])) pubkey = leaf_data['leaf']['value']['pubkey'] - self.neighbour_found.emit(doc, pubkey) + self.neighbour_found.emit(peer_doc, pubkey) else: logging.debug("Error in leaf reply") diff --git a/src/cutecoin/core/registry/identities.py b/src/cutecoin/core/registry/identities.py index 17d6d46b6f74db1306de42d046d6fce4e1975925..3810908a3f044f9d314ab133f87ebc7dd0f7cb2f 100644 --- a/src/cutecoin/core/registry/identities.py +++ b/src/cutecoin/core/registry/identities.py @@ -1,5 +1,4 @@ -from PyQt5.QtCore import QObject, pyqtSlot, pyqtSignal - +from PyQt5.QtNetwork import QNetworkReply from cutecoin.core.net.api import bma as qtbma from .identity import Identity @@ -63,7 +62,7 @@ class IdentitiesRegistry: identity = Identity.empty(pubkey) self._instances[pubkey] = identity reply = community.bma_access.simple_request(qtbma.wot.Lookup, req_args={'search': pubkey}) - reply.finished.connect(lambda: self.handle_lookup(reply, identity)) + reply.finished.connect(lambda: self.handle_lookup(reply, identity, community)) return identity @asyncio.coroutine @@ -100,28 +99,37 @@ class IdentitiesRegistry: yield from future_identity return identity - def handle_lookup(self, reply, identity): + def handle_lookup(self, reply, identity, community, tries=0): """ :param cutecoin.core.registry.identity.Identity identity: The looked up identity :return: """ - strdata = bytes(reply.readAll()).decode('utf-8') - data = json.loads(strdata) - - timestamp = 0 - for result in data['results']: - if result["pubkey"] == identity.pubkey: - uids = result['uids'] - identity_uid = "" - for uid_data in uids: - if uid_data["meta"]["timestamp"] > timestamp: - timestamp = uid_data["meta"]["timestamp"] - identity_uid = uid_data["uid"] - identity.uid = identity_uid - identity.status = Identity.FOUND - logging.debug("Lookup : found {0}".format(identity)) - identity.inner_data_changed.emit(str(qtbma.wot.Lookup)) - return + + if reply.error() == QNetworkReply.NoError: + strdata = bytes(reply.readAll()).decode('utf-8') + data = json.loads(strdata) + + timestamp = 0 + for result in data['results']: + if result["pubkey"] == identity.pubkey: + uids = result['uids'] + identity_uid = "" + for uid_data in uids: + if uid_data["meta"]["timestamp"] > timestamp: + timestamp = uid_data["meta"]["timestamp"] + identity_uid = uid_data["uid"] + identity.uid = identity_uid + identity.status = Identity.FOUND + logging.debug("Lookup : found {0}".format(identity)) + identity.inner_data_changed.emit(str(qtbma.wot.Lookup)) + else: + logging.debug("Error in reply : {0}".format(reply.error())) + if tries < 3: + tries += 1 + reply = community.bma_access.simple_request(qtbma.wot.Lookup, + req_args={'search': identity.pubkey}) + reply.finished.connect(lambda: self.handle_lookup(reply, identity, + community, tries=tries)) def from_metadata(self, metadata): """ diff --git a/src/cutecoin/core/registry/identity.py b/src/cutecoin/core/registry/identity.py index 23d35a1c509ec6522d204ebf15fe5b7a1e53c3db..746d97793cb3e578b230f48d081b1c9d353f927f 100644 --- a/src/cutecoin/core/registry/identity.py +++ b/src/cutecoin/core/registry/identity.py @@ -102,9 +102,11 @@ class Identity(QObject): if search != qtbma.blockchain.Membership.null_value: if len(search['memberships']) > 0: membership_data = search['memberships'][0] - return community.get_block(membership_data['blockNumber'])['medianTime'] - else: - return None + block = community.bma_access.get(self, qtbma.blockchain.Block, + req_args={'number': membership_data['blockNumber']}) + if block != qtbma.blockchain.Block.null_value: + return block['medianTime'] + return None else: raise MembershipNotFoundError(self.pubkey, community.name) @@ -129,7 +131,6 @@ class Identity(QObject): return expiration_date - #TODO: Manage 'OUT' memberships ? Maybe ? def membership(self, community): """