Esempio n. 1
0
 def register_payment(self, sender: str, open_block_number: int,
                      balance: int, signature: str):
     """Register a payment.
     Method will try to reconstruct (verify) balance update data
     with a signature sent by the client.
     If verification is succesfull, an internal payment state is updated.
     Parameters:
         sender (str):               sender of the balance proof
         open_block_number (int):    block the channel was opened in
         balance (int):              updated balance
         signature(str):             balance proof to verify
     """
     assert is_checksum_address(sender)
     c = self.verify_balance_proof(sender, open_block_number, balance,
                                   signature)
     if balance <= c.balance:
         raise InvalidBalanceAmount('The balance must not decrease.')
     if balance > c.deposit:
         raise InvalidBalanceProof(
             'Balance must not be greater than deposit')
     received = balance - c.balance
     c.balance = balance
     c.last_signature = signature
     c.mtime = time.time()
     self.state.set_channel(c)
     self.log.debug(
         'registered payment (sender %s, block number %s, new balance %s)',
         c.sender, open_block_number, balance)
     return c.sender, received
Esempio n. 2
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. 3
0
 def sign_close(self, sender: str, open_block_number: int, balance: int):
     """Sign an agreement for a channel closing.
     Returns:
         channel close signature (str): a signature that can be used client-side to close
         the channel by directly calling contract's close method on-chain.
     """
     assert is_checksum_address(sender)
     if (sender, open_block_number) not in self.channels:
         raise NoOpenChannel('Channel does not exist or has been closed'
                             '(sender=%s, open_block_number=%d)' %
                             (sender, open_block_number))
     c = self.channels[sender, open_block_number]
     if c.is_closed:
         raise NoOpenChannel('Channel closing has been requested already.')
     assert balance is not None
     if c.last_signature is None:
         raise NoBalanceProofReceived('Payment has not been registered.')
     if balance != c.balance:
         raise InvalidBalanceProof(
             'Requested closing balance does not match latest one.')
     c.is_closed = True
     c.mtime = time.time()
     receiver_sig = sign_close(self.private_key, sender, open_block_number,
                               c.balance,
                               self.channel_manager_contract.address)
     self.state.set_channel(c)
     self.log.info(
         'signed cooperative closing message (sender %s, block number %s)',
         sender, open_block_number)
     return receiver_sig
Esempio n. 4
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
        """
        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:
            print('NoOpenChannel key error')
            raise NoOpenChannel('Channel does not exist or has been closed'
                                '(sender=%s, open_block_number=%s)' %
                                (sender, open_block_number))
        if c.is_closed:
            print('NoOpenChannel c.is_closed')
            raise NoOpenChannel('Channel closing has been requested already.')
        print('is_same_address', self.receiver, open_block_number, balance,
              decode_hex(signature), sender)
        if not is_same_address(
                verify_balance_proof(self.receiver, open_block_number, balance,
                                     decode_hex(signature)), sender):
            raise InvalidBalanceProof(
                'Recovered signer does not match the sender')
        return c
Esempio n. 5
0
 def sign_close(self, sender, open_block_number, balance):
     """Sign an agreement for a channel closing."""
     if (sender, open_block_number) not in self.channels:
         raise NoOpenChannel('Channel does not exist or has been closed'
                             '(sender=%s, open_block_number=%d)' %
                             (sender, open_block_number))
     c = self.channels[sender, open_block_number]
     print('sign_close', c)
     if c.is_closed:
         raise NoOpenChannel('Channel closing has been requested already.')
     assert balance is not None
     # if c.last_signature is None:todo fix
     #     raise NoBalanceProofReceived('Payment has not been registered.')
     if balance != c.balance:
         raise InvalidBalanceProof(
             'Requested closing balance does not match latest one.')
     c.is_closed = True
     c.mtime = time.time()
     receiver_sig = sign_balance_proof(self.private_key, self.receiver,
                                       open_block_number, balance)
     self.state.store()
     self.log.info(
         'signed cooperative closing message (sender %s, block number %s)',
         sender, open_block_number)
     return receiver_sig
Esempio n. 6
0
 def register_payment(self, sender, open_block_number, balance, signature):
     """Register a payment."""
     c = self.verify_balance_proof(sender, open_block_number, balance, signature)
     if balance <= c.balance:
         raise InvalidBalanceAmount('The balance must increase.')
     if balance > c.deposit:
         raise InvalidBalanceProof('Balance must not be greater than deposit.')
     received = balance - c.balance
     c.balance = balance
     c.last_signature = signature
     c.mtime = time.time()
     self.state.store()
     self.log.debug('registered payment (sender %s, block number %s, new balance %s)',
                    c.sender, open_block_number, balance)
     return (c.sender, received)