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: 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)), sender): raise InvalidBalanceProof( 'Recovered signer does not match the sender') return c
def sign_close(self, sender, open_block_number, balance): """Sign an agreement for a channel closing.""" 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
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
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 balance != 0 and 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
def unregister_payment(self, sender: str, open_block_number: int): 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)) assert c.balance > 0 c.last_signature = c.old_signature c.balance = c.old_balance c.mtime = time.time() self.state.set_channel(c) self.log.debug('unregistered payment (sender %s, block number %s, new balance %s)', c.sender, open_block_number, c.balance)