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

Fix bug #594 : Sources are not restored w/ cancel

parent d97cbdee
No related branches found
No related tags found
No related merge requests found
...@@ -290,6 +290,5 @@ class BmaConnector: ...@@ -290,6 +290,5 @@ class BmaConnector:
result = await asyncio.gather(*replies, return_exceptions=True) result = await asyncio.gather(*replies, return_exceptions=True)
return tuple(result) return tuple(result)
return ()
else: else:
raise NoPeerAvailable("", len(endpoints)) raise NoPeerAvailable("", len(endpoints))
...@@ -108,7 +108,7 @@ class TransactionsProcessor: ...@@ -108,7 +108,7 @@ class TransactionsProcessor:
Cancel a local transaction Cancel a local transaction
:param sakia.data.entities.Transaction tx: the transaction :param sakia.data.entities.Transaction tx: the transaction
""" """
self.run_state_transitions(tx) return self.run_state_transitions(tx)
async def send(self, tx, txdoc, currency): async def send(self, tx, txdoc, currency):
""" """
......
...@@ -38,6 +38,7 @@ def _broadcast_failure(tx, ret_codes): ...@@ -38,6 +38,7 @@ def _broadcast_failure(tx, ret_codes):
""" """
return 200 not in ret_codes return 200 not in ret_codes
def _is_locally_created(tx): def _is_locally_created(tx):
""" """
Check if we can send back the transaction if it was locally created Check if we can send back the transaction if it was locally created
......
...@@ -126,7 +126,6 @@ class ContextMenu(QObject): ...@@ -126,7 +126,6 @@ class ContextMenu(QObject):
UserInformationController.search_and_show_pubkey(self.parent(), self._app, UserInformationController.search_and_show_pubkey(self.parent(), self._app,
identity.pubkey) identity.pubkey)
@asyncify @asyncify
async def send_money(self, identity): async def send_money(self, identity):
await TransferController.send_money_to_identity(None, self._app, self._connection, identity) await TransferController.send_money_to_identity(None, self._app, self._connection, identity)
...@@ -148,7 +147,8 @@ This money transfer will be removed and not sent."""), ...@@ -148,7 +147,8 @@ This money transfer will be removed and not sent."""),
QMessageBox.Ok | QMessageBox.Cancel) QMessageBox.Ok | QMessageBox.Cancel)
if reply == QMessageBox.Ok: if reply == QMessageBox.Ok:
transactions_processor = TransactionsProcessor.instanciate(self._app) transactions_processor = TransactionsProcessor.instanciate(self._app)
transactions_processor.cancel(transfer) if transactions_processor.cancel(transfer):
self._app.sources_service.restore_sources(self._connection.pubkey, transfer)
self._app.db.commit() self._app.db.commit()
self._app.transaction_state_changed.emit(transfer) self._app.transaction_state_changed.emit(transfer)
......
...@@ -172,3 +172,30 @@ class SourcesServices(QObject): ...@@ -172,3 +172,30 @@ class SourcesServices(QObject):
# this is acceptable I guess # this is acceptable I guess
destructions += await self.refresh_sources_of_pubkey(pubkey, transactions, dividends, current_base) destructions += await self.refresh_sources_of_pubkey(pubkey, transactions, dividends, current_base)
return destructions return destructions
def restore_sources(self, pubkey, tx):
"""
Restore the sources of a cancelled tx
:param sakia.entities.Transaction tx:
"""
txdoc = TransactionDoc.from_signed_raw(tx.raw)
for offset, output in enumerate(txdoc.outputs):
if output.conditions.left.pubkey == pubkey:
source = Source(currency=self.currency,
pubkey=pubkey,
identifier=txdoc.sha_hash,
type='T',
noffset=offset,
amount=output.amount,
base=output.base)
self._sources_processor.drop(source)
for index, input in enumerate(txdoc.inputs):
source = Source(currency=self.currency,
pubkey=txdoc.issuers[0],
identifier=input.origin_id,
type=input.source,
noffset=input.index,
amount=input.amount,
base=input.base)
if source.pubkey == pubkey:
self._sources_processor.insert(source)
import pytest import pytest
from sakia.data.entities import Transaction from sakia.data.entities import Transaction
from sakia.data.processors import TransactionsProcessor
@pytest.mark.asyncio @pytest.mark.asyncio
...@@ -32,7 +33,6 @@ async def test_send_source(application_with_one_connection, fake_server, bob, al ...@@ -32,7 +33,6 @@ async def test_send_source(application_with_one_connection, fake_server, bob, al
await fake_server.close() await fake_server.close()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_destruction(application_with_one_connection, fake_server, bob, alice): async def test_destruction(application_with_one_connection, fake_server, bob, alice):
amount = application_with_one_connection.sources_service.amount(bob.key.pubkey) amount = application_with_one_connection.sources_service.amount(bob.key.pubkey)
...@@ -49,3 +49,33 @@ async def test_destruction(application_with_one_connection, fake_server, bob, al ...@@ -49,3 +49,33 @@ async def test_destruction(application_with_one_connection, fake_server, bob, al
assert tx_after_parse[-1].comment == "Too low balance" assert tx_after_parse[-1].comment == "Too low balance"
await fake_server.close() await fake_server.close()
@pytest.mark.asyncio
async def test_send_tx_then_cancel(application_with_one_connection, fake_server, bob, alice):
tx_before_send = application_with_one_connection.transactions_service.transfers(bob.key.pubkey)
sources_before_send = application_with_one_connection.sources_service.amount(bob.key.pubkey)
bob_connection = application_with_one_connection.db.connections_repo.get_one(pubkey=bob.key.pubkey)
fake_server.reject_next_post = True
await application_with_one_connection.documents_service.send_money(bob_connection,
bob.salt,
bob.password,
alice.key.pubkey, 10, 0, "Test comment")
tx_after_send = application_with_one_connection.transactions_service.transfers(bob.key.pubkey)
sources_after_send = application_with_one_connection.sources_service.amount(bob.key.pubkey)
assert len(tx_before_send) + 1 == len(tx_after_send)
assert sources_before_send - 10 >= sources_after_send
assert tx_after_send[-1].state is Transaction.REFUSED
assert tx_after_send[-1].written_block == 0
transactions_processor = TransactionsProcessor.instanciate(application_with_one_connection)
if transactions_processor.cancel(tx_after_send[-1]):
application_with_one_connection.sources_service.restore_sources(bob.key.pubkey, tx_after_send[-1])
tx_after_cancel = application_with_one_connection.transactions_service.transfers(bob.key.pubkey)
sources_after_cancel = application_with_one_connection.sources_service.amount(bob.key.pubkey)
assert tx_after_cancel[-1].state is Transaction.DROPPED
assert tx_after_cancel[-1].written_block == 0
assert len(tx_before_send) + 1 == len(tx_after_cancel)
assert sources_before_send == sources_after_cancel
await fake_server.close()
\ No newline at end of file
...@@ -56,4 +56,3 @@ async def test_issue_dividend(application_with_one_connection, fake_server, bob) ...@@ -56,4 +56,3 @@ async def test_issue_dividend(application_with_one_connection, fake_server, bob)
dividends_after_parse = application_with_one_connection.transactions_service.dividends(bob.key.pubkey) dividends_after_parse = application_with_one_connection.transactions_service.dividends(bob.key.pubkey)
assert len(dividends_before_send) + 2 == len(dividends_after_parse) assert len(dividends_before_send) + 2 == len(dividends_after_parse)
await fake_server.close() await fake_server.close()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment