diff --git a/Tribler/Core/Modules/restapi/trustchain_endpoint.py b/Tribler/Core/Modules/restapi/trustchain_endpoint.py index 621f3d0d405..a6847129a70 100644 --- a/Tribler/Core/Modules/restapi/trustchain_endpoint.py +++ b/Tribler/Core/Modules/restapi/trustchain_endpoint.py @@ -16,7 +16,8 @@ def __init__(self, session): child_handler_dict = { "statistics": TrustchainStatsEndpoint, "blocks": TrustchainBlocksEndpoint, - "bootstrap": TrustchainBootstrapEndpoint} + "bootstrap": TrustchainBootstrapEndpoint + } for path, child_cls in child_handler_dict.iteritems(): self.putChild(path, child_cls(session)) @@ -172,65 +173,63 @@ def render_GET(self, request): class TrustchainBootstrapEndpoint(TrustchainBaseEndpoint): """ - Bootstrap a new identity and transfer some reputation to the new key. + Bootstrap a new identity and transfer some bandwidth tokens to the new key. """ def render_GET(self, request): """ - .. http:get:: /trustchain/bootstrap?up=int&down=int + .. http:get:: /trustchain/bootstrap?amount=int - A GET request to this endpoint generates a new identity and transfers some reputation to it. + A GET request to this endpoint generates a new identity and transfers bandwidth tokens to it. + The amount specifies how much tokens need to be emptied into the new identity **Example request**: .. sourcecode:: none - curl -X GET http://localhost:8085/trustchain/bootstrap?up=100000&down=40000 + curl -X GET http://localhost:8085/trustchain/bootstrap?amount=1000 **Example response**: .. sourcecode:: javascript { - "private_key" : "NEW_KEY", - "public_key" : "NEW_PUBLIC_KEY" , - "transactions" : [ - { - "hash": "ab672fd6acc0", - "tx" : { - "up": 100000, - "down": 40000, - "total_up": 100000, - "total_down": 40000, - }, - "sequence_number": 0, - "link_public_key": "PC_KEY", - "link_sequence_number": 1210, - "previous_hash": 00000000 - } - ] + "private_key": "TGliTmFDTFNLOmC4BR7otCpn+NzTBAFwKdSJdpT0KG9Zy5vPGX6s3rDXmNiDoGKyToLeYYB88vj9\nRj5NW + pbNf/ldcixYZ2YxQ7Q=\n", + "transaction": { + "down": 0, + "up": 1000 + }, + "block": { + "block_hash": "THJxNlKWMQG1Tio+Yz5CUCrnWahcyk6TDVfRLQf7w6M=\n", + "sequence_number": 1 } + } """ + mc_community = self.get_trustchain_community() if not mc_community: request.setResponseCode(http.NOT_FOUND) return json.dumps({"error": "trustchain community not found"}) - statistics = mc_community.get_statistics() - up = statistics['total_up'] - down = statistics['total_down'] - if 'up' in request.args: - try: - up = int(request.args['up'][0]) - except ValueError: - up = up + available_tokens = mc_community.get_bandwidth_tokens() - if 'down' in request.args: + if 'amount' in request.args: try: - down = int(request.args['down'][0]) + amount = int(request.args['amount'][0]) except ValueError: - down = down + request.setResponseCode(http.BAD_REQUEST) + return json.dumps({"error": "Provided token amount is not a number"}) + + if amount <= 0: + request.setResponseCode(http.BAD_REQUEST) + return json.dumps({"error": "Provided token amount is zero or negative"}) + else: + amount = available_tokens - result = mc_community.bootstrap_new_identity(up, down) + if amount <= 0 or amount > available_tokens: + request.setResponseCode(http.BAD_REQUEST) + return json.dumps({"error": "Not enough bandwidth tokens available"}) + result = mc_community.bootstrap_new_identity(amount) return json.dumps(result) diff --git a/Tribler/Test/Community/Triblerchain/test_community.py b/Tribler/Test/Community/Triblerchain/test_community.py index d5e8b03ce01..b9836af036f 100644 --- a/Tribler/Test/Community/Triblerchain/test_community.py +++ b/Tribler/Test/Community/Triblerchain/test_community.py @@ -386,3 +386,65 @@ def test_get_default_trust(self): other_trust = blockingCallFromThread(reactor, other.community.get_trust, node.community.my_member) self.assertEqual(node_trust, 1) self.assertEqual(other_trust, 1) + + def test_get_bandwidth_tokens_for_self(self): + """ + Test that the bandwidth tokens the own node has is the upload - the download total of all blocks. + """ + # Arrange + node, other = self.create_nodes(2) + transaction = {'up': 10, 'down': 5} + transaction2 = {'up': 5, 'down': 10} + TestTriblerChainCommunity.create_block(node, other, self._create_target(node, other), transaction) + TestTriblerChainCommunity.create_block(other, node, self._create_target(other, node), transaction2) + + # Get statistics + node_trust = blockingCallFromThread(reactor, node.community.get_bandwidth_tokens, node.community.my_member) + other_trust = blockingCallFromThread(reactor, other.community.get_bandwidth_tokens, other.community.my_member) + self.assertEqual(node_trust, 5) + self.assertEqual(other_trust, -5) + + def test_get_bandwidth_tokens(self): + """ + Test that the bandwidth tokens nodes have is the upload - the download total of all blocks. + """ + # Arrange + node, other = self.create_nodes(2) + transaction = {'up': 10, 'down': 5} + transaction2 = {'up': 5, 'down': 10} + TestTriblerChainCommunity.create_block(node, other, self._create_target(node, other), transaction) + TestTriblerChainCommunity.create_block(other, node, self._create_target(other, node), transaction2) + + # Get statistics + node_trust = blockingCallFromThread(reactor, node.community.get_bandwidth_tokens, other.community.my_member) + other_trust = blockingCallFromThread(reactor, other.community.get_bandwidth_tokens, node.community.my_member) + self.assertEqual(node_trust, -5) + self.assertEqual(other_trust, 5) + + def test_get_default_bandwidth_tokens(self): + """ + Test that the bandwidth token amount for nodes without blocks is 0. + """ + # Arrange + node, other = self.create_nodes(2) + + # Get statistics + node_trust = blockingCallFromThread(reactor, node.community.get_bandwidth_tokens, other.community.my_member) + other_trust = blockingCallFromThread(reactor, other.community.get_bandwidth_tokens, node.community.my_member) + self.assertEqual(node_trust, 0) + self.assertEqual(other_trust, 0) + + def test_bootstrapping(self): + """ + Test that bootstrapping process works. + """ + # Arrange + node, = self.create_nodes(1) + + node_bootstrap = blockingCallFromThread(reactor, node.community.bootstrap_new_identity, 100) + self.assertNotEqual(node_bootstrap['private_key'], + node.community.my_member.private_key.key_to_bin().encode('base64')) + self.assertEqual(node_bootstrap['transaction']['up'], 100) + self.assertEqual(node_bootstrap['transaction']['down'], 0) + self.assertEqual(node_bootstrap['block']['sequence_number'], 1) + self.assertNotEqual(node_bootstrap['block']['block_hash'], "") diff --git a/Tribler/Test/Community/Trustchain/test_trustchain_utilities.py b/Tribler/Test/Community/Trustchain/test_trustchain_utilities.py index f9df2768714..92271b4646c 100644 --- a/Tribler/Test/Community/Trustchain/test_trustchain_utilities.py +++ b/Tribler/Test/Community/Trustchain/test_trustchain_utilities.py @@ -16,7 +16,7 @@ class TestBlock(TrustChainBlock): Also used in other test files for TrustChain. """ - def __init__(self, transaction=None, previous=None): + def __init__(self, transaction=None, previous=None, key=None): crypto = ECCrypto() other = crypto.generate_key(u"curve25519").pub().key_to_bin() @@ -27,7 +27,11 @@ def __init__(self, transaction=None, previous=None): TrustChainBlock.__init__(self, (encode(transaction), previous.public_key, previous.sequence_number + 1, other, 0, previous.hash, 0, 0)) else: - self.key = crypto.generate_key(u"curve25519") + if key: + self.key = key + else: + self.key = crypto.generate_key(u"curve25519") + TrustChainBlock.__init__(self, ( encode(transaction), self.key.pub().key_to_bin(), random.randint(50, 100), other, 0, sha256(str(random.randint(0, 100000))).digest(), 0, 0)) diff --git a/Tribler/Test/Core/Modules/RestApi/test_trustchain_endpoint.py b/Tribler/Test/Core/Modules/RestApi/test_trustchain_endpoint.py index 4705d2ff1f6..5cc426aebaa 100644 --- a/Tribler/Test/Core/Modules/RestApi/test_trustchain_endpoint.py +++ b/Tribler/Test/Core/Modules/RestApi/test_trustchain_endpoint.py @@ -166,3 +166,95 @@ def test_get_blocks_unlimited(self): self.should_check_equality = False return self.do_request('trustchain/blocks/%s' % TestBlock().public_key.encode("HEX"), expected_code=200) + + @deferred(timeout=10) + def test_get_bootstrap_identity_no_community(self): + """ + Testing whether the API returns error 404 if no trustchain community is loaded when bootstrapping a new identity + """ + self.dispersy.get_communities = lambda: [] + return self.do_request('trustchain/bootstrap', expected_code=404) + + @deferred(timeout=10) + def test_get_bootstrap_identity_all_tokens(self): + """ + Testing whether the API return all available credit when no argument is supplied + """ + transaction = {'up': 100, 'down': 0, 'total_up': 100, 'total_down': 0} + transaction2 = {'up': 100, 'down': 0} + + def verify_response(response): + response_json = json.loads(response) + self.assertEqual(response_json['transaction'], transaction2) + + test_block = TestBlock(transaction=transaction, key=self.tc_community.my_member.private_key) + self.tc_community.persistence.add_block(test_block) + + self.should_check_equality = False + return self.do_request('trustchain/bootstrap', expected_code=200).addCallback(verify_response) + + @deferred(timeout=10) + def test_get_bootstrap_identity_partial_tokens(self): + """ + Testing whether the API return partial available credit when argument is supplied + """ + transaction = {'up': 100, 'down': 0, 'total_up': 100, 'total_down': 0} + transaction2 = {'up': 50, 'down': 0} + + def verify_response(response): + response_json = json.loads(response) + self.assertEqual(response_json['transaction'], transaction2) + + test_block = TestBlock(transaction=transaction, key=self.tc_community.my_member.private_key) + self.tc_community.persistence.add_block(test_block) + + self.should_check_equality = False + return self.do_request('trustchain/bootstrap?amount=50', expected_code=200).addCallback(verify_response) + + @deferred(timeout=10) + def test_get_bootstrap_identity_not_enough_tokens(self): + """ + Testing whether the API returns error 400 if bandwidth is to low when bootstrapping a new identity + """ + transaction = {'up': 100, 'down': 0, 'total_up': 100, 'total_down': 0} + test_block = TestBlock(transaction=transaction, key=self.tc_community.my_member.private_key) + self.tc_community.persistence.add_block(test_block) + + self.should_check_equality = False + return self.do_request('trustchain/bootstrap?amount=200', expected_code=400) + + @deferred(timeout=10) + def test_get_bootstrap_identity_not_enough_tokens_2(self): + """ + Testing whether the API returns error 400 if bandwidth is to low when bootstrapping a new identity + """ + transaction = {'up': 0, 'down': 100, 'total_up': 0, 'total_down': 100} + test_block = TestBlock(transaction=transaction, key=self.tc_community.my_member.private_key) + self.tc_community.persistence.add_block(test_block) + + self.should_check_equality = False + return self.do_request('trustchain/bootstrap?amount=10', expected_code=400) + + @deferred(timeout=10) + def test_get_bootstrap_identity_zero_amount(self): + """ + Testing whether the API returns error 400 if amount is zero when bootstrapping a new identity + """ + self.should_check_equality = False + return self.do_request('trustchain/bootstrap?amount=0', expected_code=400) + + @deferred(timeout=10) + def test_get_bootstrap_identity_negative_amount(self): + """ + Testing whether the API returns error 400 if amount is negative when bootstrapping a new identity + """ + self.should_check_equality = False + return self.do_request('trustchain/bootstrap?amount=-1', expected_code=400) + + @deferred(timeout=10) + def test_get_bootstrap_identity_string(self): + """ + Testing whether the API returns error 400 if amount is string when bootstrapping a new identity + """ + self.should_check_equality = False + return self.do_request('trustchain/bootstrap?amount=aaa', expected_code=400) diff --git a/Tribler/community/triblerchain/community.py b/Tribler/community/triblerchain/community.py index 9cd33daf71b..c95372721e8 100644 --- a/Tribler/community/triblerchain/community.py +++ b/Tribler/community/triblerchain/community.py @@ -215,10 +215,29 @@ def get_trust(self, member): # We need a minimum of 1 trust to have a chance to be selected in the categorical distribution. return 1 - def bootstrap_new_identity(self, up, down): - """ + def get_bandwidth_tokens(self, member=None): + """ + Get the bandwidth tokens for another member. + Currently this is just the difference in the amount of MBs exchanged with them. + + :param member: the member we interacted with + :type member: dispersy.member.Member + :return: the amount of bandwidth tokens for this member + :rtype: int + """ + if member is None: + member = self.my_member + + block = self.persistence.get_latest(member.public_key) + if block: + return block.transaction['total_up'] - block.transaction['total_down'] + + return 0 + + def bootstrap_new_identity(self, amount): + """ One-way payment channel. - Create a new temporary identity , and transfer funds to the new identity. + Create a new temporary identity, and transfer funds to the new identity. A different party can then take the result and do a transfer from the temporary identity to itself """ @@ -227,15 +246,15 @@ def bootstrap_new_identity(self, up, down): # Create the transaction specification transaction = { - 'up': up, 'down': down + 'up': 0, 'down': amount } # Create the two half blocks that form the transaction local_half_block = TriblerChainBlock.create(transaction, self.persistence, self.my_member.public_key, link_pk=tmp_member.public_key) local_half_block.sign(self.my_member.private_key) - tmp_half_block = TriblerChainBlock.create(transaction, DBShim(), tmp_member.public_key, link=local_half_block, - link_pk=self.my_member.public_key) + tmp_half_block = TriblerChainBlock.create(transaction, self.persistence, tmp_member.public_key, + link=local_half_block, link_pk=self.my_member.public_key) tmp_half_block.sign(tmp_member.private_key) self.persistence.add_block(local_half_block) @@ -245,8 +264,8 @@ def bootstrap_new_identity(self, up, down): block = {'block_hash': tmp_half_block.hash.encode('base64'), 'sequence_number': tmp_half_block.sequence_number} - result = {'transaction': transaction, 'block': block, - 'private_key': tmp_member.private_key.key_to_bin().encode('base64')} + result = {'private_key': tmp_member.private_key.key_to_bin().encode('base64'), + 'transaction': {'up': amount, 'down': 0}, 'block': block} return result @@ -266,8 +285,3 @@ def on_introduction_response(self, messages): def start_walking(self): self.register_task("take step", LoopingCall(self.take_step)).start(self.CrawlerDelay, now=False) - - -class DBShim: - def get_latest(self, x): - return {} diff --git a/TriblerGUI/qt_resources/mainwindow.ui b/TriblerGUI/qt_resources/mainwindow.ui index 84de2e372fa..e47f6c4588a 100644 --- a/TriblerGUI/qt_resources/mainwindow.ui +++ b/TriblerGUI/qt_resources/mainwindow.ui @@ -6273,32 +6273,92 @@ color: white; color: white; - Funds emptying into another account (offline) + Bandwidth tokens emptying into another account (offline) - + + + Bandwidth tokens can be emptied into another + + + + + - - - color: white; + + + + 0 + 24 + + + + + 16777215 + 24 + - Fully empty funds + FULLY EMPTY TOKENS - + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 15 + 20 + + + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + - color: white; + - Partially empty funds + PARTIALLY EMPTY TOKENS + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + @@ -6308,7 +6368,10 @@ color: white; color: orange; - Warning: one-way action that cannot be revered, if QR code is not scanned funds will be lost + Warning: this is a one-way action that cannot be reverted. If the QR code is not scanned, funds will be lost. + + + true diff --git a/TriblerGUI/widgets/settingspage.py b/TriblerGUI/widgets/settingspage.py index 73755bbae7e..f597b0fdd6d 100644 --- a/TriblerGUI/widgets/settingspage.py +++ b/TriblerGUI/widgets/settingspage.py @@ -20,6 +20,8 @@ DEPENDENCY_ERROR_TITLE = "Dependency missing" DEPENDENCY_ERROR_MESSAGE = "'qrcode' module is missing. This module can be installed through apt-get or pip" +MEBIBYTE = 1048576 + class SettingsPage(QWidget): """ @@ -32,9 +34,9 @@ def __init__(self): self.settings_request_mgr = None self.trustchain_request_mgr = None self.saved_dialog = None - self.empty_funds_barcode_dialog = None - self.empty_partial_funds_dialog = None - self.confirm_empty_funds_dialog = None + self.empty_tokens_barcode_dialog = None + self.empty_partial_tokens_dialog = None + self.confirm_empty_tokens_dialog = None def initialize_settings_page(self): self.window().settings_tab.initialize() @@ -47,86 +49,100 @@ def initialize_settings_page(self): self.window().developer_mode_enabled_checkbox.stateChanged.connect(self.on_developer_mode_checkbox_changed) self.window().use_monochrome_icon_checkbox.stateChanged.connect(self.on_use_monochrome_icon_checkbox_changed) self.window().download_settings_anon_checkbox.stateChanged.connect(self.on_anon_download_state_changed) - self.window().fully_empty_funds_button.clicked.connect(self.confirm_fully_empty_funds) - self.window().partially_empty_funds_button.clicked.connect(self.partially_empty_funds) - - def confirm_fully_empty_funds(self): - self.confirm_empty_funds_dialog = ConfirmationDialog(self, "Empty funds into another account", - "Are you sure you want to empty ALL funds into another account? " - "Warning: one-way action that cannot be revered", - [('EMPTY', BUTTON_TYPE_NORMAL), ('Cancel', BUTTON_TYPE_CONFIRM)]) - self.confirm_empty_funds_dialog.button_clicked.connect(self.on_confirm_fully_empty_funds) - self.confirm_empty_funds_dialog.show() - - def on_confirm_fully_empty_funds(self, action): - self.confirm_empty_funds_dialog.close_dialog() - self.confirm_empty_funds_dialog = None + self.window().fully_empty_tokens_button.clicked.connect(self.confirm_fully_empty_tokens) + self.window().partially_empty_tokens_button.clicked.connect(self.partially_empty_tokens) + + def confirm_fully_empty_tokens(self): + self.confirm_empty_tokens_dialog = ConfirmationDialog(self, "Empty tokens into another account", + "Are you sure you want to empty ALL bandwidth tokens " + "into another account? " + "Warning: one-way action that cannot be revered", + [ + ('EMPTY', BUTTON_TYPE_CONFIRM), + ('CANCEL', BUTTON_TYPE_NORMAL) + ]) + self.confirm_empty_tokens_dialog.button_clicked.connect(self.on_confirm_fully_empty_tokens) + self.confirm_empty_tokens_dialog.show() + + def on_confirm_fully_empty_tokens(self, action): + self.confirm_empty_tokens_dialog.close_dialog() + self.confirm_empty_tokens_dialog = None if action == 0: self.trustchain_request_mgr = TriblerRequestManager() - self.trustchain_request_mgr.perform_request("trustchain/bootstrap", self.on_emptying_funds) - - def partially_empty_funds(self): - self.empty_partial_funds_dialog = ConfirmationDialog(self, "Empty funds into another account", - "Specify the amount of funds to empty into another account below:", - [('EMPTY', BUTTON_TYPE_NORMAL), ('Cancel', BUTTON_TYPE_CONFIRM)], - show_input=True) - self.empty_partial_funds_dialog.dialog_widget.dialog_input.setPlaceholderText('') - self.empty_partial_funds_dialog.dialog_widget.dialog_input.setFocus() - self.empty_partial_funds_dialog.button_clicked.connect(self.confirm_partially_empty_funds) - self.empty_partial_funds_dialog.show() - - def confirm_partially_empty_funds(self, action): - funds = self.empty_partial_funds_dialog.dialog_widget.dialog_input.text() - self.empty_partial_funds_dialog.close_dialog() - self.empty_partial_funds_dialog = None - - try: - funds = int(float(funds)) - except ValueError: - ConfirmationDialog.show_error(self.window(), "Input error", "Input is not a number") - return + self.trustchain_request_mgr.perform_request("trustchain/bootstrap", self.on_emptying_tokens) + + def partially_empty_tokens(self): + self.empty_partial_tokens_dialog = ConfirmationDialog(self, "Empty tokens into another account", + "Specify the amount of bandwidth tokens to empty into " + "another account below:", + [ + ('EMPTY', BUTTON_TYPE_CONFIRM), + ('CANCEL', BUTTON_TYPE_NORMAL) + ], show_input=True) + self.empty_partial_tokens_dialog.dialog_widget.dialog_input.setPlaceholderText( + 'Please enter the amount of tokens in MB') + self.empty_partial_tokens_dialog.dialog_widget.dialog_input.setFocus() + self.empty_partial_tokens_dialog.button_clicked.connect(self.confirm_partially_empty_tokens) + self.empty_partial_tokens_dialog.show() + + def confirm_partially_empty_tokens(self, action): + tokens = self.empty_partial_tokens_dialog.dialog_widget.dialog_input.text() + self.empty_partial_tokens_dialog.close_dialog() + self.empty_partial_tokens_dialog = None if action == 0: - self.confirm_empty_funds_dialog = ConfirmationDialog(self, "Empty funds into another account", - "Are you sure you want to empty %d funds into another account? " - "Warning: one-way action that cannot be revered" % - funds, - [('EMPTY', BUTTON_TYPE_NORMAL), ('Cancel', BUTTON_TYPE_CONFIRM)]) - self.confirm_empty_funds_dialog.button_clicked.connect(lambda action2: self.on_confirm_partially_empty_funds(action2, funds)) - self.confirm_empty_funds_dialog.show() - - def on_confirm_partially_empty_funds(self, action, funds): - self.confirm_empty_funds_dialog.close_dialog() - self.confirm_empty_funds_dialog = None + try: + tokens = int(float(tokens)) + except ValueError: + ConfirmationDialog.show_error(self.window(), "Wrong input", "The provided amount is not a number") + return + + self.confirm_empty_tokens_dialog = ConfirmationDialog(self, "Empty tokens into another account", + "Are you sure you want to empty %d bandwidth tokens " + "into another account? " + "Warning: one-way action that cannot be revered" % + tokens, + [ + ('EMPTY', BUTTON_TYPE_NORMAL), + ('CANCEL', BUTTON_TYPE_CONFIRM) + ]) + self.confirm_empty_tokens_dialog.button_clicked.connect( + lambda action2: self.on_confirm_partially_empty_tokens(action2, tokens)) + self.confirm_empty_tokens_dialog.show() + + def on_confirm_partially_empty_tokens(self, action, tokens): + self.confirm_empty_tokens_dialog.close_dialog() + self.confirm_empty_tokens_dialog = None if action == 0: self.trustchain_request_mgr = TriblerRequestManager() - self.trustchain_request_mgr.perform_request("trustchain/bootstrap?up=%d&down=0" % funds, self.on_emptying_funds) + self.trustchain_request_mgr.perform_request("trustchain/bootstrap?amount=%d" % (tokens * MEBIBYTE), + self.on_emptying_tokens) - def on_emptying_funds(self, json_data): - data = json.dumps(json_data) + def on_emptying_tokens(self, data): + json_data = json.dumps(data) if has_qr: - self.empty_funds_barcode_dialog = QWidget() - self.empty_funds_barcode_dialog.setWindowTitle("Empty funds into another account") - self.empty_funds_barcode_dialog.setGeometry(10, 10, 500, 500) + self.empty_tokens_barcode_dialog = QWidget() + self.empty_tokens_barcode_dialog.setWindowTitle("Please scan the following QR code") + self.empty_tokens_barcode_dialog.setGeometry(10, 10, 500, 500) qr = qrcode.QRCode( version=1, error_correction=qrcode.constants.ERROR_CORRECT_M, box_size=10, border=5, ) - qr.add_data(data) + qr.add_data(json_data) qr.make(fit=True) img = qr.make_image() # PIL format qim = ImageQt(img) pixmap = QtGui.QPixmap.fromImage(qim).scaled(600, 600, QtCore.Qt.KeepAspectRatio) - label = QLabel(self.empty_funds_barcode_dialog) + label = QLabel(self.empty_tokens_barcode_dialog) label.setPixmap(pixmap) - self.empty_funds_barcode_dialog.resize(pixmap.width(), pixmap.height()) - self.empty_funds_barcode_dialog.show() + self.empty_tokens_barcode_dialog.resize(pixmap.width(), pixmap.height()) + self.empty_tokens_barcode_dialog.show() else: ConfirmationDialog.show_error(self.window(), DEPENDENCY_ERROR_TITLE, DEPENDENCY_ERROR_MESSAGE) diff --git a/tribler-headless.sh b/tribler-headless.sh deleted file mode 100755 index b71b2e1c103..00000000000 --- a/tribler-headless.sh +++ /dev/null @@ -1 +0,0 @@ -python2 -m twisted tribler --restapi 8080 --manhole 3000