示例#1
0
 def on_contact(self, messages):
     for message in messages:
         log("walktest.log",
             "in-contact",
             source_address=message.candidate.sock_addr,
             identifier=message.payload.identifier,
             **self._default_log())
示例#2
0
    def on_channelcast(self, messages):
        for message in messages:
            if DEBUG:
                print >> sys.stderr, "AllChannelCommunity: received channelcast message"
            
            toCollect = {}
            for cid, torrents in message.payload.torrents.iteritems():
                # ensure that all the PreviewChannelCommunity instances exist
                community = self._get_channel_community(cid)

                # if __debug__:
                #     dprint(type(message.payload), " ", type(message.payload.meta), force=1)
                #     for infohash in torrents:
                #         assert isinstance(infohash, str)
                #         assert len(infohash) == 20
                
                for infohash in community.selectTorrentsToCollect(torrents):
                    toCollect.setdefault(cid,set()).add(infohash)
                
            nr_requests = sum([len(torrents) for torrents in toCollect.values()])
            if nr_requests > 0:
                self.create_channelcast_request(toCollect, message.candidate)

                if __debug__:
                    if not self.integrate_with_tribler:
                        log("dispersy.log", "requesting-torrents", nr_requests = nr_requests)
示例#3
0
 def execute_scenario_cmds(self, commands):
     torrents = []
     
     for command in commands:
         cur_command = command.split()
     
         if cur_command[0] == 'create':
             log(self._logfile, "creating-community")
             self.my_channel = ChannelCommunity.create_community(self.my_member, integrate_with_tribler = False)
             
             log(self._logfile, "creating-channel-message")
             self.my_channel.create_channel(u'', u'')
         
         elif cur_command[0] == 'publish':
             if self.my_channel:
                 infohash = str(self.torrentindex)
                 infohash += ''.join(choice(letters) for _ in xrange(20-len(infohash)))
                 
                 name = u''.join(choice(letters) for _ in xrange(100))
                 files = []
                 for _ in range(10):
                     files.append((u''.join(choice(letters) for _ in xrange(30)), 123455))
                 
                 trackers = []
                 for _ in range(10):
                     trackers.append(''.join(choice(letters) for _ in xrange(30))) 
                 
                 files = tuple(files)
                 trackers = tuple(trackers)
                 
                 self.torrentindex += 1
                 torrents.append((infohash, int(time()), name, files, trackers))
         
         elif cur_command[0] == 'post':
             if self.joined_community:
                 text = ''.join(choice(letters) for i in xrange(160))
                 self.joined_community._disp_create_comment(text, int(time()), None, None, None, None)
             
         elif cur_command[0] == 'join':
             self.want_to_join = True
             
     if self.want_to_join:
         from Tribler.dispersy.dispersy import Dispersy
         dispersy = Dispersy.get_instance()
         
         log(self._logfile, "trying-to-join-community")
         
         for community in dispersy.get_communities():
             if isinstance(community, PreviewChannelCommunity) and community._channel_id:
                 self._community.disp_create_votecast(community.cid, 2, int(time()))
                 
                 log(self._logfile, "joining-community")
                 self.joined_community = community
                 
                 self.want_to_join = False
                 break
             
     if len(torrents) > 0:
         log(self._logfile, "creating-torrents")
         self.my_channel._disp_create_torrents(torrents)
示例#4
0
 def dispersy_take_step(self):
     now = time()
     log("walktest.log",
         "candidates",
         candidates=[(candidate.lan_address, candidate.get_category(self, now)) for candidate in self._dispersy._candidates.itervalues() if candidate.in_community(self, now)],
         **self._default_log())
     return super(WalktestCommunity, self).dispersy_take_step()
示例#5
0
    def create_barter_record(self, second_member, first_upload, second_upload, store=True, forward=True):
        """
        Create and return a signature request for a new barter record.

        A barter-record message is created, this message is owned by self._my_member.  A
        dispersy-signature-request message is then created to encapsulate the barter-record, send to
        OTHER_MEMBER, and returned.

        OTHER_MEMBER: the second person who will be asked to sign the barter-record message.

        MY_UPLOAD: the number of MB uploaded by self._my_member.

        OTHER_UPLOAD: the number of MB uploaded by OTHER_MEMBER.

        STORE_AND_FORWARD: when True, dispersy-signature-request is send to OTHER_MEMBER.
        """
        if __debug__:
            from Tribler.dispersy.member import Member
        assert isinstance(second_member, Member)
        assert second_member.public_key
        assert isinstance(second_member, Member)
        assert not second_member.private_key
        assert isinstance(first_upload, (int, long))
        assert isinstance(second_upload, (int, long))

        if __debug__: log("barter.log", "create-dispersy-signature-request")

        meta = self.get_meta_message(u"barter-record")
        request = meta.impl(authentication=([self._my_member, second_member],),
                            distribution=(self.claim_global_time(),),
                            payload=(first_upload, second_upload))
        return self.create_dispersy_signature_request(request, self.on_signature_response, (request, 1), store=store, forward=forward)
