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())
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)
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)
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()
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)
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)
def _watchdog(self): try: while True: yield 3600.0 except GeneratorExit: print "GeneratorExit" log("walktest.log", "stopiteration") close("walktest.log")
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
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)
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())
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)
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
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
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
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)
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
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)
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)
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
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
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)
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)
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")
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)
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)
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
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