Esempio n. 1
0
    def verify_balance_proof(self, sender, open_block_number, balance,
                             signature):
        """Verify that a balance proof is valid and return the sender.

        Does not check the balance itself.

        :returns: the channel
        """
        assert is_checksum_address(sender)
        if (sender, open_block_number) in self.unconfirmed_channels:
            raise InsufficientConfirmations(
                'Insufficient confirmations for the channel '
                '(sender=%s, open_block_number=%d)' %
                (sender, open_block_number))
        try:
            c = self.channels[sender, open_block_number]
        except KeyError:
            raise NoOpenChannel('Channel does not exist or has been closed'
                                '(sender=%s, open_block_number=%s)' %
                                (sender, open_block_number))
        if c.is_closed:
            raise NoOpenChannel('Channel closing has been requested already.')

        if not is_same_address(
                verify_balance_proof(self.receiver, open_block_number, balance,
                                     decode_hex(signature),
                                     self.channel_manager_contract.address),
                sender):
            raise InvalidBalanceProof(
                'Recovered signer does not match the sender')
        return c
Esempio n. 2
0
def test_verify_balance_proof_v0(channel_manager_address: str):
    sig = sign_balance_proof(SENDER_PRIVATE_KEY, RECEIVER_ADDR, 312524, 11,
                             channel_manager_address)
    sig = sig[:-1] + bytes([sig[-1] % 27])
    assert is_same_address(
        verify_balance_proof(RECEIVER_ADDR, 312524, 11, sig,
                             channel_manager_address), SENDER_ADDR)
Esempio n. 3
0
    def on_invalid_amount(self, method: str, url: str, response: Response,
                          **kwargs) -> bool:
        log.debug('Server claims an invalid amount sent.')
        balance_sig = response.headers.get(HTTPHeaders.BALANCE_SIGNATURE)
        if balance_sig:
            balance_sig = decode_hex(balance_sig)
        last_balance = int(response.headers.get(HTTPHeaders.SENDER_BALANCE))

        verified = balance_sig and is_same_address(
            verify_balance_proof(self.channel.receiver, self.channel.block,
                                 last_balance, balance_sig,
                                 self.client.context.channel_manager.address),
            self.channel.sender)

        if verified:
            if last_balance == self.channel.balance:
                log.error(
                    'Server tried to disguise the last unconfirmed payment as a confirmed payment.'
                )
                return False
            else:
                log.debug(
                    'Server provided proof for a different channel balance ({}). Adopting.'
                    .format(last_balance))
                self.channel.update_balance(last_balance)
        else:
            log.debug(
                'Server did not provide proof for a different channel balance. Reverting to 0.'
            )
            self.channel.update_balance(0)

        return self.on_payment_requested(method, url, response, **kwargs)
Esempio n. 4
0
def test_verify_balance_proof(channel_manager_address: str):
    sig = sign_balance_proof(
        SENDER_PRIVATE_KEY, RECEIVER_ADDR, 315123, 8, channel_manager_address
    )
    assert is_same_address(verify_balance_proof(
        RECEIVER_ADDR, 315123, 8, sig, channel_manager_address
    ), SENDER_ADDR)
Esempio n. 5
0
def test_verify_balance_proof_v27(channel_manager_address: str):
    # Should be default but test anyway.
    sig = sign_balance_proof(SENDER_PRIVATE_KEY, RECEIVER_ADDR, 312524, 11,
                             channel_manager_address)
    sig = sig[:-1] + b'\x1b'
    assert verify_balance_proof(RECEIVER_ADDR, 312524, 11, sig,
                                channel_manager_address) == SENDER_ADDR
