changed = False
for header in headers:
hw = HeaderWrapper.from_header(header)
- if hw.hash in self._tracker.shares:
+ if hw.hash in self._tracker.items:
continue
changed = True
self._tracker.add(hw)
self.updated.happened()
self._think()
- if len(self._tracker.shares) >= self._last_notified_size + 100:
- print 'Have %i/%i block headers' % (len(self._tracker.shares), self._backlog_needed)
- self._last_notified_size = len(self._tracker.shares)
+ if len(self._tracker.items) >= self._last_notified_size + 100:
+ print 'Have %i/%i block headers' % (len(self._tracker.items), self._backlog_needed)
+ self._last_notified_size = len(self._tracker.items)
@defer.inlineCallbacks
def _request(self, last):
- if last in self._tracker.shares:
+ if last in self._tracker.items:
return
if last in self._requested:
return
@classmethod
def generate_transaction(cls, tracker, share_data, block_target, desired_timestamp, desired_target, ref_merkle_link, net):
- previous_share = tracker.shares[share_data['previous_share_hash']] if share_data['previous_share_hash'] is not None else None
+ previous_share = tracker.items[share_data['previous_share_hash']] if share_data['previous_share_hash'] is not None else None
height, last = tracker.get_height_and_last(share_data['previous_share_hash'])
assert height >= net.REAL_CHAIN_LENGTH or last is None
def get_delta(self, element):
from p2pool.bitcoin import data as bitcoin_data
- share = self.tracker.shares[element]
+ share = self.tracker.items[element]
att = bitcoin_data.target_to_average_attempts(share.target)
return 1, {share.new_script: att*(65535-share.share_data['donation'])}, att*65535, att*share.share_data['donation']
self.get_cumulative_weights = WeightsSkipList(self)
def attempt_verify(self, share):
- if share.hash in self.verified.shares:
+ if share.hash in self.verified.items:
return True
height, last = self.get_height_and_last(share.hash)
if height < self.net.CHAIN_LENGTH + 1 and last is not None:
else:
if last is not None:
desired.add((
- self.shares[random.choice(list(self.reverse_shares[last]))].peer,
+ self.items[random.choice(list(self.reverse[last]))].peer,
last,
max(x.timestamp for x in self.get_chain(head, min(head_height, 5))),
min(x.target for x in self.get_chain(head, min(head_height, 5))),
))
for bad in bads:
- assert bad not in self.verified.shares
+ assert bad not in self.verified.items
assert bad in self.heads
if p2pool.DEBUG:
print "BAD", bad
break
if head_height < self.net.CHAIN_LENGTH and last_last_hash is not None:
desired.add((
- self.shares[random.choice(list(self.verified.reverse_shares[last_hash]))].peer,
+ self.items[random.choice(list(self.verified.reverse[last_hash]))].peer,
last_last_hash,
max(x.timestamp for x in self.get_chain(head, min(head_height, 5))),
min(x.target for x in self.get_chain(head, min(head_height, 5))),
# decide best verified head
decorated_heads = sorted(((
self.verified.get_work(self.verified.get_nth_parent_hash(h, min(5, self.verified.get_height(h)))),
- #self.shares[h].peer is None,
- self.shares[h].pow_hash <= self.shares[h].header['bits'].target, # is block solution
- (self.shares[h].header['previous_block'], self.shares[h].header['bits']) == (previous_block, bits) or self.shares[h].peer is None,
- -self.shares[h].time_seen,
+ #self.items[h].peer is None,
+ self.items[h].pow_hash <= self.items[h].header['bits'].target, # is block solution
+ (self.items[h].header['previous_block'], self.items[h].header['bits']) == (previous_block, bits) or self.items[h].peer is None,
+ -self.items[h].time_seen,
), h) for h in self.verified.tails.get(best_tail, []))
if p2pool.DEBUG:
print len(decorated_heads), 'heads. Top 10:'
for score, head_hash in decorated_heads[-10:]:
- print ' ', format_hash(head_hash), format_hash(self.shares[head_hash].previous_hash), score
+ print ' ', format_hash(head_hash), format_hash(self.items[head_hash].previous_hash), score
best_head_score, best = decorated_heads[-1] if decorated_heads else (None, None)
# eat away at heads
if share_hash in [head_hash for score, head_hash in decorated_heads[-5:]]:
#print 1
continue
- if self.shares[share_hash].time_seen > time.time() - 300:
+ if self.items[share_hash].time_seen > time.time() - 300:
#print 2
continue
- if share_hash not in self.verified.shares and max(self.shares[after_tail_hash].time_seen for after_tail_hash in self.reverse_shares.get(tail)) > time.time() - 120: # XXX stupid
+ if share_hash not in self.verified.items and max(self.items[after_tail_hash].time_seen for after_tail_hash in self.reverse.get(tail)) > time.time() - 120: # XXX stupid
#print 3
continue
to_remove.add(share_hash)
if not to_remove:
break
for share_hash in to_remove:
- if share_hash in self.verified.shares:
+ if share_hash in self.verified.items:
self.verified.remove(share_hash)
self.remove(share_hash)
#print "_________", to_remove
for tail, heads in self.tails.iteritems():
if min(self.get_height(head) for head in heads) < 2*self.net.CHAIN_LENGTH + 10:
continue
- for aftertail in self.reverse_shares.get(tail, set()):
- if len(self.reverse_shares[self.shares[aftertail].previous_hash]) > 1: # XXX
+ for aftertail in self.reverse.get(tail, set()):
+ if len(self.reverse[self.items[aftertail].previous_hash]) > 1: # XXX
print "raw"
continue
to_remove.add(aftertail)
# if removed from this, it must be removed from verified
#start = time.time()
for aftertail in to_remove:
- if self.shares[aftertail].previous_hash not in self.tails:
- print "erk", aftertail, self.shares[aftertail].previous_hash
+ if self.items[aftertail].previous_hash not in self.tails:
+ print "erk", aftertail, self.items[aftertail].previous_hash
continue
- if aftertail in self.verified.shares:
+ if aftertail in self.verified.items:
self.verified.remove(aftertail)
self.remove(aftertail)
#end = time.time()
#print "removed! %i %f" % (len(to_remove), (end - start)/len(to_remove))
if best is not None:
- best_share = self.shares[best]
+ best_share = self.items[best]
if (best_share.header['previous_block'], best_share.header['bits']) != (previous_block, bits) and best_share.header_hash != previous_block and best_share.peer is not None:
if p2pool.DEBUG:
print 'Stale detected! %x < %x' % (best_share.header['previous_block'], previous_block)
def get_pool_attempts_per_second(tracker, previous_share_hash, dist, min_work=False, integer=False):
assert dist >= 2
- near = tracker.shares[previous_share_hash]
- far = tracker.shares[tracker.get_nth_parent_hash(previous_share_hash, dist - 1)]
+ near = tracker.items[previous_share_hash]
+ far = tracker.items[tracker.get_nth_parent_hash(previous_share_hash, dist - 1)]
attempts = tracker.get_delta(near.hash, far.hash).work if not min_work else tracker.get_delta(near.hash, far.hash).min_work
time = near.timestamp - far.timestamp
if time <= 0:
if s is not None:
res[s] = res.get(s, 0) + bitcoin_data.target_to_average_attempts(share.target)
if rates:
- dt = tracker.shares[share_hash].timestamp - tracker.shares[tracker.get_nth_parent_hash(share_hash, lookbehind - 1)].timestamp
+ dt = tracker.items[share_hash].timestamp - tracker.items[tracker.get_nth_parent_hash(share_hash, lookbehind - 1)].timestamp
res = dict((k, v/dt) for k, v in res.iteritems())
return res
print "Loading shares..."
for i, (mode, contents) in enumerate(ss.get_shares()):
if mode == 'share':
- if contents.hash in tracker.shares:
+ if contents.hash in tracker.items:
continue
shared_share_hashes.add(contents.hash)
contents.time_seen = 0
tracker.add(contents)
- if len(tracker.shares) % 1000 == 0 and tracker.shares:
- print " %i" % (len(tracker.shares),)
+ if len(tracker.items) % 1000 == 0 and tracker.items:
+ print " %i" % (len(tracker.items),)
elif mode == 'verified_hash':
known_verified.add(contents)
else:
raise AssertionError()
print " ...inserting %i verified shares..." % (len(known_verified),)
for h in known_verified:
- if h not in tracker.shares:
+ if h not in tracker.items:
ss.forget_verified_share(h)
continue
- tracker.verified.add(tracker.shares[h])
- print " ...done loading %i shares!" % (len(tracker.shares),)
+ tracker.verified.add(tracker.items[h])
+ print " ...done loading %i shares!" % (len(tracker.items),)
print
tracker.removed.watch(lambda share: ss.forget_share(share.hash))
tracker.verified.removed.watch(lambda share: ss.forget_verified_share(share.hash))
new_count = 0
for share in shares:
- if share.hash in tracker.shares:
+ if share.hash in tracker.items:
#print 'Got duplicate share, ignoring. Hash: %s' % (p2pool_data.format_hash(share.hash),)
continue
set_best_share()
if len(shares) > 5:
- print '... done processing %i shares. New: %i Have: %i/~%i' % (len(shares), new_count, len(tracker.shares), 2*net.CHAIN_LENGTH)
+ print '... done processing %i shares. New: %i Have: %i/~%i' % (len(shares), new_count, len(tracker.items), 2*net.CHAIN_LENGTH)
def handle_share_hashes(self, hashes, peer):
t = time.time()
get_hashes = []
for share_hash in hashes:
- if share_hash in tracker.shares:
+ if share_hash in tracker.items:
continue
last_request_time, count = requested.get(share_hash, (None, 0))
if last_request_time is not None and last_request_time - 5 < t < last_request_time + 10 * 1.5**count:
def save_shares():
for share in tracker.get_chain(best_share_var.value, min(tracker.get_height(best_share_var.value), 2*net.CHAIN_LENGTH)):
ss.add_share(share)
- if share.hash in tracker.verified.shares:
+ if share.hash in tracker.verified.items:
ss.add_verified_hash(share.hash)
task.LoopingCall(save_shares).start(60)
height = tracker.get_height(best_share_var.value)
this_str = 'P2Pool: %i shares in chain (%i verified/%i total) Peers: %i (%i incoming)' % (
height,
- len(tracker.verified.shares),
- len(tracker.shares),
+ len(tracker.verified.items),
+ len(tracker.items),
len(p2p_node.peers),
sum(1 for peer in p2p_node.peers.itervalues() if peer.incoming),
) + (' FDs: %i R/%i W' % (len(reactor.getReaders()), len(reactor.getWriters())) if p2pool.DEBUG else '')
math.format(int(my_att_s)),
math.format_dt(dt),
math.format_binomial_conf(sum(1 for datum in datums if datum['dead']), len(datums), 0.95),
- math.format_dt(2**256 / tracker.shares[best_share_var.value].max_target / my_att_s) if my_att_s and best_share_var.value else '???',
+ math.format_dt(2**256 / tracker.items[best_share_var.value].max_target / my_att_s) if my_att_s and best_share_var.value else '???',
)
if height > 2:
from p2pool.util import forest, math
class DumbTracker(object):
- def __init__(self, shares=[]):
- self.shares = {} # hash -> share
- self.reverse_shares = {} # previous_hash -> set of share_hashes
+ def __init__(self, items=[]):
+ self.items = {} # hash -> item
+ self.reverse = {} # previous_hash -> set of item_hashes
- for share in shares:
- self.add(share)
-
- def add(self, share):
- if share.hash in self.shares:
- raise ValueError('share already present')
- self.shares[share.hash] = share
- self.reverse_shares.setdefault(share.previous_hash, set()).add(share.hash)
-
- def remove(self, share_hash):
- share = self.shares[share_hash]
- del share_hash
+ for item in items:
+ self.add(item)
+
+ def add(self, item):
+ if item.hash in self.items:
+ raise ValueError('item already present')
+ self.items[item.hash] = item
+ self.reverse.setdefault(item.previous_hash, set()).add(item.hash)
+
+ def remove(self, item_hash):
+ item = self.items[item_hash]
+ del item_hash
- self.shares.pop(share.hash)
- self.reverse_shares[share.previous_hash].remove(share.hash)
- if not self.reverse_shares[share.previous_hash]:
- self.reverse_shares.pop(share.previous_hash)
+ self.items.pop(item.hash)
+ self.reverse[item.previous_hash].remove(item.hash)
+ if not self.reverse[item.previous_hash]:
+ self.reverse.pop(item.previous_hash)
@property
def heads(self):
- return dict((x, self.get_last(x)) for x in self.shares if x not in self.reverse_shares)
+ return dict((x, self.get_last(x)) for x in self.items if x not in self.reverse)
@property
def tails(self):
- return dict((x, set(y for y in self.shares if self.get_last(y) == x and y not in self.reverse_shares)) for x in self.reverse_shares if x not in self.shares)
+ return dict((x, set(y for y in self.items if self.get_last(y) == x and y not in self.reverse)) for x in self.reverse if x not in self.items)
- def get_nth_parent_hash(self, share_hash, n):
+ def get_nth_parent_hash(self, item_hash, n):
for i in xrange(n):
- share_hash = self.shares[share_hash].previous_hash
- return share_hash
+ item_hash = self.items[item_hash].previous_hash
+ return item_hash
- def get_height(self, share_hash):
- height, last = self.get_height_and_last(share_hash)
+ def get_height(self, item_hash):
+ height, last = self.get_height_and_last(item_hash)
return height
- def get_last(self, share_hash):
- height, last = self.get_height_and_last(share_hash)
+ def get_last(self, item_hash):
+ height, last = self.get_height_and_last(item_hash)
return last
- def get_height_and_last(self, share_hash):
+ def get_height_and_last(self, item_hash):
height = 0
- while share_hash in self.shares:
- share_hash = self.shares[share_hash].previous_hash
+ while item_hash in self.items:
+ item_hash = self.items[item_hash].previous_hash
height += 1
- return height, share_hash
+ return height, item_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
+ yield self.items[start_hash]
+ start_hash = self.items[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):
+ def is_child_of(self, item_hash, possible_child_hash):
+ if self.get_last(item_hash) != self.get_last(possible_child_hash):
return None
while True:
- if possible_child_hash == share_hash:
+ if possible_child_hash == item_hash:
return True
- if possible_child_hash not in self.shares:
+ if possible_child_hash not in self.items:
return False
- possible_child_hash = self.shares[possible_child_hash].previous_hash
+ possible_child_hash = self.items[possible_child_hash].previous_hash
class FakeShare(object):
def __init__(self, **kwargs):
return 'FakeShare(' + ', '.join('%s=%r' % (k, v) for k, v in self._attrs.iteritems()) + ')'
def test_tracker(self):
- t = DumbTracker(self.shares.itervalues())
+ t = DumbTracker(self.items.itervalues())
- assert self.shares == t.shares, (self.shares, t.shares)
- assert self.reverse_shares == t.reverse_shares, (self.reverse_shares, t.reverse_shares)
+ assert self.items == t.items, (self.items, t.items)
+ assert self.reverse == t.reverse, (self.reverse, t.reverse)
assert self.heads == t.heads, (self.heads, t.heads)
assert self.tails == t.tails, (self.tails, t.tails)
if random.random() < 0.9:
return
- for start in self.shares:
+ for start in self.items:
a, b = self.get_height_and_last(start), t.get_height_and_last(start)
assert a == b, (a, b)
- other = random.choice(self.shares.keys())
+ other = random.choice(self.items.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)
return t
def generate_tracker_random(n):
- shares = []
+ items = []
for i in xrange(n):
- x = random.choice(shares + [FakeShare(hash=None), FakeShare(hash=random.randrange(1000000, 2000000))]).hash
- shares.append(FakeShare(hash=i, previous_hash=x))
- t = forest.Tracker(math.shuffled(shares))
+ x = random.choice(items + [FakeShare(hash=None), FakeShare(hash=random.randrange(1000000, 2000000))]).hash
+ items.append(FakeShare(hash=i, previous_hash=x))
+ t = forest.Tracker(math.shuffled(items))
test_tracker(t)
return t
for ii in xrange(20):
t = generate_tracker_random(random.randrange(100))
#print "--start--"
- while t.shares:
+ while t.items:
while True:
try:
- t.remove(random.choice(list(t.shares)))
+ t.remove(random.choice(list(t.items)))
except NotImplementedError:
pass # print "aborted", x
else:
def test_tracker3(self):
for ii in xrange(10):
- shares = []
+ items = []
for i in xrange(random.randrange(100)):
- x = random.choice(shares + [FakeShare(hash=None), FakeShare(hash=random.randrange(1000000, 2000000))]).hash
- shares.append(FakeShare(hash=i, previous_hash=x))
+ x = random.choice(items + [FakeShare(hash=None), FakeShare(hash=random.randrange(1000000, 2000000))]).hash
+ items.append(FakeShare(hash=i, previous_hash=x))
t = forest.Tracker()
test_tracker(t)
- for share in math.shuffled(shares):
- t.add(share)
+ for item in math.shuffled(items):
+ t.add(item)
test_tracker(t)
if random.randrange(3) == 0:
while True:
try:
- t.remove(random.choice(list(t.shares)))
+ t.remove(random.choice(list(t.items)))
except NotImplementedError:
pass
else:
break
test_tracker(t)
- for share in math.shuffled(shares):
- if share.hash not in t.shares:
- t.add(share)
+ for item in math.shuffled(items):
+ if item.hash not in t.items:
+ t.add(item)
test_tracker(t)
if random.randrange(3) == 0:
while True:
try:
- t.remove(random.choice(list(t.shares)))
+ t.remove(random.choice(list(t.items)))
except NotImplementedError:
pass
else:
break
test_tracker(t)
- while t.shares:
+ while t.items:
while True:
try:
- t.remove(random.choice(list(t.shares)))
+ t.remove(random.choice(list(t.items)))
except NotImplementedError:
pass
else:
self.tracker = tracker
self_ref = weakref.ref(self, lambda _: tracker.removed.unwatch(watch_id))
- watch_id = self.tracker.removed.watch(lambda share: self_ref().forget_item(share.hash))
+ watch_id = self.tracker.removed.watch(lambda item: self_ref().forget_item(item.hash))
def previous(self, element):
- return self.tracker.delta_type.from_element(self.tracker.shares[element]).tail
+ return self.tracker.delta_type.from_element(self.tracker.items[element]).tail
class DistanceSkipList(TrackerSkipList):
return cls(element_id, element_id, **dict((k, 0) for k in attrs))
@classmethod
- def from_element(cls, share):
- return cls(share.hash, share.previous_hash, **dict((k, v(share)) for k, v in attrs.iteritems()))
+ def from_element(cls, item):
+ return cls(item.hash, item.previous_hash, **dict((k, v(item)) for k, v in attrs.iteritems()))
def __init__(self, head, tail, **kwargs):
self.head, self.tail = head, tail
))
class Tracker(object):
- def __init__(self, shares=[], delta_type=AttributeDelta, subset_of=None):
- self.shares = {} # hash -> share
- self.reverse_shares = {} # delta.tail -> set of share_hashes
+ def __init__(self, items=[], delta_type=AttributeDelta, subset_of=None):
+ self.items = {} # hash -> item
+ self.reverse = {} # delta.tail -> set of item_hashes
self.heads = {} # head hash -> tail_hash
self.tails = {} # tail hash -> set of head hashes
- self.deltas = {} # share_hash -> delta, ref
- self.reverse_deltas = {} # ref -> set of share_hashes
+ self.deltas = {} # item_hash -> delta, ref
+ self.reverse_deltas = {} # ref -> set of item_hashes
self.ref_generator = itertools.count()
self.delta_refs = {} # ref -> delta
self.delta_type = delta_type
self.subset_of = subset_of
- for share in shares:
- self.add(share)
+ for item in items:
+ self.add(item)
- def add(self, share):
- assert not isinstance(share, (int, long, type(None)))
- delta = self.delta_type.from_element(share)
+ def add(self, item):
+ assert not isinstance(item, (int, long, type(None)))
+ delta = self.delta_type.from_element(item)
if self.subset_of is not None:
- assert delta.head in self.subset_of.shares
+ assert delta.head in self.subset_of.items
- if delta.head in self.shares:
- raise ValueError('share already present')
+ if delta.head in self.items:
+ raise ValueError('item already present')
if delta.head in self.tails:
heads = self.tails.pop(delta.head)
else:
tail = self.get_last(delta.tail)
- self.shares[delta.head] = share
- self.reverse_shares.setdefault(delta.tail, set()).add(delta.head)
+ self.items[delta.head] = item
+ self.reverse.setdefault(delta.tail, set()).add(delta.head)
self.tails.setdefault(tail, set()).update(heads)
if delta.tail in self.tails[tail]:
for head in heads:
self.heads[head] = tail
- self.added.happened(share)
+ self.added.happened(item)
- def remove(self, share_hash):
- assert isinstance(share_hash, (int, long, type(None)))
- if share_hash not in self.shares:
+ def remove(self, item_hash):
+ assert isinstance(item_hash, (int, long, type(None)))
+ if item_hash not in self.items:
raise KeyError()
if self.subset_of is not None:
- assert share_hash in self.subset_of.shares
+ assert item_hash in self.subset_of.items
- share = self.shares[share_hash]
- del share_hash
+ item = self.items[item_hash]
+ del item_hash
- delta = self.delta_type.from_element(share)
+ delta = self.delta_type.from_element(item)
- children = self.reverse_shares.get(delta.head, set())
+ children = self.reverse.get(delta.head, set())
if delta.head in self.heads and delta.tail in self.tails:
tail = self.heads.pop(delta.head)
elif delta.head in self.heads:
tail = self.heads.pop(delta.head)
self.tails[tail].remove(delta.head)
- if self.reverse_shares[delta.tail] != set([delta.head]):
+ if self.reverse[delta.tail] != set([delta.head]):
pass # has sibling
else:
self.tails[tail].add(delta.tail)
self.heads[delta.tail] = tail
- elif delta.tail in self.tails and len(self.reverse_shares[delta.tail]) <= 1:
+ elif delta.tail in self.tails and len(self.reverse[delta.tail]) <= 1:
# move delta refs referencing children down to this, so they can be moved up in one step
if delta.tail in self.reverse_delta_refs:
for x in list(self.reverse_deltas.get(self.reverse_delta_refs.get(delta.head, object()), set())):
ref = self.reverse_delta_refs[delta.tail]
cur_delta = self.delta_refs[ref]
assert cur_delta.tail == delta.tail
- self.delta_refs[ref] = cur_delta - self.delta_type.from_element(share)
+ self.delta_refs[ref] = cur_delta - self.delta_type.from_element(item)
assert self.delta_refs[ref].tail == delta.head
del self.reverse_delta_refs[delta.tail]
self.reverse_delta_refs[delta.head] = ref
delta2 = self.delta_refs.pop(ref)
del self.reverse_delta_refs[delta2.tail]
- self.shares.pop(delta.head)
- self.reverse_shares[delta.tail].remove(delta.head)
- if not self.reverse_shares[delta.tail]:
- self.reverse_shares.pop(delta.tail)
+ self.items.pop(delta.head)
+ self.reverse[delta.tail].remove(delta.head)
+ if not self.reverse[delta.tail]:
+ self.reverse.pop(delta.tail)
- self.removed.happened(share)
+ self.removed.happened(item)
- def get_height(self, share_hash):
- return self.get_delta_to_last(share_hash).height
+ def get_height(self, item_hash):
+ return self.get_delta_to_last(item_hash).height
- def get_work(self, share_hash):
- return self.get_delta_to_last(share_hash).work
+ def get_work(self, item_hash):
+ return self.get_delta_to_last(item_hash).work
- def get_last(self, share_hash):
- return self.get_delta_to_last(share_hash).tail
+ def get_last(self, item_hash):
+ return self.get_delta_to_last(item_hash).tail
- def get_height_and_last(self, share_hash):
- delta = self.get_delta_to_last(share_hash)
+ def get_height_and_last(self, item_hash):
+ delta = self.get_delta_to_last(item_hash)
return delta.height, delta.tail
- def _get_delta(self, share_hash):
- if share_hash in self.deltas:
- delta1, ref = self.deltas[share_hash]
+ def _get_delta(self, item_hash):
+ if item_hash in self.deltas:
+ delta1, ref = self.deltas[item_hash]
delta2 = self.delta_refs[ref]
res = delta1 + delta2
else:
- res = self.delta_type.from_element(self.shares[share_hash])
- assert res.head == share_hash
+ res = self.delta_type.from_element(self.items[item_hash])
+ assert res.head == item_hash
return res
- def _set_delta(self, share_hash, delta):
- other_share_hash = delta.tail
- if other_share_hash not in self.reverse_delta_refs:
+ def _set_delta(self, item_hash, delta):
+ other_item_hash = delta.tail
+ if other_item_hash not in self.reverse_delta_refs:
ref = self.ref_generator.next()
assert ref not in self.delta_refs
- self.delta_refs[ref] = self.delta_type.get_none(other_share_hash)
- self.reverse_delta_refs[other_share_hash] = ref
+ self.delta_refs[ref] = self.delta_type.get_none(other_item_hash)
+ self.reverse_delta_refs[other_item_hash] = ref
del ref
- ref = self.reverse_delta_refs[other_share_hash]
+ ref = self.reverse_delta_refs[other_item_hash]
ref_delta = self.delta_refs[ref]
- assert ref_delta.tail == other_share_hash
+ assert ref_delta.tail == other_item_hash
- if share_hash in self.deltas:
- prev_ref = self.deltas[share_hash][1]
- self.reverse_deltas[prev_ref].remove(share_hash)
+ if item_hash in self.deltas:
+ prev_ref = self.deltas[item_hash][1]
+ self.reverse_deltas[prev_ref].remove(item_hash)
if not self.reverse_deltas[prev_ref] and prev_ref != ref:
self.reverse_deltas.pop(prev_ref)
x = self.delta_refs.pop(prev_ref)
self.reverse_delta_refs.pop(x.tail)
- self.deltas[share_hash] = delta - ref_delta, ref
- self.reverse_deltas.setdefault(ref, set()).add(share_hash)
+ self.deltas[item_hash] = delta - ref_delta, ref
+ self.reverse_deltas.setdefault(ref, set()).add(item_hash)
- def get_delta_to_last(self, share_hash):
- assert isinstance(share_hash, (int, long, type(None)))
- delta = self.delta_type.get_none(share_hash)
+ def get_delta_to_last(self, item_hash):
+ assert isinstance(item_hash, (int, long, type(None)))
+ delta = self.delta_type.get_none(item_hash)
updates = []
- while delta.tail in self.shares:
+ while delta.tail in self.items:
updates.append((delta.tail, delta))
this_delta = self._get_delta(delta.tail)
delta += this_delta
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.delta_type.from_element(self.shares[start_hash]).tail
+ yield self.items[start_hash]
+ start_hash = self.delta_type.from_element(self.items[start_hash]).tail
- def is_child_of(self, share_hash, possible_child_hash):
- height, last = self.get_height_and_last(share_hash)
+ def is_child_of(self, item_hash, possible_child_hash):
+ height, last = self.get_height_and_last(item_hash)
child_height, child_last = self.get_height_and_last(possible_child_hash)
if child_last != last:
return None # not connected, so can't be determined
height_up = child_height - height
- return height_up >= 0 and self.get_nth_parent_hash(possible_child_hash, height_up) == share_hash
+ return height_up >= 0 and self.get_nth_parent_hash(possible_child_hash, height_up) == item_hash
pool_nonstale_hash_rate=nonstale_hash_rate,
pool_hash_rate=nonstale_hash_rate/(1 - stale_prop),
pool_stale_prop=stale_prop,
- min_difficulty=bitcoin_data.target_to_difficulty(tracker.shares[best_share_var.value].max_target),
+ min_difficulty=bitcoin_data.target_to_difficulty(tracker.items[best_share_var.value].max_target),
)
def get_local_stats():
my_work = sum(bitcoin_data.target_to_average_attempts(share.target)
for share in tracker.get_chain(best_share_var.value, lookbehind - 1)
if share.hash in my_share_hashes)
- actual_time = (tracker.shares[best_share_var.value].timestamp -
- tracker.shares[tracker.get_nth_parent_hash(best_share_var.value, lookbehind - 1)].timestamp)
+ actual_time = (tracker.items[best_share_var.value].timestamp -
+ tracker.items[tracker.get_nth_parent_hash(best_share_var.value, lookbehind - 1)].timestamp)
share_att_s = my_work / actual_time
miner_hash_rates, miner_dead_hash_rates = get_local_rates()
return json.dumps(res) if self.mime_type == 'application/json' else res
web_root.putChild('rate', WebInterface(lambda: p2pool_data.get_pool_attempts_per_second(tracker, best_share_var.value, 720)/(1-p2pool_data.get_average_stale_prop(tracker, best_share_var.value, 720))))
- web_root.putChild('difficulty', WebInterface(lambda: bitcoin_data.target_to_difficulty(tracker.shares[best_share_var.value].max_target)))
+ web_root.putChild('difficulty', WebInterface(lambda: bitcoin_data.target_to_difficulty(tracker.items[best_share_var.value].max_target)))
web_root.putChild('users', WebInterface(get_users))
web_root.putChild('fee', WebInterface(lambda: worker_fee))
web_root.putChild('current_payouts', WebInterface(lambda: dict((bitcoin_data.script2_to_address(script, net.PARENT), value/1e8) for script, value in get_current_txouts().iteritems())))
incoming=sum(1 for peer in p2p_node.peers.itervalues() if peer.incoming),
outgoing=sum(1 for peer in p2p_node.peers.itervalues() if not peer.incoming),
),
- attempts_to_share=bitcoin_data.target_to_average_attempts(tracker.shares[best_share_var.value].max_target),
+ attempts_to_share=bitcoin_data.target_to_average_attempts(tracker.items[best_share_var.value].max_target),
attempts_to_block=bitcoin_data.target_to_average_attempts(bitcoind_work.value['bits'].target),
block_value=bitcoind_work.value['subsidy']*1e-8,
))
new_root.putChild('log', WebInterface(lambda: stat_log))
def get_share(share_hash_str):
- if int(share_hash_str, 16) not in tracker.shares:
+ if int(share_hash_str, 16) not in tracker.items:
return None
- share = tracker.shares[int(share_hash_str, 16)]
+ share = tracker.items[int(share_hash_str, 16)]
return dict(
parent='%064x' % share.previous_hash,
- children=['%064x' % x for x in sorted(tracker.reverse_shares.get(share.hash, set()), key=lambda sh: -len(tracker.reverse_shares.get(sh, set())))], # sorted from most children to least children
+ children=['%064x' % x for x in sorted(tracker.reverse.get(share.hash, set()), key=lambda sh: -len(tracker.reverse.get(sh, set())))], # sorted from most children to least children
local=dict(
- verified=share.hash in tracker.verified.shares,
+ verified=share.hash in tracker.verified.items,
time_first_seen=start_time if share.time_seen == 0 else share.time_seen,
peer_first_received_from=share.peer.addr if share.peer is not None else None,
),
new_root.putChild('share', WebInterface(lambda share_hash_str: get_share(share_hash_str)))
new_root.putChild('heads', WebInterface(lambda: ['%064x' % x for x in tracker.heads]))
new_root.putChild('verified_heads', WebInterface(lambda: ['%064x' % x for x in tracker.verified.heads]))
- new_root.putChild('tails', WebInterface(lambda: ['%064x' % x for t in tracker.tails for x in tracker.reverse_shares.get(t, set())]))
- new_root.putChild('verified_tails', WebInterface(lambda: ['%064x' % x for t in tracker.verified.tails for x in tracker.verified.reverse_shares.get(t, set())]))
+ new_root.putChild('tails', WebInterface(lambda: ['%064x' % x for t in tracker.tails for x in tracker.reverse.get(t, set())]))
+ new_root.putChild('verified_tails', WebInterface(lambda: ['%064x' % x for t in tracker.verified.tails for x in tracker.verified.reverse.get(t, set())]))
new_root.putChild('best_share_hash', WebInterface(lambda: '%064x' % best_share_var.value))
new_root.putChild('currency_info', WebInterface(lambda: dict(
symbol=net.PARENT.SYMBOL,