예제 #1
0
def test_pfs_rejects_capacity_update_with_wrong_nonces(
    addresses: List[Address],
    pathfinding_service_mocked_listeners: PathfindingService,
):
    pathfinding_service_mocked_listeners.chain_id = 1

    token_network = TokenNetwork(
        token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS,
        token_address=DEFAULT_TOKEN_ADDRESS,
    )

    pathfinding_service_mocked_listeners.token_networks[
        token_network.address] = token_network

    token_network.handle_channel_opened_event(
        channel_identifier=ChannelIdentifier(0),
        participant1=addresses[0],
        participant2=addresses[1],
        settle_timeout=15,
    )

    token_network.handle_channel_new_deposit_event(
        channel_identifier=ChannelIdentifier(0),
        receiver=addresses[0],
        total_deposit=100,
    )

    token_network.handle_channel_new_deposit_event(
        channel_identifier=ChannelIdentifier(0),
        receiver=addresses[1],
        total_deposit=100,
    )

    # Check that the new channel has id == 0
    assert token_network.channel_id_to_addresses[ChannelIdentifier(0)] == (
        addresses[0],
        addresses[1],
    )

    message = get_updatepfs_message(
        updating_participant=addresses[0],
        other_participant=addresses[1],
    )

    # Check first capacity update succeeded
    pathfinding_service_mocked_listeners.on_pfs_update(message)
    view_to_partner, view_from_partner = token_network.get_channel_views_for_partner(
        channel_identifier=ChannelIdentifier(0),
        updating_participant=addresses[0],
        other_participant=addresses[1],
    )
    assert view_to_partner.capacity == 90
    assert view_to_partner.update_nonce == 1
    assert view_from_partner.capacity == 110
    assert view_from_partner.update_nonce == 0

    # Send the same Capacity Update again - leads to an exception
    with pytest.raises(InvalidCapacityUpdate) as exinfo:
        pathfinding_service_mocked_listeners.on_pfs_update(message)
    assert 'Capacity Update already received' in str(exinfo.value)
예제 #2
0
    def populate_token_network(
        token_network: TokenNetwork,
        private_keys: List[str],
        addresses: List[Address],
        web3: Web3,
        channel_descriptions: List,
    ):
        for channel_id, (
                p1_index,
                p1_deposit,
                _p1_transferred_amount,
                _p1_fee,
                p2_index,
                p2_deposit,
                _p2_transferred_amount,
                _p2_fee,
        ) in enumerate(channel_descriptions):
            token_network.handle_channel_opened_event(
                ChannelIdentifier(channel_id),
                addresses[p1_index],
                addresses[p2_index],
            )

            token_network.handle_channel_new_deposit_event(
                ChannelIdentifier(channel_id),
                addresses[p1_index],
                p1_deposit,
            )
            token_network.handle_channel_new_deposit_event(
                ChannelIdentifier(channel_id),
                addresses[p2_index],
                p2_deposit,
            )
예제 #3
0
    def populate_token_network(
        token_network: TokenNetwork,
        private_keys: List[str],
        addresses: List[Address],
        web3: Web3,
        channel_descriptions: List,
    ):
        for channel_id, (
                p1_index,
                p1_deposit,
                p1_capacity,
                _p1_fee,
                p1_reveal_timeout,
                p2_index,
                p2_deposit,
                p2_capacity,
                _p2_fee,
                p2_reveal_timeout,
                settle_timeout,
        ) in enumerate(channel_descriptions):
            token_network.handle_channel_opened_event(
                ChannelIdentifier(channel_id),
                addresses[p1_index],
                addresses[p2_index],
                settle_timeout=settle_timeout,
            )

            token_network.handle_channel_new_deposit_event(
                ChannelIdentifier(channel_id),
                addresses[p1_index],
                p1_deposit,
            )
            token_network.handle_channel_new_deposit_event(
                ChannelIdentifier(channel_id),
                addresses[p2_index],
                p2_deposit,
            )

            token_network.handle_channel_balance_update_message(
                channel_identifier=ChannelIdentifier(channel_id),
                updating_participant=addresses[p1_index],
                other_participant=addresses[p2_index],
                updating_nonce=1,
                other_nonce=1,
                updating_capacity=p1_capacity,
                other_capacity=p2_capacity,
                reveal_timeout=p1_reveal_timeout,
            )
            token_network.handle_channel_balance_update_message(
                channel_identifier=ChannelIdentifier(channel_id),
                updating_participant=addresses[p2_index],
                other_participant=addresses[p1_index],
                updating_nonce=2,
                other_nonce=1,
                updating_capacity=p2_capacity,
                other_capacity=p1_capacity,
                reveal_timeout=p2_reveal_timeout,
            )
