diff --git a/Tribler/Core/Modules/restapi/multichain_endpoint.py b/Tribler/Core/Modules/restapi/multichain_endpoint.py index 6eb07a27e59..3ad1a98f4ba 100644 --- a/Tribler/Core/Modules/restapi/multichain_endpoint.py +++ b/Tribler/Core/Modules/restapi/multichain_endpoint.py @@ -13,7 +13,7 @@ class MultichainEndpoint(resource.Resource): def __init__(self, session): resource.Resource.__init__(self) - child_handler_dict = {"statistics": MultichainStatsEndpoint} + child_handler_dict = {"statistics": MultichainStatsEndpoint, "trust-edges": MultichainTrustEdgesEndpoint} for path, child_cls in child_handler_dict.iteritems(): self.putChild(path, child_cls(session)) @@ -75,3 +75,65 @@ def render_GET(self, request): return json.dumps({"error": "multichain community not found"}) return json.dumps({'statistics': mc_community.get_statistics()}) + + +class MultichainTrustEdgesEndpoint(resource.Resource): + """ + This class handles requests regarding the trusted live edges information. + """ + + def __init__(self, session): + resource.Resource.__init__(self) + self.session = session + + def get_multichain_community(self): + """ + Search for the multichain community in the dispersy communities. + """ + for community in self.session.get_dispersy_instance().get_communities(): + if isinstance(community, MultiChainCommunity): + return community + return None + + def render_GET(self, request): + """ + .. http:get:: /multichain/trust-edges + + A GET request to this endpoint returns information about the current trusted live edges + + **Example request**: + + .. sourcecode:: none + + curl -X GET http://localhost:8085/multichain/trust-edges + + **Example response**: + + .. sourcecode:: javascript + + { + "trust-edges": + [ + { + "id": "MEAwEAYHKoZIzj0CAQYFK4EEAAEDLAAEBF7U/0J3rIkVWoxRMUetPKzU41BbAuFggbJONKz5xDUk\nTx3dMqdzkFHY", + "number_of_blocks": 0, + "last_block_time": "Never", + "node_type": "Bootstrap" + }, + + { + "id": "MEAwEAYHKoZIzj0CAQYFK4EEAAEDLAAEBV/QD6bccykf3vtqf2dDnKtk9U0PBHqKPWUb9LWxWBVo\nl6A7qQubezMJ", + "number_of_blocks": 0, + "last_block_time": "2020-01-20 15:15:15", + "node_type": "default" + } + ] + } + + """ + mc_community = self.get_multichain_community() + if not mc_community: + request.setResponseCode(http.NOT_FOUND) + return json.dumps({"error": "multichain community not found"}) + + return json.dumps({'trust-edges': mc_community.get_trusted_edges()}) diff --git a/Tribler/community/multichain/community.py b/Tribler/community/multichain/community.py index 676c6e40be4..e0dc05a6c38 100644 --- a/Tribler/community/multichain/community.py +++ b/Tribler/community/multichain/community.py @@ -387,6 +387,27 @@ def get_statistics(self): statistics["latest_block_down_mb"] = "" return statistics + @blocking_call_on_reactor_thread + def get_trusted_edges(self): + trust_edges = [] + for candidate in self._trusted_candidates.items() + filter(lambda x: x[0] in Bootstrap.get_default_addresses(), self.candidates.items()): + if candidate[1].get_member(): + candidate_info = OrderedDict() + candidate_public_key = candidate[1].get_member().public_key + candidate_info["id"] = base64.encodestring(candidate_public_key).strip() + blocks = self.persistence.get_full_blocks_between(self.my_member.public_key, candidate_public_key) + candidate_info["number_of_blocks"] = len(blocks) + if blocks: + candidate_info["last_block_time"] = blocks[-1].insert_time + else: + candidate_info["last_block_time"] = u"Never" + if candidate[0] in Bootstrap.get_default_addresses(): + candidate_info["node_type"] = u"Bootstrap" + else: + candidate_info["node_type"] = u"default" + trust_edges.append(candidate_info) + return trust_edges + def _get_next_total(self, up, down): """ Returns the next total numbers of up and down incremented with the current interaction up and down metric. diff --git a/TriblerGUI/debug_window.py b/TriblerGUI/debug_window.py index 0e4bb357d08..e955f650fd2 100644 --- a/TriblerGUI/debug_window.py +++ b/TriblerGUI/debug_window.py @@ -42,8 +42,10 @@ def tab_changed(self, index): elif index == 2: self.load_multichain_tab() elif index == 3: - self.dispersy_tab_changed(self.window().dispersy_tab_widget.currentIndex()) + self.load_trust_edges_tab() elif index == 4: + self.dispersy_tab_changed(self.window().dispersy_tab_widget.currentIndex()) + elif index == 5: self.load_events_tab() def dispersy_tab_changed(self, index): @@ -58,6 +60,16 @@ def create_and_add_widget_item(self, key, value, widget): item.setText(1, "%s" % value) widget.addTopLevelItem(item) + def create_and_add_widget_peer(self, values, widget): + assert isinstance(values, dict) + assert len(values) == 4 + item = QTreeWidgetItem(widget) + item.setText(0, "%s" % values["id"]) + item.setText(1, "%s" % values["number_of_blocks"]) + item.setText(2, "%s" % values["last_block_time"]) + item.setText(3, "%s" % values["node_type"]) + widget.addTopLevelItem(item) + def load_general_tab(self): self.request_mgr = TriblerRequestManager() self.request_mgr.perform_request("statistics/tribler", self.on_tribler_statistics) @@ -94,6 +106,16 @@ def on_multichain_statistics(self, data): for key, value in data["statistics"].iteritems(): self.create_and_add_widget_item(key, value, self.window().multichain_tree_widget) + def load_trust_edges_tab(self): + self.request_mgr = TriblerRequestManager() + self.request_mgr.perform_request("multichain/trust-edges", self.on_trust_edges) + + def on_trust_edges(self, data): + self.window().trust_edges_tree_widget.clear() + for candidate in data["trust-edges"]: + self.create_and_add_widget_peer(candidate, self.window().trust_edges_tree_widget) + + def load_dispersy_general_tab(self): self.request_mgr = TriblerRequestManager() self.request_mgr.perform_request("statistics/dispersy", self.on_dispersy_general_stats) diff --git a/TriblerGUI/qt_resources/debugwindow.ui b/TriblerGUI/qt_resources/debugwindow.ui index 90f935a7a85..58615a4a613 100644 --- a/TriblerGUI/qt_resources/debugwindow.ui +++ b/TriblerGUI/qt_resources/debugwindow.ui @@ -155,6 +155,58 @@ + + Trust Edges + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 4 + + + 200 + + + + ID + + + + + Shared Records + + + + + Last Record + + + + + Node Type + + + + + + + Dispersy @@ -179,7 +231,7 @@ 0 - + General @@ -221,7 +273,7 @@ - + Communities @@ -277,7 +329,7 @@ - + Events