def test_expiring_dict1(self):
     e = expiring_dict.ExpiringDict(3, get_touches=True)
     e[1] = 2
     yield deferral.sleep(1.5)
     assert 1 in e
     yield deferral.sleep(3)
     assert 1 not in e
 def test_expiring_dict2(self):
     e = expiring_dict.ExpiringDict(3, get_touches=True)
     e[1] = 2
     yield deferral.sleep(2.25)
     e[1]
     yield deferral.sleep(2.25)
     assert 1 in e
 def test_expiring_dict3(self):
     e = expiring_dict.ExpiringDict(3, get_touches=False)
     e[1] = 2
     yield deferral.sleep(2.25)
     e[1]
     yield deferral.sleep(2.25)
     assert 1 not in e
示例#4
0
 def __init__(self, wb, other):
     self.wb = wb
     self.other = other
     
     self.username = None
     self.handler_map = expiring_dict.ExpiringDict(300)
     
     self.watch_id = self.wb.new_work_event.watch(self._send_work)
示例#5
0
    def __init__(self, wb, other, transport):
        self.wb = wb
        self.other = other
        self.transport = transport

        self.username = None
        self.handler_map = expiring_dict.ExpiringDict(300)
        self.extranonce1 = "%08x" % random.randint(0, 0xFFFFFFFF)

        self.watch_id = self.wb.new_work_event.watch(self._send_work)
示例#6
0
    def __init__(self, wb, other, transport):
        self.pool_version_mask = 0x1fffe000
        self.wb = wb
        self.other = other
        self.transport = transport

        self.username = None
        self.handler_map = expiring_dict.ExpiringDict(300)

        self.watch_id = self.wb.new_work_event.watch(self._send_work)
示例#7
0
    def __init__(self, wb, other, transport):
        self.wb = wb
        self.other = other
        self.transport = transport

        self.desired_share_target = None

        self.username = None
        self.handler_map = expiring_dict.ExpiringDict(300)

        self.watch_id = self.wb.new_work_event.watch(self._send_work)
示例#8
0
    def __init__(self, wb, other, transport):
        self.wb = wb
        self.other = other
        self.transport = transport

        self.username = None
        self.handler_map = expiring_dict.ExpiringDict(300)

        self.watch_id = self.wb.new_work_event.watch(self._send_work)

        self.diff_multiplier = self.wb.net.DUMB_SCRYPT_DIFF
示例#9
0
class SkipList(Base):
    P = .5
    
    def __init__(self):
        self.skips = expiring_dict.ExpiringDict(600)
    
    @memoize.memoize_with_backing(expiring_dict.ExpiringDict(5, get_touches=False))
    def __call__(self, start, *args, **kwargs):
        updates = {}
        pos = start
        sol = self.initial_solution(start, args)
        if self.judge(sol, args) == 0:
            return self.finalize(sol)
        while True:
            if pos not in self.skips:
                self.skips[pos] = math.geometric(self.P), [(self.previous(pos), self.get_delta(pos))]
            skip_length, skip = self.skips[pos]
            
            # fill previous updates
            for i in xrange(skip_length):
                if i in updates:
                    that_hash, delta = updates.pop(i)
                    x, y = self.skips[that_hash]
                    assert len(y) == i
                    y.append((pos, delta))
            
            # put desired skip nodes in updates
            for i in xrange(len(skip), skip_length):
                updates[i] = pos, None
            
            #if skip_length + 1 in updates:
            #    updates[skip_length + 1] = self.combine(updates[skip_length + 1], updates[skip_length])
            
            for jump, delta in reversed(skip):
                sol_if = self.apply_delta(sol, delta, args)
                decision = self.judge(sol_if, args)
                #print pos, sol, jump, delta, sol_if, decision
                if decision == 0:
                    return self.finalize(sol_if)
                elif decision < 0:
                    sol = sol_if
                    break
            else:
                raise AssertionError()
            
            sol = sol_if
            pos = jump
            
            # XXX could be better by combining updates
            for x in updates:
                updates[x] = updates[x][0], self.combine_deltas(updates[x][1], delta) if updates[x][1] is not None else delta
        
        
        return item_hash
