-
Notifications
You must be signed in to change notification settings - Fork 0
/
acctourney.py
110 lines (87 loc) · 4.18 KB
/
acctourney.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#!/usr/bin/python
# This is a dummy peer that just illustrates the available information your peers
# have available.
# You'll want to copy this file to AgentNameXXX.py for various versions of XXX,
# probably get rid of the silly logging messages, and then add more logic.
import random
import logging
from messages import Upload, Request
from util import even_split
from peer import Peer
class AccTourney(Peer):
def post_init(self):
print(("post_init(): %s here!" % self.id))
self.dummy_state = dict()
self.dummy_state["cake"] = "lie"
def requests(self, peers, history):
"""
peers: available info about the peers (who has what pieces)
history: what's happened so far as far as this peer can see
returns: a list of Request() objects
This will be called after update_pieces() with the most recent state.
"""
needed = lambda i: self.pieces[i] < self.conf.blocks_per_piece
needed_pieces = list(filter(needed, list(range(len(self.pieces)))))
np_set = set(needed_pieces) # sets support fast intersection ops.
logging.debug("%s here: still need pieces %s" % (
self.id, needed_pieces))
logging.debug("%s still here. Here are some peers:" % self.id)
for p in peers:
logging.debug("id: %s, available pieces: %s" % (p.id, p.available_pieces))
logging.debug("And look, I have my entire history available too:")
logging.debug("look at the AgentHistory class in history.py for details")
logging.debug(str(history))
requests = [] # We'll put all the things we want here
# Symmetry breaking is good...
random.shuffle(needed_pieces)
# Sort peers by id. This is probably not a useful sort, but other
# sorts might be useful
peers.sort(key=lambda p: p.id)
# request all available pieces from all peers!
# (up to self.max_requests from each)
for peer in peers:
av_set = set(peer.available_pieces)
isect = av_set.intersection(np_set)
n = min(self.max_requests, len(isect))
# More symmetry breaking -- ask for random pieces.
# This would be the place to try fancier piece-requesting strategies
# to avoid getting the same thing from multiple peers at a time.
for piece_id in random.sample(isect, n):
# aha! The peer has this piece! Request it.
# which part of the piece do we need next?
# (must get the next-needed blocks in order)
start_block = self.pieces[piece_id]
r = Request(self.id, peer.id, piece_id, start_block)
requests.append(r)
return requests
def uploads(self, requests, peers, history):
"""
requests -- a list of the requests for this peer for this round
peers -- available info about all the peers
history -- history for all previous rounds
returns: list of Upload objects.
In each round, this will be called after requests().
"""
round = history.current_round()
logging.debug("%s again. It's round %d." % (
self.id, round))
# One could look at other stuff in the history too here.
# For example, history.downloads[round-1] (if round != 0, of course)
# has a list of Download objects for each Download to this peer in
# the previous round.
if len(requests) == 0:
logging.debug("No one wants my pieces!")
chosen = []
bws = []
else:
logging.debug("Still here: uploading to a random peer")
# change my internal state for no reason
self.dummy_state["cake"] = "pie"
request = random.choice(requests)
chosen = [request.requester_id]
# Evenly "split" my upload bandwidth among the one chosen requester
bws = even_split(self.up_bw, len(chosen))
# create actual uploads out of the list of peer ids and bandwidths
uploads = [Upload(self.id, peer_id, bw)
for (peer_id, bw) in zip(chosen, bws)]
return uploads