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

Network monitoring enhancement

- Displaying network quality in status bar
- Network crawling now triggers when a new block is mined
- Blockchain watching only refresh caches when the network
crawler detects a new block
parent 2607d1dd
No related branches found
No related tags found
No related merge requests found
...@@ -291,6 +291,6 @@ PreviousIssuer: {1}\n".format(self.prev_hash, self.prev_issuer) ...@@ -291,6 +291,6 @@ PreviousIssuer: {1}\n".format(self.prev_hash, self.prev_issuer)
doc += "Transactions:\n" doc += "Transactions:\n"
for transaction in self.transactions: for transaction in self.transactions:
doc += "{0}\n".format(transaction.inline()) doc += "{0}\n".format(transaction.compact())
return doc return doc
...@@ -120,6 +120,7 @@ class Community(QObject): ...@@ -120,6 +120,7 @@ class Community(QObject):
self.currency = currency self.currency = currency
self._network = network self._network = network
self._cache = Cache(self) self._cache = Cache(self)
self._network.new_block_mined.connect(self.new_block_mined)
self._cache.refresh() self._cache.refresh()
...@@ -297,6 +298,17 @@ class Community(QObject): ...@@ -297,6 +298,17 @@ class Community(QObject):
''' '''
return self._network return self._network
def network_quality(self):
'''
Get a ratio of the synced nodes vs the rest
'''
synced = len(self._network.synced_nodes)
online = len(self._network.online_nodes)
total = len(self._network.all_nodes)
ratio_synced = synced * 2 / total
ratio_unsynced = (online - synced) / total
return (ratio_synced + ratio_unsynced) / 3
@property @property
def parameters(self): def parameters(self):
''' '''
......
...@@ -17,6 +17,7 @@ class Network(QObject): ...@@ -17,6 +17,7 @@ class Network(QObject):
given community. given community.
''' '''
nodes_changed = pyqtSignal() nodes_changed = pyqtSignal()
new_block_mined = pyqtSignal(int)
stopped_perpetual_crawling = pyqtSignal() stopped_perpetual_crawling = pyqtSignal()
def __init__(self, currency, nodes): def __init__(self, currency, nodes):
...@@ -44,12 +45,13 @@ class Network(QObject): ...@@ -44,12 +45,13 @@ class Network(QObject):
:param node: The first knew node of the network :param node: The first knew node of the network
''' '''
nodes = [node] nodes = [node]
network = cls(node.currency, nodes) network = cls(node.currency, nodes, 0)
nodes = network.crawling() nodes = network.crawling()
block_max = max([n.block for n in nodes]) block_max = max([n.block for n in nodes])
for node in nodes: for node in nodes:
node.check_sync(block_max) node.check_sync(block_max)
network._nodes = nodes network._nodes = nodes
network.latest_block = block_max
return network return network
def merge_with_json(self, json_data): def merge_with_json(self, json_data):
...@@ -133,6 +135,13 @@ class Network(QObject): ...@@ -133,6 +135,13 @@ class Network(QObject):
''' '''
return self._nodes.copy() return self._nodes.copy()
@property
def latest_block(self):
'''
Get latest block known
'''
return max([n.block for n in self._nodes])
def add_nodes(self, node): def add_nodes(self, node):
''' '''
Add a node to the network. Add a node to the network.
...@@ -147,6 +156,7 @@ class Network(QObject): ...@@ -147,6 +156,7 @@ class Network(QObject):
''' '''
self._must_crawl = True self._must_crawl = True
while self.continue_crawling(): while self.continue_crawling():
latest_before_crawling = self.latest_block
nodes = self.crawling(interval=10) nodes = self.crawling(interval=10)
new_inlines = [n.endpoint.inline() for n in nodes] new_inlines = [n.endpoint.inline() for n in nodes]
...@@ -160,6 +170,9 @@ class Network(QObject): ...@@ -160,6 +170,9 @@ class Network(QObject):
self.nodes_changed.emit() self.nodes_changed.emit()
for n in self._nodes: for n in self._nodes:
n.changed.connect(self.nodes_changed) n.changed.connect(self.nodes_changed)
if self.latest_block != latest_before_crawling:
self.block_mined.emit(self.latest_block)
self.stopped_perpetual_crawling.emit() self.stopped_perpetual_crawling.emit()
def crawling(self, interval=0): def crawling(self, interval=0):
......
...@@ -60,7 +60,7 @@ class Cache(): ...@@ -60,7 +60,7 @@ class Cache():
return [t for t in self._transfers if t.state != Transfer.DROPPED] return [t for t in self._transfers if t.state != Transfer.DROPPED]
def _parse_transaction(self, community, tx, block_number, mediantime): def _parse_transaction(self, community, tx, block_number, mediantime):
logging.debug(tx)
receivers = [o.pubkey for o in tx.outputs receivers = [o.pubkey for o in tx.outputs
if o.pubkey != tx.issuers[0]] if o.pubkey != tx.issuers[0]]
......
...@@ -22,8 +22,6 @@ class BlockchainWatcher(Watcher): ...@@ -22,8 +22,6 @@ class BlockchainWatcher(Watcher):
self.last_block = blockid['number'] self.last_block = blockid['number']
def watch(self): def watch(self):
while not self.exiting:
time.sleep(self.time_to_wait)
try: try:
blockid = self.community.current_blockid() blockid = self.community.current_blockid()
block_number = blockid['number'] block_number = blockid['number']
...@@ -36,7 +34,6 @@ class BlockchainWatcher(Watcher): ...@@ -36,7 +34,6 @@ class BlockchainWatcher(Watcher):
logging.debug("New block, {0} mined in {1}".format(block_number, logging.debug("New block, {0} mined in {1}".format(block_number,
self.community.currency)) self.community.currency))
self.community.new_block_mined.emit(block_number)
self.last_block = block_number self.last_block = block_number
except NoPeerAvailable: except NoPeerAvailable:
pass pass
......
...@@ -35,17 +35,11 @@ class Monitor(object): ...@@ -35,17 +35,11 @@ class Monitor(object):
def persons_watcher(self, community): def persons_watcher(self, community):
return self._persons_watchers[community.name] return self._persons_watchers[community.name]
def restart_persons_watching(self, community):
watcher = self.persons_watcher(community)
thread = watcher.thread()
logging.debug("Persons watching thread is : {0}".format(thread.isFinished()))
thread.start()
def connect_watcher_to_thread(self, watcher): def connect_watcher_to_thread(self, watcher):
thread = QThread() thread = QThread()
watcher.moveToThread(thread) watcher.moveToThread(thread)
thread.started.connect(watcher.watch) thread.started.connect(watcher.watch)
success = watcher.watching_stopped.connect(thread.exit, Qt.DirectConnection) watcher.watching_stopped.connect(thread.exit, Qt.DirectConnection)
self.threads_pool.append(thread) self.threads_pool.append(thread)
...@@ -63,9 +57,9 @@ class Monitor(object): ...@@ -63,9 +57,9 @@ class Monitor(object):
self.connect_watcher_to_thread(network_watcher) self.connect_watcher_to_thread(network_watcher)
self._network_watchers[c.name] = network_watcher self._network_watchers[c.name] = network_watcher
def start_watching(self): def start_network_watchers(self):
for thread in self.threads_pool: for watcher in self._network_watchers.values():
thread.start() watcher.thread().start()
def stop_watching(self): def stop_watching(self):
for watcher in self._persons_watchers.values(): for watcher in self._persons_watchers.values():
......
...@@ -48,6 +48,7 @@ class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget): ...@@ -48,6 +48,7 @@ class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget):
self.tab_network = NetworkTabWidget(self.community) self.tab_network = NetworkTabWidget(self.community)
self.community.new_block_mined.connect(self.refresh_block) self.community.new_block_mined.connect(self.refresh_block)
self.community.network.nodes_changed.connect(self.refresh_status)
persons_watcher = self.app.monitor.persons_watcher(self.community) persons_watcher = self.app.monitor.persons_watcher(self.community)
persons_watcher.person_changed.connect(self.tab_community.refresh_person) persons_watcher.person_changed.connect(self.tab_community.refresh_person)
bc_watcher = self.app.monitor.blockchain_watcher(self.community) bc_watcher = self.app.monitor.blockchain_watcher(self.community)
...@@ -124,10 +125,7 @@ class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget): ...@@ -124,10 +125,7 @@ class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget):
QIcon(":/icons/network_icon"), QIcon(":/icons/network_icon"),
"Network") "Network")
self.tab_informations.refresh() self.tab_informations.refresh()
blockid = self.community.current_blockid() self.refresh_status()
block_number = blockid['number']
self.status_label.setText("Connected : Block {0}"
.format(block_number))
self.refresh_wallets() self.refresh_wallets()
@pyqtSlot(str) @pyqtSlot(str)
...@@ -146,9 +144,20 @@ class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget): ...@@ -146,9 +144,20 @@ class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget):
QModelIndex(), QModelIndex(),
QModelIndex(), QModelIndex(),
[]) [])
self.app.monitor.restart_persons_watching(self.community) self.app.monitor.blockchain_watcher(self.community).thread().start()
self.app.monitor.persons_watcher(self.community).thread().start()
text = "Connected : Block {0}".format(block_number) self.refresh_status()
@pyqtSlot()
def refresh_status(self):
if self.community.network_quality() > 0.66:
text = "Connected : Block {0}".format(self.community.network.latest_block)
self.status_label.setText(text)
elif self.community.network_quality() > 0.33:
text = "Connected (weak link) : Block {0}".format(self.community.network.latest_block)
self.status_label.setText(text)
else:
text = "Disconnected : Block {0}".format(self.community.network.latest_block)
self.status_label.setText(text) self.status_label.setText(text)
def refresh_wallets(self): def refresh_wallets(self):
...@@ -156,10 +165,7 @@ class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget): ...@@ -156,10 +165,7 @@ class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget):
self.tab_wallets.refresh() self.tab_wallets.refresh()
def showEvent(self, event): def showEvent(self, event):
blockid = self.community.current_blockid() self.refresh_status()
block_number = blockid['number']
self.status_label.setText("Connected : Block {0}"
.format(block_number))
def referential_changed(self): def referential_changed(self):
if self.tab_history.table_history.model(): if self.tab_history.table_history.model():
......
...@@ -125,7 +125,7 @@ class MainWindow(QMainWindow, Ui_MainWindow): ...@@ -125,7 +125,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.busybar.hide() self.busybar.hide()
QApplication.restoreOverrideCursor() QApplication.restoreOverrideCursor()
self.app.disconnect() self.app.disconnect()
self.app.monitor.start_watching() self.app.monitor.start_network_watchers()
@pyqtSlot(str) @pyqtSlot(str)
def display_error(self, error): def display_error(self, error):
......
...@@ -96,7 +96,7 @@ class PeeringTreeModel(QAbstractItemModel): ...@@ -96,7 +96,7 @@ class PeeringTreeModel(QAbstractItemModel):
Constructor Constructor
''' '''
super().__init__(None) super().__init__(None)
self.nodes = community.online_nodes self.nodes = community._network.online_nodes
self.root_item = RootItem(community.currency) self.root_item = RootItem(community.currency)
self.refresh_tree() self.refresh_tree()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment