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

Network background crawling : done

parent 30c83969
No related branches found
No related tags found
No related merge requests found
......@@ -169,6 +169,10 @@ class Community(object):
def nodes(self):
return self._network.all_nodes
@property
def network(self):
return self._network
def add_peer(self, peer):
self._network.add_node(Node.from_peer(peer))
......
......@@ -64,7 +64,6 @@ class Network(QObject):
def __del__(self):
self.must_crawl = False
@pyqtSlot()
def stop_crawling(self):
self.must_crawl = False
......@@ -80,19 +79,17 @@ class Network(QObject):
self._nodes.append(node)
node.changed.connect(self.nodes_changed)
@pyqtSlot()
def perpetual_crawling(self):
def start_perpetual_crawling(self):
self.must_crawl = True
while self.must_crawl:
self.nodes = self.crawling(interval=10)
self.nodes_changed.disconnect()
for n in self._nodes:
n.changed.connect(self.nodes_changed)
def crawling(self, interval=0):
nodes = []
traversed_pubkeys = []
for n in self._nodes:
for n in self.nodes:
logging.debug(traversed_pubkeys)
logging.debug("Peering : next to read : {0} : {1}".format(n.pubkey,
(n.pubkey not in traversed_pubkeys)))
......@@ -103,7 +100,7 @@ class Network(QObject):
block_max = max([n.block for n in nodes])
for node in [n for n in nodes if n.state == Node.ONLINE]:
node.check_sync(block_max)
node.check_sync(self.currency, block_max)
#TODO: Offline nodes for too long have to be removed
#TODO: Corrupted nodes should maybe be removed faster ?
......
......@@ -34,6 +34,7 @@ class Node(QObject):
self._pubkey = pubkey
self._block = block
self._state = state
self._neighbours = []
@classmethod
def from_peer(cls, currency, peer):
......@@ -67,6 +68,10 @@ class Node(QObject):
def state(self):
return self._state
@property
def neighbours(self):
return self._neighbours
def check_sync(self, currency, block):
if self._block < block:
self._state = Node.DESYNCED
......@@ -74,9 +79,17 @@ class Node(QObject):
self._state = Node.ONLINE
def refresh_state(self, currency):
emit_change = False
try:
informations = bma.network.Peering(self.endpoint.conn_handler()).get()
block = bma.blockchain.Current(self.endpoint.conn_handler()).get()
peers_data = bma.network.peering.Peers(self.endpoint.conn_handler()).get()
neighbours = []
for p in peers_data:
peer = Peer.from_signed_raw("{0}{1}\n".format(p['value']['raw'],
p['value']['signature']))
neighbours.append(peer.endpoints)
block_number = block["number"]
node_pubkey = informations["pubkey"]
node_currency = informations["currency"]
......@@ -85,14 +98,34 @@ class Node(QObject):
block_number = 0
except RequestException:
self._state = Node.OFFLINE
emit_change = True
if node_currency != currency:
self.state = Node.CORRUPTED
emit_change = True
if block_number != self._block:
self._block = block_number
emit_change = True
if node_pubkey != self._pubkey:
self._pubkey = node_pubkey
emit_change = True
def peering_traversal(self, currency, found_nodes, traversed_pubkeys, interval):
new_inlines = [e.inline() for e in [n for n in self._neighbours]]
last_inlines = [e.inline() for e in [n for n in self._neighbours]]
hash_new_neighbours = hash(tuple(frozenset(sorted(new_inlines))))
hash_last_neighbours = hash(tuple(frozenset(sorted(last_inlines))))
if hash_new_neighbours != hash_last_neighbours:
self._neighbours = neighbours
emit_change = True
if emit_change:
self.changed.emit()
def peering_traversal(self, currency, found_nodes,
traversed_pubkeys, interval):
logging.debug("Read {0} peering".format(self.pubkey))
traversed_pubkeys.append(self.pubkey)
self.refresh_state(currency)
......@@ -100,16 +133,18 @@ class Node(QObject):
found_nodes.append(self)
try:
next_peers = bma.network.peering.Peers(self.endpoint.conn_handler()).get()
for p in next_peers:
next_peer = Peer.from_signed_raw("{0}{1}\n".format(p['value']['raw'],
p['value']['signature']))
for n in self.neighbours:
e = next((e for e in self._endpoints if type(e) is BMAEndpoint))
peering = bma.network.Peering(self.endpoint.conn_handler()).get()
peer = Peer.from_signed_raw("{0}{1}\n".format(peering['raw'],
peering['signature']))
node = Node.from_peer(peer)
logging.debug(traversed_pubkeys)
logging.debug("Traversing : next to read : {0} : {1}".format(next_peer.pubkey,
(next_peer.pubkey not in traversed_pubkeys)))
next_node = Node.from_peer(next_peer)
if next_node.pubkey not in traversed_pubkeys:
next_node.peering_traversal(currency, found_nodes, traversed_pubkeys)
logging.debug("Traversing : next to read : {0} : {1}".format(node.pubkey,
(node.pubkey not in traversed_pubkeys)))
if node.pubkey not in traversed_pubkeys:
node.peering_traversal(currency, found_nodes,
traversed_pubkeys, interval)
time.sleep(interval)
except RequestException as e:
self._state = Node.OFFLINE
'''
Created on 27 févr. 2015
@author: inso
'''
from PyQt5.QtCore import QObject, pyqtSlot
class NetworkWatcher(QObject):
'''
This will crawl the network to always
have up to date informations about the nodes
'''
def __init__(self, community):
super().__init__()
self.community = community
@pyqtSlot()
def watch(self):
self.community.network.moveToThread(self.thread())
self.community.network.start_perpetual_crawling()
@pyqtSlot()
def stop(self):
self.community.network.stop_crawling()
'''
Created on 27 févr. 2015
@author: inso
'''
class NodesWatcher(object):
'''
This will crawl the network to always
have up to date informations about the nodes
'''
def __init__(self):
'''
Constructor
'''
......@@ -5,6 +5,8 @@ Created on 20 févr. 2015
'''
from PyQt5.QtWidgets import QWidget
from PyQt5.QtCore import QModelIndex, QThread
from ..core.watchers.network import NetworkWatcher
from ..models.network import NetworkTableModel, NetworkFilterProxyModel
from ..gen_resources.network_tab_uic import Ui_NetworkTabWidget
......@@ -25,4 +27,15 @@ class NetworkTabWidget(QWidget, Ui_NetworkTabWidget):
proxy.setSourceModel(model)
self.table_network.setModel(proxy)
self.network_watcher = NetworkWatcher(community)
self.watcher_thread = QThread()
self.network_watcher.moveToThread(self.watcher_thread)
self.watcher_thread.started.connect(self.network_watcher.watch)
self.watcher_thread.start()
community.network.nodes_changed.connect(self.refresh_nodes)
def refresh_nodes(self):
self.table_network.sourceModel.dataChanged.emit(QModelIndex(), QModelIndex())
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment