def test_get_timeout_blocks(): amount = 10 initiator = factories.HOP1 next_hop = factories.HOP2 settle_timeout = 30 block_number = 5 route = factories.make_route( next_hop, amount, settle_timeout=settle_timeout, ) early_expire = 10 early_transfer = factories.make_transfer(amount, initiator, next_hop, early_expire) early_block = mediator.get_timeout_blocks(route, early_transfer, block_number) assert early_block == 5 - mediator.TRANSIT_BLOCKS, 'must use the lock expiration' equal_expire = 30 equal_transfer = factories.make_transfer(amount, initiator, next_hop, equal_expire) equal_block = mediator.get_timeout_blocks(route, equal_transfer, block_number) assert equal_block == 25 - mediator.TRANSIT_BLOCKS large_expire = 70 large_transfer = factories.make_transfer(amount, initiator, next_hop, large_expire) large_block = mediator.get_timeout_blocks(route, large_transfer, block_number) assert large_block == 30 - mediator.TRANSIT_BLOCKS, 'must use the settle timeout' closed_route = factories.make_route( next_hop, amount, settle_timeout=settle_timeout, closed_block=2, ) large_block = mediator.get_timeout_blocks(closed_route, large_transfer, block_number) assert large_block == 27 - mediator.TRANSIT_BLOCKS, 'must use the close block' # the computed timeout may be negative, in which case the calling code must /not/ use it negative_block_number = large_expire negative_block = mediator.get_timeout_blocks(route, large_transfer, negative_block_number) assert negative_block == -mediator.TRANSIT_BLOCKS
def test_get_timeout_blocks(): amount = 10 initiator = factories.HOP1 next_hop = factories.HOP2 settle_timeout = 30 block_number = 5 route = factories.make_route( next_hop, amount, settle_timeout=settle_timeout, ) early_expire = 10 early_transfer = factories.make_transfer(amount, initiator, next_hop, early_expire) early_block = mediator.get_timeout_blocks(route, early_transfer, block_number) assert early_block == 5 - mediator.TRANSIT_BLOCKS, 'must use the lock expiration' equal_expire = 30 equal_transfer = factories.make_transfer(amount, initiator, next_hop, equal_expire) equal_block = mediator.get_timeout_blocks(route, equal_transfer, block_number) assert equal_block == 25 - mediator.TRANSIT_BLOCKS large_expire = 70 large_transfer = factories.make_transfer(amount, initiator, next_hop, large_expire) large_block = mediator.get_timeout_blocks(route, large_transfer, block_number) assert large_block == 30 - mediator.TRANSIT_BLOCKS, 'must use the settle timeout' closed_route = factories.make_route( next_hop, amount, settle_timeout=settle_timeout, closed_block=2, ) large_block = mediator.get_timeout_blocks(closed_route, large_transfer, block_number) assert large_block == 27 - mediator.TRANSIT_BLOCKS, 'must use the close block' # the computed timeout may be negative, in which case the calling code must /not/ use it negative_block_number = large_expire negative_block = mediator.get_timeout_blocks(route, large_transfer, negative_block_number) assert negative_block == -mediator.TRANSIT_BLOCKS
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
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 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 = channel.refund_transfer_matches_received( refund_transfer, original_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