import hashlib
import warnings
-from . import base58
+from . import base58, skiplists
from p2pool.util import bases, math, skiplist, intern2
import p2pool
self.tails_by_id = {}
'''
- self.get_nth_parent_hash = skiplist.DistanceSkipList(self)
+ self.get_nth_parent_hash = skiplists.DistanceSkipList(self)
def add(self, share):
assert not isinstance(share, (int, long, type(None)))
--- /dev/null
+from p2pool.util import skiplist
+
+class DistanceSkipList(skiplist.SkipList):
+ def __init__(self, tracker):
+ skiplist.SkipList.__init__(self)
+ self.tracker = tracker
+
+ def previous(self, element):
+ return self.tracker.shares[element].previous_hash
+
+ def get_delta(self, element):
+ return element, 1, self.tracker.shares[element].previous_hash
+
+ def combine_deltas(self, (from_hash1, dist1, to_hash1), (from_hash2, dist2, to_hash2)):
+ if to_hash1 != from_hash2:
+ raise AssertionError()
+ return from_hash1, dist1 + dist2, to_hash2
+
+ def initial_solution(self, start, (n,)):
+ return 0, start
+
+ def apply_delta(self, (dist1, to_hash1), (from_hash2, dist2, to_hash2), (n,)):
+ if to_hash1 != from_hash2:
+ raise AssertionError()
+ return dist1 + dist2, to_hash2
+
+ def judge(self, (dist, hash), (n,)):
+ if dist > n:
+ return 1
+ elif dist == n:
+ return 0
+ else:
+ return -1
+
+ def finalize(self, (dist, hash)):
+ return hash
+
+if __name__ == '__main__':
+ import random
+ from p2pool.bitcoin import data
+ t = data.Tracker()
+ d = DistanceSkipList(t)
+ for i in xrange(2000):
+ t.add(data.FakeShare(hash=i, previous_hash=i - 1 if i > 0 else None))
+ for i in xrange(2000):
+ a = random.randrange(2000)
+ b = random.randrange(a + 1)
+ res = d(a, b)
+ assert res == a - b, (a, b, res)
from twisted.internet import defer
from twisted.python import log
-from p2pool.bitcoin import data as bitcoin_data
-from p2pool.bitcoin import script
-from p2pool.util import memoize, expiring_dict, math, skiplist, deferral
import p2pool
+from p2pool import skiplists
+from p2pool.bitcoin import data as bitcoin_data, script
+from p2pool.util import memoize, expiring_dict, math, deferral
merkle_branch_type = bitcoin_data.ListType(bitcoin_data.ComposedType([
self.net = net
self.verified = bitcoin_data.Tracker()
- self.get_cumulative_weights = skiplist.WeightsSkipList(self)
+ self.get_cumulative_weights = skiplists.WeightsSkipList(self)
def attempt_verify(self, share, now):
if share.hash in self.verified.shares:
from twisted.python import log
import bitcoin.p2p, bitcoin.getwork, bitcoin.data
-from util import db, expiring_dict, jsonrpc, variable, deferral, math, skiplist
-from . import p2p, worker_interface
+from util import db, expiring_dict, jsonrpc, variable, deferral, math
+from . import p2p, worker_interface, skiplists
import p2pool.data as p2pool
import p2pool as p2pool_init
work1_thread()
work2_thread()
- counter = skiplist.CountsSkipList(tracker, run_identifier)
+ counter = skiplists.CountsSkipList(tracker, run_identifier)
while True:
yield deferral.sleep(random.expovariate(1/1))
--- /dev/null
+from p2pool.util import math, skiplist
+
+class WeightsSkipList(skiplist.SkipList):
+ # share_count, weights, total_weight
+
+ def __init__(self, tracker):
+ skiplist.SkipList.__init__(self)
+ self.tracker = tracker
+
+ def previous(self, element):
+ return self.tracker.shares[element].previous_hash
+
+ def get_delta(self, element):
+ from p2pool.bitcoin import data as bitcoin_data
+ if element is None:
+ return (2**256, {}, 0) # XXX
+ share = self.tracker.shares[element]
+ att = bitcoin_data.target_to_average_attempts(share.target)
+ return 1, {share.new_script: att}, att
+
+ def combine_deltas(self, (share_count1, weights1, total_weight1), (share_count2, weights2, total_weight2)):
+ return share_count1 + share_count2, math.add_dicts([weights1, weights2]), total_weight1 + total_weight2
+
+ def initial_solution(self, start, (max_shares, desired_weight)):
+ return 0, {}, 0
+
+ def apply_delta(self, (share_count1, weights1, total_weight1), (share_count2, weights2, total_weight2), (max_shares, desired_weight)):
+ if total_weight1 + total_weight2 > desired_weight and len(weights2) == 1:
+ script, = weights2.iterkeys()
+ new_weights = dict(weights1)
+ new_weights[script] = new_weights.get(script, 0) + desired_weight - total_weight1
+ return share_count1 + share_count2, new_weights, desired_weight
+ return share_count1 + share_count2, math.add_dicts([weights1, weights2]), total_weight1 + total_weight2
+
+ def judge(self, (share_count, weights, total_weight), (max_shares, desired_weight)):
+ if share_count > max_shares or total_weight > desired_weight:
+ return 1
+ elif share_count == max_shares or total_weight == desired_weight:
+ return 0
+ else:
+ return -1
+
+ def finalize(self, (share_count, weights, total_weight)):
+ return weights, total_weight
+
+class CountsSkipList(skiplist.SkipList):
+ # share_count, counts, total_count
+
+ def __init__(self, tracker, run_identifier):
+ skiplist.SkipList.__init__(self)
+ self.tracker = tracker
+ self.run_identifier = run_identifier
+
+ def previous(self, element):
+ return self.tracker.shares[element].previous_hash
+
+ def get_delta(self, element):
+ from p2pool.bitcoin import data as bitcoin_data
+ if element is None:
+ return 0 # XXX
+ share = self.tracker.shares[element]
+ weight = 1 if share.nonce[:8] == self.run_identifier else 0
+ return 1, weight, 1
+
+ def combine_deltas(self, (share_count1, weights1, total_weight1), (share_count2, weights2, total_weight2)):
+ return share_count1 + share_count2, weights1 + weights2, total_weight1 + total_weight2
+
+ def initial_solution(self, start, (max_shares, desired_weight)):
+ return 0, 0, 0
+
+
+ def apply_delta(self, (share_count1, weights1, total_weight1), (share_count2, weights2, total_weight2), (max_shares, desired_weight)):
+ return share_count1 + share_count2, weights1 + weights2, total_weight1 + total_weight2
+
+ def judge(self, (share_count, weights, total_weight), (max_shares, desired_weight)):
+ if share_count > max_shares or total_weight > desired_weight:
+ return 1
+ elif share_count == max_shares or total_weight == desired_weight:
+ return 0
+ else:
+ return -1
+
+ def finalize(self, (share_count, weights, total_weight)):
+ if share_count != total_weight:
+ raise AssertionError()
+ return weights
+
+if __name__ == '__main__':
+ import random
+ from p2pool.bitcoin import data
+ t = data.Tracker()
+ d = WeightsSkipList(t)
+ for i in xrange(2000):
+ t.add(data.FakeShare(hash=i, previous_hash=i - 1 if i > 0 else None, new_script=i, target=random.randrange(2**249, 2**250)))
+ for i in xrange(2000):
+ #a = random.randrange(2000)
+ a = 1999
+ print d(a, a, 1000000)[1]
return sol
class SkipList(Base):
+ P = .5
+
def __init__(self):
self.skips = expiring_dict.ExpiringDict(600)
return self.finalize(sol)
while True:
if pos not in self.skips:
- self.skips[pos] = math.geometric(.5), [(self.previous(pos), self.get_delta(pos))]
+ self.skips[pos] = math.geometric(self.P), [(self.previous(pos), self.get_delta(pos))]
skip_length, skip = self.skips[pos]
# fill previous updates
return item_hash
-class DumbSkipList(Base):
+class NotSkipList(Base):
def __call__(self, start, *args):
pos = start
sol = self.initial_solution(start, args)
sol = self.apply_delta(sol, delta, args)
pos = self.previous(pos)
-
-class DistanceSkipList(SkipList):
- def __init__(self, tracker):
- SkipList.__init__(self)
- self.tracker = tracker
-
- def previous(self, element):
- return self.tracker.shares[element].previous_hash
-
- def get_delta(self, element):
- return element, 1, self.tracker.shares[element].previous_hash
-
- def combine_deltas(self, (from_hash1, dist1, to_hash1), (from_hash2, dist2, to_hash2)):
- if to_hash1 != from_hash2:
- raise AssertionError()
- return from_hash1, dist1 + dist2, to_hash2
-
- def initial_solution(self, start, (n,)):
- return 0, start
-
- def apply_delta(self, (dist1, to_hash1), (from_hash2, dist2, to_hash2), (n,)):
- if to_hash1 != from_hash2:
- raise AssertionError()
- return dist1 + dist2, to_hash2
-
- def judge(self, (dist, hash), (n,)):
- if dist > n:
- return 1
- elif dist == n:
- return 0
- else:
- return -1
-
- def finalize(self, (dist, hash)):
- return hash
-
-if __name__ == '__main__':
- import random
- from p2pool.bitcoin import data
- t = data.Tracker()
- d = DistanceSkipList(t)
- for i in xrange(2000):
- t.add(data.FakeShare(hash=i, previous_hash=i - 1 if i > 0 else None))
- for i in xrange(2000):
- a = random.randrange(2000)
- b = random.randrange(a + 1)
- res = d(a, b)
- assert res == a - b, (a, b, res)
-
-class WeightsSkipList(SkipList):
- # share_count, weights, total_weight
-
- def __init__(self, tracker):
- SkipList.__init__(self)
- self.tracker = tracker
-
- def previous(self, element):
- return self.tracker.shares[element].previous_hash
-
- def get_delta(self, element):
- from p2pool.bitcoin import data as bitcoin_data
- if element is None:
- return (2**256, {}, 0) # XXX
- share = self.tracker.shares[element]
- att = bitcoin_data.target_to_average_attempts(share.target)
- return 1, {share.new_script: att}, att
-
- def combine_deltas(self, (share_count1, weights1, total_weight1), (share_count2, weights2, total_weight2)):
- return share_count1 + share_count2, math.add_dicts([weights1, weights2]), total_weight1 + total_weight2
-
- def initial_solution(self, start, (max_shares, desired_weight)):
- return 0, {}, 0
-
- def apply_delta(self, (share_count1, weights1, total_weight1), (share_count2, weights2, total_weight2), (max_shares, desired_weight)):
- if total_weight1 + total_weight2 > desired_weight and len(weights2) == 1:
- script, = weights2.iterkeys()
- new_weights = dict(weights1)
- new_weights[script] = new_weights.get(script, 0) + desired_weight - total_weight1
- return share_count1 + share_count2, new_weights, desired_weight
- return share_count1 + share_count2, math.add_dicts([weights1, weights2]), total_weight1 + total_weight2
-
- def judge(self, (share_count, weights, total_weight), (max_shares, desired_weight)):
- if share_count > max_shares or total_weight > desired_weight:
- return 1
- elif share_count == max_shares or total_weight == desired_weight:
- return 0
- else:
- return -1
-
- def finalize(self, (share_count, weights, total_weight)):
- return weights, total_weight
-
-class CountsSkipList(SkipList):
- # share_count, counts, total_count
-
- def __init__(self, tracker, run_identifier):
- SkipList.__init__(self)
- self.tracker = tracker
- self.run_identifier = run_identifier
-
- def previous(self, element):
- return self.tracker.shares[element].previous_hash
-
- def get_delta(self, element):
- from p2pool.bitcoin import data as bitcoin_data
- if element is None:
- return 0 # XXX
- share = self.tracker.shares[element]
- weight = 1 if share.nonce[:8] == self.run_identifier else 0
- return 1, weight, 1
-
- def combine_deltas(self, (share_count1, weights1, total_weight1), (share_count2, weights2, total_weight2)):
- return share_count1 + share_count2, weights1 + weights2, total_weight1 + total_weight2
-
- def initial_solution(self, start, (max_shares, desired_weight)):
- return 0, 0, 0
-
-
- def apply_delta(self, (share_count1, weights1, total_weight1), (share_count2, weights2, total_weight2), (max_shares, desired_weight)):
- return share_count1 + share_count2, weights1 + weights2, total_weight1 + total_weight2
-
- def judge(self, (share_count, weights, total_weight), (max_shares, desired_weight)):
- if share_count > max_shares or total_weight > desired_weight:
- return 1
- elif share_count == max_shares or total_weight == desired_weight:
- return 0
- else:
- return -1
-
- def finalize(self, (share_count, weights, total_weight)):
- if share_count != total_weight:
- raise AssertionError()
- return weights
-
-if __name__ == '__main__':
- import random
- from p2pool.bitcoin import data
- t = data.Tracker()
- d = WeightsSkipList(t)
- for i in xrange(2000):
- t.add(data.FakeShare(hash=i, previous_hash=i - 1 if i > 0 else None, new_script=i, target=random.randrange(2**249, 2**250)))
- for i in xrange(2000):
- #a = random.randrange(2000)
- a = 1999
- print d(a, a, 1000000)[1]