)
+class OkayTrackerDelta(object):
+ __slots__ = 'head height work my_count my_doa_count my_orphan_announce_count my_dead_announce_count tail'.split(' ')
+
+ @classmethod
+ def get_none(cls, element_id):
+ return cls(element_id, 0, 0, 0, 0, 0, 0, element_id)
+
+ @classmethod
+ def from_element(cls, share):
+ return cls(share.hash,
+ 1, bitcoin_data.target_to_average_attempts(share.target),
+ 1 if share.hash in cls.my_share_hashes else 0,
+ 1 if share.hash in cls.my_doa_share_hashes else 0,
+ 1 if share.hash in cls.my_share_hashes and share.share_data['stale_info'] == 253 else 0,
+ 1 if share.hash in cls.my_share_hashes and share.share_data['stale_info'] == 254 else 0,
+ share.previous_hash)
+
+ def __init__(self, head, height, work, my_count, my_doa_count, my_orphan_announce_count, my_dead_announce_count, tail):
+ self.head, self.height, self.work, self.tail = head, height, work, tail
+ self.my_count, self.my_doa_count, self.my_orphan_announce_count, self.my_dead_announce_count = my_count, my_doa_count, my_orphan_announce_count, my_dead_announce_count
+
+ def __add__(self, other):
+ assert self.tail == other.head
+ return OkayTrackerDelta(self.head,
+ self.height + other.height, self.work + other.work,
+ self.my_count + other.my_count, self.my_doa_count + other.my_doa_count, self.my_orphan_announce_count + other.my_orphan_announce_count, self.my_dead_announce_count + other.my_dead_announce_count,
+ other.tail)
+
+ def __sub__(self, other):
+ if self.head == other.head:
+ return OkayTrackerDelta(other.tail, self.height - other.height, self.work - other.work,
+ self.my_count - other.my_count, self.my_doa_count - other.my_doa_count, self.my_orphan_announce_count - other.my_orphan_announce_count, self.my_dead_announce_count - other.my_dead_announce_count,
+ self.tail)
+ elif self.tail == other.tail:
+ return OkayTrackerDelta(self.head, self.height - other.height, self.work - other.work,
+ self.my_count - other.my_count, self.my_doa_count - other.my_doa_count, self.my_orphan_announce_count - other.my_orphan_announce_count, self.my_dead_announce_count - other.my_dead_announce_count,
+ other.head)
+ else:
+ raise AssertionError()
+
class OkayTracker(forest.Tracker):
def __init__(self, net):
forest.Tracker.__init__(self)
self.net = net
- self.verified = forest.Tracker()
+ self.verified = forest.Tracker(delta_type=OkayTrackerDelta)
self.verified.get_nth_parent_hash = self.get_nth_parent_hash # self is a superset of self.verified
self.get_cumulative_weights = skiplists.WeightsSkipList(self)
import bitcoin.p2p as bitcoin_p2p, bitcoin.getwork as bitcoin_getwork, bitcoin.data as bitcoin_data
from bitcoin import worker_interface
from util import expiring_dict, jsonrpc, variable, deferral, math
-from . import p2p, skiplists, networks, graphs
+from . import p2p, networks, graphs
import p2pool, p2pool.data as p2pool_data
@deferral.retry('Error getting work from bitcoind:', 3)
@defer.inlineCallbacks
def main(args, net, datadir_path):
try:
+ my_share_hashes = set()
+ my_doa_share_hashes = set()
+ p2pool_data.OkayTrackerDelta.my_share_hashes = my_share_hashes
+ p2pool_data.OkayTrackerDelta.my_doa_share_hashes = my_doa_share_hashes
+
print 'p2pool (version %s)' % (p2pool.__version__,)
print
try:
if share.hash in my_doa_share_hashes and tracker.is_child_of(share.hash, current_work.value['best_share_hash']):
removed_doa_unstales.set(removed_doa_unstales.value + 1)
- stale_counter = skiplists.SumSkipList(tracker, lambda share: (
- 1 if share.hash in my_share_hashes else 0,
- 1 if share.hash in my_doa_share_hashes else 0,
- 1 if share.hash in my_share_hashes and share.share_data['stale_info'] == 253 else 0,
- 1 if share.hash in my_share_hashes and share.share_data['stale_info'] == 254 else 0,
- ), (0, 0, 0, 0), math.add_tuples)
def get_stale_counts():
'''Returns (orphans, doas), total, (orphans_recorded_in_chain, doas_recorded_in_chain)'''
my_shares = len(my_share_hashes)
my_doa_shares = len(my_doa_share_hashes)
- my_shares_in_chain, my_doa_shares_in_chain, orphans_recorded_in_chain, doas_recorded_in_chain = stale_counter(
- current_work.value['best_share_hash'],
- tracker.verified.get_height(current_work.value['best_share_hash']),
- )
- my_shares_in_chain += removed_unstales_var.value[0]
- my_doa_shares_in_chain += removed_doa_unstales_var.value
- orphans_recorded_in_chain += removed_unstales_var.value[1]
- doas_recorded_in_chain += removed_unstales_var.value[2]
+ delta = tracker.verified.get_delta(current_work.value['best_share_hash'])
+ my_shares_in_chain = delta.my_count + removed_unstales_var.value[0]
+ my_doa_shares_in_chain = delta.my_doa_count + removed_doa_unstales_var.value
+ orphans_recorded_in_chain = delta.my_orphan_announce_count + removed_unstales_var.value[1]
+ doas_recorded_in_chain = delta.my_dead_announce_count + removed_unstales_var.value[2]
my_shares_not_in_chain = my_shares - my_shares_in_chain
my_doa_shares_not_in_chain = my_doa_shares - my_doa_shares_in_chain
return (my_shares_not_in_chain - my_doa_shares_not_in_chain, my_doa_shares_not_in_chain), my_shares, (orphans_recorded_in_chain, doas_recorded_in_chain)
- my_share_hashes = set()
- my_doa_share_hashes = set()
-
class WorkerBridge(worker_interface.WorkerBridge):
def __init__(self):
worker_interface.WorkerBridge.__init__(self)
assert share_count <= max_shares and total_weight <= desired_weight
assert share_count == max_shares or total_weight == desired_weight
return math.add_dicts(*math.flatten_linked_list(weights_list)), total_weight, total_donation_weight
-
-class SumSkipList(forest.TrackerSkipList):
- def __init__(self, tracker, value_func, identity_value=0, add_func=operator.add):
- forest.TrackerSkipList.__init__(self, tracker)
- self.value_func = value_func
- self.identity_value = identity_value
- self.add_func = add_func
-
-
- def get_delta(self, element):
- return self.value_func(self.tracker.shares[element]), 1
-
- def combine_deltas(self, (result1, count1), (result2, count2)):
- return self.add_func(result1, result2), count1 + count2
-
-
- def initial_solution(self, start_hash, (desired_count,)):
- return self.identity_value, 0
-
- 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, (result, count), (desired_count,)):
- assert count == desired_count
- return result