示例#6
0
 def _replacement__introduction_response_or_timeout(self, message, community, intermediary_candidate):
     if message is None and self == community:
         log("walktest.log",
             "timeout",
             intermediary_lan_address=intermediary_candidate.lan_address,
             intermediary_wan_address=intermediary_candidate.wan_address,
             **self._default_log())
     return self._origional__introduction_response_or_timeout(message, community, intermediary_candidate)
示例#7
0
 def _watchdog(self):
     try:
         while True:
             yield 3600.0
     except GeneratorExit:
         print "GeneratorExit"
         log("walktest.log", "stopiteration")
         close("walktest.log")
示例#8
0
 def impl_introduction_request(self, meta, *args, **kargs):
     message = meta.__origional_impl(*args, **kargs)
     log("walktest.log",
         "out-introduction-request",
         destination_address=message.destination.candidates[0].sock_addr,
         advice=message.payload.advice,
         identifier=message.payload.identifier,
         **self._default_log())
     return message
示例#9
0
 def on_puncture_request(self, meta, messages):
     for message in messages:
         log("walktest.log",
             "in-puncture-request",
             source_address=message.candidate.sock_addr,
             lan_walker_address=message.payload.lan_walker_address,
             wan_walker_address=message.payload.wan_walker_address,
             identifier=message.payload.identifier,
             **self._default_log())
     return meta.__origional_handle(messages)
示例#10
0
        def create_contact(self, destination, identifier):
            meta = self._meta_messages[u"contact"]
            message = meta.impl(distribution=(self.global_time,), destination=(destination,), payload=(identifier,))
            self._dispersy.store_update_forward([message], False, False, True)

            log("walktest.log",
                "out-contact",
                destination_address=destination.sock_addr,
                identifier=identifier,
                **self._default_log())
示例#11
0
 def on_puncture(self, meta, messages):
     for message in messages:
         log("walktest.log",
             "in-puncture",
             member=message.authentication.member.mid,
             source_address=message.candidate.sock_addr,
             source_lan_address=message.payload.source_lan_address,
             source_wan_address=message.payload.source_wan_address,
             identifier=message.payload.identifier,
             **self._default_log())
     return meta.__origional_handle(messages)
示例#12
0
 def impl_puncture(self, meta, *args, **kargs):
     message = meta.__origional_impl(*args, **kargs)
     assert len(message.destination.candidates) == 1
     log("walktest.log",
         "out-puncture",
         destination_address=message.destination.candidates[0].sock_addr,
         source_lan_address=message.payload.source_lan_address,
         source_wan_address=message.payload.source_wan_address,
         identifier=message.payload.identifier,
         **self._default_log())
     return message
示例#13
0
 def impl_introduction_response(self, meta, *args, **kargs):
     message = meta.__origional_impl(*args, **kargs)
     assert len(message.destination.candidates) == 1
     log("walktest.log",
         "out-introduction-response",
         destination_address=message.destination.candidates[0].sock_addr,
         lan_introduction_address=message.payload.lan_introduction_address,
         wan_introduction_address=message.payload.wan_introduction_address,
         identifier=message.payload.identifier,
         **self._default_log())
     return message
示例#14
0
 def sleep(self, initial_delay=False):
     """ Calculate the time to sleep.
     """
     now = time.time()
     if now >= self._stopping_timestamp:
         return -1.0
     expected_time = self._starting_timestamp + (self._timestep * self._stepcount)
     st = max(0.0, expected_time - now)
     if not initial_delay and self._barter.dispersy_randomness:
         st *= random()
     log("barter.log", "sleep", delay=st, diff=expected_time - now, stepcount=self._stepcount)
     return st
示例#15
0
 def on_introduction_request(self, meta, messages):
     for message in messages:
         log("walktest.log",
             "in-introduction-request",
             source_address=message.candidate.sock_addr,
             mid=message.authentication.member.mid,
             destination_address=message.payload.destination_address,
             source_lan_address=message.payload.source_lan_address,
             source_wan_address=message.payload.source_wan_address,
             advice=message.payload.advice,
             identifier=message.payload.identifier,
             **self._default_log())
     return meta.__origional_handle(messages)
示例#16
0
        def _select_candidate_addresses(community_id, address_count, diff_range, age_range):
            addresses = set()
            sql = u"""SELECT host, port
                      FROM candidate
                      WHERE community = ?
                      ORDER BY RANDOM()
                      LIMIT ?"""
            addresses.update([(str(host), port)
                              for host, port
                              in self._dispersy.database.execute(sql, (community_id, address_count - len(addresses)))])

            # return what we have
            if addresses:
                log("dispersy.log","found-candidates")
            return addresses
示例#17
0
    def on_barter_record(self, messages):
        """ I handle received barter records

        I create or update a row in my database
        """
        if __debug__: dprint("storing ", len(messages), " records")
        execute = self._database.execute
        for message in messages:
            if __debug__: log("dispersy.log", "handled-barter-record") # TODO: maybe move to barter.log
            # check if there is already a record about this pair
            try:
                first_member, second_member, global_time = \
                              execute(u"SELECT first_member, second_member, global_time FROM \
                              record WHERE (first_member = ? AND second_member = ?) OR \
                              (first_member = ? AND second_member = ?)",
                                      (message.authentication.members[0].database_id,
                                       message.authentication.members[1].database_id,
                                       message.authentication.members[1].database_id,
                                       message.authentication.members[0].database_id)).next()
            except StopIteration:
                global_time = -1
                first_member = message.authentication.members[0].database_id
                second_member = message.authentication.members[1].database_id

            if global_time >= message.distribution.global_time:
                # ignore the message
                if __debug__:
                    dprint("Ignoring older message")
            else:
                self._database.execute(u"INSERT OR REPLACE INTO \
                record(community, global_time, first_member, second_member, \
                upload_first_member, upload_second_member) \
                VALUES(?, ?, ?, ?, ?, ?)",
                                       (self._database_id,
                                        message.distribution.global_time,
                                        first_member,
                                        second_member,
                                        message.payload.first_upload,
                                        message.payload.second_upload))
                if __debug__:
                    peer1_id = self._peer_ids.get(message.authentication.members[0].public_key, -1)
                    peer2_id = self._peer_ids.get(message.authentication.members[1].public_key, -1)
                    peer1_upload = message.payload.first_upload
                    peer2_upload = message.payload.second_upload
                    if peer1_id > peer2_id:
                        peer1_id, peer2_id = peer2_id, peer1_id
                        peer1_upload, peer2_upload = peer2_upload, peer1_upload
                    log("barter.log", "barter-record", first=peer1_id, second=peer2_id, first_upload=peer1_upload, second_upload=peer2_upload)
示例#18
0
 def sleep(self, initial_delay=False):
     """ Calculate the time to sleep.
     """
     now = time.time()
     if now >= self._stopping_timestamp:
         return -1.0
     expected_time = self._starting_timestamp + (self._timestep *
                                                 self._stepcount)
     st = max(0.0, expected_time - now)
     if not initial_delay and self._barter.dispersy_randomness:
         st *= random()
     log("barter.log",
         "sleep",
         delay=st,
         diff=expected_time - now,
         stepcount=self._stepcount)
     return st
示例#19
0
    def on_channelcast(self, messages):
        for message in messages:
            if DEBUG:
                print >> sys.stderr, "AllChannelCommunity: received channelcast message"
            
            toCollect = {}
            for cid, torrents in message.payload.torrents.iteritems():
                for infohash in self._selectTorrentsToCollect(cid, torrents):
                    toCollect.setdefault(cid,set()).add(infohash)
                
            nr_requests = sum([len(torrents) for torrents in toCollect.values()])
            if nr_requests > 0:
                self.create_channelcast_request(toCollect, message.candidate)

                if __debug__:
                    if not self.integrate_with_tribler:
                        log("dispersy.log", "requesting-torrents", nr_requests = nr_requests)
示例#20
0
    def __init__(self, *args, **kargs):
        super(WalktestCommunity, self).__init__(*args, **kargs)

        try:
            hostname = open("/etc/hostname", "r").readline().strip()
        except:
            hostname = "unknown"

        log("walktest.log",
            "init",
            mid=self.my_member.mid,
            hostname=hostname,
            **self._default_log())

        # redirect introduction-response timeout
        self._origional__introduction_response_or_timeout = self._dispersy.introduction_response_or_timeout
        self._dispersy.introduction_response_or_timeout = self._replacement__introduction_response_or_timeout
示例#21
0
        def _select_candidate_addresses(community_id, address_count,
                                        diff_range, age_range):
            addresses = set()
            sql = u"""SELECT host, port
                      FROM candidate
                      WHERE community = ?
                      ORDER BY RANDOM()
                      LIMIT ?"""
            addresses.update([
                (str(host), port)
                for host, port in self._dispersy.database.execute(
                    sql, (community_id, address_count - len(addresses)))
            ])

            # return what we have
            if addresses:
                log("dispersy.log", "found-candidates")
            return addresses
