diff --git a/lib/ucoinpy/documents/block.py b/lib/ucoinpy/documents/block.py index 64c3a7c7f87904cba0e4eb4cc593e01cd607adba..58a1b3bf8e9d29543fbd65b956b9bc144d0b2f04 100644 --- a/lib/ucoinpy/documents/block.py +++ b/lib/ucoinpy/documents/block.py @@ -291,6 +291,6 @@ PreviousIssuer: {1}\n".format(self.prev_hash, self.prev_issuer) doc += "Transactions:\n" for transaction in self.transactions: - doc += "{0}\n".format(transaction.inline()) + doc += "{0}\n".format(transaction.compact()) return doc diff --git a/src/cutecoin/core/community.py b/src/cutecoin/core/community.py index 5645a2295d793d53eb3b739083a8d1b90678d368..4b23346e692d7838afe0a6c62af981c8f421d668 100644 --- a/src/cutecoin/core/community.py +++ b/src/cutecoin/core/community.py @@ -120,6 +120,7 @@ class Community(QObject): self.currency = currency self._network = network self._cache = Cache(self) + self._network.new_block_mined.connect(self.new_block_mined) self._cache.refresh() @@ -297,6 +298,17 @@ class Community(QObject): ''' 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 def parameters(self): ''' diff --git a/src/cutecoin/core/net/network.py b/src/cutecoin/core/net/network.py index 4f66e98412eb9dd58aa5228d9764c7d092ee59b0..d552beb98cdc628455180a03f1b91e38ef326c16 100644 --- a/src/cutecoin/core/net/network.py +++ b/src/cutecoin/core/net/network.py @@ -17,6 +17,7 @@ class Network(QObject): given community. ''' nodes_changed = pyqtSignal() + new_block_mined = pyqtSignal(int) stopped_perpetual_crawling = pyqtSignal() def __init__(self, currency, nodes): @@ -44,12 +45,13 @@ class Network(QObject): :param node: The first knew node of the network ''' nodes = [node] - network = cls(node.currency, nodes) + network = cls(node.currency, nodes, 0) nodes = network.crawling() block_max = max([n.block for n in nodes]) for node in nodes: node.check_sync(block_max) network._nodes = nodes + network.latest_block = block_max return network def merge_with_json(self, json_data): @@ -133,6 +135,13 @@ class Network(QObject): ''' 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): ''' Add a node to the network. @@ -147,6 +156,7 @@ class Network(QObject): ''' self._must_crawl = True while self.continue_crawling(): + latest_before_crawling = self.latest_block nodes = self.crawling(interval=10) new_inlines = [n.endpoint.inline() for n in nodes] @@ -160,6 +170,9 @@ class Network(QObject): self.nodes_changed.emit() for n in self._nodes: 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() def crawling(self, interval=0): diff --git a/src/cutecoin/core/wallet.py b/src/cutecoin/core/wallet.py index be0cd92464b0501b2891280a2def94ab5fd6e300..835e8907eb64e8e43ca24d57b6a6d6f0eba84f4c 100644 --- a/src/cutecoin/core/wallet.py +++ b/src/cutecoin/core/wallet.py @@ -60,7 +60,7 @@ class Cache(): return [t for t in self._transfers if t.state != Transfer.DROPPED] def _parse_transaction(self, community, tx, block_number, mediantime): - + logging.debug(tx) receivers = [o.pubkey for o in tx.outputs if o.pubkey != tx.issuers[0]] diff --git a/src/cutecoin/core/watching/blockchain.py b/src/cutecoin/core/watching/blockchain.py index 20ff37af1f39d26e6ff8f1fa1438f70c57fd3492..4f00b319018687e0e88c54bd525ff58b265619ee 100644 --- a/src/cutecoin/core/watching/blockchain.py +++ b/src/cutecoin/core/watching/blockchain.py @@ -22,26 +22,23 @@ class BlockchainWatcher(Watcher): self.last_block = blockid['number'] def watch(self): - while not self.exiting: - time.sleep(self.time_to_wait) - try: - blockid = self.community.current_blockid() - block_number = blockid['number'] - if self.last_block != block_number: + try: + blockid = self.community.current_blockid() + block_number = blockid['number'] + if self.last_block != block_number: + if not self.exiting: + self.community.refresh_cache() + for w in self.account.wallets: if not self.exiting: - self.community.refresh_cache() - for w in self.account.wallets: - if not self.exiting: - w.refresh_cache(self.community) + w.refresh_cache(self.community) - logging.debug("New block, {0} mined in {1}".format(block_number, - self.community.currency)) - self.community.new_block_mined.emit(block_number) - self.last_block = block_number - except NoPeerAvailable: - pass - except RequestException as e: - self.error.emit("Cannot check new block : {0}".format(str(e))) + logging.debug("New block, {0} mined in {1}".format(block_number, + self.community.currency)) + self.last_block = block_number + except NoPeerAvailable: + pass + except RequestException as e: + self.error.emit("Cannot check new block : {0}".format(str(e))) self.watching_stopped.emit() def stop(self): diff --git a/src/cutecoin/core/watching/monitor.py b/src/cutecoin/core/watching/monitor.py index 866453da004f7db59595f1dec05bad76591771f2..fd49d9950167052199477a97accdcfc6035914dd 100644 --- a/src/cutecoin/core/watching/monitor.py +++ b/src/cutecoin/core/watching/monitor.py @@ -35,17 +35,11 @@ class Monitor(object): def persons_watcher(self, community): 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): thread = QThread() watcher.moveToThread(thread) 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) @@ -63,9 +57,9 @@ class Monitor(object): self.connect_watcher_to_thread(network_watcher) self._network_watchers[c.name] = network_watcher - def start_watching(self): - for thread in self.threads_pool: - thread.start() + def start_network_watchers(self): + for watcher in self._network_watchers.values(): + watcher.thread().start() def stop_watching(self): for watcher in self._persons_watchers.values(): diff --git a/src/cutecoin/gui/currency_tab.py b/src/cutecoin/gui/currency_tab.py index 6715f08737c49630a8caf93c27d423ac6ec58183..4f030014a695f31f6a1492ddf19bf6f0b448876b 100644 --- a/src/cutecoin/gui/currency_tab.py +++ b/src/cutecoin/gui/currency_tab.py @@ -48,6 +48,7 @@ class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget): self.tab_network = NetworkTabWidget(self.community) 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.person_changed.connect(self.tab_community.refresh_person) bc_watcher = self.app.monitor.blockchain_watcher(self.community) @@ -124,10 +125,7 @@ class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget): QIcon(":/icons/network_icon"), "Network") self.tab_informations.refresh() - blockid = self.community.current_blockid() - block_number = blockid['number'] - self.status_label.setText("Connected : Block {0}" - .format(block_number)) + self.refresh_status() self.refresh_wallets() @pyqtSlot(str) @@ -146,20 +144,28 @@ class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget): QModelIndex(), QModelIndex(), []) - self.app.monitor.restart_persons_watching(self.community) - - text = "Connected : Block {0}".format(block_number) - self.status_label.setText(text) + self.app.monitor.blockchain_watcher(self.community).thread().start() + self.app.monitor.persons_watcher(self.community).thread().start() + 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) def refresh_wallets(self): if self.app.current_account: self.tab_wallets.refresh() def showEvent(self, event): - blockid = self.community.current_blockid() - block_number = blockid['number'] - self.status_label.setText("Connected : Block {0}" - .format(block_number)) + self.refresh_status() def referential_changed(self): if self.tab_history.table_history.model(): diff --git a/src/cutecoin/gui/mainwindow.py b/src/cutecoin/gui/mainwindow.py index 480f56ea9b9555781e797a2fb256e6b5debeffb6..f2ff8d8b9754860d61f883e1c839defabcfa2666 100644 --- a/src/cutecoin/gui/mainwindow.py +++ b/src/cutecoin/gui/mainwindow.py @@ -125,7 +125,7 @@ class MainWindow(QMainWindow, Ui_MainWindow): self.busybar.hide() QApplication.restoreOverrideCursor() self.app.disconnect() - self.app.monitor.start_watching() + self.app.monitor.start_network_watchers() @pyqtSlot(str) def display_error(self, error): @@ -170,7 +170,7 @@ class MainWindow(QMainWindow, Ui_MainWindow): logging.debug("Busybar : {:} : {:}".format(value, maximum)) self.busybar.setValue(value) self.busybar.setMaximum(maximum) - + if self.app.current_account: self.app.save_cache(self.app.current_account) diff --git a/src/cutecoin/models/peering.py b/src/cutecoin/models/peering.py index f46efa622b9870cb860e7ebda7f2361dee16f8e1..e3a35969b800192d97794f2890f5d386b95417c4 100644 --- a/src/cutecoin/models/peering.py +++ b/src/cutecoin/models/peering.py @@ -96,7 +96,7 @@ class PeeringTreeModel(QAbstractItemModel): Constructor ''' super().__init__(None) - self.nodes = community.online_nodes + self.nodes = community._network.online_nodes self.root_item = RootItem(community.currency) self.refresh_tree()