示例#10
0
    def __init__(self, wb, other, transport):
        self.pool_version_mask = 0x1fffe000
        self.wb = wb
        self.other = other
        self.transport = transport
        
        self.username = None
        self.handler_map = expiring_dict.ExpiringDict(300)
        
        self.watch_id = self.wb.new_work_event.watch(self._send_work)

        self.recent_shares = []
        self.target = None
        self.share_rate = wb.share_rate
        self.fixed_target = False
        self.desired_pseudoshare_target = None
示例#11
0
 def __init__(self, worker_bridge):
     self.worker_bridge = worker_bridge
     
     self.worker_views = {}
     
     self.merkle_root_to_handler = expiring_dict.ExpiringDict(300)
示例#12
0
class Type(object):
    # the same data can have only one unpacked representation, but multiple packed binary representations

    def __hash__(self):
        rval = getattr(self, '_hash', None)
        if rval is None:
            try:
                rval = self._hash = hash(
                    (type(self), frozenset(self.__dict__.items())))
            except:
                print self.__dict__
                raise
        return rval

    def __eq__(self, other):
        return type(other) is type(self) and other.__dict__ == self.__dict__

    def __ne__(self, other):
        return not (self == other)

    def _unpack(self, data):
        obj, (data2, pos) = self.read((data, 0))

        assert data2 is data

        if pos != len(data):
            raise LateEnd()

        return obj

    def _pack(self, obj):
        f = self.write(None, obj)

        res = []
        while f is not None:
            res.append(f[1])
            f = f[0]
        res.reverse()
        return ''.join(res)

    def unpack(self, data):
        obj = self._unpack(data)

        if p2pool.DEBUG:
            data2 = self._pack(obj)
            if data2 != data:
                if self._unpack(data2) != obj:
                    raise AssertionError()

        return obj

    def pack2(self, obj):
        data = self._pack(obj)

        if p2pool.DEBUG:
            if self._unpack(data) != obj:
                raise AssertionError((self._unpack(data), obj))

        return data

    _backing = expiring_dict.ExpiringDict(100)
    pack2 = memoize.memoize_with_backing(_backing, [unpack])(pack2)
    unpack = memoize.memoize_with_backing(_backing)(
        unpack)  # doesn't have an inverse

    def pack(self, obj):
        return self.pack2(dicts.immutify(obj))

    def pack_base58(self, obj):
        return base58.base58_encode(self.pack(obj))

    def unpack_base58(self, base58_data):
        return self.unpack(base58.base58_decode(base58_data))

    def hash160(self, obj):
        return ShortHashType().unpack(
            hashlib.new('ripemd160',
                        hashlib.sha256(self.pack(obj)).digest()).digest())

    def hash256(self, obj):
        return HashType().unpack(
            hashlib.sha256(hashlib.sha256(self.pack(obj)).digest()).digest())

    def scrypt(self, obj):
        import ltc_scrypt
        return HashType().unpack(ltc_scrypt.getPoWHash(self.pack(obj)))
