def test_is_valid_refund(): initiator = factories.ADDR target = factories.HOP1 valid_sender = factories.HOP2 transfer = LockedTransferState( identifier=20, amount=30, token=factories.UNIT_TOKEN_ADDRESS, initiator=initiator, target=target, expiration=50, hashlock=factories.UNIT_HASHLOCK, secret=None, ) refund_lower_expiration = LockedTransferState( identifier=20, amount=30, token=factories.UNIT_TOKEN_ADDRESS, initiator=initiator, target=target, expiration=35, hashlock=factories.UNIT_HASHLOCK, secret=None, ) assert mediator.is_valid_refund(transfer, valid_sender, refund_lower_expiration) is True # target cannot refund assert mediator.is_valid_refund(transfer, target, refund_lower_expiration) is False refund_same_expiration = LockedTransferState( identifier=20, amount=30, token=factories.UNIT_TOKEN_ADDRESS, initiator=initiator, target=factories.HOP1, expiration=50, hashlock=factories.UNIT_HASHLOCK, secret=None, ) assert mediator.is_valid_refund(transfer, valid_sender, refund_same_expiration) is False
def test_is_valid_refund(): initiator = factories.ADDR target = factories.HOP1 valid_sender = factories.HOP2 transfer = LockedTransferState( identifier=20, amount=30, token=factories.UNIT_TOKEN_ADDRESS, initiator=initiator, target=target, expiration=50, hashlock=factories.UNIT_HASHLOCK, secret=None, ) refund_lower_expiration = LockedTransferState( identifier=20, amount=30, token=factories.UNIT_TOKEN_ADDRESS, initiator=initiator, target=target, expiration=35, hashlock=factories.UNIT_HASHLOCK, secret=None, ) assert mediator.is_valid_refund(transfer, valid_sender, refund_lower_expiration) is True # target cannot refund assert mediator.is_valid_refund(transfer, target, refund_lower_expiration) is False refund_same_expiration = LockedTransferState( identifier=20, amount=30, token=factories.UNIT_TOKEN_ADDRESS, initiator=initiator, target=factories.HOP1, expiration=50, hashlock=factories.UNIT_HASHLOCK, secret=None, ) assert mediator.is_valid_refund(transfer, valid_sender, refund_same_expiration) is False
def handle_transferrefundcancelroute( payment_state: InitiatorPaymentState, state_change: ReceiveTransferRefundCancelRoute, channelidentifiers_to_channels: initiator.ChannelMap, pseudo_random_generator: random.Random, block_number: typing.BlockNumber, ) -> TransitionResult: channel_identifier = payment_state.initiator.channel_identifier channel_state = channelidentifiers_to_channels[channel_identifier] refund_transfer = state_change.transfer original_transfer = payment_state.initiator.transfer maximum_expiration = original_transfer.lock.expiration - channel_state.reveal_timeout if channel_state.close_transaction: closed_block_number = channel_state.close_transaction.finished_block_number else: closed_block_number = None # This is overcommiting, since the initiator knows the secret it doesn't # need to wait for reveal_timeout blocks. timeout_blocks = mediator.get_timeout_blocks( channel_state.settle_timeout, closed_block_number, original_transfer.lock.expiration, block_number, ) lock_timeout = timeout_blocks - channel_state.reveal_timeout maximum_expiration = lock_timeout + block_number is_valid_lock = ( refund_transfer.lock.secrethash == original_transfer.lock.secrethash and refund_transfer.lock.amount == original_transfer.lock.amount and refund_transfer.lock.expiration <= maximum_expiration) is_valid_refund = mediator.is_valid_refund( original_transfer, refund_transfer, ) events = list() if is_valid_lock and is_valid_refund: is_valid, channel_events, _ = channel.handle_receive_refundtransfercancelroute( channel_state, refund_transfer, ) events.extend(channel_events) if is_valid: old_description = payment_state.initiator.transfer_description transfer_description = TransferDescriptionWithSecretState( old_description.payment_identifier, old_description.amount, old_description.token_network_identifier, old_description.initiator, old_description.target, state_change.secret, ) payment_state.initiator.transfer_description = transfer_description sub_iteration = handle_cancelroute( payment_state, state_change, channelidentifiers_to_channels, pseudo_random_generator, block_number, ) events.extend(sub_iteration.events) if sub_iteration.new_state is None: payment_state = None iteration = TransitionResult(payment_state, events) return iteration
def handle_transferrefund(payment_state, state_change, channelidentifiers_to_channels, block_number): channel_identifier = payment_state.initiator.channel_identifier channel_state = channelidentifiers_to_channels[channel_identifier] refund_transfer = state_change.transfer original_transfer = payment_state.initiator.transfer maximum_expiration = original_transfer.lock.expiration - channel_state.reveal_timeout if channel_state.close_transaction: closed_block_number = channel_state.close_transaction.finished_block_number else: closed_block_number = None # This is overcommiting, since the initiator knows the secret it doesn't # need to wait for reveal_timeout blocks. timeout_blocks = mediator.get_timeout_blocks( channel_state.settle_timeout, closed_block_number, original_transfer.lock.expiration, block_number, ) lock_timeout = timeout_blocks - channel_state.reveal_timeout maximum_expiration = lock_timeout + block_number is_valid_lock = ( refund_transfer.lock.secrethash == original_transfer.lock.secrethash and refund_transfer.lock.amount == original_transfer.lock.amount and refund_transfer.lock.expiration <= maximum_expiration) is_valid_refund = mediator.is_valid_refund( original_transfer, refund_transfer, ) events = list() if is_valid_lock and is_valid_refund: is_valid, _ = channel.handle_receive_refundtransfer( channel_state, refund_transfer, ) if is_valid: old_description = payment_state.initiator.transfer_description transfer_description = TransferDescriptionWithSecretState( old_description.identifier, old_description.amount, old_description.registry, old_description.token, old_description.initiator, old_description.target, state_change.secret, ) payment_state.initiator.transfer_description = transfer_description sub_iteration = handle_cancelroute( payment_state, state_change, channelidentifiers_to_channels, block_number, ) events = sub_iteration.events if sub_iteration.new_state is None: payment_state = None iteration = TransitionResult(payment_state, events) return iteration