diff --git a/src/cutecoin/core/account.py b/src/cutecoin/core/account.py index c9da40e575b877a7944acb1bf4844a7135393549..ee64ae1349c6edfdc8c15ec8c9cbedc83044a76c 100644 --- a/src/cutecoin/core/account.py +++ b/src/cutecoin/core/account.py @@ -96,13 +96,7 @@ class Account(object): peer_data = peering.get() peer = Peer.from_signed_raw("{0}{1}\n".format(peer_data['raw'], peer_data['signature'])) - - currency = "" - if peer.blockid != "0-DA39A3EE5E6B4B0D3255BFEF95601890AFD80709": - current = bma.blockchain.Current(ConnectionHandler(server, port)) - block_data = current.get() - currency = block_data['currency'] - logging.debug("Currency : {0}".format(currency)) + currency = peer.currency community = Community.create(currency, peer) self.communities.append(community) diff --git a/src/cutecoin/core/community.py b/src/cutecoin/core/community.py index 4a314a44ec71695c89c74134b84a6667bf3f087c..be398ec58a8194560b6fbdbc786769a65c4b6837 100644 --- a/src/cutecoin/core/community.py +++ b/src/cutecoin/core/community.py @@ -8,6 +8,7 @@ from ucoinpy.api import bma from ucoinpy import PROTOCOL_VERSION from ucoinpy.documents.peer import Peer, Endpoint, BMAEndpoint from ucoinpy.documents.block import Block +from ..tools.exceptions import NoPeerAvailable import logging import time import inspect @@ -44,17 +45,18 @@ class Community(object): currency = json_data['currency'] for data in json_data['peers']: - endpoint_inline = next(e for e in data['endpoints'] - if Endpoint.from_inline(e) is not None) - endpoint = Endpoint.from_inline(endpoint_inline) - try: - peering = bma.network.Peering(endpoint.conn_handler()) - peer_data = peering.get() - peer = Peer.from_signed_raw("{0}{1}\n".format(peer_data['raw'], - peer_data['signature'])) - peers.append(peer) - except: - pass + for e in data['endpoints']: + if Endpoint.from_inline(e) is not None: + endpoint = Endpoint.from_inline(e) + try: + peering = bma.network.Peering(endpoint.conn_handler()) + peer_data = peering.get() + peer = Peer.from_signed_raw("{0}{1}\n".format(peer_data['raw'], + peer_data['signature'])) + peers.append(peer) + break + except: + pass community = cls(currency, peers) return community @@ -103,47 +105,59 @@ class Community(object): members.append(m['pubkey']) return members + def check_current_block(self, endpoint): + if self.last_block is None: + peering = bma.network.Peering(endpoint.conn_handler()).get() + block_number = peering['block'].split('-')[0] + self.last_block = {"request_ts": time.time(), + "number": block_number} + elif self.last_block["request_ts"] + 60 < time.time(): + logging.debug("{0} > {1}".format(self.last_block["request_ts"] + 60, time.time())) + self.last_block["request_ts"] = time.time() + peering = bma.network.Peering(endpoint.conn_handler()).get() + block_number = peering['block'].split('-')[0] + if block_number > self.last_block['number']: + self.last_block["number"] = block_number + self.requests_cache = {} + def request(self, request, req_args={}, get_args={}): for peer in self.peers: - e = next(e for e in peer.endpoints if type(e) is BMAEndpoint) - # We request the current block every five minutes - # If a new block is mined we reset the cache - if self.last_block is None: - block = bma.blockchain.Current(e.conn_handler()).get() - self.last_block = {"request_ts": time.time(), - "number": block['number']} - elif self.last_block["request_ts"] + 60 < time.time(): - logging.debug("{0} > {1}".format(self.last_block["request_ts"] + 60, time.time())) - self.last_block["request_ts"] = time.time() - block = bma.blockchain.Current(e.conn_handler()).get() - if block['number'] > self.last_block['number']: - self.last_block["number"] = block['number'] - self.requests_cache = {} - - cache_key = (hash(request), - hash(tuple(frozenset(sorted(req_args.keys())))), - hash(tuple(frozenset(sorted(req_args.items())))), - hash(tuple(frozenset(sorted(get_args.keys())))), - hash(tuple(frozenset(sorted(get_args.items()))))) - - if cache_key not in self.requests_cache.keys(): - if e.server: - logging.debug("Connecting to {0}:{1}".format(e.server, - e.port)) - else: - logging.debug("Connecting to {0}:{1}".format(e.ipv4, - e.port)) - - req = request(e.conn_handler(), **req_args) - data = req.get(**get_args) - if inspect.isgenerator(data): - cached_data = [] - for d in data: - cached_data.append(d) - self.requests_cache[cache_key] = cached_data + try: + e = next(e for e in peer.endpoints if type(e) is BMAEndpoint) + # We request the current block every five minutes + # If a new block is mined we reset the cache + + self.check_current_block(e) + cache_key = (hash(request), + hash(tuple(frozenset(sorted(req_args.keys())))), + hash(tuple(frozenset(sorted(req_args.items())))), + hash(tuple(frozenset(sorted(get_args.keys())))), + hash(tuple(frozenset(sorted(get_args.items()))))) + + if cache_key not in self.requests_cache.keys(): + if e.server: + logging.debug("Connecting to {0}:{1}".format(e.server, + e.port)) + else: + logging.debug("Connecting to {0}:{1}".format(e.ipv4, + e.port)) + + req = request(e.conn_handler(), **req_args) + data = req.get(**get_args) + if inspect.isgenerator(data): + cached_data = [] + for d in data: + cached_data.append(d) + self.requests_cache[cache_key] = cached_data + else: + self.requests_cache[cache_key] = data + except ValueError as e: + if '502' in str(e): + continue else: - self.requests_cache[cache_key] = data + raise return self.requests_cache[cache_key] + raise NoPeerAvailable(self.currency) def post(self, request, req_args={}, post_args={}): for peer in self.peers: diff --git a/src/cutecoin/gui/process_cfg_community.py b/src/cutecoin/gui/process_cfg_community.py index b58215caa53b80885a85904fef1d1962a7864dd5..b409b5b6f2f375093989d1316beb2003abc5f191 100644 --- a/src/cutecoin/gui/process_cfg_community.py +++ b/src/cutecoin/gui/process_cfg_community.py @@ -9,13 +9,12 @@ from ucoinpy.api import bma from ucoinpy.api.bma import ConnectionHandler from ucoinpy.documents.peer import Peer -from cutecoin.gen_resources.community_cfg_uic import Ui_CommunityConfigurationDialog -from PyQt5.QtWidgets import QDialog, QMenu, QMessageBox, QInputDialog, QLineEdit -from PyQt5.QtCore import QSignalMapper -from cutecoin.models.peering import PeeringTreeModel -from cutecoin.core.person import Person -from cutecoin.tools.exceptions import PersonNotFoundError -from cutecoin.tools.exceptions import Error +from PyQt5.QtWidgets import QDialog, QMenu, QMessageBox + +from ..gen_resources.community_cfg_uic import Ui_CommunityConfigurationDialog +from ..models.peering import PeeringTreeModel +from ..core.person import Person +from ..tools.exceptions import PersonNotFoundError, NoPeerAvailable class Step(): @@ -41,7 +40,7 @@ class StepPageInit(Step): peer_data = bma.network.Peering(ConnectionHandler(server, port)) peer_data.get()['raw'] except: - QMessageBox.critical(self, "Server error", + QMessageBox.critical(self.config_dialog, "Server error", "Cannot get node peering") return False return True @@ -54,7 +53,12 @@ class StepPageInit(Step): port = self.config_dialog.spinbox_port.value() account = self.config_dialog.account logging.debug("Account : {0}".format(account)) - self.config_dialog.community = account.add_community(server, port) + try: + self.config_dialog.community = account.add_community(server, port) + except NoPeerAvailable: + QMessageBox.critical(self.config_dialog, "Server Error", + "Canno't join any peer in this community.") + raise def display_page(self): self.config_dialog.button_previous.setEnabled(False) diff --git a/src/cutecoin/tools/exceptions.py b/src/cutecoin/tools/exceptions.py index 94be374cbc3ece9d8a198f92c467ee7ba5ce6325..2397d91d3eec7b1edbe5b031f463a5673922ba74 100644 --- a/src/cutecoin/tools/exceptions.py +++ b/src/cutecoin/tools/exceptions.py @@ -130,3 +130,17 @@ class NotEnoughMoneyError(Error): currency, nb_inputs, requested)) + + +class NoPeerAvailable(Error): + ''' + Exception raised when a community doesn't have any + peer available. + ''' + def __init__(self, currency): + ''' + Constructor + ''' + super() .__init__( + "No peer found in {0} community" + .format(currency))