def _on_transaction_state_change(self, account_id: int, tx_hash: bytes, old_state: TxFlags, new_state: TxFlags) -> None: if not self._validate_account_event({ account_id }): return self._logger.debug("_on_transaction_state_change %s old=%s new=%s", hash_to_hex_str(tx_hash), TxFlags.to_repr(old_state), TxFlags.to_repr(new_state)) if new_state & TxFlags.STATE_BROADCAST_MASK: self._mark_transactions_removed([ tx_hash ]) else: self._mark_transactions_updated([ tx_hash ])
def _on_transaction_state_change(self, wallet_path: str, account_id: int, tx_hash: bytes, old_state: TxFlags, new_state: TxFlags) -> None: if not self._validate_event(wallet_path, account_id): return self._logger.debug("_on_transaction_state_change %s %s %s", tx_hash, TxFlags.to_repr(old_state), TxFlags.to_repr(new_state)) if new_state & TxFlags.STATE_BROADCAST_MASK: self.remove_transactions([tx_hash]) else: self.update_transactions([tx_hash])
def test_apply_reorg(self) -> None: common_height = 5 cache = TransactionCache(self.store) # Add the transaction that should be reset back to settled, with data fields cleared. tx_y1 = Transaction.from_hex(tx_hex_1) tx_hash_y1 = tx_y1.hash() data_y1 = TxData(height=common_height+1, position=33, fee=44, date_added=1, date_updated=1) with SynchronousWriter() as writer: cache.add([ (tx_hash_y1, data_y1, tx_y1, TxFlags.StateSettled, None) ], completion_callback=writer.get_callback()) assert writer.succeeded() # Add the transaction that would be reset but is below the common height. tx_n1 = Transaction.from_hex(tx_hex_2) tx_hash_n1 = tx_n1.hash() data_n1 = TxData(height=common_height-1, position=33, fee=44, date_added=1, date_updated=1) with SynchronousWriter() as writer: cache.add([ (tx_hash_n1, data_n1, tx_n1, TxFlags.StateSettled, None) ], completion_callback=writer.get_callback()) assert writer.succeeded() # Add the transaction that would be reset but is the common height. tx_n2 = Transaction.from_hex(tx_hex_3) tx_hash_n2 = tx_n2.hash() data_n2 = TxData(height=common_height, position=33, fee=44, date_added=1, date_updated=1) with SynchronousWriter() as writer: cache.add([ (tx_hash_n2, data_n2, tx_n2, TxFlags.StateSettled, None) ], completion_callback=writer.get_callback()) assert writer.succeeded() # Add a canary transaction that should remain untouched due to non-cleared state. tx_n3 = Transaction.from_hex(tx_hex_4) tx_hash_n3 = tx_n3.hash() data_n3 = TxData(height=111, position=333, fee=444, date_added=1, date_updated=1) with SynchronousWriter() as writer: cache.add([ (tx_hash_n3, data_n3, tx_n3, TxFlags.StateDispatched, None) ], completion_callback=writer.get_callback()) assert writer.succeeded() # Delete as if a reorg happened above the suitable but excluded canary transaction. with SynchronousWriter() as writer: cache.apply_reorg(5, completion_callback=writer.get_callback()) assert writer.succeeded() metadata_entries = cache.get_entries(TxFlags.HasByteData, TxFlags.HasByteData) assert 4 == len(metadata_entries) # Affected, canary above common height. y1 = [ m[1] for m in metadata_entries if m[0] == tx_hash_y1 ][0] assert 0 == y1.metadata.height assert None is y1.metadata.position assert data_y1.fee == y1.metadata.fee assert TxFlags.StateCleared | TxFlags.HasByteData | TxFlags.HasFee == y1.flags, \ TxFlags.to_repr(y1.flags) expected_flags = (TxFlags.HasByteData | TxFlags.HasFee | TxFlags.HasHeight | TxFlags.HasPosition) # Skipped, old enough to survive. n1 = [ m[1] for m in metadata_entries if m[0] == tx_hash_n1 ][0] assert data_n1.height == n1.metadata.height assert data_n1.position == n1.metadata.position assert data_n1.fee == n1.metadata.fee assert TxFlags.StateSettled | expected_flags == n1.flags, TxFlags.to_repr(n1.flags) # Skipped, canary common height. n2 = [ m[1] for m in metadata_entries if m[0] == tx_hash_n2 ][0] assert data_n2.height == n2.metadata.height assert data_n2.position == n2.metadata.position assert data_n2.fee == n2.metadata.fee assert TxFlags.StateSettled | expected_flags == n2.flags, TxFlags.to_repr(n2.flags) # Skipped, canary non-cleared. n3 = [ m[1] for m in metadata_entries if m[0] == tx_hash_n3 ][0] assert data_n3.height == n3.metadata.height assert data_n3.position == n3.metadata.position assert data_n3.fee == n3.metadata.fee assert TxFlags.StateDispatched | expected_flags == n3.flags, TxFlags.to_repr(n3.flags)