Skip to content
Snippets Groups Projects
Commit 5e8f718f authored by inso's avatar inso
Browse files

Network component

parent 765dd291
No related branches found
No related tags found
No related merge requests found
......@@ -230,6 +230,7 @@ class NodeConnector(QObject):
self._logger.debug("Error in previous block reply of {0} : {1}".format(self.node.pubkey[:5], str(e)))
finally:
self.node.current_buid = BlockUID(block_data['number'], block_data['hash'])
self.node.current_time = block_data['medianTime']
self._logger.debug("Changed block {0} -> {1}".format(self.node.current_buid.number,
block_data['number']))
self.changed.emit()
......
......@@ -59,6 +59,8 @@ class Node:
uid = attr.ib(convert=str, cmp=False, default="")
# The current block uid in /blockchain/current
current_buid = attr.ib(convert=block_uid, cmp=False, default=None)
# The current block time in /blockchain/current
current_time = attr.ib(convert=int, cmp=False, default=0)
# The previous block uid in /blockchain/current
previous_buid = attr.ib(convert=block_uid, cmp=False, default=None)
# The state of the node in Sakia
......
......@@ -91,6 +91,7 @@ CREATE TABLE IF NOT EXISTS nodes(
peer_buid VARCHAR(100),
uid VARCHAR(50),
current_buid VARCHAR(100),
current_time INT,
previous_buid VARCHAR(100),
state INT,
software VARCHAR(100),
......
......@@ -18,7 +18,7 @@ class NodesRepo:
with self._conn:
node_tuple = attr.astuple(node, tuple_factory=list)
node_tuple[2] = "\n".join([str(n) for n in node_tuple[2]])
node_tuple[11] = "\n".join([str(n) for n in node_tuple[11]])
node_tuple[12] = "\n".join([str(n) for n in node_tuple[11]])
values = ",".join(['?'] * len(node_tuple))
self._conn.execute("INSERT INTO nodes VALUES ({0})".format(values), node_tuple)
......
......@@ -55,6 +55,7 @@ class NavigationModel(ComponentModel):
'title': self.tr('Network'),
'icon': ':/icons/network_icon',
'component': "Network",
'network_service': self.app.network_services[connection.currency],
}
},
# {
......
......@@ -26,11 +26,10 @@ class NetworkController(ComponentController):
@classmethod
def create(cls, parent, app, **kwargs):
account = kwargs['account']
community = kwargs['community']
network_service = kwargs['network_service']
view = NetworkView(parent.view)
model = NetworkModel(None, app, account, community)
model = NetworkModel(None, app, network_service)
txhistory = cls(parent, view, model)
model.setParent(txhistory)
return txhistory
......
......@@ -8,23 +8,21 @@ class NetworkModel(ComponentModel):
A network model
"""
def __init__(self, parent, app, account, community):
def __init__(self, parent, app, network_service):
"""
Constructor of an network model
:param sakia.gui.network.controller.NetworkController parent: the controller
:param sakia.core.Application app: the app
:param sakia.core.Account account: the account
:param sakia.core.Community community: the community
:param sakia.app.Application app: the app
:param sakia.services.NetworkService network_service: the service handling network state
"""
super().__init__(parent)
self.app = app
self.account = account
self.community = community
self.network_service = network_service
self.table_model = None
def init_network_table_model(self):
model = NetworkTableModel(self.community)
model = NetworkTableModel(self.network_service)
proxy = NetworkFilterProxyModel()
proxy.setSourceModel(model)
self.table_model = proxy
......@@ -36,7 +34,7 @@ class NetworkModel(ComponentModel):
Start the refresh of the nodes
:return:
"""
self.community.network.refresh_once()
self.network_service.refresh_once()
def table_model_data(self, index):
"""
......@@ -49,13 +47,23 @@ class NetworkModel(ComponentModel):
is_root_col = self.table_model.sourceModel().columns_types.index('is_root')
is_root_index = self.table_model.sourceModel().index(source_index.row(), is_root_col)
is_root = self.table_model.sourceModel().data(is_root_index, Qt.DisplayRole)
node = self.community.network.nodes(source_index.row())
node = self.community.network.nodes()[source_index.row()]
return True, node, is_root
return False, None, None
def add_root_node(self, node):
self.community.network.add_root_node(node)
"""
The node set as root
:param sakia.data.entities.Node node: the node
"""
node.root = True
self.network_service.commit_node(node)
def unset_root_node(self, node):
self.community.network.remove_root_node(node)
"""
The node set as root
:param sakia.data.entities.Node node: the node
"""
node.root = False
self.network_service.commit_node(node)
......@@ -18,25 +18,10 @@ from sakia.decorators import asyncify, once_at_a_time
class NetworkFilterProxyModel(QSortFilterProxyModel):
def __init__(self, parent=None):
super().__init__(parent)
self.community = None
def columnCount(self, parent):
return self.sourceModel().columnCount(None) - 2
def change_community(self, community):
"""
Change current community and returns refresh task
:param sakia.core.Community community:
:return: the refresh task
:rtype: asyncio.Task
"""
self.community = community
return self.sourceModel().change_community(community)
def setSourceModel(self, sourceModel):
self.community = sourceModel.community
super().setSourceModel(sourceModel)
def lessThan(self, left, right):
"""
Sort table by given column number.
......@@ -95,13 +80,6 @@ class NetworkFilterProxyModel(QSortFilterProxyModel):
if index.column() == source_model.columns_types.index('current_hash') :
return source_data[:10]
if index.column() == source_model.columns_types.index('current_time') and source_data:
return QLocale.toString(
QLocale(),
QDateTime.fromTime_t(source_data),
QLocale.dateTimeFormat(QLocale(), QLocale.ShortFormat)
)
if role == Qt.TextAlignmentRole:
if source_index.column() == source_model.columns_types.index('address') or source_index.column() == self.sourceModel().columns_types.index('current_block'):
return Qt.AlignRight | Qt.AlignVCenter
......@@ -124,18 +102,19 @@ class NetworkTableModel(QAbstractTableModel):
A Qt abstract item model to display
"""
def __init__(self, community, parent=None):
def __init__(self, network_service, parent=None):
"""
Constructor
The table showing nodes
:param sakia.services.NetworkService network_service:
:param parent:
"""
super().__init__(parent)
self.community = community
self.network_service = network_service
self.columns_types = (
'address',
'port',
'current_block',
'current_hash',
'current_time',
'uid',
'is_member',
'pubkey',
......@@ -163,47 +142,43 @@ class NetworkTableModel(QAbstractTableModel):
Node.CORRUPTED: lambda: self.tr('Corrupted')
}
self.nodes_data = []
self.community.network.nodes_changed.connect(self.refresh_nodes)
self.network_service.nodes_changed.connect(self.refresh_nodes)
async def data_node(self, node: Node) -> tuple:
def data_node(self, node: Node) -> tuple:
"""
Return node data tuple
:param ..core.net.node.Node node: Network node
:return:
"""
try:
members_pubkey = await self.community.members_pubkeys()
is_member = node.pubkey in members_pubkey
except NoPeerAvailable as e:
logging.error(e)
is_member = None
address = ""
if node.endpoint.server:
address = node.endpoint.server
elif node.endpoint.ipv4:
address = node.endpoint.ipv4
elif node.endpoint.ipv6:
address = node.endpoint.ipv6
port = node.endpoint.port
is_root = self.community.network.is_root_node(node)
if node.block:
number, block_hash, block_time = node.block['number'], node.block['hash'], node.block['medianTime']
is_member = False
addresses = []
ports = []
for e in node.endpoints:
if e.server:
addresses.append(e.server)
elif e.ipv4:
addresses.append(e.ipv4)
elif e.ipv6:
addresses.append(e.ipv6)
ports.append(str(e.port))
address = "\n".join(addresses)
port = "\n".join(ports)
is_root = node.root
if node.current_buid:
number, block_hash = node.current_buid.number, node.current_buid.hash
else:
number, block_hash, block_time = "", "", ""
return (address, port, number, block_hash, block_time, node.uid,
is_member, node.pubkey, node.software, node.version, is_root, node.state)
number, block_hash = "", ""
return (address, port, number, block_hash, node.uid,
is_member, node.pubkey, node.software, node.version, node.root, node.state)
@once_at_a_time
@asyncify
async def refresh_nodes(self):
def refresh_nodes(self):
self.beginResetModel()
self.nodes_data = []
nodes_data = []
if self.community:
for node in self.community.network.nodes:
data = await self.data_node(node)
for node in self.network_service.nodes():
data = self.data_node(node)
nodes_data.append(data)
self.nodes_data = nodes_data
self.endResetModel()
......
......@@ -83,6 +83,16 @@ class NetworkService(QObject):
"""
asyncio.ensure_future(self.discover_network())
def nodes(self):
"""
Get all nodes
:return:
"""
return self._processor.nodes(self.currency)
def commit_node(self, node):
self._processor.commit_node(node)
async def stop_coroutines(self, closing=False):
"""
Stop network nodes crawling.
......@@ -227,7 +237,7 @@ class NetworkService(QObject):
if node.state in (Node.OFFLINE, Node.CORRUPTED) and \
node.last_change + 3600 < time.time():
node.disconnect()
self.nodes.remove(node)
self._processor.delete_node(node)
self.nodes_changed.emit()
@pyqtSlot()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment