def test_ignore_mr_for_closed_channel(request_collector, build_request_monitoring, ms_database, closing_block): """MRs that come in >=10 blocks after the channel has been closed must be ignored.""" request_monitoring = build_request_monitoring() ms_database.conn.execute( "UPDATE blockchain SET latest_committed_block = ?", [100]) ms_database.conn.execute( "INSERT INTO token_network(address) VALUES (?)", [ to_checksum_address( request_monitoring.balance_proof.token_network_address) ], ) ms_database.upsert_channel( Channel( identifier=request_monitoring.balance_proof.channel_identifier, token_network_address=request_monitoring.balance_proof. token_network_address, participant1=Address(b"1" * 20), participant2=Address(b"2" * 20), closing_block=closing_block if closing_block else None, )) request_collector.on_monitor_request(request_monitoring) # When the channel is not closed, of the closing is less than 10 blocks # before the current block (100), the MR must be saved. expected_mrs = 0 if closing_block == 100 - CHANNEL_CLOSE_MARGIN else 1 assert ms_database.monitor_request_count() == expected_mrs
def test_save_and_load_channel(ms_database): token_network_address = get_random_address() ms_database.conn.execute("INSERT INTO token_network (address) VALUES (?)", [token_network_address]) for update_status in [ None, OnChainUpdateStatus( update_sender_address=Address(get_random_address()), nonce=random.randint(0, UINT256_MAX), ), ]: channel = Channel( token_network_address=TokenNetworkAddress(token_network_address), identifier=ChannelID(random.randint(0, UINT256_MAX)), participant1=Address(get_random_address()), participant2=Address(get_random_address()), settle_timeout=random.randint(0, UINT256_MAX), state=random.choice(list(ChannelState)), closing_block=BlockNumber(random.randint(0, UINT256_MAX)), closing_participant=Address(get_random_address()), closing_tx_hash=TransactionHash('%d' % random.randint(0, UINT64_MAX)), claim_tx_hash=TransactionHash('%d' % random.randint(0, UINT64_MAX)), update_status=update_status, ) ms_database.upsert_channel(channel) loaded_channel = ms_database.get_channel( token_network_address=channel.token_network_address, channel_id=channel.identifier) assert loaded_channel == channel
def get_channel(self, token_network_address: TokenNetworkAddress, channel_id: ChannelID) -> Optional[Channel]: row = self.conn.execute( """ SELECT * FROM channel WHERE identifier = ? AND token_network_address = ? """, [hex256(channel_id), to_checksum_address(token_network_address)], ).fetchone() if row is None: return None kwargs = { key: val for key, val in zip(row.keys(), row) if not key.startswith("update_status") } kwargs["token_network_address"] = decode_hex( kwargs["token_network_address"]) kwargs["participant1"] = decode_hex(kwargs["participant1"]) kwargs["participant2"] = decode_hex(kwargs["participant2"]) if kwargs["closing_tx_hash"] is not None: kwargs["closing_tx_hash"] = decode_hex(kwargs["closing_tx_hash"]) if kwargs["claim_tx_hash"] is not None: kwargs["claim_tx_hash"] = decode_hex(kwargs["claim_tx_hash"]) return Channel( update_status=OnChainUpdateStatus( update_sender_address=decode_hex(row["update_status_sender"]), nonce=row["update_status_nonce"], ) if row["update_status_nonce"] is not None else None, **kwargs, )
def create_channel(update_status: OnChainUpdateStatus = None) -> Channel: return Channel( token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS, identifier=DEFAULT_CHANNEL_IDENTIFIER, participant1=DEFAULT_PARTICIPANT1, participant2=DEFAULT_PARTICIPANT2, settle_timeout=random.randint(0, UINT256_MAX), state=random.choice(list(ChannelState)), closing_block=BlockNumber(random.randint(0, UINT256_MAX)), closing_participant=DEFAULT_PARTICIPANT1, monitor_tx_hash=make_transaction_hash(), claim_tx_hash=make_transaction_hash(), update_status=update_status, )
def test_purge_old_monitor_requests( ms_database: Database, build_request_monitoring, request_collector, monitoring_service: MonitoringService, ): # We'll test the purge on MRs for three different channels req_mons = [ build_request_monitoring(channel_id=1), build_request_monitoring(channel_id=2), build_request_monitoring(channel_id=3), ] for req_mon in req_mons: request_collector.on_monitor_request(req_mon) # Channel 1 exists in the db token_network_address = req_mons[0].balance_proof.token_network_address ms_database.conn.execute( "INSERT INTO token_network VALUES (?, ?)", [ to_checksum_address(token_network_address), DEFAULT_TOKEN_NETWORK_SETTLE_TIMEOUT ], ) ms_database.upsert_channel( Channel( identifier=ChannelID(1), token_network_address=token_network_address, participant1=Address(b"1" * 20), participant2=Address(b"2" * 20), )) # The request for channel 2 is recent (default), but the one for channel 3 # has been added 16 minutes ago. saved_at = (datetime.utcnow() - timedelta(minutes=16)).timestamp() ms_database.conn.execute( """ UPDATE monitor_request SET saved_at = ? WHERE channel_identifier = ? """, [saved_at, hex256(3)], ) monitoring_service._purge_old_monitor_requests() # pylint: disable=protected-access remaining_mrs = ms_database.conn.execute(""" SELECT channel_identifier, waiting_for_channel FROM monitor_request ORDER BY channel_identifier """).fetchall() assert [tuple(mr) for mr in remaining_mrs] == [(1, False), (2, True)]
def channel_opened_event_handler(event: Event, context: Context) -> None: assert isinstance(event, ReceiveChannelOpenedEvent) log.info( "Received new channel", token_network_address=event.token_network_address, identifier=event.channel_identifier, channel=event, ) context.database.upsert_channel( Channel( token_network_address=event.token_network_address, identifier=event.channel_identifier, participant1=event.participant1, participant2=event.participant2, ))
def get_channel(self, token_network_address: str, channel_id: int) -> Optional[Channel]: row = self.conn.execute( """ SELECT * FROM channel WHERE identifier = ? AND token_network_address = ? """, [hex(channel_id), token_network_address], ).fetchone() if row is None: return None kwargs = { key: val for key, val in zip(row.keys(), row) if not key.startswith("update_status") } return Channel( update_status=OnChainUpdateStatus( update_sender_address=row["update_status_sender"], nonce=row["update_status_nonce"] ) if row["update_status_nonce"] is not None else None, **kwargs, )