def initiator_init(raiden, transfer_identifier, transfer_amount, transfer_secret, token_address, target_address): registry_address = raiden.default_registry.address transfer_state = TransferDescriptionWithSecretState( transfer_identifier, transfer_amount, registry_address, token_address, raiden.address, target_address, transfer_secret, ) previous_address = None routes = routing.get_best_routes( views.state_from_raiden(raiden), registry_address, token_address, raiden.address, target_address, transfer_amount, previous_address, ) init_initiator_statechange = ActionInitInitiator2( registry_address, transfer_state, routes, ) return init_initiator_statechange
def handle_transferrefundcancelroute( payment_state: InitiatorPaymentState, state_change: ReceiveTransferRefundCancelRoute, channelidentifiers_to_channels: typing.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 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 == original_transfer.lock.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_network_identifier, 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 _(properties, defaults=None) -> TransferDescriptionWithSecretState: properties: TransferDescriptionProperties = create_properties( properties, defaults) params = {key: value for key, value in properties.__dict__.items()} if params["secret"] == GENERATE: params["secret"] = random_secret() return TransferDescriptionWithSecretState(**params)
def make_transfer_description( payment_network_identifier: typing.PaymentNetworkID = EMPTY, payment_identifier: typing.PaymentID = EMPTY, amount: typing.TokenAmount = EMPTY, token_network: typing.TokenNetworkID = EMPTY, initiator: typing.InitiatorAddress = EMPTY, target: typing.TargetAddress = EMPTY, secret: typing.Secret = EMPTY, ) -> TransferDescriptionWithSecretState: payment_network_identifier = if_empty( payment_network_identifier, UNIT_PAYMENT_NETWORK_IDENTIFIER, ) payment_identifier = if_empty(payment_identifier, UNIT_TRANSFER_IDENTIFIER) amount = if_empty(amount, UNIT_TRANSFER_AMOUNT) token_network = if_empty(token_network, UNIT_TOKEN_NETWORK_ADDRESS) initiator = if_empty(initiator, UNIT_TRANSFER_INITIATOR) target = if_empty(target, UNIT_TRANSFER_TARGET) secret = if_empty(secret, random_secret()) return TransferDescriptionWithSecretState( payment_network_identifier=payment_network_identifier, payment_identifier=payment_identifier, amount=amount, token_network_identifier=token_network, initiator=initiator, target=target, secret=secret, )
def initiator_init( raiden: 'RaidenService', transfer_identifier: PaymentID, transfer_amount: PaymentAmount, transfer_secret: Secret, token_network_identifier: TokenNetworkID, target_address: TargetAddress, ): msg = 'Should never end up initiating transfer with Secret 0x0' assert transfer_secret != constants.EMPTY_HASH, msg transfer_state = TransferDescriptionWithSecretState( raiden.default_registry.address, transfer_identifier, transfer_amount, token_network_identifier, InitiatorAddress(raiden.address), target_address, transfer_secret, ) previous_address = None routes = routing.get_best_routes( chain_state=views.state_from_raiden(raiden), token_network_id=token_network_identifier, from_address=InitiatorAddress(raiden.address), to_address=target_address, amount=transfer_amount, previous_address=previous_address, config=raiden.config, ) init_initiator_statechange = ActionInitInitiator( transfer_state, routes, ) return init_initiator_statechange
def test_initiator_task_view(): """Test transfer_tasks_view(), which is used to generate the output of the pending transfers API, with an initiator task. """ channel_id = factories.UNIT_CHANNEL_ID secret = factories.make_secret() transfer = factories.create( factories.LockedTransferUnsignedStateProperties(secret=secret)) secrethash = transfer.lock.secrethash transfer_description = TransferDescriptionWithSecretState( token_network_registry_address=factories. UNIT_TOKEN_NETWORK_REGISTRY_ADDRESS, payment_identifier=transfer.payment_identifier, amount=transfer.balance_proof.locked_amount, token_network_address=factories.UNIT_TOKEN_NETWORK_ADDRESS, initiator=transfer.initiator, target=transfer.target, secret=secret, secrethash=sha256_secrethash(secret), ) transfer_state = InitiatorTransferState( route=RouteState(route=[transfer.initiator, transfer.target], forward_channel_id=channel_id), transfer_description=transfer_description, channel_identifier=channel_id, transfer=transfer, ) payment_state = InitiatorPaymentState( routes=[], initiator_transfers={secrethash: transfer_state}) task = InitiatorTask( token_network_address=factories.UNIT_TOKEN_NETWORK_ADDRESS, manager_state=payment_state) payment_mapping = {secrethash: cast(TransferTask, task)} view = transfer_tasks_view(payment_mapping) assert len(view) == 1 pending_transfer = view[0] assert pending_transfer.get("role") == "initiator" balance_proof = transfer.balance_proof assert pending_transfer.get("channel_identifier") == str( balance_proof.channel_identifier) assert pending_transfer.get("locked_amount") == str( balance_proof.locked_amount) assert pending_transfer.get("transferred_amount") == str( balance_proof.transferred_amount)
def test_initiator_task_view(): """Test transfer_tasks_view(), which is used to generate the output of the pending transfers API, with an initiator task. """ channel_id = factories.UNIT_CHANNEL_ID secret = factories.make_secret() payment_hash_invoice = factories.make_payment_hash_invoice() transfer = factories.create( factories.LockedTransferUnsignedStateProperties( secret=secret, payment_hash_invoice=payment_hash_invoice)) secrethash = transfer.lock.secrethash transfer_description = TransferDescriptionWithSecretState( payment_network_identifier=factories.UNIT_PAYMENT_NETWORK_IDENTIFIER, payment_identifier=transfer.payment_identifier, payment_hash_invoice=transfer.payment_hash_invoice, amount=transfer.balance_proof.locked_amount, allocated_fee=0, token_network_identifier=factories.UNIT_TOKEN_NETWORK_ADDRESS, initiator=transfer.initiator, target=transfer.target, secret=secret, ) transfer_state = InitiatorTransferState( transfer_description=transfer_description, channel_identifier=channel_id, transfer=transfer, revealsecret=None, ) payment_state = InitiatorPaymentState({secrethash: transfer_state}) task = InitiatorTask( token_network_identifier=factories.UNIT_TOKEN_NETWORK_ADDRESS, manager_state=payment_state) payment_mapping = {secrethash: task} view = transfer_tasks_view(payment_mapping) assert len(view) == 1 pending_transfer = view[0] assert pending_transfer.get("role") == "initiator" balance_proof = transfer.balance_proof assert pending_transfer.get("channel_identifier") == str( balance_proof.channel_identifier) assert pending_transfer.get("locked_amount") == str( balance_proof.locked_amount) assert pending_transfer.get("transferred_amount") == str( balance_proof.transferred_amount)
def make_transfer_description( payment_network_identifier=UNIT_PAYMENT_NETWORK_IDENTIFIER, payment_identifier=UNIT_TRANSFER_IDENTIFIER, amount=UNIT_TRANSFER_AMOUNT, token_network=UNIT_TOKEN_NETWORK_ADDRESS, initiator=UNIT_TRANSFER_INITIATOR, target=UNIT_TRANSFER_TARGET, secret=None, ): return TransferDescriptionWithSecretState( payment_network_identifier=payment_network_identifier, payment_identifier=payment_identifier, amount=amount, token_network_identifier=token_network, initiator=initiator, target=target, secret=secret or random_secret(), )
def make_transfer_description(amount, secret, identifier, initiator=None, target=None, token_address=UNIT_TOKEN_ADDRESS, registry=UNIT_REGISTRY_IDENTIFIER): initiator = initiator or make_address() target = target or make_address() transfer_description = TransferDescriptionWithSecretState( identifier, amount, registry, token_address, initiator, target, secret, ) return transfer_description
def initiator_init( raiden: 'RaidenService', transfer_identifier: PaymentID, transfer_amount: PaymentAmount, transfer_secret: Secret, transfer_fee: FeeAmount, token_network_identifier: TokenNetworkID, target_address: TargetAddress, ): assert transfer_secret != constants.EMPTY_HASH, f'Empty secret node:{raiden!r}' transfer_state = TransferDescriptionWithSecretState( payment_network_identifier=raiden.default_registry.address, payment_identifier=transfer_identifier, amount=transfer_amount, allocated_fee=transfer_fee, token_network_identifier=token_network_identifier, initiator=InitiatorAddress(raiden.address), target=target_address, secret=transfer_secret, ) previous_address = None routes = routing.get_best_routes( chain_state=views.state_from_raiden(raiden), token_network_id=token_network_identifier, from_address=InitiatorAddress(raiden.address), to_address=target_address, amount=transfer_amount, previous_address=previous_address, config=raiden.config, privkey=raiden.privkey, ) init_initiator_statechange = ActionInitInitiator( transfer_state, routes, ) return init_initiator_statechange
UNIT_SECRET = b'secretsecretsecretsecretsecretse' UNIT_SECRETHASH = sha3(UNIT_SECRET) UNIT_REGISTRY_IDENTIFIER = b'registryregistryregi' UNIT_TOKEN_ADDRESS = b'tokentokentokentoken' UNIT_CHANNEL_ADDRESS = b'channelchannelchanne' UNIT_TRANSFER_IDENTIFIER = 37 UNIT_TRANSFER_INITIATOR = b'initiatorinitiatorin' UNIT_TRANSFER_TARGET = b'targettargettargetta' UNIT_TRANSFER_DESCRIPTION = TransferDescriptionWithSecretState( UNIT_TRANSFER_IDENTIFIER, UNIT_TRANSFER_AMOUNT, UNIT_REGISTRY_IDENTIFIER, UNIT_TOKEN_ADDRESS, UNIT_TRANSFER_INITIATOR, UNIT_TRANSFER_TARGET, UNIT_SECRET, ) UNIT_TRANSFER_PKEY_BIN = sha3(b'transfer pkey') UNIT_TRANSFER_PKEY = PrivateKey(UNIT_TRANSFER_PKEY_BIN) UNIT_TRANSFER_SENDER = privatekey_to_address(sha3(b'transfer pkey')) HOP1_KEY = PrivateKey(b'11111111111111111111111111111111') HOP2_KEY = PrivateKey(b'22222222222222222222222222222222') HOP3_KEY = PrivateKey(b'33333333333333333333333333333333') HOP4_KEY = PrivateKey(b'44444444444444444444444444444444') HOP5_KEY = PrivateKey(b'55555555555555555555555555555555') HOP6_KEY = PrivateKey(b'66666666666666666666666666666666') HOP1 = privatekey_to_address(b'11111111111111111111111111111111')
def handle_transferrefundcancelroute( payment_state: InitiatorPaymentState, state_change: ReceiveTransferRefundCancelRoute, channelidentifiers_to_channels: ChannelMap, pseudo_random_generator: random.Random, block_number: BlockNumber, ) -> TransitionResult[InitiatorPaymentState]: initiator_state = payment_state.initiator_transfers.get( state_change.transfer.lock.secrethash) if not initiator_state: return TransitionResult(payment_state, list()) channel_identifier = initiator_state.channel_identifier channel_state = channelidentifiers_to_channels.get(channel_identifier) if not channel_state: return TransitionResult(payment_state, list()) refund_transfer = state_change.transfer original_transfer = initiator_state.transfer 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 == original_transfer.lock.expiration) is_valid_refund = channel.refund_transfer_matches_transfer( refund_transfer, original_transfer) events = list() if not is_valid_lock or not is_valid_refund: return TransitionResult(payment_state, list()) is_valid, channel_events, _ = channel.handle_receive_refundtransfercancelroute( channel_state, refund_transfer) events.extend(channel_events) if not is_valid: return TransitionResult(payment_state, list()) route_failed_event = EventRouteFailed( secrethash=original_transfer.lock.secrethash) events.append(route_failed_event) old_description = initiator_state.transfer_description transfer_description = TransferDescriptionWithSecretState( payment_network_identifier=old_description.payment_network_identifier, payment_identifier=old_description.payment_identifier, amount=old_description.amount, token_network_identifier=old_description.token_network_identifier, allocated_fee=old_description.allocated_fee, initiator=old_description.initiator, target=old_description.target, secret=state_change.secret, ) sub_iteration = maybe_try_new_route( payment_state=payment_state, initiator_state=initiator_state, transfer_description=transfer_description, available_routes=state_change.routes, channelidentifiers_to_channels=channelidentifiers_to_channels, pseudo_random_generator=pseudo_random_generator, block_number=block_number, ) events.extend(sub_iteration.events) 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 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_transferreroute( payment_state: InitiatorPaymentState, state_change: ActionTransferReroute, channelidentifiers_to_channels: Dict[ChannelID, NettingChannelState], addresses_to_channel: Dict[Tuple[TokenNetworkAddress, Address], NettingChannelState], nodeaddresses_to_networkstates: NodeNetworkStateMap, pseudo_random_generator: random.Random, block_number: BlockNumber, ) -> TransitionResult[InitiatorPaymentState]: try: initiator_state = payment_state.initiator_transfers[ state_change.transfer.lock.secrethash] channel_identifier = initiator_state.channel_identifier channel_state = channelidentifiers_to_channels[channel_identifier] except KeyError: return TransitionResult(payment_state, list()) refund_transfer = state_change.transfer original_transfer = initiator_state.transfer 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 == original_transfer.lock.expiration) is_valid_refund = channel.refund_transfer_matches_transfer( refund_transfer, original_transfer) is_valid, channel_events, _ = channel.handle_receive_lockedtransfer( channel_state, refund_transfer) if not is_valid_lock or not is_valid_refund or not is_valid: return TransitionResult(payment_state, list()) events: List[Event] = [] events.extend(channel_events) old_description = initiator_state.transfer_description filtered_route_states = routes.filter_acceptable_routes( route_states=payment_state.routes, blacklisted_channel_ids=payment_state.cancelled_channels, addresses_to_channel=addresses_to_channel, token_network_address=old_description.token_network_address, ) transfer_description = TransferDescriptionWithSecretState( token_network_registry_address=old_description. token_network_registry_address, payment_identifier=old_description.payment_identifier, amount=old_description.amount, token_network_address=old_description.token_network_address, initiator=old_description.initiator, target=old_description.target, secret=state_change.secret, secrethash=state_change.secrethash, ) sub_iteration = initiator.try_new_route( addresses_to_channel=addresses_to_channel, nodeaddresses_to_networkstates=nodeaddresses_to_networkstates, candidate_route_states=filtered_route_states, transfer_description=transfer_description, pseudo_random_generator=pseudo_random_generator, block_number=block_number, ) events.extend(sub_iteration.events) if sub_iteration.new_state is None: # Here we don't delete the initiator state, but instead let it live. # It will be deleted when the lock expires. We do that so that we # still have an initiator payment task around to process the # LockExpired message that our partner will send us. # https://github.com/raiden-network/raiden/issues/3146#issuecomment-447378046 return TransitionResult(payment_state, events) new_transfer = sub_iteration.new_state.transfer payment_state.initiator_transfers[ new_transfer.lock.secrethash] = sub_iteration.new_state return TransitionResult(payment_state, events)
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