for head in set(self.heads) - set(self.verified.heads):
head_height, last = self.get_height_and_last(head)
- for share in itertools.islice(self.get_chain_known(head), None if last is None else min(5, max(0, head_height - self.net.CHAIN_LENGTH))):
+ for share in self.get_chain(head, head_height if last is None else min(5, max(0, head_height - self.net.CHAIN_LENGTH))):
if self.attempt_verify(share, now):
break
if share.hash in self.heads:
can = max(last_height - 1 - self.net.CHAIN_LENGTH, 0) if last_last_hash is not None else last_height
get = min(want, can)
#print 'Z', head_height, last_hash is None, last_height, last_last_hash is None, want, can, get
- for share in itertools.islice(self.get_chain_known(last_hash), get):
+ for share in self.get_chain(last_hash, get):
if not self.attempt_verify(share, now):
break
if head_height < self.net.CHAIN_LENGTH and last_last_hash is not None:
score2 = 0
block_height = -1000000
max_height = min(self.net.CHAIN_LENGTH, head_height)
- for share in reversed(list(itertools.islice(self.verified.get_chain_known(self.verified.get_nth_parent_hash(share_hash, max_height//2)), max_height//2))):
+ for share in math.reversed(self.verified.get_chain(self.verified.get_nth_parent_hash(share_hash, max_height//2), max_height//2)):
block_height = max(block_height, ht.get_height_rel_highest(share.header['previous_block']))
this_score = (self.verified.get_work(share_hash) - self.verified.get_work(share.hash))//(0 - block_height + 1)
if this_score > score2:
stops = set(stops)
shares = []
for share_hash in share_hashes:
- for share in itertools.islice(tracker.get_chain_known(share_hash), parents + 1):
+ for share in tracker.get_chain(share_hash, min(parents + 1, tracker.get_height(share_hash))):
if share.hash in stops:
break
shares.append(share)
def work_changed(new_work):
#print 'Work changed:', new_work
shares = []
- for share in tracker.get_chain_known(new_work['best_share_hash']):
+ for share in tracker.get_chain(new_work['best_share_hash'], tracker.get_height(new_work['best_share_hash'])):
if share.hash in shared_share_hashes:
break
shared_share_hashes.add(share.hash)
current_work.changed.watch(work_changed)
def save_shares():
- for share in itertools.islice(tracker.get_chain_known(current_work.value['best_share_hash']), 2*net.CHAIN_LENGTH):
+ for share in tracker.get_chain(current_work.value['best_share_hash'], min(tracker.get_height(current_work.value['best_share_hash']), 2*net.CHAIN_LENGTH)):
ss.add_share(share)
if share.hash in tracker.verified.shares:
ss.add_verified_hash(share.hash)
if current_work.value['best_share_hash'] is not None:
height, last = tracker.get_height_and_last(current_work.value['best_share_hash'])
att_s = p2pool_data.get_pool_attempts_per_second(tracker, current_work.value['best_share_hash'], min(height - 1, 720))
- fracs = [share.stale_frac for share in itertools.islice(tracker.get_chain_known(current_work.value['best_share_hash']), 120) if share.stale_frac is not None]
+ 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]
return json.dumps(int(att_s / (1. - (math.median(fracs) if fracs else 0))))
return json.dumps(None)
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
- fracs = [share.stale_frac for share in itertools.islice(tracker.get_chain_known(current_work.value['best_share_hash']), 120) if share.stale_frac is not None]
+ 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]
this_str = 'Pool: %sH/s in %i shares (%i/%i verified) Recent: %.02f%% >%sH/s Shares: %i (%i orphan, %i dead) Peers: %i' % (
math.format(int(att_s / (1. - (math.median(fracs) if fracs else 0)))),
height,
work += work_inc
return height, work, share_hash
+ def get_chain(self, start_hash, length):
+ # same implementation :/
+ assert length <= self.get_height(start_hash)
+ for i in xrange(length):
+ yield self.shares[start_hash]
+ start_hash = self.shares[start_hash].previous_hash
+
def is_child_of(self, share_hash, possible_child_hash):
if self.get_last(share_hash) != self.get_last(possible_child_hash):
return None
other = random.choice(self.shares.keys())
assert self.is_child_of(start, other) == t.is_child_of(start, other)
assert self.is_child_of(other, start) == t.is_child_of(other, start)
+
+ assert list(self.get_chain(start, min(a[0], 10))) == list(t.get_chain(start, min(a[0], 10)))
def generate_tracker_simple(n):
t = forest.Tracker(math.shuffled(FakeShare(hash=i, previous_hash=i - 1 if i > 0 else None) for i in xrange(n)))
self._set_height_jump(update_hash, height - height_then, share_hash, work - work_then)
return height, work, share_hash
- def get_chain_known(self, start_hash):
- assert isinstance(start_hash, (int, long, type(None)))
- '''
- Chain starting with item of hash I{start_hash} of items that this Tracker contains
- '''
- item_hash_to_get = start_hash
- while True:
- if item_hash_to_get not in self.shares:
- break
- share = self.shares[item_hash_to_get]
- assert not isinstance(share, long)
- yield share
- item_hash_to_get = share.previous_hash
+ def get_chain(self, start_hash, length):
+ assert length <= self.get_height(start_hash)
+ for i in xrange(length):
+ yield self.shares[start_hash]
+ start_hash = self.shares[start_hash].previous_hash
def is_child_of(self, share_hash, possible_child_hash):
height, last = self.get_height_and_last(share_hash)
from __future__ import absolute_import, division
+import __builtin__
import math
import random
def interval_to_center_radius((low, high)):
return (high+low)/2, (high-low)/2
+def reversed(x):
+ try:
+ return __builtin__.reversed(x)
+ except TypeError:
+ return reversed(list(x))
+
if __name__ == '__main__':
import random
a = 1