Skip to content
Snippets Groups Projects
Commit 967339f7 authored by inso's avatar inso
Browse files

Fixed network errors

When an endpoint is incorrect, let's try the next endpoint
When no peer could be joined, throw an error
parent 4772c227
No related branches found
No related tags found
No related merge requests found
......@@ -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)
......
......@@ -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:
......
......@@ -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)
......
......@@ -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))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment