8 from p2pool.util.vector import v
9 from p2pool.bitcoin import data as bitcoin_data
13 def __getattr__(self, name):
14 res = pygame.Color(name)
15 setattr(self, name, res)
18 def get_uniform(bound, *data):
19 x = int(hashlib.sha256(repr(data)).hexdigest(), 16)
22 def get_pos(share, t, d):
23 x = 5 + get_uniform(400 - 10, share.hash, "pos")
24 y = d.get_height() - (t - share.time_seen)*10
25 if y < -10000: y = -10000
26 if y > 10000: y = 10000
30 return [get_uniform(256, data, x) for x in "rgb"]
32 def perp_and_normalize_to((dx, dy), d):
33 m = math.sqrt(dx**2 + dy**2)
34 return v(-dy/m*d, dx/m*d)
36 def go(share, tracker, t, d):
37 #c = color.green if share.peer is None else color.red
38 c = get_color(share.new_script)
39 pos = get_pos(share, t, d)
40 pygame.draw.circle(d, c, pos.rounded, 5)
41 if share.previous_hash in tracker.shares:
42 previous_share = tracker.shares[share.previous_hash]
43 previous_pos = get_pos(previous_share, t, d)
44 vec_to_previous = previous_pos - pos
45 if vec_to_previous.mag() > 1:
46 pygame.draw.polygon(d, c, [
47 (pos + perp_and_normalize_to(vec_to_previous, 5)).rounded,
48 (pos + perp_and_normalize_to(vec_to_previous, -5)).rounded,
51 if share.peer is None:
52 pygame.draw.circle(d, c, pos.rounded, 10, 2)
53 for child_hash in tracker.reverse_shares.get(share.hash, set()):
54 go(tracker.shares[child_hash], tracker, t, d)
55 d.blit(f.render(bitcoin_data.script2_to_human(share.new_script, tracker.net.PARENT), True, (255, 255, 255)), pos)
58 f = pygame.font.SysFont("Monospace", 16)
60 def get(tracker, best):
61 d = pygame.Surface((600, 600), 32)
62 if tracker.get_height(best) >= 100:
64 start = tracker.get_nth_parent_hash(best, 100)
66 go(tracker.shares[start], tracker, t, d)
67 f = StringIO.StringIO()
68 Image.fromstring("RGB", d.get_size(), pygame.image.tostring(d, "RGB")).save(f, "png")