示例#13
0
class OkayTracker(forest.Tracker):
    def __init__(self, net):
        forest.Tracker.__init__(self)
        self.net = net
        self.verified = forest.Tracker()
        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)

    def attempt_verify(self, share, now):
        if share.hash in self.verified.shares:
            return True
        height, last = self.get_height_and_last(share.hash)
        if height < self.net.CHAIN_LENGTH + 1 and last is not None:
            raise AssertionError()
        try:
            share.check(self)
        except:
            log.err(None, 'Share check failed:')
            return False
        else:
            self.verified.add(share)
            return True

    def think(self, ht, previous_block, now):
        desired = set()

        # O(len(self.heads))
        #   make 'unverified heads' set?
        # for each overall head, attempt verification
        # if it fails, attempt on parent, and repeat
        # if no successful verification because of lack of parents, request parent
        bads = set()
        for head in set(self.heads) - set(self.verified.heads):
            head_height, last = self.get_height_and_last(head)

            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:
                    bads.add(share.hash)
            else:
                if last is not None:
                    desired.add((self.shares[random.choice(
                        list(self.reverse_shares[last]))].peer, last))
        for bad in bads:
            assert bad not in self.verified.shares
            assert bad in self.heads
            if p2pool.DEBUG:
                print "BAD", bad
            self.remove(bad)

        # try to get at least CHAIN_LENGTH height for each verified head, requesting parents if needed
        for head in list(self.verified.heads):
            head_height, last_hash = self.verified.get_height_and_last(head)
            last_height, last_last_hash = self.get_height_and_last(last_hash)
            # XXX review boundary conditions
            want = max(self.net.CHAIN_LENGTH - head_height, 0)
            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 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:
                desired.add((self.verified.shares[random.choice(
                    list(self.verified.reverse_shares[last_hash]))].peer,
                             last_last_hash))
        if p2pool.DEBUG:
            print len(self.verified.tails), "tails:"
            for x in self.verified.tails:
                print format_hash(x), self.score(
                    max(self.verified.tails[x], key=self.verified.get_height),
                    ht)

        # decide best tree
        best_tail = max(
            self.verified.tails,
            key=lambda h: self.score(
                max(self.verified.tails[h], key=self.verified.get_height), ht
            )) if self.verified.tails else None
        # decide best verified head
        scores = sorted(
            self.verified.tails.get(best_tail, []),
            key=lambda h: (
                self.verified.get_work(
                    self.verified.get_nth_parent_hash(
                        h, min(5, self.verified.get_height(h)))),
                #self.verified.shares[h].peer is None,
                ht.get_height_rel_highest(self.verified.shares[h].
                                          previous_block),
                -self.verified.shares[h].time_seen))

        if p2pool.DEBUG:
            print len(self.verified.tails), "chain tails and", len(
                self.verified.tails.get(best_tail,
                                        [])), 'chain heads. Top 10 heads:'
            if len(scores) > 10:
                print '    ...'
            for h in scores[-10:]:
                print '   ', format_hash(h), format_hash(
                    self.verified.shares[h].previous_hash), (
                        self.verified.get_work(
                            self.verified.get_nth_parent_hash(
                                h, min(5, self.verified.get_height(h)))),
                        self.verified.shares[h].peer is None,
                        ht.get_height_rel_highest(
                            self.verified.shares[h].previous_block),
                        -self.verified.shares[h].time_seen)

        # eat away at heads
        if scores:
            for i in xrange(1000):
                to_remove = set()
                for share_hash, tail in self.heads.iteritems():
                    if share_hash in scores[-5:]:
                        #print 1
                        continue
                    if self.shares[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
                        #print 3
                        continue
                    to_remove.add(share_hash)
                if not to_remove:
                    break
                for share_hash in to_remove:
                    self.remove(share_hash)
                    if share_hash in self.verified.shares:
                        self.verified.remove(share_hash)
                #print "_________", to_remove

        # drop tails
        for i in xrange(1000):
            to_remove = set()
            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
                        print "raw"
                        continue
                    to_remove.add(aftertail)
            if not to_remove:
                break
            # 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
                    continue
                self.remove(aftertail)
                if aftertail in self.verified.shares:
                    self.verified.remove(aftertail)
            #end = time.time()
            #print "removed! %i %f" % (len(to_remove), (end - start)/len(to_remove))

        best = scores[-1] if scores else None

        if best is not None:
            best_share = self.verified.shares[best]
            if ht.get_height_rel_highest(
                    best_share.header['previous_block']
            ) < ht.get_height_rel_highest(
                    previous_block
            ) 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)
                best = best_share.previous_hash

        return best, desired

    @memoize.memoize_with_backing(
        expiring_dict.ExpiringDict(5, get_touches=False))
    def score(self, share_hash, ht):
        head_height, last = self.verified.get_height_and_last(share_hash)
        score2 = 0
        block_height = -1000000
        max_height = min(self.net.CHAIN_LENGTH, head_height)
        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:
                score2 = this_score
        return min(head_height, self.net.CHAIN_LENGTH), score2
示例#14
0
 def __init__(self):
     self.skips = expiring_dict.ExpiringDict(600)