Exemplo n.º 1
0
    def on_generic_introduction_request(self, source_address, data, prefix):
        auth, dist, payload = self._ez_unpack_auth(IntroductionRequestPayload,
                                                   data)
        peer = Peer(auth.public_key_bin, source_address)
        peer.last_response = time.time()

        self.network.add_verified_peer(peer)
        self.network.discover_services(peer, [
            prefix[2:],
        ])

        intro_peers = [
            p for p in self.network.get_peers_for_service(prefix[2:])
            if not (p == peer)
        ]
        if intro_peers:
            intro_peer = random.choice(intro_peers)
        else:
            intro_peer = None

        packet = self.create_introduction_response(payload.destination_address,
                                                   peer.address,
                                                   payload.identifier,
                                                   introduction=intro_peer)

        packet = prefix + packet[22:-self.signature_length]
        signature = default_eccrypto.create_signature(self.my_peer.key, packet)

        self.endpoint.send(peer.address, packet + signature)
Exemplo n.º 2
0
    def test_query_on_introduction(self):
        """
        Test querying a peer that was just introduced to us.
        """

        send_ok = []

        def mock_send(_):
            send_ok.append(1)

        self.nodes[1].overlay.send_remote_select_subscribed_channels = mock_send
        peer = self.nodes[0].my_peer
        self.nodes[1].overlay.introduction_response_callback(peer, None, None)
        self.assertIn(peer.mid, self.nodes[1].overlay.queried_subscribed_channels_peers)
        self.assertTrue(send_ok)

        # Make sure the same peer will not be queried twice in case the walker returns to it
        self.nodes[1].overlay.introduction_response_callback(peer, None, None)
        self.assertEqual(len(send_ok), 1)

        # Test clearing queried peers set when it outgrows its capacity
        self.nodes[1].overlay.queried_peers_limit = 2
        self.nodes[1].overlay.introduction_response_callback(Peer(default_eccrypto.generate_key("low")), None, None)
        self.assertEqual(len(self.nodes[1].overlay.queried_subscribed_channels_peers), 2)

        self.nodes[1].overlay.introduction_response_callback(Peer(default_eccrypto.generate_key("low")), None, None)
        self.assertEqual(len(self.nodes[1].overlay.queried_subscribed_channels_peers), 1)
Exemplo n.º 3
0
    def on_generic_introduction_request(self, source_address, data, prefix):
        auth, dist, payload = self._ez_unpack_auth(IntroductionRequestPayload,
                                                   data)
        peer = Peer(auth.public_key_bin, source_address)
        peer.address = UDPv4LANAddress(*payload.source_lan_address)
        peer.last_response = time.time()

        service_id = prefix[2:]
        self.on_peer_introduction_request(peer, source_address, service_id)

        self.network.add_verified_peer(peer)
        self.network.discover_services(peer, [
            service_id,
        ])

        intro_peers = [
            p for p in self.network.get_peers_for_service(service_id)
            if not p == peer
        ]
        if intro_peers:
            intro_peer = random.choice(intro_peers)
        else:
            intro_peer = None

        packet = self.create_introduction_response(payload.destination_address,
                                                   peer.address,
                                                   payload.identifier,
                                                   introduction=intro_peer,
                                                   prefix=prefix)
        self.endpoint.send(peer.address, packet)
Exemplo n.º 4
0
        def __init__(self, configuration, endpoint_override=None, enable_statistics=False, extra_communities=None):
            if endpoint_override:
                self.endpoint = endpoint_override
            else:
                self.endpoint = UDPEndpoint(port=configuration['port'], ip=configuration['address'])
                self.endpoint.open()
                if enable_statistics:
                    self.endpoint = StatisticsEndpoint(self, self.endpoint)

            self.network = Network()

            # Load/generate keys
            self.keys = {}
            for key_block in configuration['keys']:
                if key_block['file'] and isfile(key_block['file']):
                    with open(key_block['file'], 'r') as f:
                        content = f.read()
                        try:
                            # IPv8 Standardized bin format
                            self.keys[key_block['alias']] = Peer(default_eccrypto.key_from_private_bin(content))
                        except ValueError:
                            try:
                                # Try old Tribler M2Crypto PEM format
                                content = b64decode(content[31:-30].replace('\n', ''))
                                peer = Peer(M2CryptoSK(keystring=content))
                                peer.mid # This will error out if the keystring is not M2Crypto
                                self.keys[key_block['alias']] = peer
                            except:
                                # Try old LibNacl format
                                content = "LibNaCLSK:" + content
                                self.keys[key_block['alias']] = Peer(default_eccrypto.key_from_private_bin(content))
                else:
                    self.keys[key_block['alias']] = Peer(default_eccrypto.generate_key(key_block['generation']))
                    if key_block['file']:
                        with open(key_block['file'], 'w') as f:
                            f.write(self.keys[key_block['alias']].key.key_to_bin())

            # Setup logging
            logging.basicConfig(**configuration['logger'])

            self.overlay_lock = RLock()
            self.strategies = []
            self.overlays = []

            for overlay in configuration['overlays']:
                overlay_class = _COMMUNITIES.get(overlay['class'], (extra_communities or {}).get(overlay['class']))
                my_peer = self.keys[overlay['key']]
                overlay_instance = overlay_class(my_peer, self.endpoint, self.network, **overlay['initialize'])
                self.overlays.append(overlay_instance)
                for walker in overlay['walkers']:
                    strategy_class = _WALKERS.get(walker['strategy'],
                                                  overlay_instance.get_available_strategies().get(walker['strategy']))
                    args = walker['init']
                    target_peers = walker['peers']
                    self.strategies.append((strategy_class(overlay_instance, **args), target_peers))
                for config in overlay['on_start']:
                    reactor.callWhenRunning(getattr(overlay_instance, config[0]), *config[1:])

            self.state_machine_lc = LoopingCall(self.on_tick)
            self.state_machine_lc.start(configuration['walker_interval'], False)
Exemplo n.º 5
0
def setup_test(window=1, packet_size=1000, packets=10000):
    """
    Create two nodes who will be sending packets to each other.

    :param window: the window size for packets (1 is synchronous)
    :param packet_size: the size of each packet
    :param packets: the number of packets to send in the experiment
    :return: the deferred that fires once the experiment is complete
    """
    configuration = get_default_configuration()
    configuration['overlays'] = []
    configuration['keys'] = []

    master_peer = Peer(ECCrypto().generate_key(u"low"))

    peer_ipv8 = IPv8(configuration)
    peer_ipv8.keys = {'my_peer': Peer(ECCrypto().generate_key(u"low"))}
    peer_ipv8.overlays = [
        LoadOverlay(master_peer, peer_ipv8.keys['my_peer'], peer_ipv8.endpoint,
                    peer_ipv8.network, window, packet_size, packets)
    ]

    counterparty_ipv8 = IPv8(configuration)
    counterparty_ipv8.keys = {'my_peer': Peer(ECCrypto().generate_key(u"low"))}
    counterparty_ipv8.overlays = [
        LoadOverlay(master_peer, counterparty_ipv8.keys['my_peer'],
                    counterparty_ipv8.endpoint, counterparty_ipv8.network, 0,
                    packet_size, packets)
    ]

    peer_ipv8.overlays[0].send(counterparty_ipv8.endpoint.get_address())

    return DeferredList(
        [peer_ipv8.overlays[0].done, counterparty_ipv8.overlays[0].done])
Exemplo n.º 6
0
    def test_query_on_introduction(self):
        """
        Test querying a peer that was just introduced to us.
        """

        send_ok = []

        def mock_send(_):
            send_ok.append(1)

        self.nodes[1].overlay.send_remote_select_subscribed_channels = mock_send
        peer = self.nodes[0].my_peer
        payload = Mock()
        self.nodes[1].overlay.introduction_response_callback(peer, None, payload)
        self.assertIn(peer.mid, self.nodes[1].overlay.queried_peers)
        self.assertTrue(send_ok)

        # Make sure the same peer will not be queried twice in case the walker returns to it
        self.nodes[1].overlay.introduction_response_callback(peer, None, payload)
        self.assertEqual(len(send_ok), 1)

        # Test clearing queried peers set when it outgrows its capacity
        self.nodes[1].overlay.settings.queried_peers_limit = 2
        self.nodes[1].overlay.introduction_response_callback(Peer(default_eccrypto.generate_key("low")), None, payload)
        self.assertEqual(len(self.nodes[1].overlay.queried_peers), 2)

        self.nodes[1].overlay.introduction_response_callback(Peer(default_eccrypto.generate_key("low")), None, payload)
        # The set has been cleared, so the number of queried peers must be dropped back to 1
        self.assertEqual(len(self.nodes[1].overlay.queried_peers), 1)

        # Ensure that we're not going to query ourselves
        self.nodes[1].overlay.introduction_response_callback(self.nodes[1].overlay.my_peer, None, payload)
        self.assertEqual(len(send_ok), 3)
