Skip to content
Snippets Groups Projects
Commit 69f1d61c authored by inso's avatar inso
Browse files

Optimize SQLite writes with manual commits

parent 028b5c28
No related branches found
No related tags found
No related merge requests found
Showing
with 456 additions and 479 deletions
......@@ -109,10 +109,10 @@ class Application(QObject):
self.transactions_services[currency] = TransactionsService(currency, transactions_processor,
identities_processor, bma_connector)
self.blockchain_services[currency] = BlockchainService(currency, blockchain_processor, bma_connector,
self.blockchain_services[currency] = BlockchainService(self, currency, blockchain_processor, bma_connector,
self.identities_services[currency],
self.transactions_services[currency])
self.network_services[currency] = NetworkService.load(currency, nodes_processor,
self.network_services[currency] = NetworkService.load(self, currency, nodes_processor,
self.blockchain_services[currency])
self.sources_services[currency] = SourcesServices(currency, sources_processor, bma_connector)
......
......@@ -7,7 +7,7 @@ import aiohttp
import jsonschema
from PyQt5.QtCore import QObject, pyqtSignal
from aiohttp.errors import ClientError, DisconnectedError
from aiohttp.errors import WSClientDisconnectedError, WSServerHandshakeError, ClientResponseError
from aiohttp.errors import WSServerHandshakeError, ClientResponseError
from duniterpy.api import bma, errors
from duniterpy.documents import BlockUID, MalformedDocumentError, BMAEndpoint
......@@ -159,13 +159,13 @@ class NodeConnector(QObject):
async for msg in ws:
if msg.tp == aiohttp.MsgType.text:
self._logger.debug("Received a block : {0}".format(self.node.pubkey[:5]))
block_data = bma.parse_text(msg.data)
block_data = bma.parse_text(msg.data, bma.ws.WS_BLOCk_SCHEMA)
await self.refresh_block(block_data)
elif msg.tp == aiohttp.MsgType.closed:
break
elif msg.tp == aiohttp.MsgType.error:
break
except (WSServerHandshakeError, WSClientDisconnectedError,
except (WSServerHandshakeError,
ClientResponseError, ValueError) as e:
self._logger.debug("Websocket block {0} : {1} - {2}"
.format(type(e).__name__, str(e), self.node.pubkey[:5]))
......@@ -320,13 +320,13 @@ class NodeConnector(QObject):
async for msg in ws:
if msg.tp == aiohttp.MsgType.text:
self._logger.debug("Received a peer : {0}".format(self.node.pubkey[:5]))
peer_data = bma.parse_text(msg.data)
peer_data = bma.parse_text(msg.data, bma.ws.WS_PEER_SCHEMA)
self.refresh_peer_data(peer_data)
elif msg.tp == aiohttp.MsgType.closed:
break
elif msg.tp == aiohttp.MsgType.error:
break
except (WSServerHandshakeError, WSClientDisconnectedError,
except (WSServerHandshakeError,
ClientResponseError, ValueError) as e:
self._logger.debug("Websocket peer {0} : {1} - {2}"
.format(type(e).__name__, str(e), self.node.pubkey[:5]))
......
......@@ -117,11 +117,11 @@ class BlockchainProcessor:
"""
with_identities = []
future_requests = []
for req in (bma.blockchain.Joiners,
bma.blockchain.Leavers,
bma.blockchain.Actives,
bma.blockchain.Excluded,
bma.blockchain.Newcomers):
for req in (bma.blockchain.joiners,
bma.blockchain.leavers,
bma.blockchain.actives,
bma.blockchain.excluded,
bma.blockchain.newcomers):
future_requests.append(self._bma_connector.get(currency, req))
results = await asyncio.gather(*future_requests)
......@@ -138,7 +138,7 @@ class BlockchainProcessor:
"""
with_money = []
future_requests = []
for req in (bma.blockchain.UD, bma.blockchain.TX):
for req in (bma.blockchain.ud, bma.blockchain.tx):
future_requests.append(self._bma_connector.get(currency, req))
results = await asyncio.gather(*future_requests)
......@@ -159,7 +159,7 @@ class BlockchainProcessor:
to_block = max(numbers)
count = to_block - from_block
blocks_data = await self._bma_connector.get(currency, bma.blockchain.Blocks, req_args={'count': count,
blocks_data = await self._bma_connector.get(currency, bma.blockchain.blocks, req_args={'count': count,
'from_': from_block})
blocks = []
for data in blocks_data:
......@@ -175,10 +175,9 @@ class BlockchainProcessor:
blockchain = self._repo.get_one(currency=currency)
if not blockchain:
blockchain = Blockchain(currency=currency)
blockchain_parameters = BlockchainParameters()
log_stream("Requesting blockchain parameters")
try:
parameters = await self._bma_connector.get(currency, bma.blockchain.Parameters)
parameters = await self._bma_connector.get(currency, bma.blockchain.parameters)
blockchain.parameters.ms_validity = parameters['msValidity']
blockchain.parameters.avg_gen_time = parameters['avgGenTime']
blockchain.parameters.blocks_rot = parameters['blocksRot']
......@@ -203,7 +202,7 @@ class BlockchainProcessor:
log_stream("Requesting current block")
try:
current_block = await self._bma_connector.get(currency, bma.blockchain.Current)
current_block = await self._bma_connector.get(currency, bma.blockchain.current)
signed_raw = "{0}{1}\n".format(current_block['raw'], current_block['signature'])
block = Block.from_signed_raw(signed_raw)
blockchain.current_buid = block.blockUID
......@@ -214,7 +213,7 @@ class BlockchainProcessor:
raise
log_stream("Requesting blocks with dividend")
with_ud = await self._bma_connector.get(currency, bma.blockchain.UD)
with_ud = await self._bma_connector.get(currency, bma.blockchain.ud)
blocks_with_ud = with_ud['result']['blocks']
if len(blocks_with_ud) > 0:
......@@ -222,7 +221,7 @@ class BlockchainProcessor:
try:
index = max(len(blocks_with_ud) - 1, 0)
block_number = blocks_with_ud[index]
block_with_ud = await self._bma_connector.get(currency, bma.blockchain.Block,
block_with_ud = await self._bma_connector.get(currency, bma.blockchain.block,
req_args={'number': block_number})
if block_with_ud:
blockchain.last_members_count = block_with_ud['membersCount']
......@@ -238,7 +237,7 @@ class BlockchainProcessor:
try:
index = max(len(blocks_with_ud) - 2, 0)
block_number = blocks_with_ud[index]
block_with_ud = await self._bma_connector.get(currency, bma.blockchain.Block,
block_with_ud = await self._bma_connector.get(currency, bma.blockchain.block,
req_args={'number': block_number})
blockchain.previous_mass = block_with_ud['monetaryMass']
blockchain.previous_members_count = block_with_ud['membersCount']
......@@ -250,4 +249,3 @@ class BlockchainProcessor:
raise
self._repo.insert(blockchain)
......@@ -57,7 +57,7 @@ class CertificationsProcessor:
self._certifications_repo.insert(cert)
return cert
def commit_certification(self, cert):
def insert_or_update_certification(self, cert):
"""
Commits a certification to the DB
:param sakia.data.entities.Certification cert:
......@@ -78,8 +78,8 @@ class CertificationsProcessor:
identities = list()
certifiers = list()
try:
data = await self._bma_connector.get(identity.currency, bma.wot.CertifiersOf,
{'search': identity.pubkey})
data = await self._bma_connector.get(identity.currency, bma.wot.certifiers_of,
req_args={'search': identity.pubkey})
for certifier_data in data['certifications']:
certification = Certification(currency=identity.currency,
......@@ -110,7 +110,7 @@ class CertificationsProcessor:
log_stream("Requesting certified by data")
certified = list()
try:
data = await self._bma_connector.get(identity.currency, bma.wot.CertifiedBy, {'search': identity.pubkey})
data = await self._bma_connector.get(identity.currency, bma.wot.certified_by, req_args={'search': identity.pubkey})
for certified_data in data['certifications']:
certification = Certification(currency=identity.currency,
certifier=identity.pubkey,
......@@ -138,7 +138,7 @@ class CertificationsProcessor:
log_stream('Commiting certifications...')
for i, cert in enumerate(certifiers + certified):
log_stream('Certification {0}/{1}'.format(i, len(certifiers + certified)))
self.commit_certification(cert)
self.insert_or_update_certification(cert)
await asyncio.sleep(0)
log_stream('Commiting identities...')
......
......@@ -122,7 +122,7 @@ class IdentitiesProcessor:
else:
return written[0]
def commit_identity(self, identity):
def insert_or_update_identity(self, identity):
"""
Saves an identity state in the db
:param sakia.data.entities.Identity identity: the identity updated
......@@ -139,7 +139,7 @@ class IdentitiesProcessor:
:param function log_stream:
"""
log_stream("Requesting membership data")
memberships_data = await self._bma_connector.get(identity.currency, bma.blockchain.Membership,
memberships_data = await self._bma_connector.get(identity.currency, bma.blockchain.memberships,
req_args={'search': identity.pubkey})
if block_uid(memberships_data['sigDate']) == identity.blockstamp \
and memberships_data['uid'] == identity.uid:
......@@ -150,7 +150,7 @@ class IdentitiesProcessor:
if identity.membership_buid:
log_stream("Requesting membership timestamp")
ms_block_data = await self._bma_connector.get(identity.currency, bma.blockchain.Block,
ms_block_data = await self._bma_connector.get(identity.currency, bma.blockchain.block,
req_args={'number': identity.membership_buid.number})
if ms_block_data:
identity.membership_timestamp = ms_block_data['medianTime']
......@@ -158,8 +158,8 @@ class IdentitiesProcessor:
if memberships_data['memberships']:
log_stream("Requesting identity requirements status")
requirements_data = await self._bma_connector.get(identity.currency, bma.wot.Requirements,
get_args={'search': identity.pubkey})
requirements_data = await self._bma_connector.get(identity.currency, bma.wot.requirements,
req_args={'search': identity.pubkey})
identity.member = requirements_data['membershipExpiresIn'] > 0 and not requirements_data['outdistanced']
async def publish_selfcert(self, currency, identity, salt, password):
......@@ -183,7 +183,8 @@ class IdentitiesProcessor:
selfcert.sign([key])
self._logger.debug("Key publish : {0}".format(selfcert.signed_raw()))
responses = await self._bma_connector.broadcast(currency, bma.wot.Add, {}, {'identity': selfcert.signed_raw()})
responses = await self._bma_connector.broadcast(currency, bma.wot.add,
req_args={'identity': selfcert.signed_raw()})
result = (False, "")
for r in responses:
if r.status == 200:
......
......@@ -30,7 +30,8 @@ class SourcesProcessor:
if not one_source:
log_stream("Requesting sources")
try:
sources_data = await self._bma_connector.get(currency, bma.tx.Sources, req_args={'pubkey': pubkey})
sources_data = await self._bma_connector.get(currency, bma.tx.sources,
req_args={'pubkey': pubkey})
log_stream("Found {0} sources".format(len(sources_data['sources'])))
for i, s in enumerate(sources_data['sources']):
......
......@@ -104,10 +104,10 @@ class TransactionsProcessor:
:param community: The community target of the transaction
"""
tx.sha_hash = txdoc.sha_hash
responses = await community.bma_access.broadcast(bma.tx.Process,
responses = await community.bma_access.broadcast(bma.tx.process,
post_args={'transaction': txdoc.signed_raw()})
blockUID = community.network.current_blockUID
block = await community.bma_access.future_request(bma.blockchain.Block,
block = await community.bma_access.future_request(bma.blockchain.block,
req_args={'number': blockUID.number})
signed_raw = "{0}{1}\n".format(block['raw'], block['signature'])
block_doc = Block.from_signed_raw(signed_raw)
......
......@@ -2,6 +2,7 @@ import time
from sakia.data.entities import Transaction
from duniterpy.documents import Block
def _not_found_in_blockchain(tx, rollback, block, mediantime_target, mediantime_blocks):
"""
Check if the transaction could not be found in the blockchain
......
......@@ -17,7 +17,6 @@ class BlockchainsRepo:
Commit a blockchain to the database
:param sakia.data.entities.Blockchain blockchain: the blockchain to commit
"""
with self._conn:
blockchain_tuple = attr.astuple(blockchain.parameters) \
+ attr.astuple(blockchain, filter=attr.filters.exclude(Blockchain.parameters))
values = ",".join(['?'] * len(blockchain_tuple))
......@@ -28,7 +27,6 @@ class BlockchainsRepo:
Update an existing blockchain in the database
:param sakia.data.entities.Blockchain blockchain: the blockchain to update
"""
with self._conn:
updated_fields = attr.astuple(blockchain, filter=attr.filters.exclude(
Blockchain.parameters, *BlockchainsRepo._primary_keys))
where_fields = attr.astuple(blockchain, filter=attr.filters.include(*BlockchainsRepo._primary_keys))
......@@ -56,7 +54,6 @@ class BlockchainsRepo:
:param dict search: the criterions of the lookup
:rtype: sakia.data.entities.Blockchain
"""
with self._conn:
filters = []
values = []
for k, v in search.items():
......@@ -80,7 +77,6 @@ class BlockchainsRepo:
:param dict search: the criterions of the lookup
:rtype: [sakia.data.entities.Blockchain]
"""
with self._conn:
filters = []
values = []
if search:
......@@ -118,6 +114,5 @@ class BlockchainsRepo:
Drop an existing blockchain from the database
:param sakia.data.entities.Blockchain blockchain: the blockchain to update
"""
with self._conn:
where_fields = attr.astuple(blockchain, filter=attr.filters.include(*BlockchainsRepo._primary_keys))
self._conn.execute("DELETE FROM blockchains WHERE currency=?", where_fields)
......@@ -16,7 +16,6 @@ class CertificationsRepo:
Commit a certification to the database
:param sakia.data.entities.Certification certification: the certification to commit
"""
with self._conn:
certification_tuple = attr.astuple(certification)
values = ",".join(['?'] * len(certification_tuple))
self._conn.execute("INSERT INTO certifications VALUES ({0})".format(values), certification_tuple)
......@@ -26,7 +25,6 @@ class CertificationsRepo:
Update an existing certification in the database
:param sakia.data.entities.Certification certification: the certification to update
"""
with self._conn:
updated_fields = attr.astuple(certification, filter=attr.filters.exclude(*CertificationsRepo._primary_keys))
where_fields = attr.astuple(certification, filter=attr.filters.include(*CertificationsRepo._primary_keys))
self._conn.execute("""UPDATE certifications SET
......@@ -46,7 +44,6 @@ class CertificationsRepo:
:param dict search: the criterions of the lookup
:rtype: sakia.data.entities.Certification
"""
with self._conn:
filters = []
values = []
for k, v in search.items():
......@@ -66,7 +63,6 @@ class CertificationsRepo:
:param dict search: the criterions of the lookup
:rtype: sakia.data.entities.Certification
"""
with self._conn:
filters = []
values = []
for k, v in search.items():
......@@ -87,7 +83,6 @@ class CertificationsRepo:
Drop an existing certification from the database
:param sakia.data.entities.Certification certification: the certification to update
"""
with self._conn:
where_fields = attr.astuple(certification, filter=attr.filters.include(*CertificationsRepo._primary_keys))
self._conn.execute("""DELETE FROM certifications
WHERE
......@@ -95,3 +90,4 @@ class CertificationsRepo:
certifier=? AND
certified=? AND
block=?""", where_fields)
......@@ -16,7 +16,6 @@ class ConnectionsRepo:
Commit a connection to the database
:param sakia.data.entities.Connection connection: the connection to commit
"""
with self._conn:
connection_tuple = attr.astuple(connection, filter=attr.filters.exclude(Connection.password))
values = ",".join(['?'] * len(connection_tuple))
self._conn.execute("INSERT INTO connections VALUES ({0})".format(values), connection_tuple)
......@@ -27,7 +26,6 @@ class ConnectionsRepo:
:param dict search: the criterions of the lookup
:rtype: sakia.data.entities.Connection
"""
with self._conn:
filters = []
values = []
for k, v in search.items():
......@@ -47,7 +45,6 @@ class ConnectionsRepo:
:param dict search: the criterions of the lookup
:rtype: sakia.data.entities.Connection
"""
with self._conn:
filters = []
values = []
for k, v in search.items():
......@@ -71,7 +68,6 @@ class ConnectionsRepo:
:param dict search: the criterions of the lookup
:rtype: List[str]
"""
with self._conn:
request = "SELECT DISTINCT currency FROM connections"
c = self._conn.execute(request)
datas = c.fetchall()
......@@ -84,9 +80,9 @@ class ConnectionsRepo:
Drop an existing connection from the database
:param sakia.data.entities.Connection connection: the connection to update
"""
with self._conn:
where_fields = attr.astuple(connection, filter=attr.filters.include(*ConnectionsRepo._primary_connections))
self._conn.execute("""DELETE FROM connections
WHERE
currency=? AND
pubkey=?""", where_fields)
......@@ -17,7 +17,6 @@ class IdentitiesRepo:
Commit an identity to the database
:param sakia.data.entities.Identity identity: the identity to commit
"""
with self._conn:
identity_tuple = attr.astuple(identity)
values = ",".join(['?'] * len(identity_tuple))
self._conn.execute("INSERT INTO identities VALUES ({0})".format(values), identity_tuple)
......@@ -27,7 +26,6 @@ class IdentitiesRepo:
Update an existing identity in the database
:param sakia.data.entities.Identity identity: the identity to update
"""
with self._conn:
updated_fields = attr.astuple(identity, filter=attr.filters.exclude(*IdentitiesRepo._primary_keys))
where_fields = attr.astuple(identity, filter=attr.filters.include(*IdentitiesRepo._primary_keys))
self._conn.execute("""UPDATE identities SET
......@@ -53,7 +51,6 @@ class IdentitiesRepo:
:param dict search: the criterions of the lookup
:rtype: sakia.data.entities.Identity
"""
with self._conn:
filters = []
values = []
for k, v in search.items():
......@@ -75,7 +72,6 @@ class IdentitiesRepo:
:param dict search: the criterions of the lookup
:rtype: List[sakia.data.entities.Identity]
"""
with self._conn:
filters = []
values = []
for k, v in search.items():
......@@ -107,7 +103,6 @@ class IdentitiesRepo:
:param dict search: the criterions of the lookup
:rtype: sakia.data.entities.Identity
"""
with self._conn:
filters = []
values = []
for k, v in search.items():
......@@ -130,7 +125,6 @@ class IdentitiesRepo:
:param dict search: the criterions of the lookup
:rtype: sakia.data.entities.Identity
"""
with self._conn:
request = "SELECT * FROM identities WHERE currency=? AND (UID LIKE ? or PUBKEY LIKE ?)"
c = self._conn.execute(request, (currency, "%{0}%".format(text), "%{0}%".format(text)))
......@@ -144,10 +138,10 @@ class IdentitiesRepo:
Drop an existing identity from the database
:param sakia.data.entities.Identity identity: the identity to update
"""
with self._conn:
where_fields = attr.astuple(identity, filter=attr.filters.include(*IdentitiesRepo._primary_keys))
self._conn.execute("""DELETE FROM identities WHERE
currency=? AND
pubkey=? AND
uid=? AND
blockstamp=?""", where_fields)
......@@ -14,7 +14,8 @@ from .sources import SourcesRepo
@attr.s(frozen=True)
class SakiaDatabase:
"""The repository for Identities entities.
"""
This is Sakia unique SQLite database.
"""
conn = attr.ib() # :type sqlite3.Connection
connections_repo = attr.ib(default=None)
......@@ -93,3 +94,6 @@ class SakiaDatabase:
else:
self.conn.execute("INSERT INTO meta VALUES (1, 0)")
return 0
def commit(self):
self.conn.commit()
......@@ -15,7 +15,6 @@ class NodesRepo:
Commit a node to the database
:param sakia.data.entities.Node node: the node to commit
"""
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[12] = "\n".join([str(n) for n in node_tuple[11]])
......@@ -27,7 +26,6 @@ class NodesRepo:
Update an existing node in the database
:param sakia.data.entities.Node node: the node to update
"""
with self._conn:
updated_fields = attr.astuple(node, tuple_factory=list,
filter=attr.filters.exclude(*NodesRepo._primary_keys))
updated_fields[0] = "\n".join([str(n) for n in updated_fields[0]])
......@@ -58,7 +56,6 @@ class NodesRepo:
:param dict search: the criterions of the lookup
:rtype: sakia.data.entities.Node
"""
with self._conn:
filters = []
values = []
for k, v in search.items():
......@@ -80,7 +77,6 @@ class NodesRepo:
:param dict search: the criterions of the lookup
:rtype: sakia.data.entities.Node
"""
with self._conn:
filters = []
values = []
for k, v in search.items():
......@@ -104,7 +100,6 @@ class NodesRepo:
Drop an existing node from the database
:param sakia.data.entities.Node node: the node to update
"""
with self._conn:
where_fields = attr.astuple(node, filter=attr.filters.include(*NodesRepo._primary_keys))
self._conn.execute("""DELETE FROM nodes
WHERE
......
......@@ -15,7 +15,6 @@ class SourcesRepo:
Commit a source to the database
:param sakia.data.entities.Source source: the source to commit
"""
with self._conn:
source_tuple = attr.astuple(source)
values = ",".join(['?'] * len(source_tuple))
self._conn.execute("INSERT INTO sources VALUES ({0})".format(values), source_tuple)
......@@ -26,7 +25,6 @@ class SourcesRepo:
:param dict search: the criterions of the lookup
:rtype: sakia.data.entities.Source
"""
with self._conn:
filters = []
values = []
for k, v in search.items():
......@@ -46,7 +44,6 @@ class SourcesRepo:
:param dict search: the criterions of the lookup
:rtype: sakia.data.entities.Source
"""
with self._conn:
filters = []
values = []
for k, v in search.items():
......@@ -67,8 +64,8 @@ class SourcesRepo:
Drop an existing source from the database
:param sakia.data.entities.Source source: the source to update
"""
with self._conn:
where_fields = attr.astuple(source, filter=attr.filters.include(*SourcesRepo._primary_keys))
self._conn.execute("""DELETE FROM sources
WHERE
identifier=?""", where_fields)
......@@ -15,7 +15,6 @@ class TransactionsRepo:
Commit a transaction to the database
:param sakia.data.entities.Transaction transaction: the transaction to commit
"""
with self._conn:
transaction_tuple = attr.astuple(transaction)
values = ",".join(['?'] * len(transaction_tuple))
self._conn.execute("INSERT INTO transactions VALUES ({0})".format(values), transaction_tuple)
......@@ -25,7 +24,6 @@ class TransactionsRepo:
Update an existing transaction in the database
:param sakia.data.entities.Transaction transaction: the transaction to update
"""
with self._conn:
updated_fields = attr.astuple(transaction, filter=attr.filters.exclude(*TransactionsRepo._primary_keys))
where_fields = attr.astuple(transaction, filter=attr.filters.include(*TransactionsRepo._primary_keys))
self._conn.execute("""UPDATE transactions SET
......@@ -51,7 +49,6 @@ class TransactionsRepo:
:param dict search: the criterions of the lookup
:rtype: sakia.data.entities.Transaction
"""
with self._conn:
filters = []
values = []
for k, v in search.items():
......@@ -71,7 +68,6 @@ class TransactionsRepo:
:param dict search: the criterions of the lookup
:rtype: sakia.data.entities.Transaction
"""
with self._conn:
filters = []
values = []
for k, v in search.items():
......@@ -94,7 +90,6 @@ class TransactionsRepo:
:param str pubkey: the criterions of the lookup
:rtype: List[sakia.data.entities.Transaction]
"""
with self._conn:
request = """SELECT * FROM transactions
WHERE currency=? AND (issuer=? or receiver=?)
ORDER BY {sort_by} {sort_order}
......@@ -115,7 +110,6 @@ class TransactionsRepo:
Drop an existing transaction from the database
:param sakia.data.entities.Transaction transaction: the transaction to update
"""
with self._conn:
where_fields = attr.astuple(transaction, filter=attr.filters.include(*TransactionsRepo._primary_keys))
self._conn.execute("""DELETE FROM transactions
WHERE
......
import asyncio
import logging
from PyQt5.QtGui import QCursor
from PyQt5.QtWidgets import QDialog, QApplication, QMenu
from aiohttp.errors import DisconnectedError, ClientError, TimeoutError
from duniterpy.documents import MalformedDocumentError
......@@ -142,7 +140,7 @@ class ConnectionConfigController(ComponentController):
self.view.stacked_pages.setCurrentWidget(self.view.page_connection)
connection_identity = await self.step_key
self.model.commit_connection()
self.model.insert_or_update_connection()
self.view.stacked_pages.setCurrentWidget(self.view.page_services)
self.view.progress_bar.setValue(0)
self.view.progress_bar.setMaximum(3)
......@@ -151,7 +149,7 @@ class ConnectionConfigController(ComponentController):
if mode in (ConnectionConfigController.REGISTER, ConnectionConfigController.CONNECT):
self.view.stream_log("Saving identity...")
self.model.commit_identity(connection_identity)
self.model.insert_or_update_identity(connection_identity)
self.view.stream_log("Initializing identity informations...")
await self.model.initialize_identity(connection_identity, log_stream=self.view.stream_log)
self.view.stream_log("Initializing certifications informations...")
......@@ -172,6 +170,7 @@ class ConnectionConfigController(ComponentController):
await self.model.initialize_sources(self.view.stream_log)
self._logger.debug("Validate changes")
self.model.app.db.commit()
self.accept()
def check_key(self):
......
......@@ -50,12 +50,12 @@ class ConnectionConfigModel(ComponentModel):
self.connection.salt = salt
self.connection.pubkey = SigningKey(self.connection.salt, password).pubkey
def commit_connection(self):
def insert_or_update_connection(self):
ConnectionsProcessor(self.app.db.connections_repo).commit_connection(self.connection)
NodesProcessor(self.app.db.nodes_repo).commit_node(self.node_connector.node)
def commit_identity(self, identity):
self.identities_processor.commit_identity(identity)
def insert_or_update_identity(self, identity):
self.identities_processor.insert_or_update_identity(identity)
async def initialize_blockchain(self, log_stream):
"""
......@@ -151,7 +151,7 @@ class ConnectionConfigModel(ComponentModel):
async def execute_requests(parsers, search):
tries = 0
request = bma.wot.CertifiersOf
request = bma.wot.certifiers_of
nonlocal registered
for endpoint in [e for e in self.node_connector.node.endpoints if isinstance(e, BMAEndpoint)]:
if not registered[0] and not registered[2]:
......@@ -163,8 +163,8 @@ class ConnectionConfigModel(ComponentModel):
except errors.DuniterError as e:
if e.ucode in (errors.NO_MEMBER_MATCHING_PUB_OR_UID,
e.ucode == errors.NO_MATCHING_IDENTITY):
if request == bma.wot.CertifiersOf:
request = bma.wot.Lookup
if request == bma.wot.certifiers_of:
request = bma.wot.lookup
tries = 0
else:
tries += 1
......@@ -180,8 +180,8 @@ class ConnectionConfigModel(ComponentModel):
# We execute search based on pubkey
# And look for account UID
uid_parsers = {
bma.wot.CertifiersOf: _parse_uid_certifiers,
bma.wot.Lookup: _parse_uid_lookup
bma.wot.certifiers_of: _parse_uid_certifiers,
bma.wot.lookup: _parse_uid_lookup
}
await execute_requests(uid_parsers, identity.pubkey)
......@@ -189,8 +189,8 @@ class ConnectionConfigModel(ComponentModel):
# We look for the uid and check for the pubkey
if not registered[0] and not registered[2]:
pubkey_parsers = {
bma.wot.CertifiersOf: _parse_pubkey_certifiers,
bma.wot.Lookup: _parse_pubkey_lookup
bma.wot.certifiers_of: _parse_pubkey_certifiers,
bma.wot.lookup: _parse_pubkey_lookup
}
await execute_requests(pubkey_parsers, identity.uid)
......
from PyQt5.QtCore import QObject
from duniterpy.api import bma
import math
import logging
......@@ -9,10 +8,11 @@ class BlockchainService(QObject):
Blockchain service is managing new blocks received
to update data locally
"""
def __init__(self, currency, blockchain_processor, bma_connector, identities_service, transactions_service):
def __init__(self, app, currency, blockchain_processor, bma_connector, identities_service, transactions_service):
"""
Constructor the identities service
:param sakia.app.Application app: Sakia application
:param str currency: The currency name of the community
:param sakia.data.processors.BlockchainProcessor blockchain_processor: the blockchain processor for given currency
:param sakia.data.connectors.BmaConnector bma_connector: The connector to BMA API
......@@ -20,6 +20,7 @@ class BlockchainService(QObject):
:param sakia.services.TransactionsService transactions_service: The transactions service
"""
super().__init__()
self.app = app
self._blockchain_processor = blockchain_processor
self._bma_connector = bma_connector
self.currency = currency
......@@ -36,6 +37,7 @@ class BlockchainService(QObject):
blocks = await self._blockchain_processor.blocks(with_identities + with_money, self.currency)
await self._identities_service.handle_new_blocks(blocks)
await self._transactions_service.handle_new_blocks(blocks)
self.app.db.commit()
def current_buid(self):
return self._blockchain_processor.current_buid(self.currency)
......
......@@ -74,7 +74,7 @@ class IdentitiesService(QObject):
"""
if not identity.written_on:
try:
search = await self._bma_connector.get(self.currency, bma.blockchain.Membership,
search = await self._bma_connector.get(self.currency, bma.blockchain.membership,
{'search': self.pubkey})
blockstamp = BlockUID.empty()
membership_data = None
......@@ -89,7 +89,7 @@ class IdentitiesService(QObject):
identity.membership_type = ms["type"]
identity.membership_written_on = ms["written"]
await self.refresh_requirements(identity)
self._identities_processor.commit_identity(identity)
self._identities_processor.insert_or_update_identity(identity)
except errors.DuniterError as e:
logging.debug(str(e))
except NoPeerAvailable as e:
......@@ -104,15 +104,17 @@ class IdentitiesService(QObject):
if not identity.written_on:
try:
data = await self._bma_connector.get(self.currency, bma.wot.certifiers_of, {'search': identity.pubkey})
for certified_data in data['certifications']:
cert = Certification(self.currency, data["pubkey"],
certified_data["pubkey"], certified_data["sigDate"])
cert.block = certified_data["cert_time"]["number"]
cert.timestamp = certified_data["cert_time"]["medianTime"]
if certified_data['written']:
cert.written_on = BlockUID(certified_data['written']['number'],
certified_data['written']['hash'])
self._certs_processor.commit_certification(cert)
for certifier_data in data['certifications']:
cert = Certification(currency=self.currency,
certified=data["pubkey"],
certifier=certifier_data["pubkey"],
block=certifier_data["cert_time"]["block"],
timestamp=certifier_data["cert_time"]["medianTime"],
signature=certifier_data['signature'])
if certifier_data['written']:
cert.written_on = BlockUID(certifier_data['written']['number'],
certifier_data['written']['hash'])
self._certs_processor.insert_or_update_certification(cert)
except errors.DuniterError as e:
if e.ucode in (errors.NO_MATCHING_IDENTITY, errors.NO_MEMBER_MATCHING_PUB_OR_UID):
logging.debug("Certified by error : {0}".format(str(e)))
......@@ -129,14 +131,16 @@ class IdentitiesService(QObject):
try:
data = await self._bma_connector.get(self.currency, bma.wot.certified_by, {'search': identity.pubkey})
for certified_data in data['certifications']:
cert = Certification(self.currency, data["pubkey"],
certified_data["pubkey"], certified_data["sigDate"])
cert.block = certified_data["cert_time"]["number"]
cert.timestamp = certified_data["cert_time"]["medianTime"]
cert = Certification(currency=self.currency,
certifier=data["pubkey"],
certified=certified_data["pubkey"],
block=certified_data["cert_time"]["block"],
timestamp=certified_data["cert_time"]["medianTime"],
signature=certified_data['signature'])
if certified_data['written']:
cert.written_on = BlockUID(certified_data['written']['number'],
certified_data['written']['hash'])
self._certs_processor.commit_certification(cert)
self._certs_processor.insert_or_update_certification(cert)
except errors.DuniterError as e:
if e.ucode in (errors.NO_MATCHING_IDENTITY, errors.NO_MEMBER_MATCHING_PUB_OR_UID):
logging.debug("Certified by error : {0}".format(str(e)))
......@@ -178,7 +182,7 @@ class IdentitiesService(QObject):
written.membership_written_on = block.blockUID
written.membership_type = "IN"
written.membership_buid = ms.membership_ts
self._identities_processor.commit_identity(written)
self._identities_processor.insert_or_update_identity(written)
# If the identity was not member
# it can become one
if not written.member:
......@@ -192,7 +196,7 @@ class IdentitiesService(QObject):
written.membership_written_on = block.blockUID
written.membership_type = "OUT"
written.membership_buid = ms.membership_ts
self._identities_processor.commit_identity(written)
self._identities_processor.insert_or_update_identity(written)
# If the identity was not member
# it can stop to be one
if not written.member:
......@@ -233,12 +237,12 @@ class IdentitiesService(QObject):
req_args={'search': identity.pubkey})
identity_data = requirements['identities'][0]
identity.uid = identity_data["uid"]
identity.blockstamp = identity["meta"]["timestamp"]
identity.member = identity["membershipExpiresIn"] > 0 and identity["outdistanced"] is False
identity.blockstamp = identity_data["meta"]["timestamp"]
identity.member = identity_data["membershipExpiresIn"] > 0 and identity_data["outdistanced"] is False
median_time = self._blockchain_processor.time(self.currency)
expiration_time = self._blockchain_processor.parameters(self.currency).ms_validity
identity.membership_timestamp = median_time - (expiration_time - identity["membershipExpiresIn"])
self._identities_processor.commit_identity(identity)
identity.membership_timestamp = median_time - (expiration_time - identity_data["membershipExpiresIn"])
self._identities_processor.insert_or_update_identity(identity)
except NoPeerAvailable as e:
self._logger.debug(str(e))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment