def test_channel_must_accept_expired_locks():
    """ A node may go offline for an undetermined period of time, and when it
    comes back online it must accept the messages that are waiting, otherwise
    the partner node won't make progress with its queue.

    If a N node goes offline for a number B of blocks, and the partner does not
    close the channel, when N comes back online some of the messages from its
    partner may become expired. Neverthless these messages are ordered and must
    be accepted for the partner to make progress with its queue.

    Note: Accepting a message with an expired lock does *not* imply the token
    transfer happened, and the receiver node must *not* forward the transfer,
    only accept the message allowing the partner to progress with its message
    queue.
    """
    balance1 = 70
    balance2 = 110
    reveal_timeout = 5
    settle_timeout = 15
    privkey1, address1 = make_privkey_address()
    privkey2, address2 = make_privkey_address()
    token_address = make_address()

    our_state = ChannelEndState(
        address1,
        balance1,
        None,
        EMPTY_MERKLE_TREE,
    )
    partner_state = ChannelEndState(
        address2,
        balance2,
        None,
        EMPTY_MERKLE_TREE,
    )
    external_state = make_external_state()

    test_channel = Channel(
        our_state,
        partner_state,
        external_state,
        token_address,
        reveal_timeout,
        settle_timeout,
    )

    block_number = 10
    transfer = make_mediated_transfer(
        nonce=test_channel.get_next_nonce(),
        token=test_channel.token_address,
        channel=test_channel.channel_address,
        expiration=block_number + settle_timeout,
        recipient=address1,
    )
    transfer.sign(privkey2, address2)

    test_channel.register_transfer(
        block_number + settle_timeout + 1,
        transfer,
    )
Esempio n. 2
0
def test_channel_must_accept_expired_locks():
    """ A node may go offline for an undetermined period of time, and when it
    comes back online it must accept the messages that are waiting, otherwise
    the partner node won't make progress with its queue.

    If a N node goes offline for a number B of blocks, and the partner does not
    close the channel, when N comes back online some of the messages from its
    partner may become expired. Neverthless these messages are ordered and must
    be accepted for the partner to make progress with its queue.

    Note: Accepting a message with an expired lock does *not* imply the token
    transfer happened, and the receiver node must *not* forward the transfer,
    only accept the message allowing the partner to progress with its message
    queue.
    """
    balance1 = 70
    balance2 = 110
    reveal_timeout = 5
    settle_timeout = 15
    privkey1, address1 = make_privkey_address()
    privkey2, address2 = make_privkey_address()
    token_address = make_address()

    our_state = ChannelEndState(
        address1,
        balance1,
        None,
        EMPTY_MERKLE_TREE,
    )
    partner_state = ChannelEndState(
        address2,
        balance2,
        None,
        EMPTY_MERKLE_TREE,
    )
    external_state = make_external_state()

    test_channel = Channel(
        our_state,
        partner_state,
        external_state,
        token_address,
        reveal_timeout,
        settle_timeout,
    )

    block_number = 10
    transfer = make_mediated_transfer(
        nonce=test_channel.get_next_nonce(),
        token=test_channel.token_address,
        channel=test_channel.channel_address,
        expiration=block_number + settle_timeout,
        recipient=address1,
    )
    transfer.sign(privkey2, address2)

    test_channel.register_transfer(
        block_number + settle_timeout + 1,
        transfer,
    )
Esempio n. 3
0
    def initialize(self, block_number, random, random_seed):
        self.random_seed = random_seed

        self.block_number = block_number
        self.block_hash = factories.make_block_hash()
        self.random = random
        self.private_key, self.address = factories.make_privkey_address()

        self.chain_state = ChainState(
            pseudo_random_generator=self.random,
            block_number=self.block_number,
            block_hash=self.block_hash,
            our_address=self.address,
            chain_id=factories.UNIT_CHAIN_ID,
        )

        self.token_network_id = factories.UNIT_TOKEN_NETWORK_ADDRESS
        self.token_id = factories.UNIT_TOKEN_ADDRESS
        self.token_network_state = TokenNetworkState(self.token_network_id,
                                                     self.token_id)

        self.payment_network_id = factories.make_payment_network_identifier()
        self.payment_network_state = PaymentNetworkState(
            self.payment_network_id, [self.token_network_state])

        self.chain_state.identifiers_to_paymentnetworks[
            self.payment_network_id] = self.payment_network_state

        self.chain_state.tokennetworkaddresses_to_paymentnetworkaddresses[
            self.token_network_id] = self.payment_network_id
        channels = [
            self.new_channel_with_transaction()
            for _ in range(self.initial_number_of_channels)
        ]
        return multiple(*channels)
def test_signature_split(tester_chain, tester_nettingchannel_library_address):
    auxiliary = deploy_auxiliary_tester(tester_chain,
                                        tester_nettingchannel_library_address)

    privkey, address = make_privkey_address()
    message_identifier = random.randint(0, UINT64_MAX)
    msg = DirectTransfer(message_identifier=message_identifier,
                         payment_identifier=1,
                         nonce=1,
                         registry_address='x' * 20,
                         token='x' * 20,
                         channel=auxiliary.address,
                         transferred_amount=10,
                         recipient='y' * 20,
                         locksroot=HASH)
    msg.sign(privkey, address)
    msg = msg.encode()
    # signature = len(msg) - 65
    signature = msg[len(msg) - 65:]

    signature = signature[:-1] + chr(27).encode()
    r, s, v = auxiliary.signatureSplit(signature)
    assert v == 27
    assert r == signature[:32]
    assert s == signature[32:64]

    signature = signature[:-1] + chr(28).encode()
    _, _, v = auxiliary.signatureSplit(signature)
    assert v == 28

    with pytest.raises(TransactionFailed):
        signature = signature[:-1] + chr(4).encode()
        r, s, v = auxiliary.signatureSplit(signature)
def test_recoverAddressFromSignature(tester_chain,
                                     tester_nettingchannel_library_address):
    auxiliary = deploy_auxiliary_tester(tester_chain,
                                        tester_nettingchannel_library_address)
    privkey, address = make_privkey_address()

    message_identifier = random.randint(0, UINT64_MAX)
    msg = DirectTransfer(message_identifier=message_identifier,
                         payment_identifier=1,
                         nonce=1,
                         registry_address='x' * 20,
                         token='x' * 20,
                         channel=auxiliary.address,
                         transferred_amount=10,
                         recipient='y' * 20,
                         locksroot=HASH)
    msg.sign(privkey, address)
    data = msg.encode()
    signature = data[-65:]
    extra_hash = sha3(data[:-65])

    computed_address = auxiliary.recoverAddressFromSignature(
        msg.nonce, msg.transferred_amount, msg.locksroot, extra_hash,
        signature)

    assert normalize_address(computed_address) == msg.sender
Esempio n. 6
0
    def initialize(self, block_number, random, random_seed):
        self.random_seed = random_seed

        self.block_number = block_number
        self.block_hash = factories.make_block_hash()
        self.random = random
        self.private_key, self.address = factories.make_privkey_address()

        self.chain_state = ChainState(
            pseudo_random_generator=self.random,
            block_number=self.block_number,
            block_hash=self.block_hash,
            our_address=self.address,
            chain_id=factories.UNIT_CHAIN_ID,
        )

        self.token_network_id = factories.make_address()
        self.token_id = factories.make_address()
        self.token_network_state = TokenNetworkState(self.token_network_id,
                                                     self.token_id)

        self.payment_network_id = factories.make_payment_network_identifier()
        self.payment_network_state = PaymentNetworkState(
            self.payment_network_id,
            [self.token_network_state],
        )

        self.chain_state.identifiers_to_paymentnetworks[
            self.payment_network_id] = self.payment_network_state

        return self.new_channel_with_transaction()
def test_signature_split(tester_chain, tester_nettingchannel_library_address):
    auxiliary = deploy_auxiliary_tester(tester_chain, tester_nettingchannel_library_address)

    privkey, address = make_privkey_address()
    msg = DirectTransfer(
        identifier=1,
        nonce=1,
        token='x' * 20,
        channel=auxiliary.address,
        transferred_amount=10,
        recipient='y' * 20,
        locksroot=HASH
    )
    msg.sign(privkey, address)
    msg = msg.encode()
    # signature = len(msg) - 65
    signature = msg[len(msg) - 65:]

    signature = signature[:-1] + chr(27).encode()
    r, s, v = auxiliary.signatureSplit(signature)
    assert v == 27
    assert r == signature[:32]
    assert s == signature[32:64]

    signature = signature[:-1] + chr(28).encode()
    _, _, v = auxiliary.signatureSplit(signature)
    assert v == 28

    with pytest.raises(TransactionFailed):
        signature = signature[:-1] + chr(4).encode()
        r, s, v = auxiliary.signatureSplit(signature)
Esempio n. 8
0
    def initialize(self, block_number, random, random_seed):
        self.random_seed = random_seed

        self.block_number = block_number
        self.random = random
        self.private_key, self.address = factories.make_privkey_address()

        self.chain_state = ChainState(
            self.random,
            self.block_number,
            self.address,
            factories.UNIT_CHAIN_ID,
        )

        self.token_network_id = factories.make_address()
        self.token_id = factories.make_address()
        self.token_network_state = TokenNetworkState(self.token_network_id, self.token_id)

        self.payment_network_id = factories.make_payment_network_identifier()
        self.payment_network_state = PaymentNetworkState(
            self.payment_network_id,
            [self.token_network_state],
        )

        self.chain_state.identifiers_to_paymentnetworks[
            self.payment_network_id
        ] = self.payment_network_state

        return self.new_channel_with_transaction()
Esempio n. 9
0
    def __init__(self,
                 message_handler=None,
                 state_transition=None,
                 private_key=None):
        if private_key is None:
            self.private_key, self.address = factories.make_privkey_address()
        else:
            self.private_key = private_key
            self.address = privatekey_to_address(private_key)

        self.chain = MockChain(network_id=17, node_address=self.address)
        self.signer = LocalSigner(self.private_key)

        self.message_handler = message_handler

        self.user_deposit = Mock()

        if state_transition is None:
            state_transition = node.state_transition

        serializer = JSONSerializer
        state_manager = StateManager(state_transition, None)
        storage = SerializedSQLiteStorage(":memory:", serializer)
        self.wal = WriteAheadLog(state_manager, storage)

        state_change = ActionInitChain(
            pseudo_random_generator=random.Random(),
            block_number=0,
            block_hash=factories.make_block_hash(),
            our_address=self.chain.node_address,
            chain_id=self.chain.network_id,
        )

        self.wal.log_and_dispatch(state_change)
def test_recoverAddressFromSignature(tester_chain, tester_nettingchannel_library_address):
    auxiliary = deploy_auxiliary_tester(tester_chain, tester_nettingchannel_library_address)
    privkey, address = make_privkey_address()

    msg = DirectTransfer(
        identifier=1,
        nonce=1,
        token='x' * 20,
        channel=auxiliary.address,
        transferred_amount=10,
        recipient='y' * 20,
        locksroot=HASH
    )
    msg.sign(privkey, address)
    data = msg.encode()
    signature = data[-65:]
    extra_hash = sha3(data[:-65])

    computed_address = auxiliary.recoverAddressFromSignature(
        msg.nonce,
        msg.transferred_amount,
        msg.locksroot,
        extra_hash,
        signature
    )

    assert normalize_address(computed_address) == msg.sender
def test_receive_directtransfer_invalidsender(raiden_network, deposit,
                                              token_addresses):
    app0, app1 = raiden_network
    registry = app0.raiden.default_registry.address
    token_address = token_addresses[0]
    other_key, other_address = make_privkey_address()

    channel0 = get_channelstate(app0, app1, token_address)
    channel_identifier = channel0.identifier
    message_identifier = random.randint(0, UINT64_MAX)

    direct_transfer_message = DirectTransfer(
        message_identifier=message_identifier,
        payment_identifier=1,
        nonce=1,
        registry_address=registry,
        token=token_address,
        channel=channel_identifier,
        transferred_amount=10,
        recipient=app0.raiden.address,
        locksroot=EMPTY_MERKLE_ROOT,
    )

    sign_and_inject(
        direct_transfer_message,
        other_key,
        other_address,
        app0,
    )

    assert_synched_channel_state(token_address, app0, deposit, [], app1,
                                 deposit, [])
Esempio n. 12
0
def test_refund_transfer_no_more_routes():
    amount = UNIT_TRANSFER_AMOUNT
    block_number = 1
    refund_pkey, refund_address = factories.make_privkey_address()

    channel1 = factories.make_channel(
        our_balance=amount,
        partner_balance=amount,
        our_address=UNIT_TRANSFER_INITIATOR,
        partner_address=refund_address,
        token_address=UNIT_TOKEN_ADDRESS,
    )
    channelmap = {channel1.identifier: channel1}
    available_routes = [factories.route_from_channel(channel1)]

    current_state = make_initiator_state(
        available_routes,
        factories.UNIT_TRANSFER_DESCRIPTION,
        channelmap,
        block_number,
    )

    original_transfer = current_state.initiator.transfer
    channel_identifier = current_state.initiator.channel_identifier
    channel_state = channelmap[channel_identifier]

    expiration = original_transfer.lock.expiration - channel_state.reveal_timeout - TRANSIT_BLOCKS
    refund_transfer = factories.make_signed_transfer(
        amount,
        original_transfer.initiator,
        original_transfer.target,
        expiration,
        UNIT_SECRET,
        identifier=original_transfer.identifier,
        channel_identifier=channel1.identifier,
        pkey=refund_pkey,
        sender=refund_address,
    )

    state_change = ReceiveTransferRefundCancelRoute(
        sender=channel_state.partner_state.address,
        routes=available_routes,
        transfer=refund_transfer,
        secret=random_secret(),
    )

    iteration = initiator_manager.state_transition(
        current_state,
        state_change,
        channelmap,
        block_number,
    )
    assert iteration.new_state is None
    assert len(iteration.events) == 2

    unlocked_failed = next(e for e in iteration.events if isinstance(e, EventUnlockFailed))
    sent_failed = next(e for e in iteration.events if isinstance(e, EventTransferSentFailed))

    assert unlocked_failed
    assert sent_failed
Esempio n. 13
0
def test_waiting_messages(pathfinding_service_mock):
    participant1_privkey, participant1 = make_privkey_address()
    token_network_address = TokenNetworkAddress(b"1" * 20)
    channel_id = ChannelID(1)

    # register token network internally
    database = pathfinding_service_mock.database
    database.conn.execute(
        "INSERT INTO token_network(address) VALUES (?)",
        [to_checksum_address(token_network_address)],
    )

    fee_update = PFSFeeUpdate(
        canonical_identifier=CanonicalIdentifier(
            chain_identifier=ChainID(1),
            token_network_address=token_network_address,
            channel_identifier=channel_id,
        ),
        updating_participant=participant1,
        fee_schedule=FeeScheduleState(),
        timestamp=datetime.utcnow(),
        signature=EMPTY_SIGNATURE,
    )
    fee_update.sign(LocalSigner(participant1_privkey))

    capacity_update = PFSCapacityUpdate(
        canonical_identifier=CanonicalIdentifier(
            chain_identifier=ChainID(1),
            token_network_address=token_network_address,
            channel_identifier=channel_id,
        ),
        updating_participant=make_address(),
        other_participant=make_address(),
        updating_nonce=Nonce(1),
        other_nonce=Nonce(1),
        updating_capacity=TokenAmount(100),
        other_capacity=TokenAmount(111),
        reveal_timeout=50,
        signature=EMPTY_SIGNATURE,
    )
    capacity_update.sign(LocalSigner(participant1_privkey))

    for message in (fee_update, capacity_update):
        database.insert_waiting_message(message)

        recovered_messages = list(
            database.pop_waiting_messages(
                token_network_address=token_network_address, channel_id=channel_id
            )
        )
        assert len(recovered_messages) == 1
        assert message == recovered_messages[0]

        recovered_messages2 = list(
            database.pop_waiting_messages(
                token_network_address=token_network_address, channel_id=channel_id
            )
        )
        assert len(recovered_messages2) == 0
Esempio n. 14
0
def channel_properties(our_address, token_network_state):
    partner_privkey, address = factories.make_privkey_address()
    properties = factories.NettingChannelStateProperties(
        our_state=factories.NettingChannelEndStateProperties(balance=80, address=our_address),
        partner_state=factories.NettingChannelEndStateProperties(balance=80, address=address),
        canonical_identifier=factories.make_canonical_identifier(
            token_network_address=token_network_state.address
        ),
    )
    return properties, partner_privkey
Esempio n. 15
0
def test_channel_close_called_only_once():
    class MockCheckCallsToClose():
        def __init__(self):
            self.address = 'mockcheckcallstoclosemockcheckcallstoclo'
            self.close_calls = 0

        def opened(self):
            return 1

        def closed(self):
            return 0

        def settled(self):
            return 0

        def close(self, nonce, transferred_amount, locksroot, extra_hash,
                  signature):
            self.close_calls += 1

    netting_channel = NettingChannelMock()
    token_address = make_address()
    privkey1, address1 = make_privkey_address()
    address2 = make_address()

    balance1 = 70
    balance2 = 110

    reveal_timeout = 5
    settle_timeout = 15

    our_state = ChannelEndState(address1, balance1, netting_channel.opened())
    partner_state = ChannelEndState(address2, balance2,
                                    netting_channel.opened())

    channel_for_hashlock = list()
    netting_channel = MockCheckCallsToClose()

    external_state = ChannelExternalState(
        lambda *args: channel_for_hashlock.append(args),
        netting_channel,
    )

    test_channel = Channel(
        our_state,
        partner_state,
        external_state,
        token_address,
        reveal_timeout,
        settle_timeout,
    )

    test_channel.external_state.close('')
    test_channel.external_state.close('')

    assert netting_channel.close_calls == 1
def test_receive_lockedtransfer_invalidsender(
    raiden_network,
    token_addresses,
    deposit,
    reveal_timeout,
):

    app0, app1 = raiden_network
    token_address = token_addresses[0]
    other_key, other_address = make_privkey_address()

    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        app0.raiden.default_registry.address,
        token_address,
    )
    channel0 = get_channelstate(app0, app1, token_network_identifier)
    lock_amount = 10
    expiration = reveal_timeout * 2
    mediated_transfer_message = LockedTransfer(
        chain_id=UNIT_CHAIN_ID,
        message_identifier=random.randint(0, UINT64_MAX),
        payment_identifier=1,
        nonce=1,
        token_network_address=token_network_identifier,
        token=token_address,
        channel_identifier=channel0.identifier,
        transferred_amount=0,
        locked_amount=lock_amount,
        recipient=app0.raiden.address,
        locksroot=UNIT_SECRETHASH,
        lock=Lock(amount=lock_amount,
                  expiration=expiration,
                  secrethash=UNIT_SECRETHASH),
        target=app0.raiden.address,
        initiator=other_address,
        fee=0,
    )

    sign_and_inject(
        mediated_transfer_message,
        LocalSigner(other_key),
        app0,
    )

    assert_synced_channel_state(
        token_network_identifier,
        app0,
        deposit,
        [],
        app1,
        deposit,
        [],
    )
Esempio n. 17
0
def test_initiator_handle_contract_receive_secret_reveal():
    """ Make sure the initiator handles ContractReceiveSecretReveal
    and checks the existence of the transfer's secrethash in
    secrethashes_to_lockedlocks and secrethashes_to_onchain_unlockedlocks. """
    amount = UNIT_TRANSFER_AMOUNT * 2
    block_number = 1
    refund_pkey, refund_address = factories.make_privkey_address()
    pseudo_random_generator = random.Random()

    channel1 = factories.make_channel(
        our_balance=amount,
        token_address=UNIT_TOKEN_ADDRESS,
        token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS,
    )
    pseudo_random_generator = random.Random()

    channel_map = {
        channel1.identifier: channel1,
    }

    available_routes = [
        factories.route_from_channel(channel1),
    ]

    block_number = 10
    current_state = make_initiator_manager_state(
        routes=available_routes,
        transfer_description=factories.UNIT_TRANSFER_DESCRIPTION,
        channel_map=channel_map,
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_number,
    )

    transfer = current_state.initiator.transfer

    assert transfer.lock.secrethash in channel1.our_state.secrethashes_to_lockedlocks

    state_change = ContractReceiveSecretReveal(
        transaction_hash=factories.make_transaction_hash(),
        secret_registry_address=factories.make_address(),
        secrethash=transfer.lock.secrethash,
        secret=UNIT_SECRET,
    )

    initiator_manager.handle_onchain_secretreveal(
        payment_state=current_state,
        state_change=state_change,
        channelidentifiers_to_channels=channel_map,
        pseudo_random_generator=pseudo_random_generator,
    )

    assert transfer.lock.secrethash in channel1.our_state.secrethashes_to_lockedlocks
    assert transfer.lock.secrethash in channel1.our_state.secrethashes_to_onchain_unlockedlocks
def test_channel_close_called_only_once():
    class MockCheckCallsToClose:
        def __init__(self):
            self.address = 'mockcheckcallstoclosemockcheckcallstoclo'
            self.close_calls = 0

        def opened(self):
            return 1

        def closed(self):
            return 0

        def close(self, nonce, transferred_amount, locksroot, extra_hash, signature):
            self.close_calls += 1

    netting_channel = NettingChannelMock()
    token_address = make_address()
    privkey1, address1 = make_privkey_address()
    address2 = make_address()

    balance1 = 70
    balance2 = 110

    reveal_timeout = 5
    settle_timeout = 15

    our_state = ChannelEndState(address1, balance1, None, EMPTY_MERKLE_TREE)
    partner_state = ChannelEndState(address2, balance2, None, EMPTY_MERKLE_TREE)

    channel_for_hashlock = list()
    netting_channel = MockCheckCallsToClose()

    external_state = ChannelExternalState(
        lambda *args: channel_for_hashlock.append(args),
        netting_channel,
    )

    test_channel = Channel(
        our_state,
        partner_state,
        external_state,
        token_address,
        reveal_timeout,
        settle_timeout,
    )

    test_channel.external_state.close(None)
    test_channel.external_state.close(None)

    assert netting_channel.close_calls == 1
Esempio n. 19
0
def create_model(balance):
    privkey, address = factories.make_privkey_address()

    our_model = PartnerStateModel(
        participant_address=address,
        amount_locked=0,
        balance=balance,
        distributable=balance,
        next_nonce=1,
        merkletree_leaves=[],
        contract_balance=balance,
    )

    return our_model, privkey