Exemplo n.º 7
0
    def received_transaction(self, source_address: Address, data: bytes) -> None:
        """
        Callback when we receive a transaction from another peer.
        :param source_address: The network address of the peer that has sent us the transaction.
        :param data: The serialized, raw data in the packet.
        """
        payload = self._ez_unpack_noauth(BandwidthTransactionPayload, data, global_time=False)
        tx = BandwidthTransactionData.from_payload(payload)

        if not tx.is_valid():
            self.logger.info("Transaction %s not valid, ignoring it", tx)
            return

        if payload.public_key_a == self.my_pk or payload.public_key_b == self.my_pk:
            # This transaction involves this peer.
            latest_tx = self.database.get_latest_transaction(tx.public_key_a, tx.public_key_b)
            if payload.public_key_b == self.my_peer.public_key.key_to_bin():
                from_peer = Peer(payload.public_key_a, source_address)
                if latest_tx:
                    # Check if the amount in the received transaction is higher than the amount of the latest one
                    # in the database.
                    if payload.amount > latest_tx.amount:
                        # Sign it, store it, and send it back
                        tx.sign(self.my_peer.key, as_a=False)
                        self.database.BandwidthTransaction.insert(tx)
                        self.send_transaction(tx, from_peer.address, payload.request_id)
                    else:
                        self.logger.info("Received older bandwidth transaction - sending back the latest one")
                        self.send_transaction(latest_tx, from_peer.address, payload.request_id)
                else:
                    # This transaction is the first one with party A. Sign it, store it, and send it back.
                    tx.sign(self.my_peer.key, as_a=False)
                    self.database.BandwidthTransaction.insert(tx)
                    from_peer = Peer(payload.public_key_a, source_address)
                    self.send_transaction(tx, from_peer.address, payload.request_id)
            elif payload.public_key_a == self.my_peer.public_key.key_to_bin():
                # It seems that we initiated this transaction. Check if we are waiting for it.
                cache = self.request_cache.get("bandwidth-tx-sign", payload.request_id)
                if not cache:
                    self.logger.info("Received bandwidth transaction %s without associated cache entry, ignoring it",
                                     tx)
                    return

                if not latest_tx or (latest_tx and latest_tx.amount >= tx.amount):
                    self.database.BandwidthTransaction.insert(tx)

                cache.future.set_result(tx)
        else:
            # This transaction involves two unknown peers. We can add it to our database.
            self.database.BandwidthTransaction.insert(tx)
Exemplo n.º 8
0
    async def test_send_random_multiple_torrents(self):
        """
        Test whether sending a single channel with a multiple torrents to another peer works correctly
        """
        with db_session:
            channel = self.nodes[0].overlay.metadata_store.ChannelMetadata.create_channel("test", "bla")
            for _ in range(10):
                self.add_random_torrent(self.nodes[0].overlay.metadata_store.TorrentMetadata, channel=channel)
            channel.commit_channel_torrent()

        await self.nodes[0].overlay.prepare_gossip_blob_cache()
        self.nodes[0].overlay.send_random_to(Peer(self.nodes[1].my_peer.public_key, self.nodes[1].endpoint.wan_address))

        await self.deliver_messages(timeout=0.5)

        with db_session:
            channel = self.nodes[1].overlay.metadata_store.ChannelMetadata.get()
            torrents1 = self.nodes[1].overlay.metadata_store.TorrentMetadata.select()[:]
            self.assertLess(channel.contents_len, 10)
            self.assertLess(0, channel.contents_len)

        # We must delete the old and create all-new torrent entries for the next test.
        # Otherwise, it becomes non-deterministic.
        with db_session:
            channel = self.nodes[0].overlay.metadata_store.ChannelMetadata.get()
            self.nodes[0].overlay.metadata_store.TorrentMetadata.select(
                lambda g: g.metadata_type == REGULAR_TORRENT
            ).delete()
            self.nodes[1].overlay.metadata_store.TorrentMetadata.select().delete()

            for _ in range(10):
                self.add_random_torrent(self.nodes[0].overlay.metadata_store.TorrentMetadata, channel=channel)
            channel.commit_channel_torrent()

        # Initiate the gossip again. This time, it should be sent from the blob cache
        # so the torrents on the receiving end should not change this time.
        self.nodes[0].overlay.send_random_to(Peer(self.nodes[1].my_peer.public_key, self.nodes[1].endpoint.wan_address))

        await self.deliver_messages(timeout=0.5)
        with db_session:
            torrents2 = self.nodes[1].overlay.metadata_store.TorrentMetadata.select()[:]
            self.assertEqual(len(torrents1), len(torrents2))

        await self.nodes[0].overlay.prepare_gossip_blob_cache()
        self.nodes[0].overlay.send_random_to(Peer(self.nodes[1].my_peer.public_key, self.nodes[1].endpoint.wan_address))

        await self.deliver_messages(timeout=0.5)
        with db_session:
            torrents3 = self.nodes[1].overlay.metadata_store.TorrentMetadata.select()[:]
            self.assertLess(len(torrents2), len(torrents3))
