Exemple #1
0
    def get_monitor_request(
        self,
        token_network_address: str,
        channel_id: int,
        non_closing_signer: str,
    ) -> Optional[MonitorRequest]:
        assert is_checksum_address(token_network_address)
        assert is_checksum_address(non_closing_signer)
        row = self.conn.execute(
            """
                SELECT *,
                    (SELECT chain_id FROM blockchain) As chain_id
                FROM monitor_request
                WHERE channel_identifier = ?
                  AND token_network_address = ?
                  AND non_closing_signer = ?
            """,
            [hex(channel_id), token_network_address, non_closing_signer],
        ).fetchone()
        if row is None:
            return None

        kwargs = {
            key: val
            for key, val in zip(row.keys(), row) if key != 'non_closing_signer'
        }
        mr = MonitorRequest(**kwargs)
        return mr
Exemple #2
0
    def on_monitor_request(self, request_monitoring: RequestMonitoring) -> None:
        assert isinstance(request_monitoring, RequestMonitoring)

        # Convert Raiden's RequestMonitoring object to a MonitorRequest
        try:
            monitor_request = MonitorRequest(
                channel_identifier=request_monitoring.balance_proof.channel_identifier,
                token_network_address=to_checksum_address(
                    request_monitoring.balance_proof.token_network_address
                ),
                chain_id=request_monitoring.balance_proof.chain_id,
                balance_hash=encode_hex(request_monitoring.balance_proof.balance_hash),
                nonce=request_monitoring.balance_proof.nonce,
                additional_hash=encode_hex(request_monitoring.balance_proof.additional_hash),
                closing_signature=encode_hex(request_monitoring.balance_proof.signature),
                non_closing_signature=encode_hex(request_monitoring.non_closing_signature),
                reward_amount=request_monitoring.reward_amount,
                reward_proof_signature=encode_hex(request_monitoring.signature),
            )
        except InvalidSignature:
            log.info("Ignore MR with invalid signature", monitor_request=request_monitoring)
            return

        # Validate MR
        if monitor_request.chain_id != self.chain_id:
            log.debug("Bad chain_id", monitor_request=monitor_request, expected=self.chain_id)
            return

        # Check that received MR is newer by comparing nonces
        old_mr = self.state_db.get_monitor_request(
            token_network_address=monitor_request.token_network_address,
            channel_id=monitor_request.channel_identifier,
            non_closing_signer=monitor_request.non_closing_signer,
        )
        if old_mr and old_mr.nonce >= monitor_request.nonce:
            log.debug(
                "New MR does not have a newer nonce.",
                token_network_address=monitor_request.token_network_address,
                channel_identifier=monitor_request.channel_identifier,
                received_nonce=monitor_request.nonce,
                known_nonce=old_mr.nonce,
            )
            return

        log.info(
            "Received new MR",
            token_network_address=monitor_request.token_network_address,
            channel_identifier=monitor_request.channel_identifier,
            nonce=monitor_request.nonce,
            signer=monitor_request.signer,
            non_closing_signer=monitor_request.non_closing_signer,
            reward_signer=monitor_request.reward_proof_signer,
            reward_amount=monitor_request.reward_amount,
        )

        with self.state_db.conn:
            self.state_db.upsert_monitor_request(monitor_request)
Exemple #3
0
    def get_monitor_request(
        self,
        token_network_address: TokenNetworkAddress,
        channel_id: ChannelID,
        non_closing_signer: Address,
    ) -> Optional[MonitorRequest]:
        row = self.conn.execute(
            """
                SELECT monitor_request.*,
                    blockchain.chain_id,
                    blockchain.monitor_contract_address AS msc_address
                FROM monitor_request,
                    blockchain
                WHERE channel_identifier = ?
                  AND token_network_address = ?
                  AND non_closing_signer = ?
            """,
            [
                hex256(channel_id),
                to_checksum_address(token_network_address),
                to_checksum_address(non_closing_signer),
            ],
        ).fetchone()
        if row is None:
            return None

        kwargs = {
            key: val
            for key, val in zip(row.keys(), row)
            if key not in ("saved_at", "waiting_for_channel")
        }
        kwargs["token_network_address"] = to_canonical_address(
            kwargs["token_network_address"])
        kwargs["msc_address"] = to_canonical_address(kwargs["msc_address"])
        kwargs["closing_signature"] = decode_hex(kwargs["closing_signature"])
        kwargs["non_closing_participant"] = to_canonical_address(
            kwargs.pop("non_closing_signer"))
        kwargs["non_closing_signature"] = decode_hex(
            kwargs["non_closing_signature"])
        kwargs["reward_proof_signature"] = decode_hex(
            kwargs["reward_proof_signature"])
        return MonitorRequest(**kwargs)
