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