示例#22
0
        def on_introduction_response(self, meta, messages):
            for message in messages:
                log("walktest.log",
                    "in-introduction-response",
                    member=message.authentication.member.public_key,
                    source_address=message.candidate.sock_addr,
                    destination_address=message.payload.destination_address,
                    source_lan_address=message.payload.source_lan_address,
                    source_wan_address=message.payload.source_wan_address,
                    lan_introduction_address=message.payload.lan_introduction_address,
                    wan_introduction_address=message.payload.wan_introduction_address,
                    identifier=message.payload.identifier,
                    **self._default_log())

                # schedule the 'contact' message after one second.  this should give time for the
                # puncture to complete
                # self._dispersy.callback.register(self.create_contact, (message.candidate, message.payload.identifier), delay=1.0)

            return meta.__origional_handle(messages)
示例#23
0
    def on_channelcast(self, messages):
        for message in messages:
            if DEBUG:
                print >> sys.stderr, "AllChannelCommunity: received channelcast message"

            toCollect = {}
            for cid, torrents in message.payload.torrents.iteritems():
                for infohash in self._selectTorrentsToCollect(cid, torrents):
                    toCollect.setdefault(cid, set()).add(infohash)

            nr_requests = sum(
                [len(torrents) for torrents in toCollect.values()])
            if nr_requests > 0:
                self.create_channelcast_request(toCollect, message.candidate)

                if __debug__:
                    if not self.integrate_with_tribler:
                        log("dispersy.log",
                            "requesting-torrents",
                            nr_requests=nr_requests)
示例#24
0
    def on_signature_response(self, message, request, retry):
        """ Handle a newly created double signed message or a timeout while signing

        When request for signing times out I just return. When I receive the signature for the
        message that I created then I send it to myself and then store and forward it to others of
        the community
        """
        if __debug__: dprint(message)

        if message:
            assert message.name == u"barter-record"
            assert message.authentication.is_signed

            if __debug__: dprint(message)

            # store, update, and forward to the community
            self._dispersy.store_update_forward([message], True, True, self.barter_forward_record_on_creation)
            log("dispersy.log", "created-barter-record") # TODO: maybe move to barter.log

        elif retry < 5:
            # signature timeout
            # retry
            if __debug__:
                log("barter.log", "barter-community-signature-request-timeout", retry=retry)
                dprint("Signature request timeout. Retry!")
                self.create_dispersy_signature_request(request, self.on_signature_response, (request, retry + 1))

        else:
            # close the transfer
            if __debug__:
                log("barter.log", "barter-community-signature-request-timeout", retry=retry)
                dprint("Signature request timeout")
示例#25
0
    def create_channelcast(self):
        try:
            now = time()

            favoriteTorrents = None
            normalTorrents = None

            #cleanup blocklist
            for candidate in self._blocklist.keys():
                if self._blocklist[
                        candidate] + CHANNELCAST_BLOCK_PERIOD < now:  #unblock address
                    self._blocklist.pop(candidate)

            #loop through all candidates to see if we can find a non-blocked address
            for candidate in islice(
                (candidate
                 for candidate in self._dispersy.yield_random_candidates(self)
                 if not candidate in self._blocklist), 10):
                peer_ids = set()
                for member in candidate.get_members(self):
                    key = member.public_key
                    peer_ids.add(self._peer_db.addOrGetPeerID(key))

                #see if all members on this address are subscribed to my channel
                didFavorite = len(peer_ids) > 0
                for peer_id in peer_ids:
                    vote = self._votecast_db.getVoteForMyChannel(peer_id)
                    if vote != 2:
                        didFavorite = False
                        break

                #Modify type of message depending on if all peers have marked my channels as their favorite
                if didFavorite:
                    if not favoriteTorrents:
                        favoriteTorrents = self._channelcast_db.getRecentAndRandomTorrents(
                            0, 0, 25, 25, 5)
                    torrents = favoriteTorrents
                else:
                    if not normalTorrents:
                        normalTorrents = self._channelcast_db.getRecentAndRandomTorrents(
                        )
                    torrents = normalTorrents

                if len(torrents) > 0:
                    meta = self.get_meta_message(u"channelcast")
                    message = meta.impl(authentication=(self._my_member, ),
                                        distribution=(self.global_time, ),
                                        payload=(torrents, ))

                    if __debug__:
                        self._dispersy.statistics.outgoing(
                            meta.name, len(message.packet), 1)
                    self._dispersy.endpoint.send([candidate], [message.packet])

                    #we've send something to this address, add to blocklist
                    self._blocklist[candidate] = now

                    if DEBUG:
                        nr_torrents = sum(
                            len(torrent) for torrent in torrents.values())
                        print >> sys.stderr, "AllChannelCommunity: sending channelcast message containing", nr_torrents, "torrents to", candidate.address, "didFavorite", didFavorite

                    if __debug__:
                        if not self.integrate_with_tribler:
                            nr_torrents = sum(
                                len(torrent) for torrent in torrents.values())
                            log(
                                "dispersy.log",
                                "Sending channelcast message containing %d torrents to %s didFavorite %s"
                                %
                                (nr_torrents, candidate.address, didFavorite))

                    #we're done
                    break

            else:
                if DEBUG:
                    print >> sys.stderr, "AllChannelCommunity: no candidates to send channelcast message too"
                if __debug__:
                    if not self.integrate_with_tribler:
                        log(
                            "dispersy.log",
                            "Could not send channelcast message, no candidates"
                        )
        except:
            print_exc()
            raise

        finally:
            self._register_task(self.create_channelcast,
                                delay=CHANNELCAST_INTERVAL)
