示例#1
0
 def _recover(data: bytes, signature: bytes) -> Address:
     """ Use eth_sign compatible hasher to recover address from signed data """
     return to_canonical_address(
         eth_recover(
             data=data,
             signature=signature,
         ))
def test_client_fee_info(generate_raiden_clients):
    c1, c2 = generate_raiden_clients(2)
    channel_identifier = c1.open_channel(c2.address)
    assert is_channel_identifier(channel_identifier)

    fi = c1.get_fee_info(c2.address, nonce=5, relative_fee=1000, chain_id=2)
    fee_info_signer = eth_recover(
        data=fi.serialize_bin(),
        signature=decode_hex(fi.signature),
    )

    assert is_same_address(fee_info_signer, c1.address)

    assert fi.nonce == 5
    assert fi.relative_fee == 1000
    assert fi.chain_id == 2
示例#3
0
    def update_transfer(
        self,
        channel_identifier: typing.ChannelID,
        partner: typing.Address,
        balance_hash: typing.BalanceHash,
        nonce: typing.Nonce,
        additional_hash: typing.AdditionalHash,
        closing_signature: typing.Signature,
        non_closing_signature: typing.Signature,
    ):
        log_details = {
            'token_network': pex(self.address),
            'node': pex(self.node_address),
            'partner': pex(partner),
            'nonce': nonce,
            'balance_hash': encode_hex(balance_hash),
            'additional_hash': encode_hex(additional_hash),
            'closing_signature': encode_hex(closing_signature),
            'non_closing_signature': encode_hex(non_closing_signature),
        }
        log.debug('updateNonClosingBalanceProof called', **log_details)

        data_that_was_signed = pack_balance_proof(
            nonce=nonce,
            balance_hash=balance_hash,
            additional_hash=additional_hash,
            channel_identifier=channel_identifier,
            token_network_identifier=self.address,
            chain_id=self.proxy.contract.functions.chain_id().call(),
        )

        try:
            signer_address = to_canonical_address(
                eth_recover(
                    data=data_that_was_signed,
                    signature=closing_signature,
                ))

            # InvalidSignature is raised by eth_utils.eth_recover if signature
            # is not bytes or has the incorrect length
            #
            # ValueError is raised if the PublicKey instantiation failed, let it
            # propagate because it's a memory pressure problem.
            #
            # Exception is raised if the public key recovery failed.
        except Exception:  # pylint: disable=broad-except
            msg = "Couldn't verify the balance proof signature"
            log.critical(f'updateNonClosingBalanceProof failed, {msg}',
                         **log_details)
            raise RaidenUnrecoverableError(msg)

        if signer_address != partner:
            msg = 'Invalid balance proof signature'
            log.critical(f'updateNonClosingBalanceProof failed, {msg}',
                         **log_details)
            raise RaidenUnrecoverableError(msg)

        self._check_for_outdated_channel(
            self.node_address,
            partner,
            channel_identifier,
        )

        detail = self.detail_channel(
            participant1=self.node_address,
            participant2=partner,
            channel_identifier=channel_identifier,
        )
        if detail.state != ChannelState.CLOSED:
            msg = 'Channel is not in a closed state'
            log.critical(f'updateNonClosingBalanceProof failed, {msg}',
                         **log_details)
            raise RaidenUnrecoverableError(msg)

        if detail.settle_block_number < self.client.block_number():
            msg = ('updateNonClosingBalanceProof cannot be called '
                   'because the settlement period is over')
            log.critical(f'updateNonClosingBalanceProof failed, {msg}',
                         **log_details)
            raise RaidenRecoverableError(msg)

        transaction_hash = self.proxy.transact(
            'updateNonClosingBalanceProof',
            safe_gas_limit(GAS_REQUIRED_FOR_UPDATE_BALANCE_PROOF),
            channel_identifier,
            partner,
            self.node_address,
            balance_hash,
            nonce,
            additional_hash,
            closing_signature,
            non_closing_signature,
        )

        self.client.poll(transaction_hash)

        receipt_or_none = check_transaction_threw(self.client,
                                                  transaction_hash)
        if receipt_or_none:
            if detail.settle_block_number < receipt_or_none['blockNumber']:
                msg = ('updateNonClosingBalanceProof transaction '
                       'was mined after settlement finished')
                log.critical(f'updateNonClosingBalanceProof failed, {msg}',
                             **log_details)
                raise RaidenRecoverableError(msg)

            # This should never happen if the settlement window and gas price
            # estimation is done properly
            channel_settled = self.channel_is_settled(
                participant1=self.node_address,
                participant2=partner,
                channel_identifier=channel_identifier,
            )
            if channel_settled is True:
                msg = 'Channel is settled'
                log.critical(f'updateNonClosingBalanceProof failed, {msg}',
                             **log_details)
                raise RaidenRecoverableError(msg)

            msg = 'Update NonClosing balance proof'
            log.critical(f'updateNonClosingBalanceProof failed, {msg}',
                         **log_details)
            raise TransactionThrew(msg, receipt_or_none)

        log.info('updateNonClosingBalanceProof successful', **log_details)