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

Handle transactions to self (#557)

parent 91ecc690
No related branches found
No related tags found
No related merge requests found
...@@ -17,15 +17,20 @@ def parse_transaction_doc(tx_doc, pubkey, block_number, mediantime, txid): ...@@ -17,15 +17,20 @@ def parse_transaction_doc(tx_doc, pubkey, block_number, mediantime, txid):
receivers = [o.conditions.left.pubkey for o in tx_doc.outputs receivers = [o.conditions.left.pubkey for o in tx_doc.outputs
if o.conditions.left.pubkey != tx_doc.issuers[0]] if o.conditions.left.pubkey != tx_doc.issuers[0]]
if len(receivers) == 0:
receivers = [tx_doc.issuers[0]]
in_issuers = len([i for i in tx_doc.issuers in_issuers = len([i for i in tx_doc.issuers
if i == pubkey]) > 0 if i == pubkey]) > 0
in_outputs = len([o for o in tx_doc.outputs in_outputs = len([o for o in tx_doc.outputs
if o.conditions.left.pubkey == pubkey]) > 0 if o.conditions.left.pubkey == pubkey]) > 0
if in_issuers or in_outputs: if len(receivers) == 0:
receivers = [tx_doc.issuers[0]]
# Transaction to self
outputs = [o for o in tx_doc.outputs]
amount = 0
for o in outputs:
amount += o.amount * math.pow(10, o.base)
amount, amount_base = reduce_base(amount, 0)
elif in_issuers or in_outputs:
# If the wallet pubkey is in the issuers we sent this transaction # If the wallet pubkey is in the issuers we sent this transaction
if in_issuers: if in_issuers:
outputs = [o for o in tx_doc.outputs outputs = [o for o in tx_doc.outputs
...@@ -42,6 +47,8 @@ def parse_transaction_doc(tx_doc, pubkey, block_number, mediantime, txid): ...@@ -42,6 +47,8 @@ def parse_transaction_doc(tx_doc, pubkey, block_number, mediantime, txid):
for o in outputs: for o in outputs:
amount += o.amount * math.pow(10, o.base) amount += o.amount * math.pow(10, o.base)
amount, amount_base = reduce_base(amount, 0) amount, amount_base = reduce_base(amount, 0)
else:
return None
transaction = Transaction(currency=tx_doc.currency, transaction = Transaction(currency=tx_doc.currency,
sha_hash=tx_doc.sha_hash, sha_hash=tx_doc.sha_hash,
...@@ -58,7 +65,6 @@ def parse_transaction_doc(tx_doc, pubkey, block_number, mediantime, txid): ...@@ -58,7 +65,6 @@ def parse_transaction_doc(tx_doc, pubkey, block_number, mediantime, txid):
state=Transaction.VALIDATED, state=Transaction.VALIDATED,
raw=tx_doc.signed_raw()) raw=tx_doc.signed_raw())
return transaction return transaction
return None
@attr.s() @attr.s()
......
...@@ -38,38 +38,6 @@ def _broadcast_failure(tx, ret_codes): ...@@ -38,38 +38,6 @@ def _broadcast_failure(tx, ret_codes):
""" """
return 200 not in ret_codes return 200 not in ret_codes
def _rollback_and_removed(tx, rollback, block):
"""
Check if the transfer is not in the block anymore
:param sakia.data.entities.Transaction tx: the transaction
:param bool rollback: True if we are in a rollback procedure
:param duniterpy.documents.Block block: The block to check for the transaction
:return: True if the transfer is not found in the block
"""
if rollback:
if not block or block.blockUID != tx.blockstamp:
return True
else:
return tx.sha_hash not in [t.sha_hash for t in block.transactions]
return False
def _rollback_and_local(tx, rollback, block):
"""
Check if the transfer is not in the block anymore
:param sakia.data.entities.Transaction tx: the transaction
:param bool rollback: True if we are in a rollback procedure
:param duniterpy.documents.Block block: The block to check for the transaction
:return: True if the transfer is found in the block
"""
if rollback and tx.local and block.blockUID == tx.blockstamp:
return tx.sha_hash not in [t.sha_hash for t in block.transactions]
return False
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
...@@ -88,8 +56,7 @@ def _be_validated(tx, block): ...@@ -88,8 +56,7 @@ def _be_validated(tx, block):
:param bool rollback: True if we are in a rollback procedure :param bool rollback: True if we are in a rollback procedure
:param duniterpy.documents.Block block: The block checked :param duniterpy.documents.Block block: The block checked
""" """
tx.blockstamp = block.blockUID tx.written_block = block.number
tx.timestamp = block.mediantime
def _drop(tx): def _drop(tx):
...@@ -116,12 +83,6 @@ states = { ...@@ -116,12 +83,6 @@ states = {
(Transaction.AWAITING, (Block,)): (Transaction.AWAITING, (Block,)):
((_found_in_block, _be_validated, Transaction.VALIDATED),), ((_found_in_block, _be_validated, Transaction.VALIDATED),),
(Transaction.VALIDATED, (bool,)):
(
(_rollback_and_removed, lambda tx, r: _drop(tx), Transaction.DROPPED),
(_rollback_and_local, None, Transaction.AWAITING),
),
(Transaction.REFUSED, ()): (Transaction.REFUSED, ()):
((_is_locally_created, _drop, Transaction.DROPPED),) ((_is_locally_created, _drop, Transaction.DROPPED),)
} }
...@@ -131,6 +131,10 @@ class NavigationModel(QObject): ...@@ -131,6 +131,10 @@ class NavigationModel(QObject):
return self.app.identities_service.get_identity(connection.pubkey, connection.uid).member return self.app.identities_service.get_identity(connection.pubkey, connection.uid).member
async def remove_connection(self, connection): async def remove_connection(self, connection):
for data in self.navigation:
connected_to = self._current_data['misc'].get('connection', None)
if connected_to == connection:
self._current_data['widget'].disconnect()
await self.app.remove_connection(connection) await self.app.remove_connection(connection)
async def send_leave(self, connection, password): async def send_leave(self, connection, password):
......
...@@ -86,7 +86,7 @@ class TxFilterProxyModel(QSortFilterProxyModel): ...@@ -86,7 +86,7 @@ class TxFilterProxyModel(QSortFilterProxyModel):
block_index = model.index(source_index.row(), block_col) block_index = model.index(source_index.row(), block_col)
block_data = model.data(block_index, Qt.DisplayRole) block_data = model.data(block_index, Qt.DisplayRole)
if state_data == Transaction.VALIDATED: if state_data == Transaction.VALIDATED and block_data:
current_confirmations = self.blockchain_service.current_buid().number - block_data current_confirmations = self.blockchain_service.current_buid().number - block_data
else: else:
current_confirmations = 0 current_confirmations = 0
...@@ -215,7 +215,7 @@ class HistoryTableModel(QAbstractTableModel): ...@@ -215,7 +215,7 @@ class HistoryTableModel(QAbstractTableModel):
self.beginInsertRows(QModelIndex(), len(self.transfers_data), len(self.transfers_data)) self.beginInsertRows(QModelIndex(), len(self.transfers_data), len(self.transfers_data))
if transfer.issuer == self.connection.pubkey: if transfer.issuer == self.connection.pubkey:
self.transfers_data.append(self.data_sent(transfer)) self.transfers_data.append(self.data_sent(transfer))
else: if transfer.receiver == self.connection.pubkey:
self.transfers_data.append(self.data_received(transfer)) self.transfers_data.append(self.data_received(transfer))
self.endInsertRows() self.endInsertRows()
...@@ -231,10 +231,11 @@ class HistoryTableModel(QAbstractTableModel): ...@@ -231,10 +231,11 @@ class HistoryTableModel(QAbstractTableModel):
self.beginRemoveRows(QModelIndex(), i, i) self.beginRemoveRows(QModelIndex(), i, i)
self.transfers_data.pop(i) self.transfers_data.pop(i)
self.endRemoveRows() self.endRemoveRows()
elif transfer.issuer == self.connection.pubkey: else:
if transfer.issuer == self.connection.pubkey:
self.transfers_data[i] = self.data_sent(transfer) self.transfers_data[i] = self.data_sent(transfer)
self.dataChanged.emit(self.index(i, 0), self.index(i, len(self.columns_types))) self.dataChanged.emit(self.index(i, 0), self.index(i, len(self.columns_types)))
else: if transfer.receiver == self.connection.pubkey:
self.transfers_data[i] = self.data_received(transfer) self.transfers_data[i] = self.data_received(transfer)
self.dataChanged.emit(self.index(i, 0), self.index(i, len(self.columns_types))) self.dataChanged.emit(self.index(i, 0), self.index(i, len(self.columns_types)))
return return
...@@ -309,7 +310,7 @@ class HistoryTableModel(QAbstractTableModel): ...@@ -309,7 +310,7 @@ class HistoryTableModel(QAbstractTableModel):
if transfer.state != Transaction.DROPPED: if transfer.state != Transaction.DROPPED:
if transfer.issuer == self.connection.pubkey: if transfer.issuer == self.connection.pubkey:
self.transfers_data.append(self.data_sent(transfer)) self.transfers_data.append(self.data_sent(transfer))
else: if transfer.receiver == self.connection.pubkey:
self.transfers_data.append(self.data_received(transfer)) self.transfers_data.append(self.data_received(transfer))
dividends = self.dividends() dividends = self.dividends()
for dividend in dividends: for dividend in dividends:
......
...@@ -49,7 +49,3 @@ class NavigationView(QFrame, Ui_Navigation): ...@@ -49,7 +49,3 @@ class NavigationView(QFrame, Ui_Navigation):
def add_connection(self, raw_data): def add_connection(self, raw_data):
self.tree_view.model().insert_node(raw_data) self.tree_view.model().insert_node(raw_data)
self.tree_view.expandAll() self.tree_view.expandAll()
def remove_connection(self, raw_data):
self.tree_view.model().remove_node(raw_data)
self.tree_view.expandAll()
...@@ -46,6 +46,7 @@ class TransactionsService(QObject): ...@@ -46,6 +46,7 @@ class TransactionsService(QObject):
for tx in [t for t in self._transactions_processor.awaiting(self.currency)]: for tx in [t for t in self._transactions_processor.awaiting(self.currency)]:
if self._transactions_processor.run_state_transitions(tx, block_doc): if self._transactions_processor.run_state_transitions(tx, block_doc):
transfers_changed.append(tx) transfers_changed.append(tx)
self._logger.debug("New transaction validated : {0}".format(tx.sha_hash))
new_transactions = [t for t in block_doc.transactions new_transactions = [t for t in block_doc.transactions
if not self._transactions_processor.find_by_hash(t.sha_hash) if not self._transactions_processor.find_by_hash(t.sha_hash)
......
...@@ -12,6 +12,7 @@ async def test_send_tx_then_validate(application_with_one_connection, fake_serve ...@@ -12,6 +12,7 @@ async def test_send_tx_then_validate(application_with_one_connection, fake_serve
tx_after_send = application_with_one_connection.transactions_service.transfers(bob.key.pubkey) tx_after_send = application_with_one_connection.transactions_service.transfers(bob.key.pubkey)
assert len(tx_before_send) + 1 == len(tx_after_send) assert len(tx_before_send) + 1 == len(tx_after_send)
assert tx_after_send[-1].state is Transaction.AWAITING assert tx_after_send[-1].state is Transaction.AWAITING
assert tx_after_send[-1].written_block == 0
fake_server.forge.forge_block() fake_server.forge.forge_block()
fake_server.forge.forge_block() fake_server.forge.forge_block()
fake_server.forge.forge_block() fake_server.forge.forge_block()
...@@ -19,6 +20,7 @@ async def test_send_tx_then_validate(application_with_one_connection, fake_serve ...@@ -19,6 +20,7 @@ async def test_send_tx_then_validate(application_with_one_connection, fake_serve
await application_with_one_connection.transactions_service.handle_new_blocks(new_blocks) await application_with_one_connection.transactions_service.handle_new_blocks(new_blocks)
tx_after_parse = application_with_one_connection.transactions_service.transfers(bob.key.pubkey) tx_after_parse = application_with_one_connection.transactions_service.transfers(bob.key.pubkey)
assert tx_after_parse[-1].state is Transaction.VALIDATED assert tx_after_parse[-1].state is Transaction.VALIDATED
assert tx_after_parse[-1].written_block == fake_server.forge.blocks[-3].number
await fake_server.close() await fake_server.close()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment