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
Example #2
0
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
Example #3
0
    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,
        )
Example #4
0
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,
    )
Example #5
0
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,
        ))
Example #7
0
    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,
        )