Esempio n. 6
0
    def verify_balance_proof(self, sender, open_block_number, balance, signature):
        """Verify that a balance proof is valid and return the sender.

        This method just verifies if the balance proof is valid - no state update is performed.

        :returns: Channel, if it exists
        """
        assert is_checksum_address(sender)
        if (sender, open_block_number) in self.unconfirmed_channels:
            raise InsufficientConfirmations(
                'Insufficient confirmations for the channel '
                '(sender=%s, open_block_number=%d)' % (sender, open_block_number))
        try:
            c = self.channels[sender, open_block_number]
        except KeyError:
            raise NoOpenChannel('Channel does not exist or has been closed'
                                '(sender=%s, open_block_number=%s)' % (sender, open_block_number))
        if c.is_closed:
            raise NoOpenChannel('Channel closing has been requested already.')

        if not is_same_address(
                verify_balance_proof(
                    self.receiver,
                    open_block_number,
                    balance,
                    decode_hex(signature),
                    self.channel_manager_contract.address
                ),
                sender
        ):
            raise InvalidBalanceProof('Recovered signer does not match the sender')
        return c
Esempio n. 7
0
def test_verify_balance_proof(channel_manager_address: str):
    sig = sign_balance_proof(
        SENDER_PRIVATE_KEY, RECEIVER_ADDR, 315123, 8, channel_manager_address
    )
    assert verify_balance_proof(
        RECEIVER_ADDR, 315123, 8, sig, channel_manager_address
    ) == SENDER_ADDR
Esempio n. 8
0
def test_verify_balance_proof_v27(channel_manager_address: str):
    # Should be default but test anyway.
    sig = sign_balance_proof(SENDER_PRIVATE_KEY, RECEIVER_ADDR, 312524, 11,
                             channel_manager_address)
    sig = sig[:-1] + bytes([sig[-1] % 27 + 27])
    assert is_same_address(
        verify_balance_proof(RECEIVER_ADDR, 312524, 11, sig,
                             channel_manager_address), SENDER_ADDR)
Esempio n. 9
0
def test_verify_balance_proof_v0(channel_manager_address: str):
    sig = sign_balance_proof(
        SENDER_PRIVATE_KEY, RECEIVER_ADDR, 312524, 11, channel_manager_address
    )
    sig = sig[:-1] + bytes([sig[-1] % 27])
    assert is_same_address(verify_balance_proof(
        RECEIVER_ADDR, 312524, 11, sig, channel_manager_address
    ), SENDER_ADDR)
Esempio n. 10
0
def test_verify_balance_proof_v0(channel_manager_address: str):
    sig = sign_balance_proof(
        SENDER_PRIVATE_KEY, RECEIVER_ADDR, 312524, 11, channel_manager_address
    )
    sig = sig[:-1] + b'\x00'
    assert verify_balance_proof(
        RECEIVER_ADDR, 312524, 11, sig, channel_manager_address
    ) == SENDER_ADDR
Esempio n. 11
0
def test_verify_balance_proof_v27(channel_manager_address: str):
    # Should be default but test anyway.
    sig = sign_balance_proof(
        SENDER_PRIVATE_KEY, RECEIVER_ADDR, 312524, 11, channel_manager_address
    )
    sig = sig[:-1] + bytes([sig[-1] % 27 + 27])
    assert is_same_address(verify_balance_proof(
        RECEIVER_ADDR, 312524, 11, sig, channel_manager_address
    ), SENDER_ADDR)
Esempio n. 12
0
    def on_invalid_amount(
            self,
            method: str,
            url: str,
            response: Response,
            **kwargs
    ) -> bool:
        log.debug('Server claims an invalid amount sent.')
        balance_sig = response.headers.get(HTTPHeaders.BALANCE_SIGNATURE)
        if balance_sig:
            balance_sig = decode_hex(balance_sig)
        last_balance = int(response.headers.get(HTTPHeaders.SENDER_BALANCE))

        verified = balance_sig and is_same_address(
            verify_balance_proof(
                self.channel.receiver,
                self.channel.block,
                last_balance,
                balance_sig,
                self.client.context.channel_manager.address
            ),
            self.channel.sender
        )

        if verified:
            if last_balance == self.channel.balance:
                log.error(
                    'Server tried to disguise the last unconfirmed payment as a confirmed payment.'
                )
                return False
            else:
                log.debug(
                    'Server provided proof for a different channel balance ({}). Adopting.'.format(
                        last_balance
                    )
                )
                self.channel.update_balance(last_balance)
        else:
            log.debug(
                'Server did not provide proof for a different channel balance. Reverting to 0.'
            )
            self.channel.update_balance(0)

        return self.on_payment_requested(method, url, response, **kwargs)