ac55bec4256d977358ae0d9c01426d8875013c42
[p2pool.git] / p2pool / skiplists.py
1 from p2pool.util import forest, math
2
3 class WeightsSkipList(forest.TrackerSkipList):
4     # share_count, weights, total_weight
5     
6     def get_delta(self, element):
7         from p2pool.bitcoin import data as bitcoin_data
8         share = self.tracker.shares[element]
9         att = bitcoin_data.target_to_average_attempts(share.target)
10         return 1, {share.share_data['new_script']: att*(65535-share.share_data['donation'])}, att*65535, att*share.share_data['donation']
11     
12     def combine_deltas(self, (share_count1, weights1, total_weight1, total_donation_weight1), (share_count2, weights2, total_weight2, total_donation_weight2)):
13         return share_count1 + share_count2, math.add_dicts(weights1, weights2), total_weight1 + total_weight2, total_donation_weight1 + total_donation_weight2
14     
15     def initial_solution(self, start, (max_shares, desired_weight)):
16         assert desired_weight % 65535 == 0, divmod(desired_weight, 65535)
17         return 0, None, 0, 0
18     
19     def apply_delta(self, (share_count1, weights_list, total_weight1, total_donation_weight1), (share_count2, weights2, total_weight2, total_donation_weight2), (max_shares, desired_weight)):
20         if total_weight1 + total_weight2 > desired_weight and share_count2 == 1:
21             assert (desired_weight - total_weight1) % 65535 == 0
22             script, = weights2.iterkeys()
23             new_weights = dict(script=(desired_weight - total_weight1)//65535*weights2[script]//(total_weight2//65535))
24             return share_count1 + share_count2, (weights_list, new_weights), desired_weight, total_donation_weight1 + (desired_weight - total_weight1)//65535*total_donation_weight2//(total_weight2//65535)
25         return share_count1 + share_count2, (weights_list, weights2), total_weight1 + total_weight2, total_donation_weight1 + total_donation_weight2
26     
27     def judge(self, (share_count, weights_list, total_weight, total_donation_weight), (max_shares, desired_weight)):
28         if share_count > max_shares or total_weight > desired_weight:
29             return 1
30         elif share_count == max_shares or total_weight == desired_weight:
31             return 0
32         else:
33             return -1
34     
35     def finalize(self, (share_count, weights_list, total_weight, total_donation_weight), (max_shares, desired_weight)):
36         assert share_count <= max_shares and total_weight <= desired_weight
37         assert share_count == max_shares or total_weight == desired_weight
38         return math.add_dicts(*math.flatten_linked_list(weights_list)), total_weight, total_donation_weight