示例#26
0
    def create_channelcast(self):
        try:
            now = time()
            
            favoriteTorrents = None
            normalTorrents = None

            #cleanup blocklist
            for candidate in self._blocklist.keys():
                if self._blocklist[candidate] + CHANNELCAST_BLOCK_PERIOD < now: #unblock address
                    self._blocklist.pop(candidate)
            
            #loop through all candidates to see if we can find a non-blocked address
            for candidate in islice((candidate for candidate in self._dispersy.yield_random_candidates(self) if not candidate in self._blocklist), 10):
                peer_ids = set()
                for member in candidate.get_members(self):
                    key = member.public_key
                    peer_ids.add(self._peer_db.addOrGetPeerID(key))
                        
                #see if all members on this address are subscribed to my channel
                didFavorite = len(peer_ids) > 0
                for peer_id in peer_ids:
                    vote = self._votecast_db.getVoteForMyChannel(peer_id)
                    if vote != 2:
                        didFavorite = False
                        break
                        
                #Modify type of message depending on if all peers have marked my channels as their favorite
                if didFavorite:
                    if not favoriteTorrents:
                        favoriteTorrents = self._channelcast_db.getRecentAndRandomTorrents(0, 0, 25, 25 ,5)
                    torrents = favoriteTorrents
                else:
                    if not normalTorrents:
                        normalTorrents = self._channelcast_db.getRecentAndRandomTorrents()
                    torrents = normalTorrents
                            
                if len(torrents) > 0:
                    meta = self.get_meta_message(u"channelcast")
                    message = meta.impl(authentication=(self._my_member,),
                                        distribution=(self.global_time,), payload=(torrents,))
                            
                    self._dispersy._send([candidate], [message.packet], key = meta.name)
                            
                    #we've send something to this address, add to blocklist
                    self._blocklist[candidate] = now
                            
                    if DEBUG:
                        nr_torrents = sum(len(torrent) for torrent in torrents.values())
                        print >> sys.stderr, "AllChannelCommunity: sending channelcast message containing",nr_torrents,"torrents to",candidate.address,"didFavorite",didFavorite

                    if __debug__:
                        if not self.integrate_with_tribler:
                            nr_torrents = sum(len(torrent) for torrent in torrents.values())
                            log("dispersy.log", "Sending channelcast message containing %d torrents to %s didFavorite %s"%(nr_torrents,candidate.address,didFavorite))
                    
                    #we're done
                    break       

            else:
                if DEBUG:
                    print >> sys.stderr, "AllChannelCommunity: no candidates to send channelcast message too"
                if __debug__:
                    if not self.integrate_with_tribler:
                        log("dispersy.log", "Could not send channelcast message, no candidates")
        except:
            print_exc()
            raise
        
        finally:
            self._register_task(self.create_channelcast, delay=CHANNELCAST_INTERVAL)
