def events_for_refund_transfer( refund_channel, refund_transfer, pseudo_random_generator, timeout_blocks, block_number, ): """ Refund the transfer. Args: refund_route (RouteState): The original route that sent the mediated transfer to this node. refund_transfer (LockedTransferSignedState): The original mediated transfer from the refund_route. timeout_blocks (int): The number of blocks available from the /latest transfer/ received by this node, this transfer might be the original mediated transfer (if no route was available) or a refund transfer from a down stream node. block_number (int): The current block number. Returns: An empty list if there are not enough blocks to safely create a refund, or a list with a refund event.""" # A refund transfer works like a special SendLockedTransfer, so it must # follow the same rules and decrement reveal_timeout from the # payee_transfer. new_lock_timeout = timeout_blocks - refund_channel.reveal_timeout distributable = channel.get_distributable( refund_channel.our_state, refund_channel.partner_state, ) is_valid = (new_lock_timeout > 0 and refund_transfer.lock.amount <= distributable and channel.is_valid_amount(refund_channel.our_state, refund_transfer.lock.amount)) if is_valid: new_lock_expiration = new_lock_timeout + block_number message_identifier = message_identifier_from_prng( pseudo_random_generator) refund_transfer = channel.send_refundtransfer( refund_channel, refund_transfer.initiator, refund_transfer.target, refund_transfer.lock.amount, message_identifier, refund_transfer.payment_identifier, new_lock_expiration, refund_transfer.lock.secrethash, ) return [refund_transfer] # Can not create a refund lock with a safe expiration, so don't do anything # and wait for the received lock to expire. return list()
def events_for_refund_transfer( refund_channel, refund_transfer, pseudo_random_generator, timeout_blocks, block_number, ): """ Refund the transfer. Args: refund_route (RouteState): The original route that sent the mediated transfer to this node. refund_transfer (LockedTransferSignedState): The original mediated transfer from the refund_route. timeout_blocks (int): The number of blocks available from the /latest transfer/ received by this node, this transfer might be the original mediated transfer (if no route was available) or a refund transfer from a down stream node. block_number (int): The current block number. Returns: An empty list if there are not enough blocks to safely create a refund, or a list with a refund event.""" # A refund transfer works like a special SendLockedTransfer, so it must # follow the same rules and decrement reveal_timeout from the # payee_transfer. new_lock_timeout = timeout_blocks - refund_channel.reveal_timeout distributable = channel.get_distributable( refund_channel.our_state, refund_channel.partner_state, ) is_valid = ( new_lock_timeout > 0 and refund_transfer.lock.amount <= distributable and channel.is_valid_amount(refund_channel.our_state, refund_transfer.lock.amount) ) if is_valid: new_lock_expiration = new_lock_timeout + block_number message_identifier = message_identifier_from_prng(pseudo_random_generator) refund_transfer = channel.send_refundtransfer( refund_channel, refund_transfer.initiator, refund_transfer.target, refund_transfer.lock.amount, message_identifier, refund_transfer.payment_identifier, new_lock_expiration, refund_transfer.lock.secrethash, ) return [refund_transfer] # Can not create a refund lock with a safe expiration, so don't do anything # and wait for the received lock to expire. return list()
def backward_transfer_pair( backward_channel: NettingChannelState, payer_transfer: LockedTransferSignedState, pseudo_random_generator: random.Random, block_number: typing.BlockNumber, ) -> typing.Tuple[typing.Optional[MediationPairState], typing.List[Event]]: """ Sends a transfer backwards, allowing the previous hop to try a new route. When all the routes available for this node failed, send a transfer backwards with the same amount and secrethash, allowing the previous hop to do a retry. Args: backward_channel: The original channel which sent the mediated transfer to this node. payer_transfer: The *latest* payer transfer which is backing the mediation. block_number: The current block number. Returns: The mediator pair and the correspoding refund event. """ transfer_pair = None events = list() lock = payer_transfer.lock lock_timeout = lock.expiration - block_number # Ensure the refund transfer's lock has a safe expiration, otherwise don't # do anything and wait for the received lock to expire. if is_channel_usable(backward_channel, lock.amount, lock_timeout): message_identifier = message_identifier_from_prng(pseudo_random_generator) refund_transfer = channel.send_refundtransfer( channel_state=backward_channel, initiator=payer_transfer.initiator, target=payer_transfer.target, amount=lock.amount, message_identifier=message_identifier, payment_identifier=payer_transfer.payment_identifier, expiration=lock.expiration, secrethash=lock.secrethash, ) transfer_pair = MediationPairState( payer_transfer, backward_channel.partner_state.address, refund_transfer.transfer, ) events.append(refund_transfer) return (transfer_pair, events)
def events_for_refund_transfer( refund_channel, transfer_to_refund, pseudo_random_generator, block_number, ): """ Refund the transfer. Args: refund_route (RouteState): The original route that sent the mediated transfer to this node. transfer_to_refund (LockedTransferSignedState): The original mediated transfer from the refund_route. timeout_blocks (int): The number of blocks available from the /latest transfer/ received by this node, this transfer might be the original mediated transfer (if no route was available) or a refund transfer from a down stream node. block_number (int): The current block number. Returns: An empty list if there are not enough blocks to safely create a refund, or a list with a refund event.""" lock_timeout = transfer_to_refund.lock.expiration - block_number transfer_amount = transfer_to_refund.lock.amount if is_channel_usable(refund_channel, transfer_amount, lock_timeout): message_identifier = message_identifier_from_prng( pseudo_random_generator) refund_transfer = channel.send_refundtransfer( refund_channel, transfer_to_refund.initiator, transfer_to_refund.target, transfer_to_refund.lock.amount, message_identifier, transfer_to_refund.payment_identifier, transfer_to_refund.lock.expiration, transfer_to_refund.lock.secrethash, ) return [refund_transfer] # Can not create a refund lock with a safe expiration, so don't do anything # and wait for the received lock to expire. return list()