def test_receive_lockedtransfer_invalidsender(
        raiden_network,
        token_addresses,
        deposit,
        reveal_timeout,
):

    app0, app1 = raiden_network
    token_address = token_addresses[0]
    other_key, other_address = make_privkey_address()

    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        app0.raiden.default_registry.address,
        token_address,
    )
    channel0 = get_channelstate(app0, app1, token_network_identifier)
    lock_amount = 10
    expiration = reveal_timeout * 2
    mediated_transfer_message = LockedTransfer(
        chain_id=UNIT_CHAIN_ID,
        message_identifier=random.randint(0, UINT64_MAX),
        payment_identifier=1,
        nonce=1,
        token_network_address=token_network_identifier,
        token=token_address,
        channel_identifier=channel0.identifier,
        transferred_amount=0,
        locked_amount=lock_amount,
        recipient=app0.raiden.address,
        locksroot=UNIT_SECRETHASH,
        lock=Lock(lock_amount, expiration, UNIT_SECRETHASH),
        target=app0.raiden.address,
        initiator=other_address,
        fee=0,
    )

    sign_and_inject(
        mediated_transfer_message,
        other_key,
        other_address,
        app0,
    )

    assert_synced_channel_state(
        token_network_identifier,
        app0, deposit, [],
        app1, deposit, [],
    )
Esempio n. 21
0
def test_update_pfs():
    properties = factories.BalanceProofSignedStateProperties(pkey=PRIVKEY)
    balance_proof = factories.create(properties)
    channel_state = factories.create(factories.NettingChannelStateProperties())
    channel_state.our_state.balance_proof = balance_proof
    channel_state.partner_state.balance_proof = balance_proof
    message = UpdatePFS.from_channel_state(channel_state=channel_state)

    assert message.signature == b""
    privkey2, address2 = factories.make_privkey_address()
    signer2 = LocalSigner(privkey2)
    message.sign(signer2)
    assert recover(message._data_to_sign(), message.signature) == address2

    assert message == UpdatePFS.from_dict(message.to_dict())
Esempio n. 22
0
def test_update_pfs():
    balance_proof = make_balance_proof(signer=signer, amount=1)

    channel_state = make_channel_state()
    channel_state.our_state.balance_proof = balance_proof
    channel_state.partner_state.balance_proof = balance_proof
    message = UpdatePFS.from_channel_state(channel_state=channel_state)

    assert message.signature == b''
    privkey2, address2 = make_privkey_address()
    signer2 = LocalSigner(privkey2)
    message.sign(signer2)
    assert recover(message._data_to_sign(), message.signature) == address2

    assert message == UpdatePFS.from_dict(message.to_dict())
def test_receive_directtransfer_unknown(raiden_network):
    app0 = raiden_network[0]  # pylint: disable=unbalanced-tuple-unpacking
    graph0 = app0.raiden.token_to_channelgraph.values()[0]

    other_key, other_address = make_privkey_address()
    direct_transfer_message = DirectTransfer(
        identifier=1,
        nonce=1,
        token=graph0.token_address,
        channel=other_address,
        transferred_amount=10,
        recipient=app0.raiden.address,
        locksroot=UNIT_HASHLOCK,
    )
    sign_and_send(direct_transfer_message, other_key, other_address, app0)
def test_receive_directtransfer_unknown(raiden_network):
    app0 = raiden_network[0]  # pylint: disable=unbalanced-tuple-unpacking
    graph0 = list(app0.raiden.token_to_channelgraph.values())[0]

    other_key, other_address = make_privkey_address()
    direct_transfer_message = DirectTransfer(
        identifier=1,
        nonce=1,
        token=graph0.token_address,
        channel=other_address,
        transferred_amount=10,
        recipient=app0.raiden.address,
        locksroot=UNIT_HASHLOCK,
    )
    sign_and_send(direct_transfer_message, other_key, other_address, app0)
Esempio n. 25
0
def test_update_pfs():
    properties = factories.BalanceProofSignedStateProperties(pkey=PRIVKEY)
    balance_proof = factories.create(properties)
    channel_state = factories.create(factories.NettingChannelStateProperties())
    channel_state.our_state.balance_proof = balance_proof
    channel_state.partner_state.balance_proof = balance_proof
    message = PFSCapacityUpdate.from_channel_state(channel_state=channel_state)

    assert message.signature == EMPTY_SIGNATURE
    privkey2, address2 = factories.make_privkey_address()
    signer2 = LocalSigner(privkey2)
    message.sign(signer2)
    assert recover(message._data_to_sign(), message.signature) == address2

    assert message == DictSerializer.deserialize(DictSerializer.serialize(message))
Esempio n. 26
0
    def initialize_all(self, block_number, random, random_seed):
        self.random_seed = random_seed

        self.block_number = block_number
        self.block_hash = factories.make_block_hash()
        self.random = random

        self.token_network_address = factories.UNIT_TOKEN_NETWORK_ADDRESS
        self.token_id = factories.UNIT_TOKEN_ADDRESS
        self.token_network_state = TokenNetworkState(
            address=self.token_network_address,
            token_address=self.token_id,
            network_graph=TokenNetworkGraphState(self.token_network_address),
        )

        self.token_network_registry_address = factories.make_token_network_registry_address()
        self.token_network_registry_state = TokenNetworkRegistryState(
            self.token_network_registry_address, [self.token_network_state]
        )

        channels = []
        for _ in range(self.number_of_clients):
            private_key, address = factories.make_privkey_address()
            self.address_to_privkey[address] = private_key

            chain_state = ChainState(
                pseudo_random_generator=self.random,
                block_number=self.block_number,
                block_hash=self.block_hash,
                our_address=address,
                chain_id=factories.UNIT_CHAIN_ID,
            )
            chain_state.identifiers_to_tokennetworkregistries[
                self.token_network_registry_address
            ] = self.token_network_registry_state

            chain_state.tokennetworkaddresses_to_tokennetworkregistryaddresses[
                self.token_network_address
            ] = self.token_network_registry_address

            self.address_to_client[address] = Client(chain_state=chain_state)

            channels.extend(
                self.new_channel_with_transaction(client_address=address)
                for _ in range(self.initial_number_of_channels)
            )

        return multiple(*channels)
Esempio n. 27
0
    def __init__(self,
                 message_handler=None,
                 state_transition=None,
                 private_key=None):
        if private_key is None:
            self.privkey, self.address = factories.make_privkey_address()
        else:
            self.privkey = private_key
            self.address = privatekey_to_address(private_key)

        self.rpc_client = MockJSONRPCClient(self.address)
        self.proxy_manager = MockProxyManager(node_address=self.address)
        self.signer = LocalSigner(self.privkey)

        self.message_handler = message_handler
        self.routing_mode = RoutingMode.PRIVATE
        self.config = RaidenConfig(chain_id=self.rpc_client.chain_id,
                                   environment_type=Environment.DEVELOPMENT)

        self.default_user_deposit = Mock()
        self.default_registry = Mock()
        self.default_registry.address = factories.make_address()
        self.default_one_to_n_address = factories.make_address()
        self.default_msc_address = factories.make_address()

        self.targets_to_identifiers_to_statuses: Dict[Address,
                                                      dict] = defaultdict(dict)
        self.route_to_feedback_token: dict = {}

        if state_transition is None:
            state_transition = node.state_transition

        serializer = JSONSerializer()
        state_manager = StateManager(state_transition, None)
        storage = SerializedSQLiteStorage(":memory:", serializer)
        self.wal = WriteAheadLog(state_manager, storage)

        state_change = ActionInitChain(
            pseudo_random_generator=random.Random(),
            block_number=BlockNumber(0),
            block_hash=factories.make_block_hash(),
            our_address=self.rpc_client.address,
            chain_id=self.rpc_client.chain_id,
        )
        with self.wal.process_state_change_atomically() as dispatcher:
            dispatcher.dispatch(state_change)

        self.transport = Mock()
Esempio n. 28
0
    def initialize(self, block_number, random, random_seed):
        self.random_seed = random_seed

        self.block_number = block_number
        self.random = random
        self.private_key, self.address = factories.make_privkey_address()

        self.chain_state = ChainState(
            self.random,
            self.block_number,
            self.address,
            factories.UNIT_CHAIN_ID,
        )

        self.token_network_id = factories.make_address()
        self.token_id = factories.make_address()
        self.token_network_state = TokenNetworkState(self.token_network_id,
                                                     self.token_id)

        self.payment_network_id = factories.make_payment_network_identifier()
        self.payment_network_state = PaymentNetworkState(
            self.payment_network_id,
            [self.token_network_state],
        )

        self.chain_state.identifiers_to_paymentnetworks[
            self.payment_network_id] = self.payment_network_state

        self.channels = list()

        for partner_address in self.channels_with:
            channel = factories.make_channel(
                our_balance=1000,
                partner_balance=1000,
                token_network_identifier=self.token_network_id,
                our_address=self.address,
                partner_address=partner_address,
            )
            channel_new_state_change = ContractReceiveChannelNew(
                factories.make_transaction_hash(),
                self.token_network_id,
                channel,
                self.block_number,
            )
            node.state_transition(self.chain_state, channel_new_state_change)

            self.channels.append(channel)
Esempio n. 29
0
    def __init__(self,
                 message_handler=None,
                 state_transition=None,
                 private_key=None,
                 config=None):
        if private_key is None:
            self.privkey, self.address = factories.make_privkey_address()
        else:
            self.privkey = private_key
            self.address = privatekey_to_address(private_key)

        self.rpc_client = MockJSONRPCClient(self.address)
        self.proxy_manager = MockProxyManager(node_address=self.address)
        self.signer = LocalSigner(self.privkey)

        self.message_handler = message_handler
        self.routing_mode = RoutingMode.PRIVATE
        self.config = config

        self.user_deposit = Mock()
        self.default_registry = Mock()
        self.default_registry.address = factories.make_address()
        self.default_one_to_n_address = factories.make_address()
        self.default_msc_address = factories.make_address()

        self.targets_to_identifiers_to_statuses = defaultdict(dict)
        self.route_to_feedback_token = {}

        if state_transition is None:
            state_transition = node.state_transition

        serializer = JSONSerializer
        state_manager = StateManager(state_transition, None)
        storage = SerializedSQLiteStorage(":memory:", serializer)
        self.wal = WriteAheadLog(state_manager, storage)

        state_change = ActionInitChain(
            pseudo_random_generator=random.Random(),
            block_number=0,
            block_hash=factories.make_block_hash(),
            our_address=self.rpc_client.address,
            chain_id=self.rpc_client.chain_id,
        )

        self.wal.log_and_dispatch([state_change])
Esempio n. 30
0
def test_receive_directtransfer_invalidsender(raiden_network, deposit,
                                              token_addresses):
    app0, app1 = raiden_network
    token_address = token_addresses[0]
    other_key, other_address = make_privkey_address()
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        app0.raiden.default_registry.address,
        token_address,
    )

    channel0 = get_channelstate(app0, app1, token_network_identifier)
    channel_identifier = channel0.identifier
    message_identifier = random.randint(0, UINT64_MAX)

    direct_transfer_message = DirectTransfer(
        chain_id=UNIT_CHAIN_ID,
        message_identifier=message_identifier,
        payment_identifier=1,
        nonce=1,
        token_network_address=token_network_identifier,
        token=token_address,
        channel_identifier=channel_identifier,
        transferred_amount=10,
        locked_amount=0,
        recipient=app0.raiden.address,
        locksroot=EMPTY_MERKLE_ROOT,
    )

    sign_and_inject(
        direct_transfer_message,
        other_key,
        other_address,
        app0,
    )

    assert_synched_channel_state(
        token_network_identifier,
        app0,
        deposit,
        [],
        app1,
        deposit,
        [],
    )
Esempio n. 31
0
def test_channel_increase_nonce_and_transferred_amount():
    """ The nonce must increase with each new transfer. """
    token_address = make_address()
    privkey1, address1 = make_privkey_address()
    address2 = make_address()

    balance1 = 70
    balance2 = 110

    reveal_timeout = 5
    settle_timeout = 15

    our_state = ChannelEndState(address1, balance1, None, EMPTY_MERKLE_TREE)
    partner_state = ChannelEndState(address2, balance2, None,
                                    EMPTY_MERKLE_TREE)
    external_state = make_external_state()

    test_channel = Channel(
        our_state,
        partner_state,
        external_state,
        token_address,
        reveal_timeout,
        settle_timeout,
    )

    previous_nonce = test_channel.get_next_nonce()
    previous_transferred = test_channel.transferred_amount

    amount = 7
    block_number = 1
    for _ in range(10):
        direct_transfer = test_channel.create_directtransfer(amount,
                                                             identifier=1)
        direct_transfer.sign(privkey1, address1)
        test_channel.register_transfer(block_number, direct_transfer)

        new_nonce = test_channel.get_next_nonce()
        new_transferred = test_channel.transferred_amount

        assert new_nonce == previous_nonce + 1
        assert new_transferred == previous_transferred + amount

        previous_nonce = new_nonce
        previous_transferred = new_transferred
Esempio n. 32
0
def test_receive_mediatedtransfer_unknown(raiden_network):
    app0 = raiden_network[0]  # pylint: disable=unbalanced-tuple-unpacking
    graph0 = app0.raiden.token_to_channelgraph.values()[0]

    other_key, other_address = make_privkey_address()
    amount = 10
    mediated_transfer = MediatedTransfer(identifier=1,
                                         nonce=1,
                                         token=graph0.token_address,
                                         channel=other_address,
                                         transferred_amount=amount,
                                         recipient=app0.raiden.address,
                                         locksroot=UNIT_HASHLOCK,
                                         lock=Lock(amount, 1, UNIT_HASHLOCK),
                                         target=make_address(),
                                         initiator=other_address,
                                         fee=0)
    sign_and_send(mediated_transfer, other_key, other_address, app0)
Esempio n. 33
0
    def new_channel(self):
        """Create a new partner address with private key and channel. The
        private key and channels are listed in the instance's dictionaries,
        the address is returned and should be added to the partners Bundle.
        """

        partner_privkey, partner_address = factories.make_privkey_address()

        self.address_to_privkey[partner_address] = partner_privkey
        self.address_to_channel[partner_address] = factories.make_channel(
            our_balance=1000,
            partner_balance=1000,
            token_network_identifier=self.token_network_id,
            our_address=self.address,
            partner_address=partner_address,
        )

        return partner_address
Esempio n. 34
0
    def new_channel(self):
        """Create a new partner address with private key and channel. The
        private key and channels are listed in the instance's dictionaries,
        the address is returned and should be added to the partners Bundle.
        """

        partner_privkey, partner_address = factories.make_privkey_address()

        self.address_to_privkey[partner_address] = partner_privkey
        self.address_to_channel[partner_address] = factories.make_channel(
            our_balance=1000,
            partner_balance=1000,
            token_network_identifier=self.token_network_id,
            our_address=self.address,
            partner_address=partner_address,
        )

        return partner_address
Esempio n. 35
0
def test_refund_transfer_no_more_routes():
    amount = UNIT_TRANSFER_AMOUNT
    refund_pkey, refund_address = factories.make_privkey_address()
    setup = setup_initiator_tests(
        amount=amount,
        partner_balance=amount,
        our_address=UNIT_TRANSFER_INITIATOR,
        partner_address=refund_address,
    )

    original_transfer = setup.current_state.initiator.transfer
    refund_transfer = factories.make_signed_transfer(
        amount,
        original_transfer.initiator,
        original_transfer.target,
        original_transfer.lock.expiration,
        UNIT_SECRET,
        payment_identifier=original_transfer.payment_identifier,
        channel_identifier=setup.channel.identifier,
        pkey=refund_pkey,
        sender=refund_address,
    )

    state_change = ReceiveTransferRefundCancelRoute(
        routes=setup.available_routes,
        transfer=refund_transfer,
        secret=random_secret(),
    )

    iteration = initiator_manager.state_transition(
        setup.current_state,
        state_change,
        setup.channel_map,
        setup.prng,
        setup.block_number,
    )
    assert iteration.new_state is None

    unlocked_failed = next(e for e in iteration.events if isinstance(e, EventUnlockFailed))
    sent_failed = next(e for e in iteration.events if isinstance(e, EventPaymentSentFailed))

    assert unlocked_failed
    assert sent_failed
def test_channel_increase_nonce_and_transferred_amount():
    """ The nonce must increase with each new transfer. """
    token_address = make_address()
    privkey1, address1 = make_privkey_address()
    address2 = make_address()

    balance1 = 70
    balance2 = 110

    reveal_timeout = 5
    settle_timeout = 15

    our_state = ChannelEndState(address1, balance1, None, EMPTY_MERKLE_TREE)
    partner_state = ChannelEndState(address2, balance2, None, EMPTY_MERKLE_TREE)
    external_state = make_external_state()

    test_channel = Channel(
        our_state,
        partner_state,
        external_state,
        token_address,
        reveal_timeout,
        settle_timeout,
    )

    previous_nonce = test_channel.get_next_nonce()
    previous_transferred = test_channel.transferred_amount

    amount = 7
    block_number = 1
    for _ in range(10):
        direct_transfer = test_channel.create_directtransfer(amount, identifier=1)
        direct_transfer.sign(privkey1, address1)
        test_channel.register_transfer(block_number, direct_transfer)

        new_nonce = test_channel.get_next_nonce()
        new_transferred = test_channel.transferred_amount

        assert new_nonce == previous_nonce + 1
        assert new_transferred == previous_transferred + amount

        previous_nonce = new_nonce
        previous_transferred = new_transferred
Esempio n. 37
0
def test_receive_lockedtransfer_invalidsender(raiden_network, token_addresses,
                                              deposit, reveal_timeout):

    app0, app1 = raiden_network
    token_address = token_addresses[0]
    other_key, other_address = make_privkey_address()

    channel0 = get_channelstate(app0, app1, token_address)
    lock_amount = 10
    expiration = reveal_timeout * 2
    mediated_transfer_message = LockedTransfer(
        message_identifier=random.randint(0, UINT64_MAX),
        payment_identifier=1,
        nonce=1,
        registry_address=app0.raiden.default_registry.address,
        token=token_address,
        channel=channel0.identifier,
        transferred_amount=0,
        locked_amount=lock_amount,
        recipient=app0.raiden.address,
        locksroot=UNIT_SECRETHASH,
        lock=Lock(lock_amount, expiration, UNIT_SECRETHASH),
        target=app0.raiden.address,
        initiator=other_address,
        fee=0)

    sign_and_inject(
        mediated_transfer_message,
        other_key,
        other_address,
        app0,
    )

    assert_synched_channel_state(
        token_address,
        app0,
        deposit,
        [],
        app1,
        deposit,
        [],
    )
Esempio n. 38
0
    def new_channel(self):
        """Create a new partner address with private key and channel. The
        private key and channels are listed in the instance's dictionaries,
        the address is returned and should be added to the partners Bundle.
        """

        partner_privkey, partner_address = factories.make_privkey_address()

        self.address_to_privkey[partner_address] = partner_privkey
        self.address_to_channel[partner_address] = factories.create(
            factories.NettingChannelStateProperties(
                our_state=factories.NettingChannelEndStateProperties(
                    balance=1000, address=self.address),
                partner_state=factories.NettingChannelEndStateProperties(
                    balance=1000, address=partner_address),
                canonical_identifier=factories.make_canonical_identifier(
                    token_network_address=self.token_network_address),
            ))

        return partner_address
def test_receive_mediatedtransfer_unknown(raiden_network):
    app0 = raiden_network[0]  # pylint: disable=unbalanced-tuple-unpacking
    graph0 = list(app0.raiden.token_to_channelgraph.values())[0]

    other_key, other_address = make_privkey_address()
    amount = 10
    mediated_transfer = MediatedTransfer(
        identifier=1,
        nonce=1,
        token=graph0.token_address,
        channel=other_address,
        transferred_amount=amount,
        recipient=app0.raiden.address,
        locksroot=UNIT_HASHLOCK,
        lock=Lock(amount, 1, UNIT_HASHLOCK),
        target=make_address(),
        initiator=other_address,
        fee=0
    )
    sign_and_send(mediated_transfer, other_key, other_address, app0)
def test_receive_directtransfer_invalidsender(raiden_network, deposit, token_addresses):
    app0, app1 = raiden_network
    token_address = token_addresses[0]
    other_key, other_address = make_privkey_address()
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        app0.raiden.default_registry.address,
        token_address,
    )

    channel0 = get_channelstate(app0, app1, token_network_identifier)
    channel_identifier = channel0.identifier
    message_identifier = random.randint(0, UINT64_MAX)

    direct_transfer_message = DirectTransfer(
        chain_id=UNIT_CHAIN_ID,
        message_identifier=message_identifier,
        payment_identifier=1,
        nonce=1,
        token_network_address=token_network_identifier,
        token=token_address,
        channel_identifier=channel_identifier,
        transferred_amount=10,
        locked_amount=0,
        recipient=app0.raiden.address,
        locksroot=EMPTY_MERKLE_ROOT,
    )

    sign_and_inject(
        direct_transfer_message,
        other_key,
        other_address,
        app0,
    )

    assert_synched_channel_state(
        token_network_identifier,
        app0, deposit, [],
        app1, deposit, [],
    )
def test_receive_lockedtransfer_invalidsender(raiden_network, token_addresses,
                                              deposit, reveal_timeout):
    app0, app1 = raiden_network
    token_address = token_addresses[0]
    other_key, other_address = make_privkey_address()

    token_network_address = views.get_token_network_address_by_token_address(
        views.state_from_app(app0), app0.raiden.default_registry.address,
        token_address)
    assert token_network_address
    channel0 = get_channelstate(app0, app1, token_network_address)
    lock_amount = TokenAmount(10)
    expiration = reveal_timeout * 2
    mediated_transfer_message = LockedTransfer(
        chain_id=UNIT_CHAIN_ID,
        message_identifier=make_message_identifier(),
        payment_identifier=PaymentID(1),
        nonce=Nonce(1),
        token_network_address=token_network_address,
        token=token_address,
        channel_identifier=channel0.identifier,
        transferred_amount=TokenAmount(0),
        locked_amount=lock_amount,
        recipient=app0.raiden.address,
        locksroot=make_locksroot(),
        lock=Lock(
            amount=PaymentWithFeeAmount(lock_amount),
            expiration=expiration,
            secrethash=UNIT_SECRETHASH,
        ),
        target=app0.raiden.address,
        initiator=InitiatorAddress(other_address),
        signature=EMPTY_SIGNATURE,
        metadata=Metadata(routes=[RouteMetadata(route=[app0.raiden.address])]),
    )

    sign_and_inject(mediated_transfer_message, LocalSigner(other_key), app0)

    assert_synced_channel_state(token_network_address, app0, deposit, [], app1,
                                deposit, [])
