From 837026f5669939a366fdce14c143c0e8889a8afc Mon Sep 17 00:00:00 2001 From: Forrest Voight Date: Fri, 23 Dec 2011 20:36:10 -0500 Subject: [PATCH] removed run_identifier and sped up stale counting --- p2pool/main.py | 61 +++++++++++++++++++++++++---------------- p2pool/skiplists.py | 48 +++++++++++++------------------- p2pool/test/util/test_math.py | 7 +++++ p2pool/util/math.py | 7 +++++ 4 files changed, 71 insertions(+), 52 deletions(-) create mode 100644 p2pool/test/util/test_math.py diff --git a/p2pool/main.py b/p2pool/main.py index e81b89c..8bf7c8a 100644 --- a/p2pool/main.py +++ b/p2pool/main.py @@ -388,25 +388,38 @@ def main(args, net, datadir_path): # setup worker logic merkle_root_to_transactions = expiring_dict.ExpiringDict(300) - run_identifier = struct.pack(' target:\nhash : %x\ntarget: %x' % (pow_hash, share_info['bits'].target) return False share = p2pool_data.Share(net, header, share_info, other_txs=transactions[1:]) - my_shares.add(share.hash) + my_share_hashes.add(share.hash) if share.previous_hash != current_work.value['best_share_hash']: - doa_shares.add(share.hash) + my_doa_share_hashes.add(share.hash) print 'GOT SHARE! %s %s prev %s age %.2fs' % (request.getUser(), p2pool_data.format_hash(share.hash), p2pool_data.format_hash(share.previous_hash), time.time() - getwork_time) + (' DEAD ON ARRIVAL' if share.previous_hash != current_work.value['best_share_hash'] else '') good = share.previous_hash == current_work.value['best_share_hash'] # maybe revert back to tracker being non-blocking so 'good' can be more accurate? @@ -620,8 +633,7 @@ def main(args, net, datadir_path): if height > 2: att_s = p2pool_data.get_pool_attempts_per_second(tracker, current_work.value['best_share_hash'], min(height - 1, 720)) weights, total_weight, donation_weight = tracker.get_cumulative_weights(current_work.value['best_share_hash'], min(height, 720), 65535*2**256) - shares, stale_doa_shares, stale_not_doa_shares = get_share_counts(True) - stale_shares = stale_doa_shares + stale_not_doa_shares + (stale_orphan_shares, stale_doa_shares), shares = get_stale_counts() fracs = [share.stale_frac for share in tracker.get_chain(current_work.value['best_share_hash'], min(120, height)) if share.stale_frac is not None] real_att_s = att_s / (1. - (math.median(fracs) if fracs else 0)) my_att_s = real_att_s*weights.get(my_script, 0)/total_weight @@ -633,7 +645,7 @@ def main(args, net, datadir_path): weights.get(my_script, 0)/total_weight*100, math.format(int(my_att_s)), shares, - stale_not_doa_shares, + stale_orphan_shares, stale_doa_shares, len(p2p_node.peers), ) + (' FDs: %i R/%i W' % (len(reactor.getReaders()), len(reactor.getWriters())) if p2pool.DEBUG else '') @@ -645,6 +657,7 @@ def main(args, net, datadir_path): this_str += '\nPool stales: %i%%' % (int(100*med+.5),) conf = 0.95 if shares: + stale_shares = stale_orphan_shares + stale_doa_shares this_str += u' Own: %i±%i%%' % tuple(int(100*x+.5) for x in math.interval_to_center_radius(math.binomial_conf_interval(stale_shares, shares, conf))) if med < .99: this_str += u' Own efficiency: %i±%i%%' % tuple(int(100*x+.5) for x in math.interval_to_center_radius((1 - y)/(1 - med) for y in math.binomial_conf_interval(stale_shares, shares, conf)[::-1])) diff --git a/p2pool/skiplists.py b/p2pool/skiplists.py index 6ff9905..da5dcf0 100644 --- a/p2pool/skiplists.py +++ b/p2pool/skiplists.py @@ -1,3 +1,5 @@ +import operator + from p2pool.util import forest, math class WeightsSkipList(forest.TrackerSkipList): @@ -38,39 +40,29 @@ class WeightsSkipList(forest.TrackerSkipList): def finalize(self, (share_count, weights, total_weight, total_donation_weight)): return weights, total_weight, total_donation_weight -class CountsSkipList(forest.TrackerSkipList): - # share_count, counts, total_count - - def __init__(self, tracker, run_identifier): +class SumSkipList(forest.TrackerSkipList): + def __init__(self, tracker, value_func, identity_value=0, add_func=operator.add): forest.TrackerSkipList.__init__(self, tracker) - self.run_identifier = run_identifier + self.value_func = value_func + self.identity_value = identity_value + self.add_func = add_func + def get_delta(self, element): - if element is None: - raise AssertionError() - share = self.tracker.shares[element] - return 1, set([share.hash]) if share.nonce.startswith(self.run_identifier) else set() + return self.value_func(self.tracker.shares[element]), 1 - def combine_deltas(self, (share_count1, share_hashes1), (share_count2, share_hashes2)): - if share_hashes1 & share_hashes2: - raise AssertionError() - return share_count1 + share_count2, share_hashes1 | share_hashes2 + def combine_deltas(self, (result1, count1), (result2, count2)): + return self.add_func(result1, result2), count1 + count2 - def initial_solution(self, start, (desired_shares,)): - return 0, set() - def apply_delta(self, (share_count1, share_hashes1), (share_count2, share_hashes2), (desired_shares,)): - if share_hashes1 & share_hashes2: - raise AssertionError() - return share_count1 + share_count2, share_hashes1 | share_hashes2 + def initial_solution(self, start_hash, (desired_count,)): + return self.identity_value, 0 - def judge(self, (share_count, share_hashes), (desired_shares,)): - if share_count > desired_shares: - return 1 - elif share_count == desired_shares: - return 0 - else: - return -1 + def apply_delta(self, (result, count), (d_result, d_count), (desired_count,)): + return self.add_func(result, d_result), count + d_count + + def judge(self, (result, count), (desired_count,)): + return cmp(count, desired_count) - def finalize(self, (share_count, share_hashes)): - return share_hashes + def finalize(self, (result, count)): + return result diff --git a/p2pool/test/util/test_math.py b/p2pool/test/util/test_math.py new file mode 100644 index 0000000..86d81fc --- /dev/null +++ b/p2pool/test/util/test_math.py @@ -0,0 +1,7 @@ +import unittest + +from p2pool.util import math + +class Test(unittest.TestCase): + def test_add_tuples(self): + assert math.add_tuples((1, 2, 3), (4, 5, 6)) == (5, 7, 9) diff --git a/p2pool/util/math.py b/p2pool/util/math.py index 6229994..66b802e 100644 --- a/p2pool/util/math.py +++ b/p2pool/util/math.py @@ -123,6 +123,13 @@ class Object(object): for k, v in kwargs.iteritems(): setattr(self, k, v) +def add_tuples(res, *tuples): + for t in tuples: + if len(t) != len(res): + print 'tuples must all be the same length' + res = tuple(a + b for a, b in zip(res, t)) + return res + if __name__ == '__main__': import random a = 1 -- 1.7.1