Exemple #4
0
    def get_monitor_request(
        self,
        token_network_address: TokenNetworkAddress,
        channel_id: ChannelID,
        non_closing_signer: Address,
    ) -> Optional[MonitorRequest]:
        row = self.conn.execute(
            """
                SELECT *,
                    (SELECT chain_id FROM blockchain) As chain_id
                FROM monitor_request
                WHERE channel_identifier = ?
                  AND token_network_address = ?
                  AND non_closing_signer = ?
            """,
            [
                hex256(channel_id),
                to_checksum_address(token_network_address),
                to_checksum_address(non_closing_signer),
            ],
        ).fetchone()
        if row is None:
            return None

        kwargs = {
            key: val
            for key, val in zip(row.keys(), row) if key != "non_closing_signer"
        }
        kwargs["token_network_address"] = to_canonical_address(
            kwargs["token_network_address"])
        kwargs["closing_signature"] = decode_hex(kwargs["closing_signature"])
        kwargs["non_closing_signature"] = decode_hex(
            kwargs["non_closing_signature"])
        kwargs["reward_proof_signature"] = decode_hex(
            kwargs["reward_proof_signature"])
        return MonitorRequest(**kwargs)
Exemple #5
0
    def on_monitor_request(self,
                           request_monitoring: RequestMonitoring) -> None:
        assert isinstance(request_monitoring, RequestMonitoring)
        assert request_monitoring.non_closing_signature is not None
        assert request_monitoring.reward_proof_signature is not None

        # Convert Raiden's RequestMonitoring object to a MonitorRequest
        try:
            monitor_request = MonitorRequest(
                channel_identifier=request_monitoring.balance_proof.
                channel_identifier,
                token_network_address=TokenNetworkAddress(
                    request_monitoring.balance_proof.token_network_address),
                chain_id=request_monitoring.balance_proof.chain_id,
                balance_hash=encode_hex(
                    request_monitoring.balance_proof.balance_hash),
                nonce=request_monitoring.balance_proof.nonce,
                additional_hash=encode_hex(
                    request_monitoring.balance_proof.additional_hash),
                closing_signature=request_monitoring.balance_proof.signature,
                non_closing_signature=request_monitoring.non_closing_signature,
                reward_amount=request_monitoring.reward_amount,
                non_closing_participant=request_monitoring.
                non_closing_participant,
                reward_proof_signature=request_monitoring.signature,
                msc_address=request_monitoring.
                monitoring_service_contract_address,
            )
        except InvalidSignature:
            log.info("Ignore MR with invalid signature",
                     monitor_request=request_monitoring)
            return

        # Validate MR
        if monitor_request.chain_id != self.chain_id:
            log.debug("Bad chain_id",
                      monitor_request=monitor_request,
                      expected=self.chain_id)
            return
        if monitor_request.non_closing_signer != monitor_request.non_closing_participant:
            log.info("MR not signed by non_closing_participant",
                     monitor_request=monitor_request)
            return
        if monitor_request.non_closing_signer != monitor_request.reward_proof_signer:
            log.debug("The two MR signatures don't match",
                      monitor_request=monitor_request)
            return

        # Ignore MRs for channels that are already closed for a while.
        # We need to do this to prevent clients from wasting the MS' gas by
        # updating the BP after the MS has already called `monitor`, see
        # https://github.com/raiden-network/raiden-services/issues/504.
        close_age = self.state_db.channel_close_age(
            token_network_address=monitor_request.token_network_address,
            channel_id=monitor_request.channel_identifier,
        )
        # This is x blocks after that event is already confirmed, so that should be plenty!
        if close_age is not None and close_age >= CHANNEL_CLOSE_MARGIN:
            log.warning(
                "Ignore MR for long closed channel",
                monitor_request=monitor_request,
                close_age=close_age,
            )
            return

        # Check that received MR is newer by comparing nonces
        old_mr = self.state_db.get_monitor_request(
            token_network_address=monitor_request.token_network_address,
            channel_id=monitor_request.channel_identifier,
            non_closing_signer=monitor_request.non_closing_signer,
        )
        if old_mr and old_mr.nonce >= monitor_request.nonce:
            log.debug(
                "New MR does not have a newer nonce.",
                token_network_address=monitor_request.token_network_address,
                channel_identifier=monitor_request.channel_identifier,
                received_nonce=monitor_request.nonce,
                known_nonce=old_mr.nonce,
            )
            return

        log.info(
            "Received new MR",
            token_network_address=monitor_request.token_network_address,
            channel_identifier=monitor_request.channel_identifier,
            nonce=monitor_request.nonce,
            signer=monitor_request.signer,
            non_closing_signer=monitor_request.non_closing_signer,
            reward_signer=monitor_request.reward_proof_signer,
            reward_amount=monitor_request.reward_amount,
        )

        self.state_db.upsert_monitor_request(monitor_request)