Esempio n. 42
0
def test_routing_priority(
        chain_state,
        payment_network_state,
        token_network_state,
        our_address,
):
    open_block_number = 10
    pseudo_random_generator = random.Random()
    pkey1, address1 = factories.make_privkey_address()
    pkey2, address2 = factories.make_privkey_address()
    pkey3, address3 = factories.make_privkey_address()
    pkey4, address4 = factories.make_privkey_address()

    # Create a network with the following topology
    #
    # our  ----- 1/1 ----> (1)
    #  |                    |
    #  |                    |
    #  2/0                  x
    #  |                    |
    #  v                    v
    # (2)  ----- x ----->  (3)
    #  |                    |
    #  |                    |
    #  x                    x
    #  |                    |
    #  v                    v
    # (4)                  (4)

    channel_state1 = factories.make_channel(
        our_balance=1,
        our_address=our_address,
        partner_balance=1,
        partner_address=address1,
    )
    channel_state2 = factories.make_channel(
        our_balance=2,
        our_address=our_address,
        partner_balance=0,
        partner_address=address2,
    )

    # create new channels as participant
    channel_new_state_change1 = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_state=channel_state1,
        block_number=open_block_number,
    )
    channel_new_state_change2 = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_state=channel_state2,
        block_number=open_block_number,
    )

    channel_new_iteration1 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=token_network_state,
        state_change=channel_new_state_change1,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number,
    )

    channel_new_iteration2 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=channel_new_iteration1.new_state,
        state_change=channel_new_state_change2,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number,
    )

    # create new channels without being participant
    channel_new_state_change3 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=3,
        participant1=address2,
        participant2=address3,
        block_number=open_block_number,
    )

    channel_new_iteration3 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=channel_new_iteration2.new_state,
        state_change=channel_new_state_change3,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number + 10,
    )

    channel_new_state_change4 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=4,
        participant1=address3,
        participant2=address1,
        block_number=open_block_number,
    )

    channel_new_iteration4 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=channel_new_iteration3.new_state,
        state_change=channel_new_state_change4,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number + 10,
    )

    channel_new_state_change5 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=4,
        participant1=address3,
        participant2=address4,
        block_number=open_block_number,
    )

    channel_new_iteration5 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=channel_new_iteration4.new_state,
        state_change=channel_new_state_change5,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number + 10,
    )

    channel_new_state_change6 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=4,
        participant1=address2,
        participant2=address4,
        block_number=open_block_number,
    )

    token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=channel_new_iteration5.new_state,
        state_change=channel_new_state_change6,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number + 10,
    )

    # test routing priority with all nodes available
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_REACHABLE,
        address2: NODE_NETWORK_REACHABLE,
        address3: NODE_NETWORK_REACHABLE,
    }

    routes = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address3,
        amount=1,
        previous_address=None,
        config={},
    )
    assert routes[0].node_address == address1
    assert routes[1].node_address == address2

    # number of hops overwrites refunding capacity (route over node 2 involves less hops)
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_REACHABLE,
        address2: NODE_NETWORK_REACHABLE,
        address3: NODE_NETWORK_REACHABLE,
        address4: NODE_NETWORK_REACHABLE,
    }

    routes = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address4,
        amount=1,
        previous_address=None,
        config={},
    )
    assert routes[0].node_address == address2
    assert routes[1].node_address == address1

    # sufficient routing capacity overwrites refunding capacity
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_REACHABLE,
        address2: NODE_NETWORK_REACHABLE,
        address3: NODE_NETWORK_REACHABLE,
    }

    routes = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address3,
        amount=2,
        previous_address=None,
        config={},
    )
    assert routes[0].node_address == address2

    # availability overwrites refunding capacity (node 1 offline)
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_UNREACHABLE,
        address2: NODE_NETWORK_REACHABLE,
        address3: NODE_NETWORK_REACHABLE,
    }

    routes = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address3,
        amount=1,
        previous_address=None,
        config={},
    )
    assert routes[0].node_address == address2
Esempio n. 43
0
def test_routing_issue2663(
        chain_state,
        payment_network_state,
        token_network_state,
        our_address,
):
    open_block_number = 10
    pseudo_random_generator = random.Random()
    pkey1, address1 = factories.make_privkey_address()
    pkey2, address2 = factories.make_privkey_address()
    pkey3, address3 = factories.make_privkey_address()

    # Create a network with the following topology
    #
    # our  ----- 50 ---->  (1)
    #  |                    ^
    #  |                    |
    # 100                  100
    #  |                    |
    #  v                    |
    # (2)  ----- 100 --->  (3)

    channel_state1 = factories.make_channel(
        our_balance=50,
        our_address=our_address,
        partner_balance=0,
        partner_address=address1,
    )
    channel_state2 = factories.make_channel(
        our_balance=100,
        our_address=our_address,
        partner_balance=0,
        partner_address=address2,
    )

    # create new channels as participant
    channel_new_state_change1 = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_state=channel_state1,
        block_number=open_block_number,
    )
    channel_new_state_change2 = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_state=channel_state2,
        block_number=open_block_number,
    )

    channel_new_iteration1 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=token_network_state,
        state_change=channel_new_state_change1,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number,
    )

    channel_new_iteration2 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=channel_new_iteration1.new_state,
        state_change=channel_new_state_change2,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number,
    )

    graph_state = channel_new_iteration2.new_state.network_graph
    assert len(graph_state.channel_identifier_to_participants) == 2
    assert len(graph_state.network.edges()) == 2

    # create new channels without being participant
    channel_new_state_change3 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=3,
        participant1=address2,
        participant2=address3,
        block_number=open_block_number,
    )

    channel_new_iteration3 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=channel_new_iteration2.new_state,
        state_change=channel_new_state_change3,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number + 10,
    )

    graph_state = channel_new_iteration3.new_state.network_graph
    assert len(graph_state.channel_identifier_to_participants) == 3
    assert len(graph_state.network.edges()) == 3

    channel_new_state_change4 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=4,
        participant1=address3,
        participant2=address1,
        block_number=open_block_number,
    )
    channel_new_iteration4 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=channel_new_iteration3.new_state,
        state_change=channel_new_state_change4,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number + 10,
    )

    graph_state = channel_new_iteration4.new_state.network_graph
    assert len(graph_state.channel_identifier_to_participants) == 4
    assert len(graph_state.network.edges()) == 4

    # test routing with all nodes available
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_REACHABLE,
        address2: NODE_NETWORK_REACHABLE,
        address3: NODE_NETWORK_REACHABLE,
    }

    routes1 = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address1,
        amount=50,
        previous_address=None,
        config={},
    )
    assert routes1[0].node_address == address1
    assert routes1[1].node_address == address2

    routes2 = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address1,
        amount=51,
        previous_address=None,
        config={},
    )
    assert routes2[0].node_address == address2

    # test routing with node 2 offline
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_REACHABLE,
        address2: NODE_NETWORK_UNREACHABLE,
        address3: NODE_NETWORK_REACHABLE,
    }

    routes1 = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address1,
        amount=50,
        previous_address=None,
        config={},
    )
    assert routes1[0].node_address == address1

    routes2 = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address1,
        amount=51,
        previous_address=None,
        config={},
    )
    assert routes2 == []

    # test routing with node 3 offline
    # the routing doesn't care as node 3 is not directly connected
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_REACHABLE,
        address2: NODE_NETWORK_REACHABLE,
        address3: NODE_NETWORK_UNREACHABLE,
    }

    routes1 = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address1,
        amount=50,
        previous_address=None,
        config={},
    )
    assert routes1[0].node_address == address1
    assert routes1[1].node_address == address2

    routes2 = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address1,
        amount=51,
        previous_address=None,
        config={},
    )
    assert routes2[0].node_address == address2

    # test routing with node 1 offline
    chain_state.nodeaddresses_to_networkstates = {
        address1: NODE_NETWORK_UNREACHABLE,
        address2: NODE_NETWORK_REACHABLE,
        address3: NODE_NETWORK_REACHABLE,
    }

    routes1 = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address1,
        amount=50,
        previous_address=None,
        config={},
    )
    # right now the channel to 1 gets filtered out as it is offline
    assert routes1[0].node_address == address2

    routes2 = get_best_routes(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
        from_address=our_address,
        to_address=address1,
        amount=51,
        previous_address=None,
        config={},
    )
    assert routes2[0].node_address == address2
Esempio n. 44
0
def test_routing_updates(
        token_network_state,
        our_address,
):
    open_block_number = 10
    pseudo_random_generator = random.Random()
    pkey1, address1 = factories.make_privkey_address()
    pkey2, address2 = factories.make_privkey_address()
    pkey3, address3 = factories.make_privkey_address()

    amount = 30
    our_balance = amount + 50
    channel_state = factories.make_channel(
        our_balance=our_balance,
        our_address=our_address,
        partner_balance=our_balance,
        partner_address=address1,
    )
    payment_network_identifier = factories.make_payment_network_identifier()

    # create a new channel as participant, check graph update
    channel_new_state_change = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_state=channel_state,
        block_number=open_block_number,
    )

    channel_new_iteration1 = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=token_network_state,
        state_change=channel_new_state_change,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number,
    )

    graph_state = channel_new_iteration1.new_state.network_graph
    assert channel_state.identifier in graph_state.channel_identifier_to_participants
    assert len(graph_state.channel_identifier_to_participants) == 1
    assert graph_state.network[our_address][address1] is not None
    assert len(graph_state.network.edges()) == 1

    # create a new channel without being participant, check graph update
    new_channel_identifier = factories.make_channel_identifier()
    channel_new_state_change = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=new_channel_identifier,
        participant1=address2,
        participant2=address3,
        block_number=open_block_number,
    )

    channel_new_iteration2 = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=channel_new_iteration1.new_state,
        state_change=channel_new_state_change,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number + 10,
    )

    graph_state = channel_new_iteration2.new_state.network_graph
    assert channel_state.identifier in graph_state.channel_identifier_to_participants
    assert new_channel_identifier in graph_state.channel_identifier_to_participants
    assert len(graph_state.channel_identifier_to_participants) == 2
    assert graph_state.network[our_address][address1] is not None
    assert graph_state.network[address2][address3] is not None
    assert len(graph_state.network.edges()) == 2

    # close the channel the node is a participant of, check edge is removed from graph
    closed_block_number = open_block_number + 20
    channel_close_state_change1 = ContractReceiveChannelClosed(
        transaction_hash=factories.make_transaction_hash(),
        transaction_from=channel_state.partner_state.address,
        token_network_identifier=token_network_state.address,
        channel_identifier=channel_state.identifier,
        block_number=closed_block_number,
    )

    channel_closed_iteration1 = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=channel_new_iteration2.new_state,
        state_change=channel_close_state_change1,
        pseudo_random_generator=pseudo_random_generator,
        block_number=closed_block_number,
    )

    # Check that a second ContractReceiveChannelClosed events is handled properly
    # This might have been sent from the other participant of the channel
    # See issue #2449
    channel_close_state_change2 = ContractReceiveChannelClosed(
        transaction_hash=factories.make_transaction_hash(),
        transaction_from=channel_state.our_state.address,
        token_network_identifier=token_network_state.address,
        channel_identifier=channel_state.identifier,
        block_number=closed_block_number,
    )

    channel_closed_iteration2 = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=channel_closed_iteration1.new_state,
        state_change=channel_close_state_change2,
        pseudo_random_generator=pseudo_random_generator,
        block_number=closed_block_number,
    )

    graph_state = channel_closed_iteration2.new_state.network_graph
    assert channel_state.identifier not in graph_state.channel_identifier_to_participants
    assert new_channel_identifier in graph_state.channel_identifier_to_participants
    assert len(graph_state.channel_identifier_to_participants) == 1
    assert graph_state.network[address2][address3] is not None
    assert len(graph_state.network.edges()) == 1

    # close the channel the node is not a participant of, check edge is removed from graph
    channel_close_state_change3 = ContractReceiveRouteClosed(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=new_channel_identifier,
        block_number=closed_block_number,
    )

    channel_closed_iteration3 = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=channel_closed_iteration2.new_state,
        state_change=channel_close_state_change3,
        pseudo_random_generator=pseudo_random_generator,
        block_number=closed_block_number + 10,
    )

    # Check that a second ContractReceiveRouteClosed events is handled properly.
    # This might have been sent from the second participant of the channel
    # See issue #2449
    channel_close_state_change4 = ContractReceiveRouteClosed(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=new_channel_identifier,
        block_number=closed_block_number + 10,
    )

    channel_closed_iteration4 = token_network.state_transition(
        payment_network_identifier=payment_network_identifier,
        token_network_state=channel_closed_iteration3.new_state,
        state_change=channel_close_state_change4,
        pseudo_random_generator=pseudo_random_generator,
        block_number=closed_block_number + 10,
    )

    graph_state = channel_closed_iteration4.new_state.network_graph
    assert channel_state.identifier not in graph_state.channel_identifier_to_participants
    assert new_channel_identifier not in graph_state.channel_identifier_to_participants
    assert len(graph_state.channel_identifier_to_participants) == 0
    assert len(graph_state.network.edges()) == 0
