def handle_message_refundtransfer(self, raiden: RaidenService, message: RefundTransfer): token_network_address = message.token_network_address from_transfer = lockedtransfersigned_from_message(message) chain_state = views.state_from_raiden(raiden) routes = get_best_routes( chain_state=chain_state, token_network_id=typing.TokenNetworkID(token_network_address), from_address=typing.InitiatorAddress(raiden.address), to_address=from_transfer.target, amount=from_transfer.lock.amount, previous_address=message.sender, config=raiden.config, ) role = views.get_transfer_role( chain_state, from_transfer.lock.secrethash, ) if role == 'initiator': secret = random_secret() state_change = ReceiveTransferRefundCancelRoute( routes=routes, transfer=from_transfer, secret=secret, ) else: state_change = ReceiveTransferRefund( transfer=from_transfer, routes=routes, ) raiden.handle_state_change(state_change)
def _data_to_sign(self) -> bytes: balance_hash = hash_balance_data( self.transferred_amount, self.locked_amount, self.locksroot, ) balance_proof_packed = pack_balance_proof( nonce=self.nonce, balance_hash=balance_hash, additional_hash=self.message_hash, channel_identifier=self.channel_identifier, token_network_identifier=typing.TokenNetworkID(self.token_network_address), chain_id=self.chain_id, ) return balance_proof_packed
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=typing.TokenNetworkID(self.address), chain_id=self.proxy.contract.functions.chain_id().call(), ) try: signer_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) self._check_channel_state_for_update( channel_identifier=channel_identifier, closer=partner, update_nonce=nonce, log_details=log_details, ) 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) self._check_channel_state_for_update( channel_identifier=channel_identifier, closer=partner, update_nonce=nonce, log_details=log_details, ) # 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)