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 on_mediatedtransfer(self, transfer): assert isinstance(transfer, MediatedTransfer) log.debug('ON MEDIATED TRANSFER', address=pex(self.raiden.address)) channel = self.assetmanager.channels[transfer.sender] channel.register_transfer(transfer) # this raises if the transfer is invalid # either we are the target of the transfer, so we need to send a # SecretRequest if transfer.target == self.raiden.address: secret_request = SecretRequest(transfer.lock.hashlock) self.raiden.sign(secret_request) self.raiden.send(transfer.initiator, secret_request) secret_request_task = ForwardSecretTask( self, transfer.lock.hashlock, recipient=transfer.sender, ) secret_request_task.start() # or we are a participating node in the network and need to keep # forwarding the MediatedTransfer else: transfer_task = MediatedTransferTask( self, transfer.lock.amount, transfer.target, transfer.lock.hashlock, originating_transfer=transfer, ) transfer_task.start()
def on_mediatedtransfer(self, transfer): assert isinstance(transfer, MediatedTransfer) log.debug('ON MEDIATED TRANSFER', address=pex(self.raiden.address)) channel = self.assetmanager.channels[transfer.sender] channel.register_transfer( transfer) # this raises if the transfer is invalid # either we are the target of the transfer, so we need to send a # SecretRequest if transfer.target == self.raiden.address: secret_request = SecretRequest(transfer.lock.hashlock) self.raiden.sign(secret_request) self.raiden.send(transfer.initiator, secret_request) secret_request_task = ForwardSecretTask( self, transfer.lock.hashlock, recipient=transfer.sender, ) secret_request_task.start() # or we are a participating node in the network and need to keep # forwarding the MediatedTransfer else: transfer_task = MediatedTransferTask( self, transfer.lock.amount, transfer.target, transfer.lock.hashlock, originating_transfer=transfer, ) transfer_task.start()
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 on_mediatedtransfer(self, transfer): assert isinstance(transfer, MediatedTransfer) log.debug('ON MEDIATED TRANSFER', address=pex(self.raiden.address)) channel = self.assetmanager.channels[transfer.sender] channel.register_transfer( transfer) # this raises if the transfer is invalid config = self.raiden.config # either we are the target of the transfer, so we need to send a # SecretRequest if transfer.target == self.raiden.address: secret_request = SecretRequest(transfer.lock.hashlock) self.raiden.sign(secret_request) self.raiden.send(transfer.initiator, secret_request) secret_request_task = ForwardSecretTask( self, transfer.lock.hashlock, recipient=transfer.sender, msg_timeout=config[ 'msg_timeout'] # FIXME additional config['secret_request_timeout'] ? ) secret_request_task.start() # or we are a participating node in the network and need to keep # forwarding the MediatedTransfer else: # subtract reveal_timeout from the lock expiration of the incoming transfer expiration = transfer.lock.expiration - config['reveal_timeout'] transfer_task = MediatedTransferTask( self, transfer.lock.amount, transfer.target, transfer.lock.hashlock, expiration, originating_transfer=transfer, ) transfer_task.start()
def on_mediatedtransfer(self, transfer): assert isinstance(transfer, MediatedTransfer) log.debug('ON MEDIATED TRANSFER', address=pex(self.raiden.address)) channel = self.assetmanager.channels[transfer.sender] channel.register_transfer(transfer) # this raises if the transfer is invalid config = self.raiden.config # either we are the target of the transfer, so we need to send a # SecretRequest if transfer.target == self.raiden.address: secret_request = SecretRequest(transfer.lock.hashlock) self.raiden.sign(secret_request) self.raiden.send(transfer.initiator, secret_request) secret_request_task = ForwardSecretTask( self, transfer.lock.hashlock, recipient=transfer.sender, msg_timeout=config['msg_timeout'] # FIXME additional config['secret_request_timeout'] ? ) secret_request_task.start() # or we are a participating node in the network and need to keep # forwarding the MediatedTransfer else: # subtract reveal_timeout from the lock expiration of the incoming transfer expiration = transfer.lock.expiration - config['reveal_timeout'] transfer_task = MediatedTransferTask( self, transfer.lock.amount, transfer.target, transfer.lock.hashlock, expiration, originating_transfer=transfer, ) transfer_task.start()
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()