Esempio n. 45
0
def test_multiple_channel_states(
        chain_state,
        token_network_state,
        our_address,
):
    open_block_number = 10
    pseudo_random_generator = random.Random()
    pkey, address = factories.make_privkey_address()

    amount = 30
    our_balance = amount + 50
    channel_state = factories.make_channel(
        our_balance=our_balance,
        our_address=our_address,
        partner_balance=our_balance,
        partner_address=address,
        token_network_identifier=token_network_state.address,
    )
    payment_network_identifier = factories.make_payment_network_identifier()

    channel_new_state_change = ContractReceiveChannelNew(
        factories.make_transaction_hash(),
        token_network_state.address,
        channel_state,
        open_block_number,
    )

    channel_new_iteration = token_network.state_transition(
        payment_network_identifier,
        token_network_state,
        channel_new_state_change,
        pseudo_random_generator,
        open_block_number,
    )

    lock_amount = 30
    lock_expiration = 20
    lock_secret = sha3(b'test_end_state')
    lock_secrethash = sha3(lock_secret)
    lock = HashTimeLockState(
        lock_amount,
        lock_expiration,
        lock_secrethash,
    )

    mediated_transfer = make_receive_transfer_mediated(
        channel_state=channel_state,
        privkey=pkey,
        nonce=1,
        transferred_amount=0,
        lock=lock,
    )

    from_route = factories.route_from_channel(channel_state)
    init_target = ActionInitTarget(
        from_route,
        mediated_transfer,
    )

    node.state_transition(chain_state, init_target)

    closed_block_number = open_block_number + 10
    channel_close_state_change = ContractReceiveChannelClosed(
        factories.make_transaction_hash(),
        channel_state.partner_state.address,
        token_network_state.address,
        channel_state.identifier,
        closed_block_number,
    )

    channel_closed_iteration = token_network.state_transition(
        payment_network_identifier,
        channel_new_iteration.new_state,
        channel_close_state_change,
        pseudo_random_generator,
        closed_block_number,
    )

    settle_block_number = closed_block_number + channel_state.settle_timeout + 1
    channel_settled_state_change = ContractReceiveChannelSettled(
        factories.make_transaction_hash(),
        token_network_state.address,
        channel_state.identifier,
        settle_block_number,
    )

    channel_settled_iteration = token_network.state_transition(
        payment_network_identifier,
        channel_closed_iteration.new_state,
        channel_settled_state_change,
        pseudo_random_generator,
        closed_block_number,
    )

    token_network_state_after_settle = channel_settled_iteration.new_state
    ids_to_channels = token_network_state_after_settle.channelidentifiers_to_channels
    assert len(ids_to_channels) == 1
    assert channel_state.identifier in ids_to_channels

    # Create new channel while the previous one is pending unlock
    new_channel_state = factories.make_channel(
        our_balance=our_balance,
        partner_balance=our_balance,
        partner_address=address,
    )
    channel_new_state_change = ContractReceiveChannelNew(
        factories.make_transaction_hash(),
        token_network_state.address,
        new_channel_state,
        closed_block_number + 1,
    )

    channel_new_iteration = token_network.state_transition(
        payment_network_identifier,
        token_network_state,
        channel_new_state_change,
        pseudo_random_generator,
        open_block_number,
    )

    token_network_state_after_new_open = channel_new_iteration.new_state
    ids_to_channels = token_network_state_after_new_open.channelidentifiers_to_channels

    assert len(ids_to_channels) == 2
    assert channel_state.identifier in ids_to_channels
Esempio n. 46
0
def test_mediator_clear_pairs_after_batch_unlock(
        chain_state,
        token_network_state,
        our_address,
):
    """ Regression test for https://github.com/raiden-network/raiden/issues/2932
    The mediator must also clear the transfer pairs once a ReceiveBatchUnlock where
    he is a participant is received.
    """
    open_block_number = 10
    pseudo_random_generator = random.Random()
    pkey, address = factories.make_privkey_address()

    amount = 30
    our_balance = amount + 50
    channel_state = factories.make_channel(
        our_balance=our_balance,
        our_address=our_address,
        partner_balance=our_balance,
        partner_address=address,
        token_network_identifier=token_network_state.address,
    )
    payment_network_identifier = factories.make_payment_network_identifier()

    channel_new_state_change = ContractReceiveChannelNew(
        factories.make_transaction_hash(),
        token_network_state.address,
        channel_state,
        open_block_number,
    )

    channel_new_iteration = token_network.state_transition(
        payment_network_identifier,
        token_network_state,
        channel_new_state_change,
        pseudo_random_generator,
        open_block_number,
    )

    lock_amount = 30
    lock_expiration = 20
    lock_secret = sha3(b'test_end_state')
    lock_secrethash = sha3(lock_secret)
    lock = HashTimeLockState(
        lock_amount,
        lock_expiration,
        lock_secrethash,
    )

    mediated_transfer = make_receive_transfer_mediated(
        channel_state=channel_state,
        privkey=pkey,
        nonce=1,
        transferred_amount=0,
        lock=lock,
    )

    from_route = factories.route_from_channel(channel_state)
    init_mediator = ActionInitMediator(
        routes=[from_route],
        from_route=from_route,
        from_transfer=mediated_transfer,
    )

    node.state_transition(chain_state, init_mediator)

    closed_block_number = open_block_number + 10
    channel_close_state_change = ContractReceiveChannelClosed(
        factories.make_transaction_hash(),
        channel_state.partner_state.address,
        token_network_state.address,
        channel_state.identifier,
        closed_block_number,
    )

    channel_closed_iteration = token_network.state_transition(
        payment_network_identifier,
        channel_new_iteration.new_state,
        channel_close_state_change,
        pseudo_random_generator,
        closed_block_number,
    )

    settle_block_number = closed_block_number + channel_state.settle_timeout + 1
    channel_settled_state_change = ContractReceiveChannelSettled(
        factories.make_transaction_hash(),
        token_network_state.address,
        channel_state.identifier,
        settle_block_number,
    )

    channel_settled_iteration = token_network.state_transition(
        payment_network_identifier,
        channel_closed_iteration.new_state,
        channel_settled_state_change,
        pseudo_random_generator,
        closed_block_number,
    )

    token_network_state_after_settle = channel_settled_iteration.new_state
    ids_to_channels = token_network_state_after_settle.channelidentifiers_to_channels
    assert len(ids_to_channels) == 1
    assert channel_state.identifier in ids_to_channels

    block_number = closed_block_number + 1
    channel_batch_unlock_state_change = ContractReceiveChannelBatchUnlock(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        participant=our_address,
        partner=address,
        locksroot=lock_secrethash,
        unlocked_amount=lock_amount,
        returned_tokens=0,
        block_number=block_number,
    )
    channel_unlock_iteration = node.state_transition(
        chain_state=chain_state,
        state_change=channel_batch_unlock_state_change,
    )
    chain_state = channel_unlock_iteration.new_state
    token_network_state = views.get_token_network_by_identifier(
        chain_state=chain_state,
        token_network_id=token_network_state.address,
    )
    ids_to_channels = token_network_state.channelidentifiers_to_channels
    assert len(ids_to_channels) == 0

    # Make sure that all is fine in the next block
    block = Block(
        block_number=block_number + 1,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )
    iteration = node.state_transition(
        chain_state=chain_state,
        state_change=block,
    )
    assert iteration.new_state

    # Make sure that mediator task was cleared during the next block processing
    # since the channel was removed
    mediator_task = chain_state.payment_mapping.secrethashes_to_task.get(lock_secrethash)
    assert not mediator_task
def test_python_channel():
    token_address = make_address()
    privkey1, address1 = make_privkey_address()
    address2 = make_address()

    balance1 = 70
    balance2 = 110

    reveal_timeout = 5
    settle_timeout = 15
    block_number = 10

    our_state = ChannelEndState(address1, balance1, None, EMPTY_MERKLE_TREE)
    partner_state = ChannelEndState(address2, balance2, None, EMPTY_MERKLE_TREE)
    external_state = make_external_state()

    test_channel = Channel(
        our_state,
        partner_state,
        external_state,
        token_address,
        reveal_timeout,
        settle_timeout,
    )

    assert test_channel.contract_balance == our_state.contract_balance
    assert test_channel.transferred_amount == our_state.transferred_amount
    assert test_channel.distributable == our_state.contract_balance
    assert test_channel.outstanding == our_state.amount_locked
    assert test_channel.outstanding == 0
    assert test_channel.locked == partner_state.amount_locked
    assert test_channel.our_state.amount_locked == 0
    assert test_channel.partner_state.amount_locked == 0
    assert test_channel.get_next_nonce() == 1

    with pytest.raises(ValueError):
        test_channel.create_directtransfer(
            -10,
            identifier=1,
        )

    with pytest.raises(ValueError):
        test_channel.create_directtransfer(
            balance1 + 10,
            identifier=1,
        )

    amount1 = 10
    directtransfer = test_channel.create_directtransfer(
        amount1,
        identifier=1,
    )
    directtransfer.sign(privkey1, address1)
    test_channel.register_transfer(
        block_number,
        directtransfer,
    )

    assert test_channel.contract_balance == balance1
    assert test_channel.balance == balance1 - amount1
    assert test_channel.transferred_amount == amount1
    assert test_channel.distributable == balance1 - amount1
    assert test_channel.outstanding == 0
    assert test_channel.locked == 0
    assert test_channel.our_state.amount_locked == 0
    assert test_channel.partner_state.amount_locked == 0
    assert test_channel.get_next_nonce() == 2

    secret = sha3(b'test_channel')
    hashlock = sha3(secret)
    amount2 = 10
    fee = 0
    expiration = block_number + settle_timeout - 5
    identifier = 1
    mediatedtransfer = test_channel.create_mediatedtransfer(
        address1,
        address2,
        fee,
        amount2,
        identifier,
        expiration,
        hashlock,
    )
    mediatedtransfer.sign(privkey1, address1)

    test_channel.register_transfer(
        block_number,
        mediatedtransfer,
    )

    assert test_channel.contract_balance == balance1
    assert test_channel.balance == balance1 - amount1
    assert test_channel.transferred_amount == amount1
    assert test_channel.distributable == balance1 - amount1 - amount2
    assert test_channel.outstanding == 0
    assert test_channel.locked == amount2
    assert test_channel.our_state.amount_locked == amount2
    assert test_channel.partner_state.amount_locked == 0
    assert test_channel.get_next_nonce() == 3

    secret_message = test_channel.create_secret(identifier, secret)
    secret_message.sign(privkey1, address1)
    test_channel.register_transfer(block_number, secret_message)

    assert test_channel.contract_balance == balance1
    assert test_channel.balance == balance1 - amount1 - amount2
    assert test_channel.transferred_amount == amount1 + amount2
    assert test_channel.distributable == balance1 - amount1 - amount2
    assert test_channel.outstanding == 0
    assert test_channel.locked == 0
    assert test_channel.our_state.amount_locked == 0
    assert test_channel.partner_state.amount_locked == 0
    assert test_channel.get_next_nonce() == 4
Esempio n. 48
0
def test_refund_transfer_next_route():
    amount = UNIT_TRANSFER_AMOUNT
    our_address = factories.ADDR
    refund_pkey, refund_address = factories.make_privkey_address()
    pseudo_random_generator = random.Random()

    channel1 = factories.make_channel(
        our_balance=amount,
        partner_balance=amount,
        our_address=our_address,
        partner_address=refund_address,
        token_address=UNIT_TOKEN_ADDRESS,
        token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS,
    )
    channel2 = factories.make_channel(
        our_balance=0,
        our_address=our_address,
        token_address=UNIT_TOKEN_ADDRESS,
        token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS,
    )
    channel3 = factories.make_channel(
        our_balance=amount,
        our_address=our_address,
        token_address=UNIT_TOKEN_ADDRESS,
        token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS,
    )

    channel_map = {
        channel1.identifier: channel1,
        channel2.identifier: channel2,
        channel3.identifier: channel3,
    }

    available_routes = [
        factories.route_from_channel(channel1),
        factories.route_from_channel(channel2),
        factories.route_from_channel(channel3),
    ]

    block_number = 10
    current_state = make_initiator_manager_state(
        available_routes,
        factories.UNIT_TRANSFER_DESCRIPTION,
        channel_map,
        pseudo_random_generator,
        block_number,
    )

    original_transfer = current_state.initiator.transfer

    refund_transfer = factories.make_signed_transfer(
        amount,
        our_address,
        original_transfer.target,
        original_transfer.lock.expiration,
        UNIT_SECRET,
        payment_identifier=original_transfer.payment_identifier,
        channel_identifier=channel1.identifier,
        pkey=refund_pkey,
        sender=refund_address,
    )
    assert channel1.partner_state.address == refund_address

    state_change = ReceiveTransferRefundCancelRoute(
        routes=available_routes,
        transfer=refund_transfer,
        secret=random_secret(),
    )

    iteration = initiator_manager.state_transition(
        current_state,
        state_change,
        channel_map,
        pseudo_random_generator,
        block_number,
    )
    assert iteration.new_state is not None

    route_cancelled = next(e for e in iteration.events if isinstance(e, EventUnlockFailed))
    new_transfer = next(e for e in iteration.events if isinstance(e, SendLockedTransfer))

    assert route_cancelled, 'The previous transfer must be cancelled'
    assert new_transfer, 'No mediated transfer event emitted, should have tried a new route'
    msg = 'the new transfer must use a new secret / secrethash'
    assert new_transfer.transfer.lock.secrethash != refund_transfer.lock.secrethash, msg
    assert iteration.new_state.initiator is not None
Esempio n. 49
0
def test_refund_transfer_no_more_routes():
    amount = UNIT_TRANSFER_AMOUNT
    refund_pkey, refund_address = factories.make_privkey_address()
    setup = setup_initiator_tests(
        amount=amount,
        partner_balance=amount,
        our_address=UNIT_TRANSFER_INITIATOR,
        partner_address=refund_address,
    )

    original_transfer = setup.current_state.initiator.transfer
    refund_transfer = factories.make_signed_transfer(
        amount,
        original_transfer.initiator,
        original_transfer.target,
        original_transfer.lock.expiration,
        UNIT_SECRET,
        payment_identifier=original_transfer.payment_identifier,
        channel_identifier=setup.channel.identifier,
        pkey=refund_pkey,
        sender=refund_address,
    )

    state_change = ReceiveTransferRefundCancelRoute(
        routes=setup.available_routes,
        transfer=refund_transfer,
        secret=random_secret(),
    )

    iteration = initiator_manager.state_transition(
        setup.current_state,
        state_change,
        setup.channel_map,
        setup.prng,
        setup.block_number,
    )
    current_state = iteration.new_state
    # As per the description of the issue here:
    # https://github.com/raiden-network/raiden/issues/3146#issuecomment-447378046
    # We can fail the payment but can't delete the payment task if there are no
    # more routes, but we have to wait for the lock expiration
    assert iteration.new_state is not None

    unlocked_failed = next(e for e in iteration.events if isinstance(e, EventUnlockFailed))
    sent_failed = next(e for e in iteration.events if isinstance(e, EventPaymentSentFailed))

    assert unlocked_failed
    assert sent_failed

    invalid_balance_proof = factories.make_signed_balance_proof(
        nonce=2,
        transferred_amount=original_transfer.balance_proof.transferred_amount,
        locked_amount=0,
        token_network_address=original_transfer.balance_proof.token_network_identifier,
        channel_identifier=setup.channel.identifier,
        locksroot=EMPTY_MERKLE_ROOT,
        extra_hash=original_transfer.lock.secrethash,
        sender_address=refund_address,
    )
    balance_proof = factories.make_signed_balance_proof(
        nonce=2,
        transferred_amount=original_transfer.balance_proof.transferred_amount,
        locked_amount=0,
        token_network_address=original_transfer.balance_proof.token_network_identifier,
        channel_identifier=setup.channel.identifier,
        locksroot=EMPTY_MERKLE_ROOT,
        extra_hash=original_transfer.lock.secrethash,
        sender_address=refund_address,
        private_key=refund_pkey,
    )
    invalid_lock_expired_state_change = ReceiveLockExpired(
        invalid_balance_proof,
        secrethash=original_transfer.lock.secrethash,
        message_identifier=5,
    )
    lock_expired_state_change = ReceiveLockExpired(
        balance_proof,
        secrethash=original_transfer.lock.secrethash,
        message_identifier=5,
    )
    before_expiry_block = original_transfer.lock.expiration - 1
    expiry_block = channel.get_sender_expiration_threshold(original_transfer.lock)

    # a block before lock expiration, no events should be emitted
    current_state = iteration.new_state
    state_change = Block(
        block_number=before_expiry_block,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )
    iteration = initiator_manager.state_transition(
        current_state,
        state_change,
        setup.channel_map,
        setup.prng,
        expiry_block,
    )
    assert not iteration.events
    assert iteration.new_state, 'payment task should not be deleted at this block'

    # process an invalid lock expired message before lock expiration
    current_state = iteration.new_state
    iteration = initiator_manager.state_transition(
        current_state,
        invalid_lock_expired_state_change,
        setup.channel_map,
        setup.prng,
        before_expiry_block,
    )
    assert iteration.new_state, 'payment task should not be deleted at this lock expired'
    # should not be accepted
    assert not events.must_contain_entry(iteration.events, SendProcessed, {})
    assert events.must_contain_entry(iteration.events, EventInvalidReceivedLockExpired, {})

    # process a valid lock expired message before lock expiration
    current_state = iteration.new_state
    iteration = initiator_manager.state_transition(
        current_state,
        lock_expired_state_change,
        setup.channel_map,
        setup.prng,
        before_expiry_block,
    )
    assert iteration.new_state, 'payment task should not be deleted at this lock expired'
    # should not be accepted
    assert not events.must_contain_entry(iteration.events, SendProcessed, {})

    # now we get to the lock expiration block
    current_state = iteration.new_state
    state_change = Block(
        block_number=expiry_block,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )
    iteration = initiator_manager.state_transition(
        current_state,
        state_change,
        setup.channel_map,
        setup.prng,
        expiry_block,
    )
    assert events.must_contain_entry(iteration.events, SendLockExpired, {})
    # Since there was a refund transfer the payment task must not have been deleted
    assert iteration.new_state is not None

    # process the lock expired message after lock expiration
    current_state = iteration.new_state
    iteration = initiator_manager.state_transition(
        current_state,
        lock_expired_state_change,
        setup.channel_map,
        setup.prng,
        expiry_block,
    )
    # should be accepted
    assert events.must_contain_entry(iteration.events, SendProcessed, {})
    assert iteration.new_state, 'payment task should be there waiting for next block'

    # process the the block after lock expiration
    current_state = iteration.new_state
    state_change = Block(
        block_number=expiry_block + 1,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )
    iteration = initiator_manager.state_transition(
        current_state,
        state_change,
        setup.channel_map,
        setup.prng,
        expiry_block + 1,
    )
    assert iteration.new_state is None, 'from this point on the payment task should go'
def test_end_state():
    token_address = make_address()
    privkey1, address1 = make_privkey_address()
    address2 = make_address()
    channel_address = make_address()

    balance1 = 70
    balance2 = 110

    lock_secret = sha3(b'test_end_state')
    lock_amount = 30
    lock_expiration = 10
    lock_hashlock = sha3(lock_secret)

    state1 = ChannelEndState(address1, balance1, None, EMPTY_MERKLE_TREE)
    state2 = ChannelEndState(address2, balance2, None, EMPTY_MERKLE_TREE)

    assert state1.contract_balance == balance1
    assert state2.contract_balance == balance2
    assert state1.balance(state2) == balance1
    assert state2.balance(state1) == balance2

    assert state1.is_locked(lock_hashlock) is False
    assert state2.is_locked(lock_hashlock) is False

    assert merkleroot(state1.merkletree) == EMPTY_MERKLE_ROOT
    assert merkleroot(state2.merkletree) == EMPTY_MERKLE_ROOT

    assert state1.nonce is None
    assert state2.nonce is None

    lock = Lock(
        lock_amount,
        lock_expiration,
        lock_hashlock,
    )
    lock_hash = sha3(lock.as_bytes)

    transferred_amount = 0
    locksroot = state2.compute_merkleroot_with(lock)

    locked_transfer = LockedTransfer(
        1,
        nonce=1,
        token=token_address,
        channel=channel_address,
        transferred_amount=transferred_amount,
        recipient=state2.address,
        locksroot=locksroot,
        lock=lock,
    )

    transfer_target = make_address()
    transfer_initiator = make_address()
    fee = 0
    mediated_transfer = locked_transfer.to_mediatedtransfer(
        transfer_target,
        transfer_initiator,
        fee,
    )
    mediated_transfer.sign(privkey1, address1)

    state1.register_locked_transfer(mediated_transfer)

    assert state1.contract_balance == balance1
    assert state2.contract_balance == balance2
    assert state1.balance(state2) == balance1
    assert state2.balance(state1) == balance2

    assert state1.distributable(state2) == balance1 - lock_amount
    assert state2.distributable(state1) == balance2

    assert state1.amount_locked == lock_amount
    assert state2.amount_locked == 0

    assert state1.is_locked(lock_hashlock) is True
    assert state2.is_locked(lock_hashlock) is False

    assert merkleroot(state1.merkletree) == lock_hash
    assert merkleroot(state2.merkletree) == EMPTY_MERKLE_ROOT

    assert state1.nonce is 1
    assert state2.nonce is None

    with pytest.raises(ValueError):
        state1.update_contract_balance(balance1 - 10)

    state1.update_contract_balance(balance1 + 10)

    assert state1.contract_balance == balance1 + 10
    assert state2.contract_balance == balance2
    assert state1.balance(state2) == balance1 + 10
    assert state2.balance(state1) == balance2

    assert state1.distributable(state2) == balance1 - lock_amount + 10
    assert state2.distributable(state1) == balance2

    assert state1.amount_locked == lock_amount
    assert state2.amount_locked == 0

    assert state1.is_locked(lock_hashlock) is True
    assert state2.is_locked(lock_hashlock) is False

    assert merkleroot(state1.merkletree) == lock_hash
    assert merkleroot(state2.merkletree) == EMPTY_MERKLE_ROOT

    assert state1.nonce is 1
    assert state2.nonce is None

    # registering the secret should not change the locked amount
    state1.register_secret(lock_secret)

    assert state1.contract_balance == balance1 + 10
    assert state2.contract_balance == balance2
    assert state1.balance(state2) == balance1 + 10
    assert state2.balance(state1) == balance2

    assert state1.is_locked(lock_hashlock) is False
    assert state2.is_locked(lock_hashlock) is False

    assert merkleroot(state1.merkletree) == lock_hash
    assert merkleroot(state2.merkletree) == EMPTY_MERKLE_ROOT

    assert state1.nonce is 1
    assert state2.nonce is None

    secret_message = Secret(
        identifier=1,
        nonce=2,
        channel=channel_address,
        transferred_amount=transferred_amount + lock_amount,
        locksroot=EMPTY_MERKLE_ROOT,
        secret=lock_secret,
    )
    secret_message.sign(privkey1, address1)
    state1.register_secretmessage(secret_message)

    assert state1.contract_balance == balance1 + 10
    assert state2.contract_balance == balance2
    assert state1.balance(state2) == balance1 + 10 - lock_amount
    assert state2.balance(state1) == balance2 + lock_amount

    assert state1.distributable(state2) == balance1 + 10 - lock_amount
    assert state2.distributable(state1) == balance2 + lock_amount

    assert state1.amount_locked == 0
    assert state2.amount_locked == 0

    assert state1.is_locked(lock_hashlock) is False
    assert state2.is_locked(lock_hashlock) is False

    assert merkleroot(state1.merkletree) == EMPTY_MERKLE_ROOT
    assert merkleroot(state2.merkletree) == EMPTY_MERKLE_ROOT

    assert state1.nonce is 2
    assert state2.nonce is None
def test_receiver_cannot_spend_locked_amount():
    token_address = make_address()
    privkey1, address1 = make_privkey_address()
    privkey2, address2 = make_privkey_address()

    balance1 = 33
    balance2 = 11

    reveal_timeout = 7
    settle_timeout = 21
    block_number = 7

    our_state = ChannelEndState(address1, balance1, None, EMPTY_MERKLE_TREE)
    partner_state = ChannelEndState(address2, balance2, None, EMPTY_MERKLE_TREE)
    external_state = make_external_state()

    test_channel = Channel(
        our_state,
        partner_state,
        external_state,
        token_address,
        reveal_timeout,
        settle_timeout,
    )

    amount1 = balance2
    expiration = block_number + settle_timeout
    receive_mediated_transfer0 = test_channel.create_mediatedtransfer(
        address1,
        address2,
        fee=0,
        amount=amount1,
        identifier=1,
        expiration=expiration,
        hashlock=sha3(b'test_locked_amount_cannot_be_spent'),
    )
    receive_mediated_transfer0.sign(privkey2, address2)

    test_channel.register_transfer(
        block_number,
        receive_mediated_transfer0,
    )

    # trying to send one unit of the locked token
    amount2 = balance1 + 1
    lock2 = Lock(
        amount=amount2,
        expiration=expiration,
        hashlock=sha3(b'test_locked_amount_cannot_be_spent2'),
    )
    layers = compute_layers([sha3(lock2.as_bytes)])
    tree2 = MerkleTreeState(layers)
    locksroot2 = merkleroot(tree2)

    send_mediated_transfer0 = MediatedTransfer(
        identifier=1,
        nonce=1,
        token=token_address,
        channel=test_channel.channel_address,
        transferred_amount=0,
        recipient=address2,
        locksroot=locksroot2,
        lock=lock2,
        target=address2,
        initiator=address1,
        fee=0,
    )
    send_mediated_transfer0.sign(privkey1, address1)

    # address1 balance is all locked
    with pytest.raises(InsufficientBalance):
        test_channel.register_transfer(
            block_number,
            send_mediated_transfer0,
        )
Esempio n. 52
0
def create_square_network_topology(
        payment_network_state,
        token_network_state,
        our_address,
) -> typing.Tuple[
    TokenNetworkState,
    typing.List[typing.Address],
    typing.List[NettingChannelState],
]:
    open_block_number = 10
    pseudo_random_generator = random.Random()
    pkey1, address1 = factories.make_privkey_address()
    pkey2, address2 = factories.make_privkey_address()
    pkey3, address3 = factories.make_privkey_address()

    # Create a network with the following topology
    #
    # our  ----- 50 ---->  (1)
    #  |                    ^
    #  |                    |
    # 100                  100
    #  |                    |
    #  v                    |
    # (2)  ----- 100 --->  (3)

    channel_state1 = factories.make_channel(
        our_balance=50,
        our_address=our_address,
        partner_balance=0,
        partner_address=address1,
    )
    channel_state2 = factories.make_channel(
        our_balance=100,
        our_address=our_address,
        partner_balance=0,
        partner_address=address2,
    )

    # create new channels as participant
    channel_new_state_change1 = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_state=channel_state1,
        block_number=open_block_number,
    )
    channel_new_state_change2 = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_state=channel_state2,
        block_number=open_block_number,
    )

    channel_new_iteration1 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=token_network_state,
        state_change=channel_new_state_change1,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number,
    )

    channel_new_iteration2 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=channel_new_iteration1.new_state,
        state_change=channel_new_state_change2,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number,
    )

    graph_state = channel_new_iteration2.new_state.network_graph
    assert len(graph_state.channel_identifier_to_participants) == 2
    assert len(graph_state.network.edges()) == 2

    # create new channels without being participant
    channel_new_state_change3 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=3,
        participant1=address2,
        participant2=address3,
        block_number=open_block_number,
    )

    channel_new_iteration3 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=channel_new_iteration2.new_state,
        state_change=channel_new_state_change3,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number + 10,
    )

    graph_state = channel_new_iteration3.new_state.network_graph
    assert len(graph_state.channel_identifier_to_participants) == 3
    assert len(graph_state.network.edges()) == 3

    channel_new_state_change4 = ContractReceiveRouteNew(
        transaction_hash=factories.make_transaction_hash(),
        token_network_identifier=token_network_state.address,
        channel_identifier=4,
        participant1=address3,
        participant2=address1,
        block_number=open_block_number,
    )
    channel_new_iteration4 = token_network.state_transition(
        payment_network_identifier=payment_network_state.address,
        token_network_state=channel_new_iteration3.new_state,
        state_change=channel_new_state_change4,
        pseudo_random_generator=pseudo_random_generator,
        block_number=open_block_number + 10,
    )

    graph_state = channel_new_iteration4.new_state.network_graph
    assert len(graph_state.channel_identifier_to_participants) == 4
    assert len(graph_state.network.edges()) == 4

    return (
        channel_new_iteration4.new_state,
        [address1, address2, address3],
        (channel_state1, channel_state2),
    )
def test_sender_cannot_overspend():
    token_address = make_address()
    privkey1, address1 = make_privkey_address()
    address2 = make_address()

    balance1 = 70
    balance2 = 110

    reveal_timeout = 5
    settle_timeout = 15
    block_number = 10

    our_state = ChannelEndState(address1, balance1, None, EMPTY_MERKLE_TREE)
    partner_state = ChannelEndState(address2, balance2, None, EMPTY_MERKLE_TREE)
    external_state = make_external_state()

    test_channel = Channel(
        our_state,
        partner_state,
        external_state,
        token_address,
        reveal_timeout,
        settle_timeout,
    )

    amount = balance1
    expiration = block_number + settle_timeout
    sent_mediated_transfer0 = test_channel.create_mediatedtransfer(
        address1,
        address2,
        fee=0,
        amount=amount,
        identifier=1,
        expiration=expiration,
        hashlock=sha3(b'test_locked_amount_cannot_be_spent'),
    )
    sent_mediated_transfer0.sign(privkey1, address1)

    test_channel.register_transfer(
        block_number,
        sent_mediated_transfer0,
    )

    lock2 = Lock(
        amount=amount,
        expiration=expiration,
        hashlock=sha3(b'test_locked_amount_cannot_be_spent2'),
    )
    leaves = [
        sha3(sent_mediated_transfer0.lock.as_bytes),
        sha3(lock2.as_bytes),
    ]
    tree2 = MerkleTreeState(compute_layers(leaves))
    locksroot2 = merkleroot(tree2)

    sent_mediated_transfer1 = MediatedTransfer(
        identifier=2,
        nonce=sent_mediated_transfer0.nonce + 1,
        token=token_address,
        channel=test_channel.channel_address,
        transferred_amount=0,
        recipient=address2,
        locksroot=locksroot2,
        lock=lock2,
        target=address2,
        initiator=address1,
        fee=0,
    )
    sent_mediated_transfer1.sign(privkey1, address1)

    # address1 balance is all locked
    with pytest.raises(InsufficientBalance):
        test_channel.register_transfer(
            block_number,
            sent_mediated_transfer1,
        )
Esempio n. 54
0
    UINT64_MAX,
    UINT256_MAX,
)
from raiden.utils import sha3
from raiden.tests.utils.tests import fixture_all_combinations
from raiden.tests.utils.factories import make_privkey_address, UNIT_CHAIN_ID
from raiden.transfer.state import EMPTY_MERKLE_ROOT
from raiden.messages import (
    DirectTransfer,
    Lock,
    LockedTransfer,
    RefundTransfer,
)


PRIVKEY, ADDRESS = make_privkey_address()
CHANNEL_ID = keccak(b'somechannel')
INVALID_ADDRESSES = [
    b' ',
    b' ' * 19,
    b' ' * 21,
]

VALID_SECRETS = [
    letter.encode() * 32
    for letter in string.ascii_uppercase[:7]
]
SECRETHASHES_SECRESTS = {
    sha3(secret): secret
    for secret in VALID_SECRETS
}