diff --git a/src/cutecoin/core/community.py b/src/cutecoin/core/community.py index ae85f2e1b61d3fc10d2dc5a825ffe3821c8f1824..0b0b940a9fb4134fa1f747da386b05dc317d9b2e 100644 --- a/src/cutecoin/core/community.py +++ b/src/cutecoin/core/community.py @@ -183,9 +183,12 @@ class Community(QObject): """ # Get cached block by block number block_number = self.network.latest_block_number - block = yield from self.bma_access.future_request(bma.blockchain.Block, - req_args={'number': block_number}) - return block['monetaryMass'] + if block_number: + block = yield from self.bma_access.future_request(bma.blockchain.Block, + req_args={'number': block_number}) + return block['monetaryMass'] + else: + return 0 @asyncio.coroutine def nb_members(self): diff --git a/src/cutecoin/core/graph.py b/src/cutecoin/core/graph.py index 682fbdf09766cf055a68aa510b44ce666fac85ed..4001afb66aa224a460c3854d35c53ff301db271d 100644 --- a/src/cutecoin/core/graph.py +++ b/src/cutecoin/core/graph.py @@ -206,8 +206,9 @@ class Graph(object): 'cert_time': certifier['cert_time'] } - if certifier['block_number']: - current_validations = self.community.network.latest_block_number - certifier['block_number'] + latest_block_number = self.community.network.latest_block_number + if latest_block_number and certifier['block_number']: + current_validations = latest_block_number - certifier['block_number'] else: current_validations = 0 members_pubkeys = yield from self.community.members_pubkeys() @@ -283,8 +284,9 @@ class Graph(object): 'cert_time': certified['cert_time'] } - if certified['block_number']: - current_validations = self.community.network.latest_block_number - certified['block_number'] + latest_block_number = self.community.network.latest_block_number + if latest_block_number and certified['block_number']: + current_validations = latest_block_number - certified['block_number'] else: current_validations = 0 members_pubkeys = yield from self.community.members_pubkeys() diff --git a/src/cutecoin/core/net/network.py b/src/cutecoin/core/net/network.py index 18b50f31ec08c1e16f9dc13e2b55443412be459b..f7bfeb96855d6716e554dc6d5e1f0ceceb06d781 100644 --- a/src/cutecoin/core/net/network.py +++ b/src/cutecoin/core/net/network.py @@ -175,7 +175,7 @@ class Network(QObject): if len(blocks_numbers) > 0: return blocks_numbers[0] else: - return 0 + return None @property def latest_block_hash(self): diff --git a/src/cutecoin/core/txhistory.py b/src/cutecoin/core/txhistory.py index 2561ef0fa44a580cf1dea9f19dc612af9b04cec4..61f8530db7a9eb0b4c7c3a213bc58c2252ea24a3 100644 --- a/src/cutecoin/core/txhistory.py +++ b/src/cutecoin/core/txhistory.py @@ -305,28 +305,30 @@ class TxHistory(): def refresh(self, community, received_list): # We update the block goal try: - current_block = yield from community.bma_access.future_request(bma.blockchain.Block, - req_args={'number': community.network.latest_block_number}) - members_pubkeys = yield from community.members_pubkeys() - # We look for the first block to parse, depending on awaiting and validating transfers and ud... - blocks = [tx.metadata['block'] for tx in self._transfers - if tx.state in (Transfer.AWAITING, Transfer.VALIDATING)] +\ - [ud['block_number'] for ud in self._dividends - if ud['state'] in (Transfer.AWAITING, Transfer.VALIDATING)] +\ - [max(0, self.latest_block - community.network.fork_window(members_pubkeys))] - parsed_block = min(set(blocks)) - self._block_to = current_block - - # We wait for current refresh coroutines - if len(self._running_refresh) > 0: - logging.debug("Wait for the end of previous refresh") - done, pending = yield from asyncio.wait(self._running_refresh) - for cor in done: - self._running_refresh.remove(cor) - - # Then we start a new one - task = asyncio.async(self._refresh(community, parsed_block, received_list)) - self._running_refresh.append(task) + latest_block_number = community.network.latest_block_number + if latest_block_number: + current_block = yield from community.bma_access.future_request(bma.blockchain.Block, + req_args={'number': latest_block_number}) + members_pubkeys = yield from community.members_pubkeys() + # We look for the first block to parse, depending on awaiting and validating transfers and ud... + blocks = [tx.metadata['block'] for tx in self._transfers + if tx.state in (Transfer.AWAITING, Transfer.VALIDATING)] +\ + [ud['block_number'] for ud in self._dividends + if ud['state'] in (Transfer.AWAITING, Transfer.VALIDATING)] +\ + [max(0, self.latest_block - community.network.fork_window(members_pubkeys))] + parsed_block = min(set(blocks)) + self._block_to = current_block + + # We wait for current refresh coroutines + if len(self._running_refresh) > 0: + logging.debug("Wait for the end of previous refresh") + done, pending = yield from asyncio.wait(self._running_refresh) + for cor in done: + self._running_refresh.remove(cor) + + # Then we start a new one + task = asyncio.async(self._refresh(community, parsed_block, received_list)) + self._running_refresh.append(task) except ValueError as e: logging.debug("Block not found") except NoPeerAvailable: diff --git a/src/cutecoin/gui/community_tile.py b/src/cutecoin/gui/community_tile.py index 5e820a5cd2aa372ad87ed21bb8b00a2c9d447d16..7a382388a72a0655127bd9807e42b148a232fb36 100644 --- a/src/cutecoin/gui/community_tile.py +++ b/src/cutecoin/gui/community_tile.py @@ -8,8 +8,18 @@ from PyQt5.QtCore import QEvent, QSize, pyqtSignal from ..tools.decorators import asyncify from ..tools.exceptions import NoPeerAvailable import asyncio +import enum +from ucoinpy.documents.block import Block from .busy import Busy + +@enum.unique +class CommunityState(enum.Enum): + NOT_INIT = 0 + OFFLINE = 1 + READY = 2 + + class CommunityTile(QFrame): clicked = pyqtSignal() @@ -17,6 +27,7 @@ class CommunityTile(QFrame): super().__init__(parent) self.app = app self.community = community + self.community.network.nodes_changed.connect(self.handle_nodes_change) self.text_label = QLabel() self.setLayout(QVBoxLayout()) self.layout().setSizeConstraint(QLayout.SetFixedSize) @@ -25,18 +36,31 @@ class CommunityTile(QFrame): self.setFrameShadow(QFrame.Raised) self.busy = Busy(self) self.busy.hide() + self._state = CommunityState.NOT_INIT self.refresh() def sizeHint(self): return QSize(250, 250) + def handle_nodes_change(self): + if len(self.community.network.online_nodes) > 0: + if self.community.network.latest_block_hash == Block.Empty_Hash: + state = CommunityState.NOT_INIT + else: + state = CommunityState.READY + else: + state = CommunityState.OFFLINE + + if state != self._state: + self.refresh() + @asyncify @asyncio.coroutine def refresh(self): self.busy.show() self.setFixedSize(QSize(150, 150)) try: - current_block = yield from self.community.get_block(self.community.network.latest_block_number) + current_block = yield from self.community.get_block() members_pubkeys = yield from self.community.members_pubkeys() amount = yield from self.app.current_account.amount(self.community) localized_amount = yield from self.app.current_account.current_ref(amount, @@ -70,6 +94,7 @@ class CommunityTile(QFrame): balance_label=self.tr("Balance"), balance=localized_amount) self.text_label.setText(description) + self._state = CommunityState.READY except NoPeerAvailable: description = """<html> <body> @@ -81,6 +106,7 @@ class CommunityTile(QFrame): </html>""".format(currency=self.community.currency, message=self.tr("Not connected")) self.text_label.setText(description) + self._state = CommunityState.OFFLINE except ValueError as e: if '404' in str(e): description = """<html> @@ -92,7 +118,10 @@ class CommunityTile(QFrame): </body> </html>""".format(currency=self.community.currency, message=self.tr("Community not initialized")) - self.text_label.setText(description) + self.text_label.setText(description) + self._state = CommunityState.NOT_INIT + else: + raise self.busy.hide() diff --git a/src/cutecoin/gui/community_view.py b/src/cutecoin/gui/community_view.py index f09ef623ab40460bc5e50a5787752734a4972467..dd24228b6ebedadc6ce5c97a57c59fb7e423723f 100644 --- a/src/cutecoin/gui/community_view.py +++ b/src/cutecoin/gui/community_view.py @@ -179,20 +179,23 @@ class CommunityWidget(QWidget, Ui_CommunityWidget): """ logging.debug("Refresh status") if self.community: - text = self.tr(" Block {0}").format(self.community.network.latest_block_number) - try: - block = yield from self.community.get_block(self.community.network.latest_block_number) - text += " ( {0} )".format(QLocale.toString( - QLocale(), - QDateTime.fromTime_t(block['medianTime']), - QLocale.dateTimeFormat(QLocale(), QLocale.NarrowFormat) - )) - except NoPeerAvailable as e: - logging.debug(str(e)) - text += " ( ### ) " - except ValueError as e: - logging.debug(str(e)) + text = "" + latest_block_number = self.community.network.latest_block_number + if latest_block_number: + text += self.tr(" Block {0}").format() + try: + block = yield from self.community.get_block(latest_block_number) + text += " ( {0} )".format(QLocale.toString( + QLocale(), + QDateTime.fromTime_t(block['medianTime']), + QLocale.dateTimeFormat(QLocale(), QLocale.NarrowFormat) + )) + except NoPeerAvailable as e: + logging.debug(str(e)) + text += " ( ### ) " + except ValueError as e: + logging.debug(str(e)) if len(self.community.network.synced_nodes) == 0: self.button_membership.setEnabled(False) diff --git a/src/cutecoin/models/txhistory.py b/src/cutecoin/models/txhistory.py index 60c743eac23c5651340dab4fa9c350251b84afac..482fed11b3c063ae61790717a2342a33312ad9f7 100644 --- a/src/cutecoin/models/txhistory.py +++ b/src/cutecoin/models/txhistory.py @@ -151,10 +151,11 @@ class TxFilterProxyModel(QSortFilterProxyModel): block_index = model.index(source_index.row(), block_col) block_data = model.data(block_index, Qt.DisplayRole) + current_validations = 0 if state_data == Transfer.VALIDATING: - current_validations = self.community.network.latest_block_number - block_data - else: - current_validations = 0 + latest_block_number = self.community.network.latest_block_number + if latest_block_number: + current_validations = latest_block_number - block_data max_validations = self.sourceModel().max_validations() if self.app.preferences['expert_mode']: