def mediated_transfer(initiator_app, target_app, asset, amount): # pylint: disable=too-many-arguments """ Nice to read shortcut to make a MediatedTransfer. The secret will be revealed and the apps will be synchronized. """ has_channel = target_app.raiden.address in initiator_app.raiden.assetmanagers[asset].channel # api.transfer() would do a DirectTransfer if has_channel: initiator_channel = channel(initiator_app, target_app, asset) secret = sha3('{}{}'.format( initiator_channel.nettingcontract_address, str(initiator_channel.our_state.nonce), )) hashlock = sha3(secret) transfermanager = target_app.raiden.assetmanagers[asset].transfermanager task = MediatedTransferTask( transfermanager, amount, target_app.address, hashlock, expiration=None, originating_transfer=None, secret=secret, ) task.start() task.join() else: initiator_app.raiden.api.transfer(asset, amount, target_app.raiden.address)
def transfer(self, amount, target, hashlock=None, secret=None, callback=None): """ Transfer `amount` between this node and `target`. This method will start a asyncronous transfer, the transfer might fail or succeed depending on a couple of factors: - Existence of a path that can be used, through the usage of direct or intermediary channels. - Network speed, making the transfer suficiently fast so it doesn't timeout. """ # either we have a direct channel with `target` if target in self.assetmanager.channels and not hashlock: channel = self.assetmanager.channels[target] direct_transfer = channel.create_directtransfer(amount, secret=secret) self.raiden.sign(direct_transfer) channel.register_transfer(direct_transfer, callback=callback) task = self.raiden.protocol.send(direct_transfer.recipient, direct_transfer) task.join() # or we need to use the network to mediate the transfer else: if not (hashlock or secret): secret = sha3(hex(random.getrandbits(256))) hashlock = sha3(secret) task = MediatedTransferTask( self, amount, target, hashlock, # FIXME: # optimum value: expiration = self.raiden.chain.block_number + channel.settle_timeout - config['reveal_timeout'] # PROBLEM: we dont know yet which channel to use! channel.settle_timeout not known # TODO: create InitMediatedTransferTask, that spawns MediatedTransfers and waits for timeout/success. # on timeout, it alters timeout/expiration arguments, handles locks and lock forwarding lock_expiration=None, originating_transfer=None, secret=secret, ) if callback: self.on_task_completed_callbacks.append(callback) task.start() task.join()
def transfer(self, amount, target, hashlock=None, secret=None, callback=None): """ Transfer `amount` between this node and `target`. This method will start a asyncronous transfer, the transfer might fail or succeed depending on a couple of factors: - Existence of a path that can be used, through the usage of direct or intermediary channels. - Network speed, making the transfer suficiently fast so it doesn't timeout. """ # either we have a direct channel with `target` if target in self.assetmanager.channels and not hashlock: channel = self.assetmanager.channels[target] direct_transfer = channel.create_directtransfer(amount, secret=secret) self.raiden.sign(direct_transfer) channel.register_transfer(direct_transfer, callback=callback) task = self.raiden.protocol.send(direct_transfer.recipient, direct_transfer) task.join() # or we need to use the network to mediate the transfer else: if not (hashlock or secret): secret = sha3(hex(random.getrandbits(256))) hashlock = sha3(secret) task = MediatedTransferTask( self, amount, target, hashlock, expiration=None, originating_transfer=None, secret=secret, ) if callback: self.on_task_completed_callbacks.append(callback) task.start() task.join()