diff --git a/lib/ucoinpy/documents/block.py b/lib/ucoinpy/documents/block.py index a02a550dac8f71302bf3140503ceae7c98a40bd6..00ce0f779ce1fc9cef56a5f5b41ecabedf6bd2bd 100644 --- a/lib/ucoinpy/documents/block.py +++ b/lib/ucoinpy/documents/block.py @@ -77,6 +77,8 @@ BOTTOM_SIGNATURE re_certifications = re.compile("Certifications:\n") re_transactions = re.compile("Transactions:\n") + Empty_Hash = "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709" + def __init__(self, version, currency, noonce, number, powmin, time, mediantime, ud, issuer, prev_hash, prev_issuer, parameters, members_count, identities, joiners, diff --git a/src/cutecoin/core/community.py b/src/cutecoin/core/community.py index 5c4ad26dc724d23db34486a58f4d00ae645c9ff3..6d4eb5dc167dcd75f26c0bc4170cd99f4621900f 100644 --- a/src/cutecoin/core/community.py +++ b/src/cutecoin/core/community.py @@ -183,7 +183,7 @@ class Community(QObject): :return: The monetary mass value """ # Get cached block by block number - block_number = self.network.latest_block + block_number = self.network.latest_block_number block = self.bma_access.get(self, qtbma.blockchain.Block, req_args={'number': block_number}) return block['monetaryMass'] @@ -197,7 +197,7 @@ class Community(QObject): """ try: # Get cached block by block number - block_number = self.network.latest_block + block_number = self.network.latest_block_number block = self.bma_access.get(qtbma.blockchain.Block, req_args={'number': block_number}) return block['membersCount'] diff --git a/src/cutecoin/core/net/api/bma/access.py b/src/cutecoin/core/net/api/bma/access.py index d6fa54a797c437682bf5945ee496ed41e184e575..21487ad6ee2043e10cad459339d49eac2607c30e 100644 --- a/src/cutecoin/core/net/api/bma/access.py +++ b/src/cutecoin/core/net/api/bma/access.py @@ -106,7 +106,7 @@ class BmaAccess(QObject): cached_data = self._data[cache_key] need_reload = True if str(request) in BmaAccess.__saved_requests \ - or cached_data['metadata']['block'] >= self._network.latest_block: + or cached_data['metadata']['block'] >= self._network.latest_block_number: need_reload = False ret_data = cached_data['value'] else: @@ -130,7 +130,7 @@ class BmaAccess(QObject): 'value': {}} if not self._compare_json(self._data[cache_key]['value'], data): - self._data[cache_key]['metadata']['block'] = self._network.latest_block + self._data[cache_key]['metadata']['block'] = self._network.latest_block_number self._data[cache_key]['metadata']['cutecoin_version'] = __version__ self._data[cache_key]['value'] = data return True diff --git a/src/cutecoin/core/net/network.py b/src/cutecoin/core/net/network.py index cae7e7afaa80cd529b288c0620ddcdaaa305203e..9f83fb0df1998673b3fb61fd663eb6a2626ab97b 100644 --- a/src/cutecoin/core/net/network.py +++ b/src/cutecoin/core/net/network.py @@ -36,7 +36,7 @@ class Network(QObject): self.currency = currency self._must_crawl = False self.network_manager = network_manager - self._block_found = self.latest_block + self._block_found = self.latest_block_hash self._timer = QTimer() @classmethod @@ -66,8 +66,8 @@ class Network(QObject): logging.debug("Loading : {:}".format(data['pubkey'])) else: other_node = [n for n in self.nodes if n.pubkey == node.pubkey][0] - if other_node.block < node.block: - other_node.block = node.block + if other_node.block_hash != node.block_hash: + other_node.set_block(node.block_number, node.block_hash) other_node.last_change = node.last_change other_node.state = node.state @@ -145,11 +145,22 @@ class Network(QObject): return self._root_nodes @property - def latest_block(self): + def latest_block_number(self): """ - Get latest block known + Get the latest block considered valid + It is the most frequent last block of every known nodes """ - return max([n.block for n in self.nodes]) + blocks = [n.block_number for n in self.nodes] + return max(set(blocks), key=blocks.count) + + @property + def latest_block_hash(self): + """ + Get the latest block considered valid + It is the most frequent last block of every known nodes + """ + blocks = [n.block_hash for n in self.nodes] + return max(set(blocks), key=blocks.count) def add_node(self, node): """ @@ -217,15 +228,15 @@ class Network(QObject): def handle_change(self): node = self.sender() if node.state in (Node.ONLINE, Node.DESYNCED): - node.check_sync(self.latest_block) + node.check_sync(self.latest_block_hash) else: if node.last_change + 3600 < time.time(): node.disconnect() self.nodes.remove(node) self.nodes_changed.emit() - logging.debug("{0} -> {1}".format(self.latest_block, self.latest_block)) - if self._block_found < self.latest_block: - logging.debug("New block found : {0}".format(self.latest_block)) - self._block_found = self.latest_block - self.new_block_mined.emit(self.latest_block) + logging.debug("{0} -> {1}".format(self.latest_block_number, self.latest_block_number)) + if self._block_found != self.latest_block_hash: + logging.debug("Latest block changed : {0}".format(self.latest_block_number)) + self._block_found = self.latest_block_hash + self.new_block_mined.emit(self.latest_block_number) diff --git a/src/cutecoin/core/net/node.py b/src/cutecoin/core/net/node.py index 7659bb39c4fe3b341c327d51f0a854ee3d85675b..ff6afaead7ca8608e1e84d1cc43bd41236e4556b 100644 --- a/src/cutecoin/core/net/node.py +++ b/src/cutecoin/core/net/node.py @@ -5,6 +5,7 @@ Created on 21 févr. 2015 """ from ucoinpy.documents.peer import Peer +from ucoinpy.documents.block import Block from ...tools.exceptions import InvalidNodeCurrency from ..net.api import bma as qtbma from ..net.endpoint import Endpoint, BMAEndpoint @@ -36,7 +37,7 @@ class Node(QObject): changed = pyqtSignal() neighbour_found = pyqtSignal(Peer, str) - def __init__(self, network_manager, currency, endpoints, uid, pubkey, block, + def __init__(self, network_manager, currency, endpoints, uid, pubkey, block_number, block_hash, state, last_change, last_merkle, software, version): """ Constructor @@ -46,7 +47,8 @@ class Node(QObject): self._endpoints = endpoints self._uid = uid self._pubkey = pubkey - self.block = block + self._block_number = block_number + self._block_hash = block_hash self._state = state self._neighbours = [] self._currency = currency @@ -91,7 +93,7 @@ class Node(QObject): node = cls(network_manager, peer.currency, [Endpoint.from_inline(e.inline()) for e in peer.endpoints], - "", peer.pubkey, 0, Node.ONLINE, time.time(), + "", peer.pubkey, 0, Block.Empty_Hash, Node.ONLINE, time.time(), {'root': "", 'leaves': []}, "", "") logging.debug("Node from address : {:}".format(str(node))) return node @@ -127,7 +129,8 @@ class Node(QObject): pubkey = "" software = "" version = "" - block = 0 + block_number = 0 + block_hash = Block.Empty_Hash last_change = time.time() state = Node.ONLINE logging.debug(data) @@ -146,8 +149,11 @@ class Node(QObject): if 'last_change' in data: last_change = data['last_change'] - if 'block' in data: - block = data['block'] + if 'block_number' in data: + block_number = data['block_number'] + + if 'block_hash' in data: + block_hash = data['block_hash'] if 'state' in data: state = data['state'] @@ -161,7 +167,7 @@ class Node(QObject): logging.debug("Error : no state in node") node = cls(network_manager, currency, endpoints, - uid, pubkey, block, + uid, pubkey, block_number, block_hash, state, last_change, {'root': "", 'leaves': []}, software, version) @@ -186,7 +192,8 @@ class Node(QObject): 'currency': self._currency, 'state': self._state, 'last_change': self._last_change, - 'block': self.block} + 'block_number': self.block_number, + 'block_hash': self.block_hash} endpoints = [] for e in self._endpoints: endpoints.append(e.inline()) @@ -202,12 +209,16 @@ class Node(QObject): return next((e for e in self._endpoints if type(e) is BMAEndpoint)) @property - def block(self): - return self._block + def block_number(self): + return self._block_number + + @property + def block_hash(self): + return self._block_hash - @block.setter - def block(self, new_block): - self._block = new_block + def set_block(self, block_number, block_hash): + self._block_number = block_number + self._block_hash = block_hash @property def state(self): @@ -263,9 +274,9 @@ class Node(QObject): self.last_change = time.time() self._state = new_state - def check_sync(self, block): + def check_sync(self, block_hash): logging.debug("Check sync") - if self.block < block: + if self.block_hash != block_hash: self.state = Node.DESYNCED else: self.state = Node.ONLINE @@ -309,12 +320,13 @@ class Node(QObject): strdata = bytes(reply.readAll()).decode('utf-8') block_data = json.loads(strdata) block_number = block_data['number'] + block_hash = block_data['hash'] elif status_code == 404: - block_number = 0 + self.set_block(0, Block.Empty_Hash) - if block_number != self.block: - self.block = block_number - logging.debug("Changed block {0} -> {1}".format(self.block, + if block_hash != self.block_hash: + self.set_block(block_number, block_hash) + logging.debug("Changed block {0} -> {1}".format(self.block_number, block_number)) self.changed.emit() @@ -454,5 +466,5 @@ class Node(QObject): self.changed.emit() def __str__(self): - return ','.join([str(self.pubkey), str(self.endpoint.server), str(self.endpoint.port), str(self.block), + return ','.join([str(self.pubkey), str(self.endpoint.server), str(self.endpoint.port), str(self.block_number), str(self.currency), str(self.state), str(self.neighbours)]) diff --git a/src/cutecoin/core/txhistory.py b/src/cutecoin/core/txhistory.py index 4a11de3243d6bb50156fa862e50b99d27f3978c1..2a65098877e918bb9a55f4d8c39064d39a05794a 100644 --- a/src/cutecoin/core/txhistory.py +++ b/src/cutecoin/core/txhistory.py @@ -149,7 +149,7 @@ class TxHistory(): :param list received_list: List of transactions received """ parsed_block = self.latest_block - current_block = community.network.latest_block + current_block = community.network.latest_block_number logging.debug("Refresh from : {0} to {1}".format(self.latest_block, current_block)) dividends_data = qtbma.ud.History.null_value while dividends_data == qtbma.ud.History.null_value: diff --git a/src/cutecoin/gui/currency_tab.py b/src/cutecoin/gui/currency_tab.py index 04224f0a30856a18e19c95257bbcc43d18298eb1..9073c101f9e5db66535f4dc3d94f5da1cea8e57b 100644 --- a/src/cutecoin/gui/currency_tab.py +++ b/src/cutecoin/gui/currency_tab.py @@ -160,9 +160,9 @@ class CurrencyTabWidget(QWidget, Ui_CurrencyTabWidget): Refresh status bar """ logging.debug("Refresh status") - text = self.tr(" Block {0}").format(self.community.network.latest_block) + text = self.tr(" Block {0}").format(self.community.network.latest_block_number) - block = self.community.get_block(self.community.network.latest_block) + block = self.community.get_block(self.community.network.latest_block_number) if block != qtbma.blockchain.Block.null_value: text += " ( {0} )".format(QLocale.toString( QLocale(), diff --git a/src/cutecoin/models/network.py b/src/cutecoin/models/network.py index 6056a9feeb6d16b072d8d05e9e25f6cc2aaaefc5..782edce407e7ba0720efc49a6e864e51fd3b65fd 100644 --- a/src/cutecoin/models/network.py +++ b/src/cutecoin/models/network.py @@ -156,7 +156,7 @@ class NetworkTableModel(QAbstractTableModel): is_root = self.community.network.is_root_node(node) - return (address, port, node.block, node.uid, + return (address, port, node.block_number, node.uid, is_member, node.pubkey, node.software, node.version, is_root) def data(self, index, role):