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): ...@@ -169,6 +169,10 @@ class Community(object):
def nodes(self): def nodes(self):
return self._network.all_nodes return self._network.all_nodes
@property
def network(self):
return self._network
def add_peer(self, peer): def add_peer(self, peer):
self._network.add_node(Node.from_peer(peer)) self._network.add_node(Node.from_peer(peer))
......
...@@ -64,7 +64,6 @@ class Network(QObject): ...@@ -64,7 +64,6 @@ class Network(QObject):
def __del__(self): def __del__(self):
self.must_crawl = False self.must_crawl = False
@pyqtSlot()
def stop_crawling(self): def stop_crawling(self):
self.must_crawl = False self.must_crawl = False
...@@ -80,19 +79,17 @@ class Network(QObject): ...@@ -80,19 +79,17 @@ class Network(QObject):
self._nodes.append(node) self._nodes.append(node)
node.changed.connect(self.nodes_changed) node.changed.connect(self.nodes_changed)
@pyqtSlot() def start_perpetual_crawling(self):
def perpetual_crawling(self):
self.must_crawl = True self.must_crawl = True
while self.must_crawl: while self.must_crawl:
self.nodes = self.crawling(interval=10) self.nodes = self.crawling(interval=10)
self.nodes_changed.disconnect()
for n in self._nodes: for n in self._nodes:
n.changed.connect(self.nodes_changed) n.changed.connect(self.nodes_changed)
def crawling(self, interval=0): def crawling(self, interval=0):
nodes = [] nodes = []
traversed_pubkeys = [] traversed_pubkeys = []
for n in self._nodes: for n in self.nodes:
logging.debug(traversed_pubkeys) logging.debug(traversed_pubkeys)
logging.debug("Peering : next to read : {0} : {1}".format(n.pubkey, logging.debug("Peering : next to read : {0} : {1}".format(n.pubkey,
(n.pubkey not in traversed_pubkeys))) (n.pubkey not in traversed_pubkeys)))
...@@ -103,7 +100,7 @@ class Network(QObject): ...@@ -103,7 +100,7 @@ class Network(QObject):
block_max = max([n.block for n in nodes]) block_max = max([n.block for n in nodes])
for node in [n for n in nodes if n.state == Node.ONLINE]: 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: Offline nodes for too long have to be removed
#TODO: Corrupted nodes should maybe be removed faster ? #TODO: Corrupted nodes should maybe be removed faster ?
......
...@@ -34,6 +34,7 @@ class Node(QObject): ...@@ -34,6 +34,7 @@ class Node(QObject):
self._pubkey = pubkey self._pubkey = pubkey
self._block = block self._block = block
self._state = state self._state = state
self._neighbours = []
@classmethod @classmethod
def from_peer(cls, currency, peer): def from_peer(cls, currency, peer):
...@@ -67,6 +68,10 @@ class Node(QObject): ...@@ -67,6 +68,10 @@ class Node(QObject):
def state(self): def state(self):
return self._state return self._state
@property
def neighbours(self):
return self._neighbours
def check_sync(self, currency, block): def check_sync(self, currency, block):
if self._block < block: if self._block < block:
self._state = Node.DESYNCED self._state = Node.DESYNCED
...@@ -74,9 +79,17 @@ class Node(QObject): ...@@ -74,9 +79,17 @@ class Node(QObject):
self._state = Node.ONLINE self._state = Node.ONLINE
def refresh_state(self, currency): def refresh_state(self, currency):
emit_change = False
try: try:
informations = bma.network.Peering(self.endpoint.conn_handler()).get() informations = bma.network.Peering(self.endpoint.conn_handler()).get()
block = bma.blockchain.Current(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"] block_number = block["number"]
node_pubkey = informations["pubkey"] node_pubkey = informations["pubkey"]
node_currency = informations["currency"] node_currency = informations["currency"]
...@@ -85,14 +98,34 @@ class Node(QObject): ...@@ -85,14 +98,34 @@ class Node(QObject):
block_number = 0 block_number = 0
except RequestException: except RequestException:
self._state = Node.OFFLINE self._state = Node.OFFLINE
emit_change = True
if node_currency != currency: if node_currency != currency:
self.state = Node.CORRUPTED self.state = Node.CORRUPTED
emit_change = True
if block_number != self._block:
self._block = block_number
emit_change = True
self._block = block_number if node_pubkey != self._pubkey:
self._pubkey = node_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)) logging.debug("Read {0} peering".format(self.pubkey))
traversed_pubkeys.append(self.pubkey) traversed_pubkeys.append(self.pubkey)
self.refresh_state(currency) self.refresh_state(currency)
...@@ -100,16 +133,18 @@ class Node(QObject): ...@@ -100,16 +133,18 @@ class Node(QObject):
found_nodes.append(self) found_nodes.append(self)
try: try:
next_peers = bma.network.peering.Peers(self.endpoint.conn_handler()).get() for n in self.neighbours:
for p in next_peers: e = next((e for e in self._endpoints if type(e) is BMAEndpoint))
next_peer = Peer.from_signed_raw("{0}{1}\n".format(p['value']['raw'], peering = bma.network.Peering(self.endpoint.conn_handler()).get()
p['value']['signature'])) peer = Peer.from_signed_raw("{0}{1}\n".format(peering['raw'],
peering['signature']))
node = Node.from_peer(peer)
logging.debug(traversed_pubkeys) logging.debug(traversed_pubkeys)
logging.debug("Traversing : next to read : {0} : {1}".format(next_peer.pubkey, logging.debug("Traversing : next to read : {0} : {1}".format(node.pubkey,
(next_peer.pubkey not in traversed_pubkeys))) (node.pubkey not in traversed_pubkeys)))
next_node = Node.from_peer(next_peer) if node.pubkey not in traversed_pubkeys:
if next_node.pubkey not in traversed_pubkeys: node.peering_traversal(currency, found_nodes,
next_node.peering_traversal(currency, found_nodes, traversed_pubkeys) traversed_pubkeys, interval)
time.sleep(interval) time.sleep(interval)
except RequestException as e: except RequestException as e:
self._state = Node.OFFLINE 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 ...@@ -5,6 +5,8 @@ Created on 20 févr. 2015
''' '''
from PyQt5.QtWidgets import QWidget from PyQt5.QtWidgets import QWidget
from PyQt5.QtCore import QModelIndex, QThread
from ..core.watchers.network import NetworkWatcher
from ..models.network import NetworkTableModel, NetworkFilterProxyModel from ..models.network import NetworkTableModel, NetworkFilterProxyModel
from ..gen_resources.network_tab_uic import Ui_NetworkTabWidget from ..gen_resources.network_tab_uic import Ui_NetworkTabWidget
...@@ -25,4 +27,15 @@ class NetworkTabWidget(QWidget, Ui_NetworkTabWidget): ...@@ -25,4 +27,15 @@ class NetworkTabWidget(QWidget, Ui_NetworkTabWidget):
proxy.setSourceModel(model) proxy.setSourceModel(model)
self.table_network.setModel(proxy) 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.
Finish editing this message first!
Please register or to comment