diff --git a/src/cutecoin/core/account.py b/src/cutecoin/core/account.py index 3339dbd88e20d5b1e313b32f836199ea5ea0e7e3..ac949e699d26c9e17c8b2229765ab9c8c23161c3 100644 --- a/src/cutecoin/core/account.py +++ b/src/cutecoin/core/account.py @@ -31,8 +31,8 @@ class Account(QObject): Each account has only one key, and a key can be locally referenced by only one account. """ - loading_progressed = pyqtSignal(int, int) - loading_finished = pyqtSignal(list) + loading_progressed = pyqtSignal(Community, int, int) + loading_finished = pyqtSignal(Community, list) wallets_changed = pyqtSignal() def __init__(self, salt, pubkey, name, communities, wallets, contacts, identities_registry): @@ -168,7 +168,7 @@ class Account(QObject): maximums[hash] = maximum account_value = sum(values.values()) account_max = sum(maximums.values()) - self.loading_progressed.emit(account_value, account_max) + self.loading_progressed.emit(community, account_value, account_max) def wallet_finished(received): logging.debug("Finished loading wallet") @@ -177,7 +177,7 @@ class Account(QObject): if loaded_wallets == len(self.wallets): logging.debug("All wallets loaded") self._refreshing = False - self.loading_finished.emit(received_list) + self.loading_finished.emit(community, received_list) for w in self.wallets: w.refresh_progressed.disconnect(progressing) w.refresh_finished.disconnect(wallet_finished) diff --git a/src/cutecoin/core/app.py b/src/cutecoin/core/app.py index 4b9bb8716814c35161d5ef41ab9b21957c2d0e3d..f63223d057259ecead6f0f861c12cb1a47862198 100644 --- a/src/cutecoin/core/app.py +++ b/src/cutecoin/core/app.py @@ -78,7 +78,6 @@ class Application(QObject): API.aiohttp_connector = ProxyConnector("http://{0}:{1}".format( app.preferences['proxy_address'], app.preferences['proxy_port'])) - if app.preferences["account"] != "": account = app.get_account(app.preferences["account"]) app.change_current_account(account) @@ -172,6 +171,11 @@ class Application(QObject): self.current_account = account if self.current_account is not None: + for community in self.current_account.communities: + community.network.new_block_mined.connect(lambda: + self.current_account.refresh_transactions(self, community) + ) + self.current_account.refresh_transactions(self, community) self.current_account.start_coroutines() def stop_current_account(self): diff --git a/src/cutecoin/core/net/node.py b/src/cutecoin/core/net/node.py index 28d44778936342545273feed8a916ce28e6948c8..8150f46e79876dec351f4ff0849225adc513a8fb 100644 --- a/src/cutecoin/core/net/node.py +++ b/src/cutecoin/core/net/node.py @@ -246,14 +246,14 @@ class Node(QObject): @last_change.setter def last_change(self, val): - logging.debug("{:} | Changed state : {:}".format(self.pubkey[:5], - val)) + #logging.debug("{:} | Changed state : {:}".format(self.pubkey[:5], + # val)) self._last_change = val @state.setter def state(self, new_state): - logging.debug("{:} | Last state : {:} / new state : {:}".format(self.pubkey[:5], - self.state, new_state)) + #logging.debug("{:} | Last state : {:} / new state : {:}".format(self.pubkey[:5], + # self.state, new_state)) if self._state != new_state: self.last_change = time.time() self._state = new_state diff --git a/src/cutecoin/core/txhistory.py b/src/cutecoin/core/txhistory.py index 3c2f05a4a280c5b0cecf438464235484f185f72e..cb1cbfbc59ad36a8b7082edb17a7bee128ba1122 100644 --- a/src/cutecoin/core/txhistory.py +++ b/src/cutecoin/core/txhistory.py @@ -14,7 +14,8 @@ class TxHistory(): self.wallet = wallet self.app = app self._stop_coroutines = False - + self._running_refresh = [] + self._block_to = None self._transfers = [] self.available_sources = [] self._dividends = [] @@ -209,10 +210,11 @@ class TxHistory(): block_doc.mediantime, received_list, current_block, txid+txmax) if transfer != None: - logging.debug("Transfer amount : {0}".format(transfer.metadata['amount'])) + #logging.debug("Transfer amount : {0}".format(transfer.metadata['amount'])) transfers.append(transfer) else: - logging.debug("None transfer") + pass + #logging.debug("None transfer") else: logging.debug("Could not find or parse block {0}".format(block_number)) return transfers @@ -235,7 +237,7 @@ class TxHistory(): return {} @asyncio.coroutine - def refresh(self, community, received_list): + def _refresh(self, community, block_number_from, received_list): """ Refresh last transactions @@ -243,18 +245,8 @@ class TxHistory(): :param list received_list: List of transactions received """ try: - current_block = yield from community.bma_access.future_request(bma.blockchain.Block, - req_args={'number': community.network.latest_block_number}) - members_pubkeys = yield from community.members_pubkeys() - # We look for the first block to parse, depending on awaiting and validating transfers and ud... - blocks = [tx.metadata['block'] for tx in self._transfers - if tx.state in (Transfer.AWAITING, Transfer.VALIDATING)] +\ - [ud['block_number'] for ud in self._dividends - if ud['state'] in (Transfer.AWAITING, Transfer.VALIDATING)] +\ - [max(0, self.latest_block - community.network.fork_window(members_pubkeys))] - parsed_block = min(set(blocks)) - logging.debug("Refresh from : {0} to {1}".format(self.latest_block, current_block['number'])) - dividends = yield from self.request_dividends(community, parsed_block) + logging.debug("Refresh from : {0} to {1}".format(block_number_from, self._block_to['number'])) + dividends = yield from self.request_dividends(community, block_number_from) with_tx_data = yield from community.bma_access.future_request(bma.blockchain.TX) blocks_with_tx = with_tx_data['result']['blocks'] new_transfers = [] @@ -262,10 +254,10 @@ class TxHistory(): # Lets look if transactions took too long to be validated awaiting = [t for t in self._transfers if t.state == Transfer.AWAITING] - while parsed_block <= current_block['number']: + while block_number_from <= self._block_to['number']: udid = 0 - for d in [ud for ud in dividends if ud['block_number'] == parsed_block]: - state = yield from TxHistory._validation_state(community, d['block_number'], current_block) + for d in [ud for ud in dividends if ud['block_number'] == block_number_from]: + state = yield from TxHistory._validation_state(community, d['block_number'], self._block_to) if d['block_number'] not in [ud['block_number'] for ud in self._dividends]: d['id'] = udid @@ -278,24 +270,25 @@ class TxHistory(): known_dividend['state'] = state # We parse only blocks with transactions - if parsed_block in blocks_with_tx: - transfers = yield from self._parse_block(community, parsed_block, - received_list, current_block, + if block_number_from in blocks_with_tx: + transfers = yield from self._parse_block(community, block_number_from, + received_list, self._block_to, udid + len(new_transfers)) new_transfers += transfers - self.wallet.refresh_progressed.emit(parsed_block, current_block['number'], self.wallet.pubkey) - parsed_block += 1 + self.wallet.refresh_progressed.emit(block_number_from, self._block_to['number'], self.wallet.pubkey) + block_number_from += 1 - if current_block['number'] > self.latest_block: + # We check if latest parsed block_number is a new high number + if block_number_from > self.latest_block: self.available_sources = yield from self.wallet.sources(community) if self._stop_coroutines: return - self.latest_block = current_block['number'] + self.latest_block = block_number_from parameters = yield from community.parameters() for transfer in awaiting: - transfer.check_refused(current_block['medianTime'], + transfer.check_refused(self._block_to['medianTime'], parameters['avgGenTime'], parameters['medianTimeBlocks']) except NoPeerAvailable as e: @@ -307,3 +300,29 @@ class TxHistory(): self._dividends = self._dividends + new_dividends self.wallet.refresh_finished.emit(received_list) + + @asyncio.coroutine + def refresh(self, community, received_list): + # We update the block goal + current_block = yield from community.bma_access.future_request(bma.blockchain.Block, + req_args={'number': community.network.latest_block_number}) + members_pubkeys = yield from community.members_pubkeys() + # We look for the first block to parse, depending on awaiting and validating transfers and ud... + blocks = [tx.metadata['block'] for tx in self._transfers + if tx.state in (Transfer.AWAITING, Transfer.VALIDATING)] +\ + [ud['block_number'] for ud in self._dividends + if ud['state'] in (Transfer.AWAITING, Transfer.VALIDATING)] +\ + [max(0, self.latest_block - community.network.fork_window(members_pubkeys))] + parsed_block = min(set(blocks)) + self._block_to = current_block + + # We wait for current refresh coroutines + if len(self._running_refresh) > 0: + logging.debug("Wait for the end of previous refresh") + done, pending = yield from asyncio.wait(self._running_refresh) + for cor in done: + self._running_refresh.remove(cor) + + # Then we start a new one + task = asyncio.async(self._refresh(community, parsed_block, received_list)) + self._running_refresh.append(task) \ No newline at end of file diff --git a/src/cutecoin/gui/community_view.py b/src/cutecoin/gui/community_view.py index 7d95edd9f8dc3abab93e8d87d9f5fe55b477a834..f09ef623ab40460bc5e50a5787752734a4972467 100644 --- a/src/cutecoin/gui/community_view.py +++ b/src/cutecoin/gui/community_view.py @@ -161,8 +161,6 @@ class CommunityWidget(QWidget, Ui_CommunityWidget): except MembershipNotFoundError as e: pass - - self.tab_history.start_progress() self.refresh_data() def refresh_data(self): diff --git a/src/cutecoin/gui/transactions_tab.py b/src/cutecoin/gui/transactions_tab.py index 8ef3ee4075815b6012ef9c8d0665726be47ddb9d..5100725cdd548a57b99e4d07b8d5c3cf9ac2e610 100644 --- a/src/cutecoin/gui/transactions_tab.py +++ b/src/cutecoin/gui/transactions_tab.py @@ -70,13 +70,14 @@ class TransactionsTabWidget(QWidget, Ui_transactionsTabWidget): self.account = account self.password_asker = password_asker self.table_history.model().sourceModel().change_account(account) + self.connect_progress() def change_community(self, community): self.cancel_once_tasks() self.community = community + self.progressbar.hide() self.table_history.model().sourceModel().change_community(self.community) self.refresh() - self.stop_progress([]) @once_at_a_time @asyncify @@ -104,33 +105,36 @@ class TransactionsTabWidget(QWidget, Ui_transactionsTabWidget): def refresh(self): #TODO: Use resetmodel instead of destroy/create if self.community: + self.table_history.model().sourceModel().refresh_transfers() + self.table_history.resizeColumnsToContents() self.refresh_minimum_maximum() self.refresh_balance() - def start_progress(self): - def progressing(value, maximum): - self.progressbar.setValue(value) - self.progressbar.setMaximum(maximum) + def connect_progress(self): + def progressing(community, value, maximum): + if community == self.community: + self.progressbar.show() + self.progressbar.setValue(value) + self.progressbar.setMaximum(maximum) self.app.current_account.loading_progressed.connect(progressing) self.app.current_account.loading_finished.connect(self.stop_progress) - self.app.current_account.refresh_transactions(self.app, self.community) - self.progressbar.show() @pyqtSlot(list) - def stop_progress(self, received_list): - amount = 0 - for r in received_list: - amount += r.metadata['amount'] - self.progressbar.hide() - if len(received_list) > 0: - text = self.tr("Received {0} {1} from {2} transfers").format(amount, - self.community.currency, - len(received_list)) - if self.app.preferences['notifications']: - toast.display(self.tr("New transactions received"), text) - - self.table_history.model().sourceModel().refresh_transfers() - self.table_history.resizeColumnsToContents() + def stop_progress(self, community, received_list): + if community == self.community: + amount = 0 + for r in received_list: + amount += r.metadata['amount'] + self.progressbar.hide() + if len(received_list) > 0: + text = self.tr("Received {0} {1} from {2} transfers").format(amount, + self.community.currency, + len(received_list)) + if self.app.preferences['notifications']: + toast.display(self.tr("New transactions received"), text) + + self.table_history.model().sourceModel().refresh_transfers() + self.table_history.resizeColumnsToContents() @once_at_a_time @asyncify