示例#27
0
    def run(self):
        if __debug__: log("barter.log", "start-barter-script")
        # this master key NEEDS to be the same as that in BarterTrackerScript as they work together
        master_key = "3081a7301006072a8648ce3d020106052b81040027038192000403cbbfd2dfb67a7db66c88988df56f93fa6e7f982f9a6a0fa8898492c8b8cae23e10b159ace60b7047012082a5aa4c6e221d7e58107bb550436d57e046c11ab4f51f0ab18fa8f58d0346cc12d1cc2b61fc86fe5ed192309152e11e3f02489e30c7c971dd989e1ce5030ea0fb77d5220a92cceb567cbc94bc39ba246a42e215b55e9315b543ddeff0209e916f77c0d747".decode("HEX")

        # remove all trackers.  this experiment may not be contaminated by outside influences
        self._dispersy.database.execute(u"DELETE FROM candidate where community=0")
        assert self._dispersy._total_send == 0
        assert self._dispersy._total_received == 0

        self._members = {}
        self.original_on_incoming_packets = self._dispersy.on_incoming_packets
        self.original_send = self._dispersy._send

        def _select_candidate_addresses(community_id, address_count, diff_range, age_range):
            addresses = set()
            sql = u"""SELECT host, port
                      FROM candidate
                      WHERE community = ?
                      ORDER BY RANDOM()
                      LIMIT ?"""
            addresses.update([(str(host), port)
                              for host, port
                              in self._dispersy.database.execute(sql, (community_id, address_count - len(addresses)))])

            # return what we have
            if addresses:
                log("dispersy.log","found-candidates")
            return addresses
            # return set(["1.1.1.1",1111]) # send UDP packet to nowhere
        self._dispersy._select_candidate_addresses = _select_candidate_addresses

        #
        # Read our configuration from the peer.conf file
        # name, ip, port, public and private key
        #
        with open('data/peer.conf') as fp:
            my_name, ip, port, public_key, private_key = fp.readline().split()
            public_key = public_key.decode("HEX")
            private_key = private_key.decode("HEX")
            my_address = (ip, int(port))
        if __debug__: log("barter.log", "read-config-done")

        # create my member
        my_member = Member(public_key, private_key, sync_with_database=True)
        dprint(my_member)
        my_public_key = public_key

        # populate the candidate and user tables
        if __debug__:
            _peer_counter = 0
        # assume that this will be the ID, check after community is joined that the value is correct
        community_database_id = 1
        _peer_ids = {}
        all_peers = []
        execute = self._dispersy.database.execute
        with open('data/peers') as file:
            for index, line in zip(count(), file):
                name, ip, port, public_key, private_key = line.split(' ')
                if __debug__:
                    _peer_counter += 1
                    log("barter.log", "read-peer-config", position=_peer_counter, name=name, ip=ip, port=port)
                port = int(port)
                public_key = public_key.decode('HEX')
                private_key = private_key.strip().decode("HEX") # stip to remove newline character
                _peer_ids[public_key] = int(name)
                all_peers.append((index, (ip, port), public_key, private_key))
                if name == my_name: continue

                #self._dispersy._send([(ip, port)], [message.packet])
                execute(u"INSERT OR IGNORE INTO candidate(community, host, port, incoming_time, outgoing_time) VALUES(?, ?, ?, DATETIME(), '2010-01-01 00:00:00')", (community_database_id, unicode(ip), port))
                # execute(u"INSERT OR IGNORE INTO user(mid, public_key, host, port) VALUES(?, ?, ?, ?)", (buffer(sha1(public_key).digest()), buffer(public_key), unicode(ip), port))
                #if __debug__:
                #    log("barter.log", "mid_add", mid=sha1(public_key).digest())

        # join the barter community with the newly created member
        self._barter = BarterCommunity.join_community(sha1(master_key).digest(), master_key, my_member)
        assert self._barter.database_id == community_database_id

        self._barter._peer_ids = _peer_ids # we set this internally in the BarterCommunity object

        # generate and insert all dispersy-identity messages
        incoming_packets = []
        meta = self._barter.get_meta_message(u"dispersy-identity")
        for index, address, public_key, private_key in all_peers:
            temp_member = Member(public_key, private_key, sync_with_database=False)
            message = meta.impl(authentication=(temp_member,),
                                distribution=(index + 10,), # give it a global time
                                payload=(address,))
            incoming_packets.append((address, message.packet))
        self._barter.dispersy.on_incoming_packets(incoming_packets)

        dprint("Joined barter community ", self._barter._my_member)
        if __debug__:
            log("barter.log", "joined-barter-community")
            log("barter.log", "barter-community-property", name="candidate_request_initial_delay", value=self._barter.dispersy_candidate_request_initial_delay)
            log("barter.log", "barter-community-property", name="candidate_request_interval", value=self._barter.dispersy_candidate_request_interval)
            log("barter.log", "barter-community-property", name="sync_initial_delay", value=self._barter.dispersy_sync_initial_delay.__doc__)
            log("barter.log", "barter-community-property", name="sync_interval", value=self._barter.dispersy_sync_interval.__doc__)
            log("barter.log", "barter-community-property", name="sync_member_count", value=self._barter.dispersy_sync_member_count)
            log("barter.log", "barter-community-property", name="sync_response_limit", value=self._barter.dispersy_sync_response_limit)
            log("barter.log", "barter-community-property", name="timestep", value=self._timestep)
            log("barter.log", "barter-community-property", name="barter_history_size", value="unused_(currently_using_FullSyncDistribution)")
            log("barter.log", "barter-community-property", name="barter_forward_record_on_creation", value=self._barter.barter_forward_record_on_creation)
            log("barter.log", "barter-community-property", name="barter_push_node_count", value=self._barter.get_meta_message(u"barter-record").destination.node_count)
            log("barter.log", "barter-community-property", name="peer_id", value=_peer_ids[my_public_key])

        yield 2.0

        if __debug__:
            log("barter.log", "done-reading-peers")

        yield 2.0

        # open the scenario files, as generated from Mircea's Scenario
        # Generator
        bartercast_fp = open('data/bartercast.log')
        availability_fp = open('data/availability.log')

        self._stepcount = 0

        # wait until we reach the starting time
        yield self.sleep(initial_delay=True)

        self._stepcount = 1

        # start the scenario
        while True:
            # get commands
            barter_cmds = self.get_commands_from_fp(bartercast_fp, self._stepcount)
            availability_cmds = self.get_commands_from_fp(availability_fp, self._stepcount)

            # if there are no commands exit the while loop
            if barter_cmds == -1 and availability_cmds == -1:
                if __debug__: log("barter.log", "no-commands")
                break
            else:
                # if there is a start in the avaibility_cmds then go
                # online
                if availability_cmds != -1 and 'start' in availability_cmds:
                    self.set_online()

                # if there are barter_cmds then execute them
                if barter_cmds != -1:
                    for cmd in barter_cmds:
                        name, up, down = cmd.split()
                        up, down = map(int, (up, down))
                        # note a peer creates a record when it has
                        # interest (e.g. it's upload is larger than
                        # its download)
                        if up >= down:
                            peer_member, address = self.find_peer_by_name(name)
                            self._barter.create_barter_record(peer_member, up, down)

                # if there is a stop in the availability_cmds then go
                # offline
                if availability_cmds != -1 and 'stop' in availability_cmds:
                    self.set_offline()

            # sleep until the next step
            delay = self.sleep()
            if delay >= 0.0:
                yield delay
            else:
                break
            self._stepcount += 1

        # I finished the scenario execution. I should stay online
        # until killed. Note that I can still sync and exchange
        # messages with other peers.
        delay = self.sleep()
        while delay >= 0.0:
            # wait to be killed
            yield 5.0

        while True:
            now = time.time()
            if now >= self._shutdown_timestamp:
                break
            yield 5.0
示例#28
0
    def run(self):
        if __debug__: log("barter.log", "start-barter-script")
        # this master key NEEDS to be the same as that in BarterTrackerScript as they work together
        master_key = "3081a7301006072a8648ce3d020106052b81040027038192000403cbbfd2dfb67a7db66c88988df56f93fa6e7f982f9a6a0fa8898492c8b8cae23e10b159ace60b7047012082a5aa4c6e221d7e58107bb550436d57e046c11ab4f51f0ab18fa8f58d0346cc12d1cc2b61fc86fe5ed192309152e11e3f02489e30c7c971dd989e1ce5030ea0fb77d5220a92cceb567cbc94bc39ba246a42e215b55e9315b543ddeff0209e916f77c0d747".decode(
            "HEX")

        # remove all trackers.  this experiment may not be contaminated by outside influences
        self._dispersy.database.execute(
            u"DELETE FROM candidate where community=0")
        assert self._dispersy._total_send == 0
        assert self._dispersy._total_received == 0

        self._members = {}
        self.original_on_incoming_packets = self._dispersy.on_incoming_packets
        self.original_send = self._dispersy._send

        def _select_candidate_addresses(community_id, address_count,
                                        diff_range, age_range):
            addresses = set()
            sql = u"""SELECT host, port
                      FROM candidate
                      WHERE community = ?
                      ORDER BY RANDOM()
                      LIMIT ?"""
            addresses.update([
                (str(host), port)
                for host, port in self._dispersy.database.execute(
                    sql, (community_id, address_count - len(addresses)))
            ])

            # return what we have
            if addresses:
                log("dispersy.log", "found-candidates")
            return addresses
            # return set(["1.1.1.1",1111]) # send UDP packet to nowhere

        self._dispersy._select_candidate_addresses = _select_candidate_addresses

        #
        # Read our configuration from the peer.conf file
        # name, ip, port, public and private key
        #
        with open('data/peer.conf') as fp:
            my_name, ip, port, public_key, private_key = fp.readline().split()
            public_key = public_key.decode("HEX")
            private_key = private_key.decode("HEX")
            my_address = (ip, int(port))
        if __debug__: log("barter.log", "read-config-done")

        # create my member
        my_member = Member(public_key, private_key, sync_with_database=True)
        dprint(my_member)
        my_public_key = public_key

        # populate the candidate and user tables
        if __debug__:
            _peer_counter = 0
        # assume that this will be the ID, check after community is joined that the value is correct
        community_database_id = 1
        _peer_ids = {}
        all_peers = []
        execute = self._dispersy.database.execute
        with open('data/peers') as file:
            for index, line in zip(count(), file):
                name, ip, port, public_key, private_key = line.split(' ')
                if __debug__:
                    _peer_counter += 1
                    log("barter.log",
                        "read-peer-config",
                        position=_peer_counter,
                        name=name,
                        ip=ip,
                        port=port)
                port = int(port)
                public_key = public_key.decode('HEX')
                private_key = private_key.strip().decode(
                    "HEX")  # stip to remove newline character
                _peer_ids[public_key] = int(name)
                all_peers.append((index, (ip, port), public_key, private_key))
                if name == my_name: continue

                #self._dispersy._send([(ip, port)], [message.packet])
                execute(
                    u"INSERT OR IGNORE INTO candidate(community, host, port, incoming_time, outgoing_time) VALUES(?, ?, ?, DATETIME(), '2010-01-01 00:00:00')",
                    (community_database_id, unicode(ip), port))
                # execute(u"INSERT OR IGNORE INTO user(mid, public_key, host, port) VALUES(?, ?, ?, ?)", (buffer(sha1(public_key).digest()), buffer(public_key), unicode(ip), port))
                #if __debug__:
                #    log("barter.log", "mid_add", mid=sha1(public_key).digest())

        # join the barter community with the newly created member
        self._barter = BarterCommunity.join_community(
            sha1(master_key).digest(), master_key, my_member)
        assert self._barter.database_id == community_database_id

        self._barter._peer_ids = _peer_ids  # we set this internally in the BarterCommunity object

        # generate and insert all dispersy-identity messages
        incoming_packets = []
        meta = self._barter.get_meta_message(u"dispersy-identity")
        for index, address, public_key, private_key in all_peers:
            temp_member = Member(public_key,
                                 private_key,
                                 sync_with_database=False)
            message = meta.impl(
                authentication=(temp_member, ),
                distribution=(index + 10, ),  # give it a global time
                payload=(address, ))
            incoming_packets.append((address, message.packet))
        self._barter.dispersy.on_incoming_packets(incoming_packets)

        dprint("Joined barter community ", self._barter._my_member)
        if __debug__:
            log("barter.log", "joined-barter-community")
            log("barter.log",
                "barter-community-property",
                name="candidate_request_initial_delay",
                value=self._barter.dispersy_candidate_request_initial_delay)
            log("barter.log",
                "barter-community-property",
                name="candidate_request_interval",
                value=self._barter.dispersy_candidate_request_interval)
            log("barter.log",
                "barter-community-property",
                name="sync_initial_delay",
                value=self._barter.dispersy_sync_initial_delay.__doc__)
            log("barter.log",
                "barter-community-property",
                name="sync_interval",
                value=self._barter.dispersy_sync_interval.__doc__)
            log("barter.log",
                "barter-community-property",
                name="sync_member_count",
                value=self._barter.dispersy_sync_member_count)
            log("barter.log",
                "barter-community-property",
                name="sync_response_limit",
                value=self._barter.dispersy_sync_response_limit)
            log("barter.log",
                "barter-community-property",
                name="timestep",
                value=self._timestep)
            log("barter.log",
                "barter-community-property",
                name="barter_history_size",
                value="unused_(currently_using_FullSyncDistribution)")
            log("barter.log",
                "barter-community-property",
                name="barter_forward_record_on_creation",
                value=self._barter.barter_forward_record_on_creation)
            log("barter.log",
                "barter-community-property",
                name="barter_push_node_count",
                value=self._barter.get_meta_message(
                    u"barter-record").destination.node_count)
            log("barter.log",
                "barter-community-property",
                name="peer_id",
                value=_peer_ids[my_public_key])

        yield 2.0

        if __debug__:
            log("barter.log", "done-reading-peers")

        yield 2.0

        # open the scenario files, as generated from Mircea's Scenario
        # Generator
        bartercast_fp = open('data/bartercast.log')
        availability_fp = open('data/availability.log')

        self._stepcount = 0

        # wait until we reach the starting time
        yield self.sleep(initial_delay=True)

        self._stepcount = 1

        # start the scenario
        while True:
            # get commands
            barter_cmds = self.get_commands_from_fp(bartercast_fp,
                                                    self._stepcount)
            availability_cmds = self.get_commands_from_fp(
                availability_fp, self._stepcount)

            # if there are no commands exit the while loop
            if barter_cmds == -1 and availability_cmds == -1:
                if __debug__: log("barter.log", "no-commands")
                break
            else:
                # if there is a start in the avaibility_cmds then go
                # online
                if availability_cmds != -1 and 'start' in availability_cmds:
                    self.set_online()

                # if there are barter_cmds then execute them
                if barter_cmds != -1:
                    for cmd in barter_cmds:
                        name, up, down = cmd.split()
                        up, down = map(int, (up, down))
                        # note a peer creates a record when it has
                        # interest (e.g. it's upload is larger than
                        # its download)
                        if up >= down:
                            peer_member, address = self.find_peer_by_name(name)
                            self._barter.create_barter_record(
                                peer_member, up, down)

                # if there is a stop in the availability_cmds then go
                # offline
                if availability_cmds != -1 and 'stop' in availability_cmds:
                    self.set_offline()

            # sleep until the next step
            delay = self.sleep()
            if delay >= 0.0:
                yield delay
            else:
                break
            self._stepcount += 1

        # I finished the scenario execution. I should stay online
        # until killed. Note that I can still sync and exchange
        # messages with other peers.
        delay = self.sleep()
        while delay >= 0.0:
            # wait to be killed
            yield 5.0

        while True:
            now = time.time()
            if now >= self._shutdown_timestamp:
                break
            yield 5.0