def send_mediatedtransfer( initiator_state: InitiatorTransferState, channel_state: NettingChannelState, block_number: typing.BlockNumber, ) -> SendMediatedTransfer: """ Create a mediated transfer using channel. Raises: AssertionError: If the channel does not have enough capacity. """ assert channel_state.token_address == initiator_state.transfer_description.token transfer_description = initiator_state.transfer_description lock_expiration = get_initial_lock_expiration( block_number, channel_state.settle_timeout, ) mediatedtransfer_event = channel.send_mediatedtransfer( channel_state, transfer_description.initiator, transfer_description.target, transfer_description.amount, transfer_description.identifier, lock_expiration, transfer_description.hashlock, ) assert mediatedtransfer_event initiator_state.transfer = mediatedtransfer_event.transfer return mediatedtransfer_event
def test_channelstate_send_mediatedtransfer(): """Sending a mediated transfer must update the participant state. This tests only the state of the sending node, without synchronisation. """ our_model1, _ = create_model(70) partner_model1, _ = create_model(100) channel_state = create_channel_from_models(our_model1, partner_model1) lock_amount = 30 lock_expiration = 10 lock_secret = sha3(b'test_end_state') lock_hashlock = sha3(lock_secret) lock = HashTimeLockState( lock_amount, lock_expiration, lock_hashlock, ) identifier = 1 transfer_target = factories.make_address() transfer_initiator = factories.make_address() channel.send_mediatedtransfer( channel_state, transfer_initiator, transfer_target, lock_amount, identifier, lock_expiration, lock_hashlock, ) our_model2 = our_model1._replace( distributable=our_model1.distributable - lock_amount, amount_locked=lock_amount, next_nonce=2, merkletree_leaves=[lock.lockhash], ) partner_model2 = partner_model1 assert_partner_state(channel_state.our_state, channel_state.partner_state, our_model2) assert_partner_state(channel_state.partner_state, channel_state.our_state, partner_model2)
def make_mediated_transfer( from_channel, partner_channel, initiator, target, lock, pkey, secret=None ): """ Helper to create and register a mediated transfer from `from_channel` to `partner_channel`.""" identifier = channel.get_next_nonce(from_channel.our_state) mediatedtransfer = channel.send_mediatedtransfer( from_channel, initiator, target, lock.amount, identifier, lock.expiration, lock.hashlock, ) mediated_transfer_msg = MediatedTransfer.from_event(mediatedtransfer) address = privatekey_to_address(pkey) sign_key = PrivateKey(pkey) mediated_transfer_msg.sign(sign_key, address) # compute the signature balance_proof = balanceproof_from_envelope(mediated_transfer_msg) mediatedtransfer.balance_proof = balance_proof # if this fails it's not the right key for the current `from_channel` assert mediated_transfer_msg.sender == from_channel.our_state.address receive_mediatedtransfer = lockedtransfersigned_from_message(mediated_transfer_msg) channel.handle_receive_mediatedtransfer( partner_channel, receive_mediatedtransfer, ) if secret is not None: random_sender = make_address() from_secretreveal = ReceiveSecretReveal(secret, random_sender) channel.handle_receive_secretreveal(from_channel, from_secretreveal) partner_secretreveal = ReceiveSecretReveal(secret, random_sender) channel.handle_receive_secretreveal(partner_channel, partner_secretreveal) return mediated_transfer_msg
def next_transfer_pair(payer_transfer: LockedTransferSignedState, available_routes: List['RouteState'], channelidentifiers_to_channels: Dict, timeout_blocks: int, block_number: int): """ Given a payer transfer tries a new route to proceed with the mediation. Args: payer_transfer: The transfer received from the payer_channel. routes: Current available routes that may be used, it's assumed that the routes list is ordered from best to worst. timeout_blocks: Base number of available blocks used to compute the lock timeout. block_number: The current block number. """ assert timeout_blocks > 0 assert timeout_blocks <= payer_transfer.lock.expiration - block_number transfer_pair = None mediated_events = list() payee_channel = next_channel_from_routes( available_routes, channelidentifiers_to_channels, payer_transfer.lock.amount, timeout_blocks, ) if payee_channel: assert payee_channel.reveal_timeout < timeout_blocks assert payee_channel.token_address == payer_transfer.token lock_timeout = timeout_blocks - payee_channel.reveal_timeout lock_expiration = lock_timeout + block_number mediatedtransfer_event = channel.send_mediatedtransfer( payee_channel, payer_transfer.initiator, payer_transfer.target, payer_transfer.lock.amount, payer_transfer.identifier, lock_expiration, payer_transfer.lock.hashlock) assert mediatedtransfer_event transfer_pair = MediationPairState( payer_transfer, payee_channel.partner_state.address, mediatedtransfer_event.transfer, ) mediated_events = [mediatedtransfer_event] return ( transfer_pair, mediated_events, )