예제 #4
0
def test_balance_proof():
    # test balance proof with computed balance hash
    balance_proof = BalanceProof(
        channel_identifier=ChannelIdentifier(
            '0x3131313131313131313131313131313131313131313131313131313131313131',
        ),
        token_network_address=Address(
            '0x82dd0e0eA3E84D00Cc119c46Ee22060939E5D1FC'),
        nonce=1,
        chain_id=321,
        transferred_amount=5,
        locksroot='0x%064x' % 5,
        additional_hash='0x%064x' % 0,
    )
    serialized = balance_proof.serialize_data()

    assert serialized['channel_identifier'] == balance_proof.channel_identifier
    assert is_same_address(
        serialized['token_network_address'],
        balance_proof.token_network_address,
    )
    assert serialized['nonce'] == balance_proof.nonce
    assert serialized['chain_id'] == balance_proof.chain_id
    assert serialized['additional_hash'] == balance_proof.additional_hash
    assert serialized['balance_hash'] == balance_proof.balance_hash

    assert serialized['locksroot'] == balance_proof.locksroot
    assert serialized['transferred_amount'] == balance_proof.transferred_amount
    assert serialized['locked_amount'] == balance_proof.locked_amount

    # test balance proof with balance hash set from constructor
    balance_proof = BalanceProof(
        channel_identifier=ChannelIdentifier(
            '0x3131313131313131313131313131313131313131313131313131313131313131',
        ),
        token_network_address=Address(
            '0x82dd0e0eA3E84D00Cc119c46Ee22060939E5D1FC'),
        nonce=1,
        chain_id=321,
        balance_hash='0x%064x' % 5,
        locked_amount=0,
        additional_hash='0x%064x' % 0,
    )
    serialized = balance_proof.serialize_data()

    with pytest.raises(KeyError):
        serialized['transferred_amount']

    assert serialized['channel_identifier'] == balance_proof.channel_identifier
    assert is_same_address(
        serialized['token_network_address'],
        balance_proof.token_network_address,
    )
    assert serialized['nonce'] == balance_proof.nonce
    assert serialized['chain_id'] == balance_proof.chain_id
    assert serialized['additional_hash'] == balance_proof.additional_hash
    assert serialized['balance_hash'] == balance_proof.balance_hash
예제 #5
0
def test_put_balance_sync_check(
    api_sut: ServiceApi,
    api_url: str,
    token_networks: List[TokenNetwork],
    token_network_addresses: List[Address],
    private_keys: List[str],
):
    url = api_url + '/{}/{}/balance'.format(token_network_addresses[0], ID_12)

    token_networks[0].update_balance = mock.Mock(
        return_value=None)  # type: ignore

    balance_proof = BalanceProof(
        channel_identifier=ChannelIdentifier(ID_123),
        token_network_address=token_network_addresses[0],
        nonce=1,
        chain_id=321,
        additional_hash="0x%064x" % 0,
        balance_hash="0x%064x" % 0,
    )
    balance_proof.signature = encode_hex(
        sign_data(private_keys[0], balance_proof.serialize_bin()))

    body = balance_proof.serialize_full()

    # path channel id and BP channel id are not equal
    response = requests.put(url, json=body)
    assert response.status_code == 400
    assert response.json()['error'].startswith(
        'The channel identifier from the balance proof '
        f'({ID_123}) and the request ({ID_12}) do not match')

    balance_proof = BalanceProof(
        channel_identifier=ChannelIdentifier(ID_123),
        token_network_address=token_network_addresses[1],
        nonce=1,
        chain_id=321,
        additional_hash="0x%064x" % 0,
        balance_hash="0x%064x" % 0,
    )
    balance_proof.signature = encode_hex(
        sign_data(private_keys[0], balance_proof.serialize_bin()))

    body = balance_proof.serialize_full()

    # now the network address doesn't match
    response = requests.put(url, json=body)
    assert response.status_code == 400
    assert response.json()['error'].startswith(
        'The token network address from the balance proof')
예제 #6
0
def test_balance_proof():
    balance_proof = BalanceProof(
        channel_identifier=ChannelIdentifier(123),
        token_network_address=Address('0x82dd0e0eA3E84D00Cc119c46Ee22060939E5D1FC'),
        nonce=1,
        chain_id=321,
        balance_hash='0x%064x' % 5,
        transferred_amount=1,
        locked_amount=0,
        additional_hash='0x%064x' % 0,
    )
    serialized = balance_proof.serialize_data()

    assert serialized['channel_identifier'] == balance_proof.channel_identifier
    assert is_same_address(
        serialized['token_network_address'],
        balance_proof.token_network_address
    )
    assert serialized['nonce'] == balance_proof.nonce
    assert serialized['chain_id'] == balance_proof.chain_id
    assert serialized['additional_hash'] == balance_proof.additional_hash
    assert serialized['balance_hash'] == balance_proof.balance_hash

    with pytest.raises(KeyError):
        serialized['transferred_amount']

    balance_proof = BalanceProof(
        channel_identifier=ChannelIdentifier(123),
        token_network_address=Address('0x82dd0e0eA3E84D00Cc119c46Ee22060939E5D1FC'),
        nonce=1,
        chain_id=321,
        locksroot='0x%064x' % 5,
        transferred_amount=1,
        locked_amount=0,
        additional_hash='0x%064x' % 0,
    )
    serialized = balance_proof.serialize_data()

    assert serialized['channel_identifier'] == balance_proof.channel_identifier
    assert is_same_address(
        serialized['token_network_address'],
        balance_proof.token_network_address
    )
    assert serialized['nonce'] == balance_proof.nonce
    assert serialized['chain_id'] == balance_proof.chain_id
    assert serialized['additional_hash'] == balance_proof.additional_hash

    assert serialized['locksroot'] == balance_proof.locksroot
    assert serialized['transferred_amount'] == balance_proof.transferred_amount
    assert serialized['locked_amount'] == balance_proof.locked_amount
예제 #7
0
def test_pfs_rejects_capacity_update_with_wrong_other_participant(
    addresses: List[Address],
    pathfinding_service_mocked_listeners: PathfindingService,
):
    pathfinding_service_mocked_listeners.chain_id = 1

    token_network = TokenNetwork(
        token_network_address=DEFAULT_TOKEN_NETWORK_ADDRESS,
        token_address=DEFAULT_TOKEN_ADDRESS,
    )

    pathfinding_service_mocked_listeners.token_networks[
        token_network.address] = token_network

    token_network.handle_channel_opened_event(
        channel_identifier=ChannelIdentifier(0),
        participant1=addresses[0],
        participant2=addresses[1],
        settle_timeout=15,
    )

    token_network.handle_channel_new_deposit_event(
        channel_identifier=ChannelIdentifier(0),
        receiver=addresses[0],
        total_deposit=100,
    )

    token_network.handle_channel_new_deposit_event(
        channel_identifier=ChannelIdentifier(0),
        receiver=addresses[1],
        total_deposit=100,
    )

    # Check that the new channel has id == 0
    assert token_network.channel_id_to_addresses[ChannelIdentifier(0)] == (
        addresses[0],
        addresses[1],
    )

    message = get_updatepfs_message(
        updating_participant=addresses[0],
        other_participant=addresses[2],
    )

    with pytest.raises(InvalidCapacityUpdate) as exinfo:
        pathfinding_service_mocked_listeners.on_pfs_update(message)
    assert 'Other Participant of Capacity Update does not match' in str(
        exinfo.value)
예제 #8
0
def populate_token_networks_random(
    token_networks: List[TokenNetwork],
    private_keys: List[str],
) -> None:
    # seed for pseudo-randomness from config constant, that changes from time to time
    random.seed(NUMBER_OF_CHANNELS)

    for token_network in token_networks:
        for channel_id_int in range(NUMBER_OF_CHANNELS):
            channel_id = ChannelIdentifier(channel_id_int)

            private_key1, private_key2 = random.sample(private_keys, 2)
            address1 = Address(private_key_to_address(private_key1))
            address2 = Address(private_key_to_address(private_key2))
            fee1 = random.randint(100, 10000)
            fee2 = random.randint(100, 10000)
            token_network.handle_channel_opened_event(channel_id, address1,
                                                      address2)

            # deposit to channels
            deposit1, deposit2 = random.sample(range(1000), 2)
            address1, address2 = token_network.channel_id_to_addresses[
                channel_id]
            token_network.handle_channel_new_deposit_event(
                channel_id, address1, deposit1)
            token_network.handle_channel_new_deposit_event(
                channel_id, address2, deposit2)
            # cuts negative values of probability distribution, fix with > 0 distribution

            token_network.update_fee(channel_id, address1, channel_id + 1,
                                     fee1)

            token_network.update_fee(channel_id, address2, channel_id + 1,
                                     fee2)
예제 #9
0
def populate_token_network_random(
    token_network_model: TokenNetwork,
    private_keys: List[str],
) -> None:
    # seed for pseudo-randomness from config constant, that changes from time to time
    random.seed(NUMBER_OF_CHANNELS)

    for channel_id_int in range(NUMBER_OF_CHANNELS):
        channel_id = ChannelIdentifier(channel_id_int)

        private_key1, private_key2 = random.sample(private_keys, 2)
        address1 = Address(private_key_to_address(private_key1))
        address2 = Address(private_key_to_address(private_key2))
        token_network_model.handle_channel_opened_event(
            channel_id,
            address1,
            address2,
        )

        # deposit to channels
        deposit1, deposit2 = random.sample(range(1000), 2)
        address1, address2 = token_network_model.channel_id_to_addresses[
            channel_id]
        token_network_model.handle_channel_new_deposit_event(
            channel_id,
            address1,
            deposit1,
        )
        token_network_model.handle_channel_new_deposit_event(
            channel_id,
            address2,
            deposit2,
        )
예제 #10
0
def test_put_fee_validation(
    api_sut: ServiceApi,
    api_url: str,
    token_networks: List[TokenNetwork],
    token_network_addresses: List[Address],
    private_keys: List[str],
):
    url = api_url + '/{}/{}/fee'.format(token_network_addresses[0], ID_123)

    token_networks[0].update_fee = mock.Mock(return_value=None)  # type: ignore

    fee_info = FeeInfo(token_network_address=token_network_addresses[0],
                       channel_identifier=ChannelIdentifier(ID_123),
                       chain_id=1,
                       nonce=1,
                       relative_fee=1000)
    fee_info.signature = encode_hex(
        sign_data(private_keys[0], fee_info.serialize_bin()))

    body = fee_info.serialize_data()
    body['message_type'] = 'FeeInfo'

    # remove the fee to make it an invalid message
    del body['relative_fee']

    response = requests.put(url, json=body)
    assert response.status_code == 400
    assert response.json()['error'] == "'relative_fee' is a required property"
예제 #11
0
def test_put_fee(
    api_sut: ServiceApi,
    api_url: str,
    token_networks: List[TokenNetwork],
    token_network_addresses: List[Address],
    private_keys: List[str],
):
    url = api_url + '/{}/{}/fee'.format(token_network_addresses[0], ID_123)

    token_networks[0].update_fee = mock.Mock(return_value=None)  # type: ignore

    fee_info = FeeInfo(token_network_address=token_network_addresses[0],
                       channel_identifier=ChannelIdentifier(ID_123),
                       chain_id=1,
                       nonce=1,
                       relative_fee=1000)
    fee_info.signature = encode_hex(
        sign_data(private_keys[0], fee_info.serialize_bin()))

    body = fee_info.serialize_full()

    response = requests.put(url, json=body)
    assert response.status_code == 200
    token_networks[0].update_fee.assert_called_once()  # type: ignore
    call_args = token_networks[0].update_fee.call_args[0]  # type: ignore

    channel_id: int = call_args[0]
    sender: str = call_args[1]
    nonce: int = call_args[2]
    fee: float = call_args[3]

    assert channel_id == ID_123
    assert is_same_address(sender, private_key_to_address(private_keys[0]))
    assert nonce == 1
    assert fee == 1000
예제 #12
0
def test_put_fee_sync_check(
    api_sut: ServiceApi,
    api_url: str,
    token_networks: List[TokenNetwork],
    token_network_addresses: List[Address],
    private_keys: List[str],
):
    url = api_url + '/{}/{}/fee'.format(token_network_addresses[0], ID_12)

    token_networks[0].update_fee = mock.Mock(return_value=None)  # type: ignore

    fee_info = FeeInfo(token_network_address=token_network_addresses[0],
                       channel_identifier=ChannelIdentifier(ID_123),
                       chain_id=1,
                       nonce=1,
                       relative_fee=1000)
    fee_info.signature = encode_hex(
        sign_data(private_keys[0], fee_info.serialize_bin()))

    body = fee_info.serialize_full()

    # path channel id and FeeInfo id are not equal
    response = requests.put(url, json=body)
    assert response.status_code == 400
    assert response.json()['error'].startswith(
        'The channel identifier from the fee info '
        f'({ID_123}) and the request ({ID_12}) do not match')

    fee_info = FeeInfo(token_network_address=token_network_addresses[1],
                       channel_identifier=ChannelIdentifier(ID_123),
                       chain_id=1,
                       nonce=1,
                       relative_fee=1000)
    fee_info.signature = encode_hex(
        sign_data(private_keys[0], fee_info.serialize_bin()))

    body = fee_info.serialize_full()

    # now the network address doesn't match
    response = requests.put(url, json=body)
    assert response.status_code == 400
    assert response.json()['error'].startswith(
        'The token network address from the fee info')
예제 #13
0
def populate_token_network_random(
    token_network_model: TokenNetwork,
    private_keys: List[str],
) -> None:
    # seed for pseudo-randomness from config constant, that changes from time to time
    random.seed(NUMBER_OF_CHANNELS)

    for channel_id_int in range(NUMBER_OF_CHANNELS):
        channel_id = ChannelIdentifier(channel_id_int)

        private_key1, private_key2 = random.sample(private_keys, 2)
        address1 = Address(private_key_to_address(private_key1))
        address2 = Address(private_key_to_address(private_key2))
        settle_timeout = 15
        token_network_model.handle_channel_opened_event(
            channel_id,
            address1,
            address2,
            settle_timeout,
        )

        # deposit to channels
        deposit1, deposit2 = random.sample(range(1000), 2)
        address1, address2 = token_network_model.channel_id_to_addresses[
            channel_id]
        token_network_model.handle_channel_new_deposit_event(
            channel_id,
            address1,
            deposit1,
        )
        token_network_model.handle_channel_new_deposit_event(
            channel_id,
            address2,
            deposit2,
        )
        token_network_model.handle_channel_balance_update_message(
            channel_identifier=channel_id,
            updating_participant=address1,
            other_participant=address2,
            updating_nonce=1,
            other_nonce=1,
            updating_capacity=deposit1,
            other_capacity=deposit2,
            reveal_timeout=2,
        )
        token_network_model.handle_channel_balance_update_message(
            channel_identifier=channel_id,
            updating_participant=address2,
            other_participant=address1,
            updating_nonce=2,
            other_nonce=1,
            updating_capacity=deposit1,
            other_capacity=deposit2,
            reveal_timeout=2,
        )
예제 #14
0
def test_edge_weight(addresses):
    channel_id = ChannelIdentifier(1)
    participant1 = addresses[0]
    participant2 = addresses[1]
    settle_timeout = 15
    view = ChannelView(channel_id, participant1, participant2, settle_timeout)

    assert TokenNetwork.edge_weight(
        dict(),
        dict(view=view),
    ) == 1
예제 #15
0
    def open_channel(self, partner_address: Address) -> ChannelIdentifier:
        """Opens channel with a single partner
        Parameters:
            partner_address - a valid ethereum address of the partner
        Return:
            channel_id - id of the channel
        """
        assert is_checksum_address(partner_address)
        assert partner_address in self.client_registry
        # disallow multiple open channels with a same partner
        if partner_address in self.partner_to_channel_id:
            return self.partner_to_channel_id[partner_address]
        # if it doesn't exist, register new channel
        txid = self.contract.functions.openChannel(
            self.address,
            partner_address,
            15,
        ).transact({'from': self.address})
        assert txid is not None
        tx = self.web3.eth.getTransactionReceipt(txid)
        assert tx is not None
        assert len(tx['logs']) == 1
        event = get_event_data(
            find_matching_event_abi(self.contract.abi, 'ChannelOpened'),
            tx['logs'][0],
        )

        channel_id = event['args']['channel_identifier']
        assert isinstance(channel_id, T_ChannelIdentifier)
        assert channel_id > 0 and channel_id <= UINT256_MAX
        assert (is_same_address(event['args']['participant1'], self.address) or
                is_same_address(event['args']['participant2'], self.address))
        assert (is_same_address(event['args']['participant1'], partner_address)
                or is_same_address(event['args']['participant2'],
                                   partner_address))

        self.partner_to_channel_id[partner_address] = ChannelIdentifier(
            channel_id)
        self.client_registry[partner_address].open_channel(self.address)

        return ChannelIdentifier(channel_id)
예제 #16
0
def test_put_balance(
    api_sut: ServiceApi,
    api_url: str,
    token_networks: List[TokenNetwork],
    token_network_addresses: List[Address],
    private_keys: List[str],
):
    url = api_url + '/{}/{}/balance'.format(token_network_addresses[0], ID_123)

    token_networks[0].update_balance = mock.Mock(
        return_value=None)  # type: ignore

    balance_proof = BalanceProof(
        channel_identifier=ChannelIdentifier(ID_123),
        token_network_address=token_network_addresses[0],
        nonce=1,
        chain_id=1,
        locksroot="0x%064x" % 0,
        transferred_amount=1,
        locked_amount=0,
        additional_hash="0x%064x" % 0,
    )
    balance_proof.signature = encode_hex(
        sign_data(private_keys[0], balance_proof.serialize_bin()))

    body = balance_proof.serialize_full()

    response = requests.put(url, json=body)
    assert response.status_code == 200

    token_networks[0].update_balance.assert_called_once()  # type: ignore
    call_args = token_networks[0].update_balance.call_args[0]  # type: ignore

    channel_identifier: ChannelIdentifier = call_args[0]
    signer: Address = call_args[1]
    nonce: int = call_args[2]
    transferred_amount: int = call_args[3]
    locked_amount: int = call_args[4]

    assert channel_identifier == ID_123
    assert is_same_address(signer, private_key_to_address(private_keys[0]))
    assert nonce == 1
    assert transferred_amount == 1
    assert locked_amount == 0
예제 #17
0
    def f(
        channel_identifier: ChannelIdentifier = None,
        contract_address: Address = None
    ):
        contract_address = contract_address or get_random_address()
        channel_identifier = channel_identifier or ChannelIdentifier(random.randint(0, UINT64_MAX))

        balance_hash_data = '%d' % random.randint(0, UINT64_MAX)
        additional_hash_data = '%d' % random.randint(0, UINT64_MAX)

        balance_proof = BalanceProof(
            channel_identifier,
            contract_address,
            balance_hash=keccak_256(balance_hash_data.encode()).hexdigest(),
            nonce=random.randint(0, UINT64_MAX),
            additional_hash=keccak_256(additional_hash_data.encode()).hexdigest(),
            chain_id=1,
        )
        return balance_proof
예제 #18
0
def test_put_balance_validation(api_sut: ServiceApi, api_url: str,
                                token_network_addresses: List[Address]):
    url = api_url + '/{}/{}/balance'.format(token_network_addresses[0], ID_123)

    body: Dict = dict()
    response = requests.put(url, json=body)
    assert response.status_code == 400
    assert response.json()['error'] == "'message_type' is a required property"

    # here the balance_hash property is missing
    body = dict(
        message_type='BalanceProof',
        channel_identifier=ChannelIdentifier(ID_123),
        token_network_address=token_network_addresses[1],
        nonce=1,
        chain_id=321,
        additional_hash="0x%064x" % 0,
    )
    response = requests.put(url, json=body)
    assert response.status_code == 400
    assert response.json()['error'] == "'balance_hash' is a required property"
예제 #19
0
    def populate_token_networks(token_networks: List[TokenNetwork],
                                private_keys: List[str],
                                addresses: List[Address], web3: Web3,
                                channel_descriptions: List):
        for channel_id, (p1_index, p1_deposit, p1_transferred_amount, p1_fee,
                         p2_index, p2_deposit, p2_transferred_amount,
                         p2_fee) in enumerate(channel_descriptions):
            for token_network in token_networks:
                token_network.handle_channel_opened_event(
                    ChannelIdentifier(channel_id), addresses[p1_index],
                    addresses[p2_index])

                token_network.handle_channel_new_deposit_event(
                    ChannelIdentifier(channel_id), addresses[p1_index],
                    p1_deposit)
                token_network.handle_channel_new_deposit_event(
                    ChannelIdentifier(channel_id), addresses[p2_index],
                    p2_deposit)

                token_network.update_balance(ChannelIdentifier(channel_id),
                                             addresses[p1_index], 1,
                                             p1_transferred_amount, 0)
                token_network.update_balance(ChannelIdentifier(channel_id),
                                             addresses[p2_index], 1,
                                             p2_transferred_amount, 0)

                token_network.update_fee(
                    channel_identifier=ChannelIdentifier(channel_id),
                    signer=addresses[p1_index],
                    nonce=channel_id + 1,
                    relative_fee=p1_fee)
                token_network.update_fee(
                    channel_identifier=ChannelIdentifier(channel_id),
                    signer=addresses[p2_index],
                    nonce=channel_id + 1,
                    relative_fee=p2_fee)
예제 #20
0
 def f():
     return ChannelIdentifier(random.randint(0, UINT256_MAX))
예제 #21
0
def test_pfs_with_mocked_events(
    token_network_model: TokenNetwork,
    addresses: List[Address],
    pathfinding_service_mocked_listeners: PathfindingService,
    channel_descriptions_case_1: List,
):
    registry_listener = pathfinding_service_mocked_listeners.token_network_registry_listener
    # assert registry_listener

    token_network_address = token_network_model.address

    # this is a new pathfinding service, there should be no token networks registered
    assert len(pathfinding_service_mocked_listeners.token_networks.keys()) == 0

    # emit a TokenNetworkCreated event
    registry_listener.emit_event(
        dict(
            event='TokenNetworkCreated',
            blockNumber=12,
            args=dict(
                token_network_address=token_network_address,
                token_address=token_network_model.token_address,
            ),
        ))

    # now there should be a token network registered
    assert token_network_address in pathfinding_service_mocked_listeners.token_networks
    token_network = pathfinding_service_mocked_listeners.token_networks[
        token_network_address]

    assert len(
        pathfinding_service_mocked_listeners.token_network_listeners) == 1
    network_listener = pathfinding_service_mocked_listeners.token_network_listeners[
        0]

    # Now initialize some channels in this network.
    for index, (
            p1_index,
            p1_deposit,
            p1_capacity,
            _p1_fee,
            p1_reveal_timeout,
            p2_index,
            p2_deposit,
            p2_capacity,
            _p2_fee,
            p2_reveal_timeout,
            settle_timeout,
    ) in enumerate(channel_descriptions_case_1):
        network_listener.emit_event(
            dict(
                address=token_network_address,
                event='ChannelOpened',
                args=dict(
                    channel_identifier=index,
                    participant1=addresses[p1_index],
                    participant2=addresses[p2_index],
                    settle_timeout=settle_timeout,
                ),
            ))

        network_listener.emit_event(
            dict(
                address=token_network_address,
                event='ChannelNewDeposit',
                args=dict(
                    channel_identifier=index,
                    participant=addresses[p1_index],
                    total_deposit=p1_deposit,
                ),
            ))

        network_listener.emit_event(
            dict(
                address=token_network_address,
                event='ChannelNewDeposit',
                args=dict(
                    channel_identifier=index,
                    participant=addresses[p2_index],
                    total_deposit=p2_deposit,
                ),
            ))

        token_network.handle_channel_balance_update_message(
            channel_identifier=ChannelIdentifier(index),
            updating_participant=addresses[p1_index],
            other_participant=addresses[p2_index],
            updating_nonce=1,
            other_nonce=1,
            updating_capacity=p1_capacity,
            other_capacity=p2_capacity,
            reveal_timeout=p1_reveal_timeout,
        )
        token_network.handle_channel_balance_update_message(
            channel_identifier=ChannelIdentifier(index),
            updating_participant=addresses[p2_index],
            other_participant=addresses[p1_index],
            updating_nonce=2,
            other_nonce=1,
            updating_capacity=p2_capacity,
            other_capacity=p1_capacity,
            reveal_timeout=p2_reveal_timeout,
        )

    # now there should be seven channels
    assert len(token_network.channel_id_to_addresses.keys()) == 7
    # check that deposits got registered
    for index, (
            p1_index,
            p1_deposit,
            _p1_capacity,
            _p1_fee,
            _p1_reveal_timeout,
            p2_index,
            p2_deposit,
            _p2_capacity,
            _p2_fee,
            _p2_reveal_timeout,
            _settle_timeout,
    ) in enumerate(channel_descriptions_case_1):
        p1, p2 = token_network.channel_id_to_addresses[ChannelIdentifier(
            index)]
        assert p1 == addresses[p1_index]
        assert p2 == addresses[p2_index]

        view1 = token_network.G[p1][p2]['view']
        view2 = token_network.G[p2][p1]['view']

        assert view1.deposit == p1_deposit
        assert view2.deposit == p2_deposit

    # check pathfinding with respecting transferred amounts
    # channel 2 <-> 3 has settle_timeout 3, so path is not eligible
    # channel 0 <-> 2 has no capacity
    paths = token_network.get_paths(addresses[0], addresses[3], 10, 5)
    assert len(paths) == 1
    assert paths[0]['path'] == [
        addresses[0], addresses[1], addresses[4], addresses[3]
    ]

    # check pathfinding without having enough capacity on 2 <-> 1 and not on 2 <-> 3 <-> 4 <-> 1
    # so only 1 path is provided
    paths2 = token_network.get_paths(addresses[2], addresses[1], 85, 5)
    assert len(paths2) == 1
    assert paths2[0]['path'] == [addresses[2], addresses[0], addresses[1]]

    # wow close all channels
    for index, (
            p1_index,
            _p1_deposit,
            _p1_capacity,
            _p1_fee,
            _p1_reveal_timeout,
            _p2_index,
            _p2_deposit,
            _p2_capacity,
            _p2_fee,
            _p2_reveal_timeout,
            _settle_timeout,
    ) in enumerate(channel_descriptions_case_1):
        network_listener.emit_event(
            dict(
                address=token_network_address,
                event='ChannelClosed',
                args=dict(
                    channel_identifier=index,
                    closing_participant=addresses[p1_index],
                ),
            ))

    # there should be no channels
    assert len(token_network.channel_id_to_addresses.keys()) == 0