Skip to content
Snippets Groups Projects
Commit eef66fe0 authored by Vincent Texier's avatar Vincent Texier
Browse files

[enh] add refresh button to update tx history of selected time period

Many UD are missing because BMA ud/history only returns non consumed UD...
parent 9216858c
Branches
Tags
1 merge request!7750.50.0
import asyncio
import logging
from PyQt5.QtCore import QTime, pyqtSignal, QObject, QDateTime
......@@ -39,6 +40,7 @@ class TxHistoryController(QObject):
self.view.table_history.customContextMenuRequested["QPoint"].connect(
self.history_context_menu
)
self.view.button_refresh.clicked.connect(self.refresh_from_network)
self.refresh()
@classmethod
......@@ -172,3 +174,36 @@ class TxHistoryController(QObject):
# refresh
self.refresh_balance()
self.refresh_pages()
@asyncify
async def refresh_from_network(self, _):
"""
Update tx history from network for the selected date period
:return:
"""
self._logger.debug("Manually refresh tx history...")
pubkey = self.model.connection.pubkey
(
changed_tx,
new_tx
) = await self.model.transactions_service.update_transactions_history(pubkey,
self.view.table_history.model().ts_from,
self.view.table_history.model().ts_to)
for tx in changed_tx:
self.model.app.transaction_state_changed.emit(tx)
for tx in new_tx:
self.model.app.new_transfer.emit(self.model.connection, tx)
new_dividends = await self.model.transactions_service.update_dividends_history(
pubkey,
self.view.table_history.model().ts_from,
self.view.table_history.model().ts_to,
new_tx
)
self._logger.debug("Found {} new dividends".format(len(new_dividends)))
for ud in new_dividends:
self.app.new_dividend.emit(self.model.connection, ud)
......@@ -120,6 +120,9 @@
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<property name="topMargin">
<number>5</number>
</property>
......@@ -143,6 +146,29 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="button_refresh">
<property name="maximumSize">
<size>
<width>30</width>
<height>30</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../../../res/icons/sakia.icons.qrc">
<normaloff>:/icons/refresh_icon</normaloff>:/icons/refresh_icon</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item>
......
from datetime import datetime
from PyQt5.QtCore import QObject
from sakia.data.entities.transaction import (
parse_transaction_doc,
......@@ -9,7 +11,6 @@ from duniterpy.documents import SimpleTransaction, Block
from sakia.data.entities import Dividend
from duniterpy.api import bma
import logging
import sqlite3
class TransactionsService(QObject):
......@@ -91,7 +92,8 @@ class TransactionsService(QObject):
async def parse_transactions_history(self, connections, start, end):
"""
Request transactions from the network to initialize data for a given pubkey
Request transactions from the network to add data for given connections
:param List[sakia.data.entities.Connection] connections: the list of connections found by tx parsing
:param int start: the first block
:param int end: the last block
......@@ -140,7 +142,8 @@ class TransactionsService(QObject):
async def parse_dividends_history(self, connections, start, end, transactions):
"""
Request transactions from the network to initialize data for a given pubkey
Request transactions from the network to add data for a given connections
:param List[sakia.data.entities.Connection] connections: the list of connections found by tx parsing
:param List[duniterpy.documents.Block] blocks: the list of transactions found by tx parsing
:param List[sakia.data.entities.Transaction] transactions: the list of transactions found by tx parsing
......@@ -201,6 +204,126 @@ class TransactionsService(QObject):
dividends[connection].append(dividend)
return dividends
async def update_transactions_history(self, pubkey, start, end):
"""
Request transactions from the network to update data for a given pubkey
:param str pubkey: pubkey for tx history
:param int start: start timestamp
:param int end: end timestamp
"""
self._logger.debug("Manually refresh transactions...")
transfers_changed = []
new_transfers = []
txid = 0
history_data = await self._bma_connector.get(
self.currency,
bma.tx.times,
req_args={"pubkey": pubkey, "start": start, "end": end},
)
for tx_data in history_data["history"]["sent"]:
for tx in [
t for t in self._transactions_processor.awaiting(self.currency)
]:
if self._transactions_processor.run_state_transitions(
tx, tx_data["hash"], tx_data["block_number"]
):
transfers_changed.append(tx)
self._logger.debug(
"New transaction validated : {0}".format(tx.sha_hash)
)
for tx_data in history_data["history"]["received"]:
tx_doc = TransactionDoc.from_bma_history(
history_data["currency"], tx_data
)
if not self._transactions_processor.find_by_hash(
pubkey, tx_doc.sha_hash
) and SimpleTransaction.is_simple(tx_doc):
tx = parse_transaction_doc(
tx_doc,
pubkey,
tx_data["block_number"],
tx_data["time"],
txid,
)
if tx:
new_transfers.append(tx)
self._transactions_processor.commit(tx)
else:
logging.debug("Error during transfer parsing")
return transfers_changed, new_transfers
async def update_dividends_history(self, pubkey, start, end, transactions):
"""
Request transactions from the network to update data for a given pubkey
:param str pubkey: pubkey for dividend history
:param int start: start timestamp
:param int end: end timestamp
:param List[sakia.data.entities.Transaction] transactions: the list of transactions found by tx parsing
"""
self._logger.debug("Manually refresh dividends...")
dividends = []
# fixme: this request only returns non consumed UD. Should returns all UD created by pubkey in a time period.
# missing UD will result... Use another request asap !
history_data = await self._bma_connector.get(
self.currency, bma.ud.history, req_args={"pubkey": pubkey}
)
block_timestamps = []
block_numbers = []
for ud_data in history_data["history"]["history"]:
dividend = Dividend(
currency=self.currency,
pubkey=pubkey,
block_number=ud_data["block_number"],
timestamp=ud_data["time"],
amount=ud_data["amount"],
base=ud_data["base"],
)
if start <= dividend.timestamp <= end:
self._logger.debug(
"Dividend from transaction input of block {0} ({1})".format(dividend.block_number,
datetime.fromtimestamp(
dividend.timestamp))
)
block_timestamps.append(dividend.timestamp)
block_numbers.append(dividend.block_number)
if self._dividends_processor.commit(dividend):
dividends.append(dividend)
for tx in transactions:
txdoc = TransactionDoc.from_signed_raw(tx.raw)
for input in txdoc.inputs:
# For each dividends inputs, if it is consumed (not present in ud history)
if (
input.source == "D"
and input.origin_id == pubkey
and input.index not in block_numbers
):
block_data = await self._bma_connector.get(
self.currency,
bma.blockchain.block,
req_args={"number": input.index},
)
block = Block.from_signed_raw(
block_data["raw"] + block_data["signature"] + "\n"
)
dividend = Dividend(
currency=self.currency,
pubkey=pubkey,
block_number=input.index,
timestamp=block.mediantime,
amount=block.ud,
base=block.unit_base,
)
self._logger.debug(
"Dividend from transaction input of block {0} ({1})".format(dividend.block_number, datetime.fromtimestamp(dividend.timestamp))
)
if self._dividends_processor.commit(dividend):
dividends.append(dividend)
return dividends
def transfers(self, pubkey):
"""
Get all transfers from or to a given pubkey
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment