From 3c17ee16f06c8ab89dc502568c4fe1521c61504b Mon Sep 17 00:00:00 2001 From: Inso <insomniak.fr@gmail.com> Date: Sat, 23 Jan 2016 19:46:46 +0100 Subject: [PATCH] Add peer to node files --- src/sakia/core/account.py | 9 ++++- src/sakia/core/app.py | 3 +- src/sakia/core/community.py | 15 ++------ src/sakia/core/net/network.py | 13 +++++-- src/sakia/core/net/node.py | 69 ++++++++++++++++++++--------------- 5 files changed, 60 insertions(+), 49 deletions(-) diff --git a/src/sakia/core/account.py b/src/sakia/core/account.py index 386788b2..820f0604 100644 --- a/src/sakia/core/account.py +++ b/src/sakia/core/account.py @@ -11,6 +11,7 @@ from ucoinpy.key import SigningKey import logging import time import asyncio +from distutils.version import StrictVersion from PyQt5.QtCore import QObject, pyqtSignal @@ -18,7 +19,7 @@ from . import money from .wallet import Wallet from .community import Community from .registry import LocalState -from ..tools.exceptions import ContactAlreadyExists, NoPeerAvailable +from ..tools.exceptions import ContactAlreadyExists from ucoinpy.api import bma from ucoinpy.api.bma import PROTOCOL_VERSION from aiohttp.errors import ClientError @@ -102,6 +103,10 @@ class Account(QObject): """ salt = json_data['salt'] pubkey = json_data['pubkey'] + if 'version' in json_data: + version = StrictVersion(json_data['version']) + else: + version = StrictVersion('0.11.5') name = json_data['name'] contacts = [] @@ -115,7 +120,7 @@ class Account(QObject): communities = [] for data in json_data['communities']: - community = Community.load(data) + community = Community.load(data, version) communities.append(community) account = cls(salt, pubkey, name, communities, wallets, diff --git a/src/sakia/core/app.py b/src/sakia/core/app.py index 8feedba6..a5ac832e 100644 --- a/src/sakia/core/app.py +++ b/src/sakia/core/app.py @@ -11,6 +11,7 @@ import shutil import json import datetime import aiohttp +from distutils.version import StrictVersion from PyQt5.QtCore import QObject, pyqtSignal, QTranslator, QCoreApplication, QLocale from ucoinpy.api.bma import API @@ -278,7 +279,7 @@ class Application(QObject): with open(network_path, 'r') as json_data: data = json.load(json_data) logging.debug("Merging network : {0}".format(data)) - community.network.merge_with_json(data['network']) + community.network.merge_with_json(data['network'], StrictVersion(data['version'])) if os.path.exists(bma_path): with open(bma_path, 'r') as json_data: diff --git a/src/sakia/core/community.py b/src/sakia/core/community.py index e9104305..2a368bc3 100644 --- a/src/sakia/core/community.py +++ b/src/sakia/core/community.py @@ -57,28 +57,19 @@ class Community(QObject): return community @classmethod - def load(cls, json_data): + def load(cls, json_data, version): """ Load a community from json :param dict json_data: The community as a dict in json format + :param distutils.version.StrictVersion version: the file sakia version """ currency = json_data['currency'] - network = Network.from_json(currency, json_data['peers']) + network = Network.from_json(currency, json_data['peers'], version) bma_access = BmaAccess.create(network) community = cls(currency, network, bma_access) return community - def load_cache(self, bma_access_cache, network_cache): - """ - Load the community cache. - - :param dict bma_access_cache: The BmaAccess cache in json - :param dict network_cache: The network cache in json - """ - self._bma_access.load_from_json(bma_access_cache) - self._network.merge_with_json(network_cache) - @property def name(self): """ diff --git a/src/sakia/core/net/network.py b/src/sakia/core/net/network.py index eeb9d3a5..4ca32327 100644 --- a/src/sakia/core/net/network.py +++ b/src/sakia/core/net/network.py @@ -57,15 +57,16 @@ class Network(QObject): network = cls(node.currency, nodes) return network - def merge_with_json(self, json_data): + def merge_with_json(self, json_data, file_version): """ We merge with knew nodes when we last stopped sakia :param dict json_data: Nodes in json format + :param distutils.version.StrictVersion file_version: The node version """ for data in json_data: - node = Node.from_json(self.currency, data) + node = Node.from_json(self.currency, data, file_version) if node.pubkey not in [n.pubkey for n in self.nodes]: self.add_node(node) logging.debug("Loading : {:}".format(data['pubkey'])) @@ -74,6 +75,7 @@ class Network(QObject): other_node._uid = node.uid other_node._version = node.version other_node._software = node.software + other_node._peer = node.peer switch = False if other_node.block and node.block: if other_node.block['hash'] != node.block['hash']: @@ -86,16 +88,17 @@ class Network(QObject): other_node.state = node.state @classmethod - def from_json(cls, currency, json_data): + def from_json(cls, currency, json_data, version): """ Load a network from a configured community :param str currency: The currency name of a community :param dict json_data: A json_data view of a network + :param distutils.version.StrictVersion version: the version of the json file """ nodes = [] for data in json_data: - node = Node.from_json(currency, data) + node = Node.from_json(currency, data, version) nodes.append(node) network = cls(currency, nodes) return network @@ -340,6 +343,8 @@ class Network(QObject): self.nodes_changed.emit() except InvalidNodeCurrency as e: logging.debug(str(e)) + else: + node = [n for n in self.nodes if n.pubkey == pubkey][0] @pyqtSlot() def handle_identity_change(self): diff --git a/src/sakia/core/net/node.py b/src/sakia/core/net/node.py index 348aa406..1b2a8341 100644 --- a/src/sakia/core/net/node.py +++ b/src/sakia/core/net/node.py @@ -5,18 +5,18 @@ Created on 21 févr. 2015 """ from ucoinpy.documents.peer import Peer, Endpoint, BMAEndpoint +from ucoinpy.documents import Block from ...tools.exceptions import InvalidNodeCurrency from ...tools.decorators import asyncify from ucoinpy.api import bma as bma from ucoinpy.api.bma import ConnectionHandler -import asyncio from aiohttp.errors import ClientError, DisconnectedError from asyncio import TimeoutError import logging import time import jsonschema -import aiohttp +from distutils.version import StrictVersion from socket import gaierror from PyQt5.QtCore import QObject, pyqtSignal @@ -42,20 +42,19 @@ class Node(QObject): identity_changed = pyqtSignal() neighbour_found = pyqtSignal(Peer, str) - def __init__(self, currency, endpoints, uid, pubkey, block, + def __init__(self, peer, uid, pubkey, block, state, last_change, last_merkle, software, version, fork_window): """ Constructor """ super().__init__() - self._endpoints = endpoints + self._peer = peer self._uid = uid self._pubkey = pubkey self._block = block self.main_chain_previous_block = None self._state = state self._neighbours = [] - self._currency = currency self._last_change = last_change self._last_merkle = last_merkle self._software = software @@ -84,8 +83,7 @@ class Node(QObject): if peer.currency != currency: raise InvalidNodeCurrency(peer.currency, currency) - node = cls(peer.currency, - [Endpoint.from_inline(e.inline()) for e in peer.endpoints], + node = cls(peer, "", peer.pubkey, None, Node.ONLINE, time.time(), {'root': "", 'leaves': []}, "", "", 0) logging.debug("Node from address : {:}".format(str(node))) @@ -106,8 +104,7 @@ class Node(QObject): if peer.currency != currency: raise InvalidNodeCurrency(peer.currency, currency) - node = cls(peer.currency, peer.endpoints, - "", pubkey, None, + node = cls(peer, "", pubkey, None, Node.OFFLINE, time.time(), {'root': "", 'leaves': []}, "", "", 0) @@ -115,7 +112,16 @@ class Node(QObject): return node @classmethod - def from_json(cls, currency, data): + def from_json(cls, currency, data, file_version): + """ + Loads a node from json data + + :param str currency: the currency of the community + :param dict data: the json data of the node + :param StrictVersion file_version: the version of the file + :return: A new node + :rtype: Node + """ endpoints = [] uid = "" pubkey = "" @@ -126,12 +132,6 @@ class Node(QObject): last_change = time.time() state = Node.OFFLINE logging.debug(data) - for endpoint_data in data['endpoints']: - endpoints.append(Endpoint.from_inline(endpoint_data)) - - if currency in data: - currency = data['currency'] - if 'uid' in data: uid = data['uid'] @@ -156,11 +156,23 @@ class Node(QObject): if 'fork_window' in data: fork_window = data['fork_window'] - node = cls(currency, endpoints, - uid, pubkey, block, + if file_version < StrictVersion("0.12"): + for endpoint_data in data['endpoints']: + endpoints.append(Endpoint.from_inline(endpoint_data)) + + if currency in data: + currency = data['currency'] + + peer = Peer("1", currency, pubkey, "0-{0}".format(Block.Empty_Hash), endpoints, "SOMEFAKESIGNATURE") + else: + if 'peer' in data: + peer = Peer.from_signed_raw(data['peer']) + + node = cls(peer, uid, pubkey, block, state, last_change, {'root': "", 'leaves': []}, software, version, fork_window) + logging.debug("Node from json : {:}".format(str(node))) return node @@ -168,18 +180,15 @@ class Node(QObject): logging.debug("Saving root node : {:}".format(str(self))) data = {'pubkey': self._pubkey, 'uid': self._uid, - 'currency': self._currency} - endpoints = [] - for e in self._endpoints: - endpoints.append(e.inline()) - data['endpoints'] = endpoints + 'currency': self._currency, + 'peer': self._peer.signed_raw()} return data def jsonify(self): logging.debug("Saving node : {:}".format(str(self))) data = {'pubkey': self._pubkey, 'uid': self._uid, - 'currency': self._currency, + 'peer': self._peer.signed_raw(), 'state': self._state, 'last_change': self._last_change, 'block': self.block, @@ -187,10 +196,6 @@ class Node(QObject): 'version': self._version, 'fork_window': self._fork_window } - endpoints = [] - for e in self._endpoints: - endpoints.append(e.inline()) - data['endpoints'] = endpoints return data @property @@ -199,7 +204,7 @@ class Node(QObject): @property def endpoint(self) -> BMAEndpoint: - return next((e for e in self._endpoints if type(e) is BMAEndpoint)) + return next((e for e in self._peer.endpoints if type(e) is BMAEndpoint)) @property def block(self): @@ -214,7 +219,7 @@ class Node(QObject): @property def currency(self): - return self._currency + return self._peer.currency @property def neighbours(self): @@ -232,6 +237,10 @@ class Node(QObject): def software(self): return self._software + @property + def peer(self): + return self._peer + @software.setter def software(self, new_soft): if self._software != new_soft: -- GitLab