diff --git a/src/cutecoin/core/graph.py b/src/cutecoin/core/graph.py index 54db4f9d49f81bf33325714a4dfa4404e4ee2815..d29e66ed098eca787dd690f7821ff7c172c79c8f 100644 --- a/src/cutecoin/core/graph.py +++ b/src/cutecoin/core/graph.py @@ -182,9 +182,21 @@ class Graph(object): 'cert_time': certifier['cert_time'] } - if certifier['identity'].blockchain_state == BlockchainState.VALIDATED: - arc['current_validation'] = self.community.network.latest_block_number - certifier['block_number'] - arc['max_validation'] = self.community.network.fork_window(self.community.members_pubkeys()) + if certifier['block_number']: + current_validations = self.community.network.latest_block_number - certifier['block_number'] + else: + current_validations = 0 + max_validation = self.community.network.fork_window(self.community.members_pubkeys()) + + if current_validations < max_validation: + if self.app.preferences['expert_mode']: + arc['validation_text'] = "{0}/{1}".format(current_validations, + max_validation) + else: + validation = current_validations / max_validation * 100 + arc['validation_text'] = "{0} %".format(QLocale().toString(float(validation), 'f', 0)) + else: + arc['validation_text'] = None # Â add arc to certifier self._graph[certifier['identity'].pubkey]['arcs'].append(arc) @@ -236,9 +248,22 @@ class Graph(object): 'cert_time': certified['cert_time'] } - if certified['identity'].blockchain_state == BlockchainState.VALIDATED: - arc['current_validation'] = self.community.network.latest_block_number - certified['block_number'] - arc['max_validation'] = self.community.network.fork_window(self.community.members_pubkeys()) + if certified['block_number']: + current_validations = self.community.network.latest_block_number - certified['block_number'] + else: + current_validations = 0 + max_validation = self.community.network.fork_window(self.community.members_pubkeys()) + + if current_validations < max_validation: + if self.app.preferences['expert_mode']: + arc['validation_text'] = "{0}/{1}".format(current_validations, + max_validation) + else: + validation = current_validations / max_validation * 100 + arc['validation_text'] = "{0} %".format(QLocale().toString(float(validation), 'f', 0)) + else: + arc['validation_text'] = None + # replace old arc if this one is more recent new_arc = True diff --git a/src/cutecoin/core/transfer.py b/src/cutecoin/core/transfer.py index e7ec95069395c3768a7e1edc5304901ea341aa8a..f64303d7b34a8cfd2fa7fdcbf8d4a23986ecdcfb 100644 --- a/src/cutecoin/core/transfer.py +++ b/src/cutecoin/core/transfer.py @@ -10,6 +10,7 @@ from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject from PyQt5.QtNetwork import QNetworkReply import hashlib + class Transfer(QObject): """ A transfer is the lifecycle of a transaction. @@ -138,22 +139,22 @@ class Transfer(QObject): return self.broadcast_error.emit(r.error(), strdata) - def check_registered(self, tx, block, time, data_validation): + def check_registered(self, txhash, block_number, time, data_validation): """ Check if the transfer was registered in a block. Update the transfer state to VALIDATED if it was registered. - :param tx: A transaction ucoinpy object found in the block - :param int block: The block number checked + :param txhash: A transaction ucoinpy object found in the block + :param int block_number: The block number checked :param int time: The time of the block """ - if tx.signed_raw() == self.txdoc.signed_raw(): + if txhash == self.hash: if self.state == Transfer.AWAITING: self.state = Transfer.VALIDATING - self._metadata['block'] = block + self._metadata['block'] = block_number self._metadata['time'] = time elif self.state == Transfer.VALIDATING and \ - self._metadata['block'] - block > data_validation: + self._metadata['block'] - block_number > data_validation: self.state = Transfer.VALIDATED def check_refused(self, time, block_time, mediantime_blocks): diff --git a/src/cutecoin/core/txhistory.py b/src/cutecoin/core/txhistory.py index c801a10b3e5c683c094044cdb8123d2af4c5af42..43023613f39a5ae5845b864dc69a3887ceb8c5af 100644 --- a/src/cutecoin/core/txhistory.py +++ b/src/cutecoin/core/txhistory.py @@ -70,6 +70,14 @@ class TxHistory(): def stop_coroutines(self): self._stop_coroutines = True + @staticmethod + def _validation_state(community, block_number, current_block): + if block_number + community.network.fork_window(community.members_pubkeys()) < current_block["number"]: + state = Transfer.VALIDATED + else: + state = Transfer.VALIDATING + return state + @asyncio.coroutine def _parse_transaction(self, community, txdata, received_list, txid, current_block): tx_outputs = [OutputSource.from_inline(o) for o in txdata['outputs']] @@ -77,13 +85,9 @@ class TxHistory(): if o.pubkey != txdata['issuers'][0]] block_number = txdata['block_number'] - if block_number + self.app.preferences['data_validation'] >= current_block["number"]: - state = Transfer.VALIDATED - else: - state = Transfer.VALIDATING mediantime = txdata['time'] - logging.debug(txdata) + state = TxHistory._validation_state(community, block_number, current_block) if len(receivers) == 0: receivers = [txdata['issuers'][0]] @@ -149,8 +153,8 @@ class TxHistory(): return transfer else: transfer = [t for t in awaiting if t.hash == txdata['hash']][0] - transfer.check_registered(txdata['hash'], current_block, mediantime, - self.app.preferences['data_validation']) + transfer.check_registered(txdata['hash'], current_block['number'], mediantime, + community.network.fork_window(community.members_pubkeys())) return None @asyncio.coroutine @@ -192,11 +196,18 @@ class TxHistory(): return udid = 0 - for d in dividends: - if d['block_number'] in range(parsed_block, parsed_block+100): + for d in [ud for ud in dividends if ud['block_number'] in range(parsed_block, parsed_block+100)]: + state = TxHistory._validation_state(community, d['block_number'], current_block) + + if d['block_number'] not in [ud['block_number'] for ud in self._dividends]: d['id'] = udid + d['state'] = state new_dividends.append(d) udid += 1 + else: + known_dividend = [ud for ud in self._dividends + if ud['block_number'] == d['block_number']][0] + known_dividend['state'] = state # We parse only blocks with transactions transactions = tx_history['history']['received'] + tx_history['history']['sent'] diff --git a/src/cutecoin/gui/views/wot.py b/src/cutecoin/gui/views/wot.py index f5206211db03c8900ea7cc4f080c171d89ab8b9b..64e803b5ffe567717d10ab41be63470f8c405661 100644 --- a/src/cutecoin/gui/views/wot.py +++ b/src/cutecoin/gui/views/wot.py @@ -5,7 +5,7 @@ from PyQt5.QtGui import QPainter, QBrush, QPen, QPolygonF, QColor, QRadialGradie QPainterPath, QMouseEvent, QWheelEvent, QTransform, QCursor from PyQt5.QtCore import Qt, QRectF, QLineF, QPoint, QPointF, QSizeF, \ qFuzzyCompare, pyqtSignal, QT_TRANSLATE_NOOP, \ - QCoreApplication + QCoreApplication, QLocale from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QGraphicsEllipseItem, \ QGraphicsSimpleTextItem, QGraphicsLineItem, QMenu, QAction, QGraphicsSceneHoverEvent, \ QGraphicsSceneContextMenuEvent @@ -471,9 +471,5 @@ class Arc(QGraphicsLineItem): painter.setBrush(color) painter.drawPolygon(QPolygonF([head_point, destination_arrow_p1, destination_arrow_p2])) - if 'current_validation' in self.metadata: - if self.metadata['current_validation'] < self.metadata['max_validation']: - validation = self.metadata['current_validation'] / self.metadata['max_validation'] * 100 - painter.drawText(head_point, "{0} %".format(validation)) - else: - painter.drawText(head_point, "0%") + if self.metadata["validation_text"]: + painter.drawText(head_point, self.metadata["validation_text"]) diff --git a/src/cutecoin/models/txhistory.py b/src/cutecoin/models/txhistory.py index 41c6131787f697c69fd9b7068427b4aebd3ae56b..6f0e897209d468a5cb0134a199db0e5247341dd7 100644 --- a/src/cutecoin/models/txhistory.py +++ b/src/cutecoin/models/txhistory.py @@ -117,7 +117,7 @@ class TxFilterProxyModel(QSortFilterProxyModel): if role == Qt.FontRole: font = QFont() - if state_data == Transfer.AWAITING: + if state_data == Transfer.AWAITING or state_data == Transfer.VALIDATING: font.setItalic(True) elif state_data == Transfer.REFUSED: font.setItalic(True) @@ -141,15 +141,27 @@ class TxFilterProxyModel(QSortFilterProxyModel): return Qt.AlignCenter if role == Qt.ToolTipRole: - if state_data == Transfer.VALIDATING: + if source_index.column() == self.sourceModel().columns_types.index('date'): + return QDateTime.fromTime_t(source_data).toString(Qt.SystemLocaleLongDate) + + if state_data == Transfer.VALIDATING or state_data == Transfer.AWAITING: block_col = model.columns_types.index('block_number') block_index = model.index(source_index.row(), block_col) block_data = model.data(block_index, Qt.DisplayRole) - return "{0} / {1} validations".format(self.community.network.latest_block_number - block_data, - self.app.preferences['data_validation']) - if source_index.column() == self.sourceModel().columns_types.index('date'): - return QDateTime.fromTime_t(source_data).toString(Qt.SystemLocaleLongDate) + if state_data == Transfer.VALIDATING: + current_validations = self.community.network.latest_block_number - block_data + else: + current_validations = 0 + max_validations = self.community.network.fork_window(self.community.members_pubkeys()) + + if self.app.preferences['expert_mode']: + return self.tr("{0} / {1} validations").format(current_validations, max_validations) + else: + validation = current_validations / max_validations * 100 + return self.tr("Validating... {0} %").format(QLocale().toString(float(validation), 'f', 0)) + + return None return source_data @@ -244,9 +256,12 @@ class HistoryTableModel(QAbstractTableModel): receiver = self.account.name date_ts = dividend['time'] id = dividend['id'] + block_number = dividend['block_number'] + state = dividend['state'] + return (date_ts, receiver, "", - amount, "", Transfer.VALIDATED, id, - self.account.pubkey) + amount, "", state, id, + self.account.pubkey, block_number) def refresh_transfers(self): self.beginResetModel() @@ -287,8 +302,8 @@ class HistoryTableModel(QAbstractTableModel): if role == Qt.DisplayRole: return self.transfers_data[row][col] - if role == Qt.ToolTipRole and col == 0: - return self.transfers_data[self.columns_types.index('date')] + if role == Qt.ToolTipRole: + return self.transfers_data[row][col] def flags(self, index): return Qt.ItemIsSelectable | Qt.ItemIsEnabled