Exemplo n.º 9
0
    def test_strategy_multi_peer(self):
        """
        If we have multiple peers, we should select one and send it our channel views.
        Also, we should still inspect our download queue.
        """
        self.community.get_peers_return = [
            Peer(default_eccrypto.generate_key(u"very-low")),
            Peer(default_eccrypto.generate_key(u"very-low")),
            Peer(default_eccrypto.generate_key(u"very-low")),
        ]
        self.strategy.take_step()

        self.assertEqual(1, len(self.community.send_random_to_called))
        self.assertIn(self.community.send_random_to_called[0], self.community.get_peers_return)
Exemplo n.º 10
0
    def test_channels_peers_mapping_drop_excess_peers(self):
        """
        Test dropping old excess peers from a channel to peers mapping
        """
        mapping = ChannelsPeersMapping()
        chan_pk = Mock()
        chan_id = 123

        num_excess_peers = 20
        t = time.time() - 1000
        first_peer_timestamp = t
        for k in range(0, mapping.max_peers_per_channel + num_excess_peers):
            peer = Peer(default_eccrypto.generate_key("very-low"),
                        ("1.2.3.4", 5))
            peer.last_response = t
            t += 1.0
            mapping.add(peer, chan_pk, chan_id)
            if k == 0:
                first_peer_timestamp = peer.last_response

        chan_peers_3 = mapping.get_last_seen_peers_for_channel(
            chan_pk, chan_id, 3)
        assert len(chan_peers_3) == 3

        chan_peers = mapping.get_last_seen_peers_for_channel(chan_pk, chan_id)
        assert len(chan_peers) == mapping.max_peers_per_channel

        assert chan_peers_3 == chan_peers[0:3]
        assert chan_peers == sorted(chan_peers,
                                    key=lambda x: x.last_response,
                                    reverse=True)

        # Make sure only the older peers are dropped as excess
        for p in chan_peers:
            assert p.last_response > first_peer_timestamp

        # Test removing a peer directly, e.g. as a result of a query timeout
        peer = Peer(default_eccrypto.generate_key("very-low"), ("1.2.3.4", 5))
        mapping.add(peer, chan_pk, chan_id)
        mapping.remove_peer(peer)
        for p in chan_peers:
            mapping.remove_peer(p)

        assert mapping.get_last_seen_peers_for_channel(chan_pk, chan_id) == []

        # Make sure the stuff is cleaned up
        assert len(mapping._peers_channels) == 0
        assert len(mapping._channels_dict) == 0
Exemplo n.º 11
0
    async def on_payout_block(self, source_address, data):
        if not self.bandwidth_wallet:
            self.logger.warning(
                "Got payout while not having a TrustChain community running!")
            return

        payload = self._ez_unpack_noauth(PayoutPayload,
                                         data,
                                         global_time=False)
        peer = Peer(payload.public_key, source_address)
        block = TriblerBandwidthBlock.from_payload(payload, self.serializer)

        try:
            blocks = await self.bandwidth_wallet.trustchain.process_half_block(
                block, peer)
        except:
            return

        # Send the next payout
        if blocks and payload.circuit_id in self.relay_from_to and block.transaction[
                b'down'] > payload.base_amount:
            relay = self.relay_from_to[payload.circuit_id]
            self._logger.info("Sending next payout to peer %s", relay.peer)
            self.do_payout(
                relay.peer, relay.circuit_id,
                block.transaction[b'down'] - payload.base_amount * 2,
                payload.base_amount)

        # Check whether the block has been added to the database and has been verified
        if not self.bandwidth_wallet.trustchain.persistence.contains(block):
            self.logger.warning(
                "Not proceeding with payout - received payout block is not valid"
            )
            return
Exemplo n.º 12
0
    def test_peer_inequality_address(self):
        """
        Check if peers with the same key and a different address are not equal.
        """
        other = Peer(self.peer.key)

        self.assertNotEqual(self.peer, other)
Exemplo n.º 13
0
    def test_peer_inequality_key(self):
        """
        Check if peers with a different key and same address are not equal.
        """
        other = Peer(ECCrypto().generate_key(u"very-low"), self.peer.address)

        self.assertNotEqual(self.peer, other)
Exemplo n.º 14
0
    def test_peer_equality(self):
        """
        Check if peers with the same key and address are equal.
        """
        other = Peer(self.peer.key, self.peer.address)

        self.assertEqual(self.peer, other)
