From ac91a0156f5e96bb4f04bb07e0f1acece6f43dcd Mon Sep 17 00:00:00 2001 From: Inso <insomniak.fr@gmail.com> Date: Tue, 20 May 2014 17:29:58 +0200 Subject: [PATCH] WHT management : we can now push a WHT --- lib/ucoin/pks/__init__.py | 2 +- res/ui/walletTabWidget.ui | 36 +++++++++- src/cutecoin/gui/processConfigureAccount.py | 13 ++-- src/cutecoin/gui/processConfigureCommunity.py | 14 +++- src/cutecoin/models/account/__init__.py | 2 +- .../models/account/wallets/__init__.py | 6 +- src/cutecoin/models/wallet/__init__.py | 72 +++++++++++-------- 7 files changed, 105 insertions(+), 40 deletions(-) diff --git a/lib/ucoin/pks/__init__.py b/lib/ucoin/pks/__init__.py index d13a28a6..ecb92cac 100644 --- a/lib/ucoin/pks/__init__.py +++ b/lib/ucoin/pks/__init__.py @@ -24,7 +24,7 @@ logger = logging.getLogger("ucoin/pks") class PKS(API): def __init__(self, module='pks', server=None, port=None): - super().__init__(module=module, server, port) + super().__init__(module=module, server=server, port=port) class Add(PKS): diff --git a/res/ui/walletTabWidget.ui b/res/ui/walletTabWidget.ui index 7d041555..a8e08a35 100644 --- a/res/ui/walletTabWidget.ui +++ b/res/ui/walletTabWidget.ui @@ -26,6 +26,40 @@ <item> <widget class="QTreeView" name="trusts_tree_view"/> </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <property name="topMargin"> + <number>5</number> + </property> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Required trust to accept a transaction : </string> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="spinbox_trusts"> + <property name="maximum"> + <number>999</number> + </property> + </widget> + </item> + </layout> + </item> </layout> </item> <item> @@ -36,6 +70,6 @@ <resources/> <connections/> <slots> - <slot>open_issuance_dialog()</slot> + <slot>required_trusts_changed(int)</slot> </slots> </ui> diff --git a/src/cutecoin/gui/processConfigureAccount.py b/src/cutecoin/gui/processConfigureAccount.py index f74222db..4dc3b0be 100644 --- a/src/cutecoin/gui/processConfigureAccount.py +++ b/src/cutecoin/gui/processConfigureAccount.py @@ -62,12 +62,14 @@ class StepPageCommunities(Step): self.config_dialog.community = account.communities.add_community( default_node) #TODO: Get existing Wallet from ucoin node - account.wallets.add_wallet(account.fingerprint, + account.wallets.add_wallet(account.keyid, self.config_dialog.community) def display_page(self): self.config_dialog.button_previous.setEnabled(False) self.config_dialog.button_next.setText("Ok") + list_model = CommunitiesListModel(self.config_dialog.account) + self.config_dialog.list_communities.setModel(list_model) class ProcessConfigureAccount(QDialog, Ui_AccountConfigurationDialog): @@ -88,6 +90,7 @@ class ProcessConfigureAccount(QDialog, Ui_AccountConfigurationDialog): step_communities = StepPageCommunities(self) step_init.next_step = step_communities self.step = step_init + self.step.display_page() if self.account is None: self.setWindowTitle("New account") else: @@ -119,9 +122,9 @@ class ProcessConfigureAccount(QDialog, Ui_AccountConfigurationDialog): self.edit_account_name.setText(self.account.name) def open_process_add_community(self): - dialog = ProcessConfigureCommunity(self.account, None) - dialog.accepted.connect(self.action_add_community) - dialog.exec_() + dialog = ProcessConfigureCommunity(self.account, None) + dialog.accepted.connect(self.action_add_community) + dialog.exec_() def action_add_community(self): self.combo_keys_list.setEnabled(False) @@ -142,7 +145,7 @@ class ProcessConfigureAccount(QDialog, Ui_AccountConfigurationDialog): def open_process_edit_community(self, index): community = self.account.communities[index.row()] dialog = ProcessConfigureCommunity(self.account, community) - dialog.button_box.accepted.connect(self.action_edit_community) + dialog.accepted.connect(self.action_edit_community) dialog.exec_() def key_changed(self, key_index): diff --git a/src/cutecoin/gui/processConfigureCommunity.py b/src/cutecoin/gui/processConfigureCommunity.py index 0a099fcb..1b9d5ddf 100644 --- a/src/cutecoin/gui/processConfigureCommunity.py +++ b/src/cutecoin/gui/processConfigureCommunity.py @@ -144,8 +144,7 @@ class ProcessConfigureCommunity(QDialog, Ui_CommunityConfigurationDialog): self.stacked_pages.setCurrentIndex(next_index) self.step.display_page() else: - self.accepted.emit() - self.close() + self.accept() def previous(self): if self.step.previous_step is not None: @@ -165,6 +164,10 @@ class ProcessConfigureCommunity(QDialog, Ui_CommunityConfigurationDialog): self.tree_nodes.setModel(NodesTreeModel(self.community, self.nodes)) + def required_trusts_changed(self, value): + wallet = self.account.wallets[self.tabs_wallets.currentIndex()] + wallet.required_trusts = value + def showContextMenu(self, point): if self.stacked_pages.currentIndex() == 1: menu = QMenu() @@ -173,3 +176,10 @@ class ProcessConfigureCommunity(QDialog, Ui_CommunityConfigurationDialog): if len(self.nodes) == 1: action.setEnabled(False) menu.exec_(self.mapToGlobal(point)) + + def accept(self): + for wallet in self.account.wallets: + wallet.push_wht() + + self.accepted.emit() + self.close() diff --git a/src/cutecoin/models/account/__init__.py b/src/cutecoin/models/account/__init__.py index 943c36a0..fb0da9ed 100644 --- a/src/cutecoin/models/account/__init__.py +++ b/src/cutecoin/models/account/__init__.py @@ -72,7 +72,7 @@ class Account(object): amendment_data = promoted.get() currency = amendment_data['currency'] community = self.communities.add_community(currency) - self.wallets.add_wallet(self.fingerprint(), + self.wallets.add_wallet(self.keyid, currency, default_node) return community diff --git a/src/cutecoin/models/account/wallets/__init__.py b/src/cutecoin/models/account/wallets/__init__.py index 9dd15ef9..6f7c8683 100644 --- a/src/cutecoin/models/account/wallets/__init__.py +++ b/src/cutecoin/models/account/wallets/__init__.py @@ -46,13 +46,15 @@ class Wallets(object): def __getitem__(self, key): return self._wallets_list[key] - def add_wallet(self, fingerprint, community, node, name="Main Wallet"): + def add_wallet(self, keyid, community, node, + required_trusts=1, name="Main Wallet"): ''' Create a new wallet of a specific currency. This wallet must not already be present in the account, it means the wallet must have a different name or a different currency. ''' - wallet = Wallet.create(fingerprint, community, node, name) + wallet = Wallet.create(keyid, community, node, + required_trusts, name) if wallet not in self._wallets_list: self._wallets_list.append(wallet) return wallet diff --git a/src/cutecoin/models/wallet/__init__.py b/src/cutecoin/models/wallet/__init__.py index 843af0b5..54971e9b 100644 --- a/src/cutecoin/models/wallet/__init__.py +++ b/src/cutecoin/models/wallet/__init__.py @@ -8,6 +8,7 @@ import ucoin import logging import gnupg import json +import time from cutecoin.models.coin import Coin from cutecoin.models.node import Node from cutecoin.models.transaction import Transaction @@ -21,21 +22,23 @@ class Wallet(object): It's only used to sort coins. ''' - def __init__(self, fingerprint, coins, currency, nodes, name): + def __init__(self, keyid, coins, currency, + nodes, required_trusts, name): ''' Constructor ''' self.coins = coins - self.fingerprint = fingerprint + self.keyid = keyid self.currency = currency self.name = name self.nodes = nodes + self.required_trusts = required_trusts @classmethod - def create(cls, fingerprint, currency, node, name): + def create(cls, keyid, currency, node, required_trusts, name): node.trust = True node.hoster = True - return cls(fingerprint, [], currency, [node], name) + return cls(keyid, [], currency, [node], required_trusts, name) @classmethod def load(cls, json_data): @@ -47,10 +50,11 @@ class Wallet(object): for node_data in json_data['nodes']: nodes.append(Node.load(node_data)) - fingerprint = json_data['fingerprint'] + keyid = json_data['keyid'] name = json_data['name'] currency = json_data['currency'] - return cls(fingerprint, coins, currency, nodes, name) + required_trusts = json_data['required_trusts'] + return cls(keyid, coins, currency, nodes, required_trusts, name) def __eq__(self, other): return (self.community == other.community) @@ -64,7 +68,7 @@ class Wallet(object): def transactions_received(self): received = [] transactions_data = self.request( - ucoin.hdc.transactions.Recipient(self.fingerprint)) + ucoin.hdc.transactions.Recipient(self.fingerprint())) for trx_data in transactions_data: received.append( Transaction.create( @@ -77,7 +81,7 @@ class Wallet(object): sent = [] transactions_data = self.request( ucoin.hdc.transactions.sender.Last( - self.fingerprint, 20)) + self.fingerprint(), 20)) for trx_data in transactions_data: # Small bug in ucoinpy library if not isinstance(trx_data, str): @@ -95,7 +99,7 @@ class Wallet(object): except ValueError: return None - def push_wht(self, community): + def push_wht(self): hosters_fg = [] trusts_fg = [] for trust in self.trusts(): @@ -106,27 +110,29 @@ class Wallet(object): logging.debug(peering) peering = hoster.peering() hosters_fg.append(peering['fingerprint']) - entry = { - 'version': '1', - 'currency': self.currency, - 'issuer': self.fingerprint(), - 'requiredTrusts': self.required_trusts, - 'hosters': hosters_fg, - 'trusts': trusts_fg - } - logging.debug(entry) - json_entry = json.JSONEncoder(indent=2).encode(entry) + wht_message = '''Version: 1 +Currency: %s +Key: %s +Date: %s +RequiredTrusts: %d +Hosters: +''' % (self.currency, self.fingerprint(), int(time.time()), + self.required_trusts) + for hoster in hosters_fg: + wht_message += '''%s\n''' % hoster + wht_message += '''Trusts:\n''' + for trust in trusts_fg: + wht_message += '''%s\n''' % trust + + wht_message = wht_message.replace("\n", "\r\n") gpg = gnupg.GPG() - signature = gpg.sign(json_entry, keyid=self.keyid, clearsign=True) + signature = gpg.sign(wht_message, keyid=self.keyid, detach=True) - dataPost = { - 'entry': entry, - 'signature': str(signature) - } + data_post = {'entry': wht_message, + 'signature': str(signature)} + logging.debug(data_post) - self.post(ucoin.network.Wallet( - pgp_fingerprint=self.fingerprint()), - dataPost) + self.post(ucoin.network.Wallet(), data_post) # TODO: Check if its working def _search_node_by_fingerprint(self, node_fg, next_node, traversed_nodes=[]): @@ -175,6 +181,16 @@ class Wallet(object): def hosters(self): return [node for node in self.nodes if node.hoster] + def fingerprint(self): + gpg = gnupg.GPG() + available_keys = gpg.list_keys() + logging.debug(self.keyid) + for k in available_keys: + logging.debug(k) + if k['keyid'] == self.keyid: + return k['fingerprint'] + return "" + def get_text(self): return self.name + " : " + \ str(self.value()) + " " + self.currency @@ -193,7 +209,7 @@ class Wallet(object): def jsonify(self): return {'coins': self.jsonify_coins_list(), - 'fingerprint': self.fingerprint, + 'fingerprint': self.fingerprint(), 'name': self.name, 'currency': self.currency, 'nodes': self.jsonify_nodes_list()} -- GitLab