Exemplo n.º 15
0
class MyCommunity(Community):
    master_peer = Peer(ECCrypto().generate_key(u"medium"))

    def started(self):
        async def check_peers():
            global INSTANCES, LOW_EDGE, LOW_EDGE_PEER, START_TIME
            if self.get_peers():
                if LOW_EDGE and self.my_peer != LOW_EDGE_PEER:
                    print("%.4f,%.4f" % (LOW_EDGE, time.time() - START_TIME))

                    async def shutdown():
                        for instance in INSTANCES:
                            await instance.stop(False)
                        get_event_loop().stop()

                    ensure_future(shutdown())
                else:
                    LOW_EDGE = time.time() - START_TIME
                    LOW_EDGE_PEER = self.my_peer

        self.register_task("check_peers", check_peers, interval=0.1, delay=0)

    def create_introduction_response(self,
                                     lan_socket_address,
                                     socket_address,
                                     identifier,
                                     introduction=None):
        return super(MyCommunity, self).create_introduction_response(
            lan_socket_address, socket_address, identifier, introduction, b'1')

    def create_introduction_request(self, socket_address):
        return super(MyCommunity,
                     self).create_introduction_request(socket_address, b'2')
Exemplo n.º 16
0
class MyCommunity(Community):
    master_peer = Peer(ECCrypto().generate_key(u"medium"))

    def started(self):
        def check_peers():
            global INSTANCES, LOW_EDGE, LOW_EDGE_PEER, START_TIME
            if self.get_peers():
                if LOW_EDGE and self.my_peer != LOW_EDGE_PEER:
                    for instance in INSTANCES:
                        instance.stop(False)
                    reactor.callFromThread(reactor.stop)
                    print("%.4f,%.4f" % (LOW_EDGE, time.time() - START_TIME))
                else:
                    LOW_EDGE = time.time() - START_TIME
                    LOW_EDGE_PEER = self.my_peer

        self.register_task("check_peers",
                           LoopingCall(check_peers)).start(0.1, True)

    def create_introduction_response(self,
                                     lan_socket_address,
                                     socket_address,
                                     identifier,
                                     introduction=None):
        return super(MyCommunity, self).create_introduction_response(
            lan_socket_address, socket_address, identifier, introduction, b'1')

    def create_introduction_request(self, socket_address):
        return super(MyCommunity,
                     self).create_introduction_request(socket_address, b'2')
Exemplo n.º 17
0
    async def test_send_personal_and_random_channels(self):
        """
        Test whether sending the personal channel works correctly
        """
        with db_session:
            # Add non-personal channel
            channel = self.nodes[0].overlay.metadata_store.ChannelMetadata.create_channel("non-personal", "bla")
            self.add_random_torrent(self.nodes[0].overlay.metadata_store.TorrentMetadata, channel=channel)
            channel.commit_channel_torrent()

            # Add personal channel
            self.nodes[0].overlay.metadata_store.ChannelNode._my_key = default_eccrypto.generate_key(u"curve25519")
            # After the previous line the previously created channel becomes non-personal
            channel = self.nodes[0].overlay.metadata_store.ChannelMetadata.create_channel("personal", "bla")
            self.add_random_torrent(self.nodes[0].overlay.metadata_store.TorrentMetadata, channel=channel)
            channel.commit_channel_torrent()

        await self.nodes[0].overlay.prepare_gossip_blob_cache()
        self.nodes[0].overlay.send_random_to(Peer(self.nodes[1].my_peer.public_key, self.nodes[1].endpoint.wan_address))
        await self.deliver_messages(timeout=0.5)
        with db_session:
            self.assertEqual(len(self.nodes[1].overlay.metadata_store.ChannelMetadata.select()), 2)
            channels = self.nodes[1].overlay.metadata_store.ChannelMetadata.select()[:]
            self.assertEqual(channels[0].contents_len, 1)
            self.assertEqual(channels[1].contents_len, 1)
Exemplo n.º 18
0
    def create_node(self):
        config = TunnelCommunitySettings()
        mock_ipv8 = MockIPv8("curve25519",
                             TriblerTunnelCommunity,
                             settings={'remove_tunnel_delay': 0},
                             config=config,
                             exitnode_cache=Path(self.temporary_directory()) /
                             "exitnode_cache.dat")
        mock_ipv8.overlay.settings.max_circuits = 1

        db = BandwidthDatabase(
            db_path=MEMORY_DB,
            my_pub_key=mock_ipv8.my_peer.public_key.key_to_bin())

        # Load the bandwidth accounting community
        mock_ipv8.overlay.bandwidth_community = BandwidthAccountingCommunity(
            mock_ipv8.my_peer,
            mock_ipv8.endpoint,
            mock_ipv8.network,
            settings=BandwidthAccountingSettings(),
            database=db)
        mock_ipv8.overlay.dht_provider = MockDHTProvider(
            Peer(mock_ipv8.overlay.my_peer.key,
                 mock_ipv8.overlay.my_estimated_wan))

        return mock_ipv8
Exemplo n.º 19
0
async def test_get_channels_peers(rest_api, endpoint, metadata_store,
                                  mock_gigachannel_community):  # pylint: disable=W0621, C0321
    """
    Test getting debug info about the state of channels to peers mapping
    """

    mapping = mock_gigachannel_community.channels_peers = ChannelsPeersMapping(
    )

    peer_key = default_eccrypto.generate_key("curve25519")
    chan_key = default_eccrypto.generate_key("curve25519")
    with db_session:
        chan = metadata_store.ChannelMetadata(sign_with=chan_key,
                                              name="bla",
                                              infohash=random_infohash())

    peer = Peer(peer_key, ("1.2.3.4", 5))
    mapping.add(peer, chan.public_key, chan.id_)

    result = await do_request(
        rest_api,
        'remote_query/channels_peers',
        request_type="GET",
        expected_code=200,
    )
    first_result = result["channels_list"][0]
    assert first_result["channel_name"] == chan.title
    assert first_result["channel_pk"] == hexlify(chan.public_key)
    assert first_result["channel_id"] == chan.id_
    assert first_result["peers"][0][0] == hexlify(peer.mid)
Exemplo n.º 20
0
    async def test_send_and_get_channel_update_back(self):
        """
        Test if sending back information on updated version of a channel works
        """
        with db_session:
            # Add channel to node 0
            channel = self.nodes[0].overlay.metadata_store.ChannelMetadata.create_channel("test", "bla")
            for _ in range(20):
                self.add_random_torrent(self.nodes[0].overlay.metadata_store.TorrentMetadata, channel=channel)
            channel.commit_channel_torrent()
            channel_v1_dict = channel.to_dict()
            channel_v1_dict.pop("health")
            self.add_random_torrent(self.nodes[0].overlay.metadata_store.TorrentMetadata, channel=channel)
            channel.commit_channel_torrent()

        with db_session:
            # Add the outdated version of the channel to node 1
            self.nodes[1].overlay.metadata_store.ChannelMetadata.from_dict(channel_v1_dict)

        # node1 --outdated_channel--> node0
        await self.nodes[1].overlay.prepare_gossip_blob_cache()
        self.nodes[1].overlay.send_random_to(Peer(self.nodes[0].my_peer.public_key, self.nodes[0].endpoint.wan_address))

        await self.deliver_messages(timeout=0.5)

        with db_session:
            self.assertEqual(
                self.nodes[1].overlay.metadata_store.ChannelMetadata.select()[:][0].timestamp,
                self.nodes[0].overlay.metadata_store.ChannelMetadata.select()[:][0].timestamp,
            )
Exemplo n.º 21
0
class RemoteQueryTestnetCommunity(RemoteQueryCommunity):
    master_peer = Peer(
        unhexlify(
            "4c69624e61434c504b3a7fcf64783215dba08c1623fb14c3c86127b8591f858c56763e2281"
            "a8e121ef08caae395b2597879f7f4658b608f22df280073661f85174fd7c565cbee3e4328f"
        )
    )
Exemplo n.º 22
0
class MockedCommunity(Community, CommunityRoutines):
    master_peer = Peer(default_eccrypto.generate_key(u"very-low"))

    def __init__(self, *args, **kwargs):
        if kwargs.get("work_dir"):
            self.work_dir = kwargs.pop("work_dir")
        super().__init__(*args, **kwargs)
        self._req = RequestCache()

        for base in self.__class__.__bases__:
            if issubclass(base, MessageStateMachine):
                base.setup_messages(self)

    @property
    def persistence(self) -> BaseDB:
        return MockDBManager()

    @property
    def settings(self) -> Any:
        return MockSettings()

    def send_packet(self, *args, **kwargs) -> None:
        self.ez_send(*args, **kwargs)

    @property
    def request_cache(self) -> RequestCache:
        return self._req

    async def unload(self):
        await self._req.shutdown()
        return await super().unload()
Exemplo n.º 23
0
    async def run(self):
        await super().run()

        config = self.session.config

        self._task_manager = TaskManager()

        port = config.ipv8.port
        address = config.ipv8.address
        self.logger.info('Starting ipv8')
        self.logger.info(f'Port: {port}. Address: {address}')
        ipv8_config_builder = (
            ConfigBuilder().set_port(port).set_address(address).clear_overlays(
            ).clear_keys()  # We load the keys ourselves
            .set_working_directory(str(config.state_dir)).set_walker_interval(
                config.ipv8.walk_interval))

        if config.gui_test_mode:
            endpoint = DispatcherEndpoint([])
        else:
            # IPv8 includes IPv6 support by default.
            # We only load IPv4 to not kill all Tribler overlays (currently, it would instantly crash all users).
            # If you want to test IPv6 in Tribler you can set ``endpoint = None`` here.
            endpoint = DispatcherEndpoint(["UDPIPv4"],
                                          UDPIPv4={
                                              'port': port,
                                              'ip': address
                                          })
        ipv8 = IPv8(ipv8_config_builder.finalize(),
                    enable_statistics=config.ipv8.statistics
                    and not config.gui_test_mode,
                    endpoint_override=endpoint)
        await ipv8.start()
        self.ipv8 = ipv8

        key_component = await self.require_component(KeyComponent)
        self.peer = Peer(key_component.primary_key)

        if config.ipv8.statistics and not config.gui_test_mode:
            # Enable gathering IPv8 statistics
            for overlay in ipv8.overlays:
                ipv8.endpoint.enable_community_statistics(
                    overlay.get_prefix(), True)

        if config.ipv8.walk_scaling_enabled and not config.gui_test_mode:
            from tribler_core.components.ipv8.ipv8_health_monitor import IPv8Monitor
            IPv8Monitor(ipv8, config.ipv8.walk_interval,
                        config.ipv8.walk_scaling_upper_limit).start(
                            self._task_manager)

        if config.dht.enabled:
            self._init_dht_discovery_community()

        if not config.gui_test_mode:
            if config.discovery_community.enabled:
                self._init_peer_discovery_community()
        else:
            if config.dht.enabled:
                self.dht_discovery_community.routing_tables[
                    UDPv4Address] = RoutingTable('\x00' * 20)
Exemplo n.º 24
0
class EndpointServer(Community):
    """
    Make some small modifications to the Community to allow it a dynamic prefix.
    We will also only answer introduction requests.
    """
    master_peer = Peer(default_eccrypto.generate_key(u"very-low"))

    def __init__(self, endpoint):
        my_peer = Peer(default_eccrypto.generate_key(u"very-low"))
        self.signature_length = default_eccrypto.get_signature_length(my_peer.public_key)
        super(EndpointServer, self).__init__(my_peer, endpoint, Network())
        self.churn_strategy = SimpleChurn(self)
        self.churn_lc = self.register_task("churn", LoopingCall(self.churn_strategy.take_step)).start(30.0, now=False)

    def on_packet(self, packet, warn_unknown=False):
        source_address, data = packet
        try:
            probable_peer = self.network.get_verified_by_address(source_address)
            if probable_peer:
                probable_peer.last_response = time.time()
            if data[22] == chr(246):
                self.on_generic_introduction_request(source_address, data, data[:22])
            elif warn_unknown:
                self.logger.warning("Tracker received unknown message %s", str(data[22]))
        except:
            import traceback
            traceback.print_exc()

    def on_generic_introduction_request(self, source_address, data, prefix):
        auth, dist, payload = self._ez_unpack_auth(IntroductionRequestPayload, data)
        peer = Peer(auth.public_key_bin, source_address)
        peer.last_response = time.time()

        self.network.add_verified_peer(peer)
        self.network.discover_services(peer, [prefix[2:], ])

        intro_peers = [p for p in self.network.get_peers_for_service(prefix[2:]) if not(p == peer)]
        if intro_peers:
            intro_peer = random.choice(intro_peers)
        else:
            intro_peer = None

        packet = self.create_introduction_response(payload.destination_address, peer.address, payload.identifier,
                                                   introduction=intro_peer)

        packet = prefix + packet[22:-self.signature_length]
        signature = default_eccrypto.create_signature(self.my_peer.key, packet)

        self.endpoint.send(peer.address, packet + signature)

    def get_peer_for_introduction(self, exclude=None):
        """
        We explicitly provide create_introduction_response with a peer.
        If on_generic_introduction_request provides None, this method should not suggest a peer.
        More so as the get_peer_for_introduction peer would be for the DiscoveryCommunity.
        """
        return None
Exemplo n.º 25
0
 def __init__(self, endpoint):
     my_peer = Peer(default_eccrypto.generate_key(u"very-low"))
     self.signature_length = default_eccrypto.get_signature_length(
         my_peer.public_key)
     super(EndpointServer, self).__init__(my_peer, endpoint, Network())
     self.churn_strategy = SimpleChurn(self)
     self.churn_task = self.register_task("churn",
                                          self.churn_strategy.take_step,
                                          interval=30)
Exemplo n.º 26
0
class TriblerTunnelTestnetCommunity(TriblerTunnelCommunity):
    """
    This community defines a testnet for the anonymous tunnels.
    """

    master_peer = (
        "4c69624e61434c504b3a7773497078402b39b61b4d26851dad4a8d956243558ff387239a80429c362f52df70e1e"
        "8a97182311d7fb9c13fb80fae616bc82c691c7f03e69560da8c7295d8")
    master_peer = Peer(unhexlify(master_peer))
Exemplo n.º 27
0
 def __init__(self, endpoint):
     my_peer = Peer(default_eccrypto.generate_key(u"very-low"))
     self.signature_length = default_eccrypto.get_signature_length(
         my_peer.public_key)
     super(EndpointServer, self).__init__(my_peer, endpoint, Network())
     self.churn_strategy = SimpleChurn(self)
     self.churn_lc = self.register_task(
         "churn",
         LoopingCall(self.churn_strategy.take_step)).start(30.0, now=False)
Exemplo n.º 28
0
    def test_strategy_one_peer(self):
        """
        If we have one peer, we should send it our channel views and inspect our download queue.
        """
        self.community.get_peers_return = [Peer(default_eccrypto.generate_key(u"very-low"))]
        self.strategy.take_step()

        self.assertEqual(1, len(self.community.send_random_to_called))
        self.assertEqual(self.community.get_peers_return[0], self.community.send_random_to_called[0])
Exemplo n.º 29
0
class MsgCommunity(Community):

    master_peer = Peer(
        unhexlify(
            "307e301006072a8648ce3d020106052b81040024036a000400bd9cae587628a7d169fa193729465b4d"
            "2e4a382b5fac38e356a225339e8ff5336c70fd426d173796090416be826bcc5730533a0000e5c6db19"
            "107f6930d3c3a1017fe131fa396840e4facd620add83dadbd4d79185d4eabdf843efc292d7f898af46"
            "297c76736c"))

    inbox = []

    def __init__(self, my_peer, endpoint, network):
        super(MsgCommunity, self).__init__(my_peer, endpoint, network)
        # Register the message handler for messages with the identifier "1".
        self.add_message_handler(1, self.on_message)

    def started(self):
        print("Started")

    #    async def start_communication():
    #         for p in self.get_peers():

    #             self.send_message(p.address, "yoyo")
    #    self.register_task("start_communication", start_communication, interval=5.0, delay=0)

    def send_message(self, mid, message):
        # Send a message with our digital signature on it.
        # We use the latest version of our Lamport clock.
        for p in self.get_peers():
            m = b64encode(p.mid).decode("utf-8")
            if m == mid:
                self.endpoint.send(
                    p.address,
                    self.ezr_pack(1, MyMessage(message.encode('utf-8'))))
                print("Sending message '%s' to %s" % (message, mid))
                return True
            else:
                print("Skipping mid " + m)
        print("Peer %s not found, cannot send message '%s'" % (mid, message))
        return False

    def delete_message(self, message_id):
        l = len(self.inbox)
        self.inbox = [i for i in self.inbox if i['id'] != message_id]
        return l != len(self.inbox)

    @lazy_wrapper(MyMessage)
    def on_message(self, peer, payload):
        print("Got message from peer")
        message = {
            'time': time.time(),
            'id': str(uuid4()),
            'peer': peer,
            'message': payload.message
        }
        self.inbox.append(message)
Exemplo n.º 30
0
    def __init__(self,
                 path,
                 port,
                 interface='127.0.0.1',
                 configuration=None):
        """
        Create a test peer with a REST API interface.

        :param path: the for the working directory of this peer
        :param port: this peer's port
        :param interface: IP or alias of the peer. Defaults to '127.0.0.1'
        :param configuration: IPv8 configuration object. Defaults to None
        """
        self._logger = logging.getLogger(self.__class__.__name__)
        self._logger.info("Peer starting-up.")

        self._rest_manager = None

        self._port = port
        self._interface = interface

        self._path = path
        self._configuration = configuration

        # Check to see if we've received a custom configuration
        if configuration is None:
            # Create a default configuration
            self._configuration = get_default_configuration()

            self._configuration['logger'] = {'level': "ERROR"}

            overlays = ['AttestationCommunity', 'IdentityCommunity']
            self._configuration['overlays'] = [o for o in self._configuration['overlays'] if o['class'] in overlays]
            for o in self._configuration['overlays']:
                o['walkers'] = [{
                    'strategy': "RandomWalk",
                    'peers': 20,
                    'init': {
                        'timeout': 60.0
                    }
                }]

        self._create_working_directory(self._path)
        self._logger.info("Created working directory.")
        os.chdir(self._path)

        self._ipv8 = IPv8(self._configuration)
        os.chdir(os.path.dirname(__file__))

        # Change the master_peers of the IPv8 object's overlays, in order to avoid conflict with the live networks
        for idx, overlay in enumerate(self._ipv8.overlays):
            self._ipv8.overlays[idx].master_peer = Peer(COMMUNITY_TO_MASTER_PEER_KEY[type(overlay).__name__])

        self._rest_manager = TestPeer.RestAPITestWrapper(self._ipv8, self._port, self._interface)
        self._rest_manager.start()
        self._logger.info("Peer started up.")