Ejemplo n.º 1
0
 def _send_work(self):
     try:
         x, got_response = self.wb.get_work(*self.wb.preprocess_request(
             '' if self.username is None else self.username))
     except:
         log.err()
         self.transport.loseConnection()
         return
     jobid = str(random.randrange(2**128))
     self.other.svc_mining.rpc_set_difficulty(
         dash_data.target_to_difficulty(x['share_target']) *
         self.wb.net.DUMB_SCRYPT_DIFF).addErrback(lambda err: None)
     self.other.svc_mining.rpc_notify(
         jobid,  # jobid
         getwork._swap4(pack.IntType(256).pack(
             x['previous_block'])).encode('hex'),  # prevhash
         x['coinb1'].encode('hex'),  # coinb1
         x['coinb2'].encode('hex'),  # coinb2
         [
             pack.IntType(256).pack(s).encode('hex')
             for s in x['merkle_link']['branch']
         ],  # merkle_branch
         getwork._swap4(pack.IntType(32).pack(
             x['version'])).encode('hex'),  # version
         getwork._swap4(pack.IntType(32).pack(
             x['bits'].bits)).encode('hex'),  # nbits
         getwork._swap4(pack.IntType(32).pack(
             x['timestamp'])).encode('hex'),  # ntime
         True,  # clean_jobs
     ).addErrback(lambda err: None)
     self.handler_map[jobid] = x, got_response
Ejemplo n.º 2
0
 def _send_work(self):
     try:
         x, got_response = self.wb.get_work(*self.wb.preprocess_request('' if self.username is None else self.username))
     except:
         log.err()
         self.transport.loseConnection()
         return
     jobid = str(random.randrange(2**128))
     self.other.svc_mining.rpc_set_difficulty(dash_data.target_to_difficulty(x['share_target'])*self.wb.net.DUMB_SCRYPT_DIFF).addErrback(lambda err: None)
     self.other.svc_mining.rpc_notify(
         jobid, # jobid
         getwork._swap4(pack.IntType(256).pack(x['previous_block'])).encode('hex'), # prevhash
         x['coinb1'].encode('hex'), # coinb1
         x['coinb2'].encode('hex'), # coinb2
         [pack.IntType(256).pack(s).encode('hex') for s in x['merkle_link']['branch']], # merkle_branch
         getwork._swap4(pack.IntType(32).pack(x['version'])).encode('hex'), # version
         getwork._swap4(pack.IntType(32).pack(x['bits'].bits)).encode('hex'), # nbits
         getwork._swap4(pack.IntType(32).pack(x['timestamp'])).encode('hex'), # ntime
         True, # clean_jobs
     ).addErrback(lambda err: None)
     self.handler_map[jobid] = x, got_response
Ejemplo n.º 3
0
 def think(self, block_rel_height_func, previous_block, bits, known_txs):
     desired = set()
     bad_peer_addresses = 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 = []
     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):
                 break
             bads.append(share.hash)
         else:
             if last is not None:
                 desired.add((
                     self.items[random.choice(list(self.reverse[last]))].peer_addr,
                     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.items
         #assert bad in self.heads
         bad_share = self.items[bad]
         if bad_share.peer_addr is not None:
             bad_peer_addresses.add(bad_share.peer_addr)
         if p2pool.DEBUG:
             print "BAD", bad
         try:
             self.remove(bad)
         except NotImplementedError:
             pass
     
     # 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):
                 break
         if head_height < self.net.CHAIN_LENGTH and last_last_hash is not None:
             desired.add((
                 self.items[random.choice(list(self.verified.reverse[last_hash]))].peer_addr,
                 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 tree
     decorated_tails = sorted((self.score(max(self.verified.tails[tail_hash], key=self.verified.get_work), block_rel_height_func), tail_hash) for tail_hash in self.verified.tails)
     if p2pool.DEBUG:
         print len(decorated_tails), 'tails:'
         for score, tail_hash in decorated_tails:
             print format_hash(tail_hash), score
     best_tail_score, best_tail = decorated_tails[-1] if decorated_tails else (None, None)
     
     # 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.items[h].peer_addr is None,
         -self.items[h].should_punish_reason(previous_block, bits, self, known_txs)[0],
         -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.items[head_hash].previous_hash), score
     best_head_score, best = decorated_heads[-1] if decorated_heads else (None, None)
     
     if best is not None:
         best_share = self.items[best]
         punish, punish_reason = best_share.should_punish_reason(previous_block, bits, self, known_txs)
         if punish > 0:
             print 'Punishing share for %r! Jumping from %s to %s!' % (punish_reason, format_hash(best), format_hash(best_share.previous_hash))
             best = best_share.previous_hash
         
         timestamp_cutoff = min(int(time.time()), best_share.timestamp) - 3600
         target_cutoff = int(2**256//(self.net.SHARE_PERIOD*best_tail_score[1] + 1) * 2 + .5) if best_tail_score[1] is not None else 2**256-1
     else:
         timestamp_cutoff = int(time.time()) - 24*60*60
         target_cutoff = 2**256-1
     
     if p2pool.DEBUG:
         print 'Desire %i shares. Cutoff: %s old diff>%.2f' % (len(desired), math.format_dt(time.time() - timestamp_cutoff), dash_data.target_to_difficulty(target_cutoff))
         for peer_addr, hash, ts, targ in desired:
             print '   ', None if peer_addr is None else '%s:%i' % peer_addr, format_hash(hash), math.format_dt(time.time() - ts), dash_data.target_to_difficulty(targ), ts >= timestamp_cutoff, targ <= target_cutoff
     
     return best, [(peer_addr, hash) for peer_addr, hash, ts, targ in desired if ts >= timestamp_cutoff], decorated_heads, bad_peer_addresses
Ejemplo n.º 4
0
    def think(self, block_rel_height_func, previous_block, bits, known_txs):
        desired = set()
        bad_peer_addresses = 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 = []
        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):
                    break
                bads.append(share.hash)
            else:
                if last is not None:
                    desired.add((
                        self.items[random.choice(list(
                            self.reverse[last]))].peer_addr,
                        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.items
            #assert bad in self.heads
            bad_share = self.items[bad]
            if bad_share.peer_addr is not None:
                bad_peer_addresses.add(bad_share.peer_addr)
            if p2pool.DEBUG:
                print "BAD", bad
            try:
                self.remove(bad)
            except NotImplementedError:
                pass

        # 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):
                    break
            if head_height < self.net.CHAIN_LENGTH and last_last_hash is not None:
                desired.add((
                    self.items[random.choice(
                        list(self.verified.reverse[last_hash]))].peer_addr,
                    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 tree
        decorated_tails = sorted((self.score(
            max(self.verified.tails[tail_hash], key=self.verified.get_work),
            block_rel_height_func), tail_hash)
                                 for tail_hash in self.verified.tails)
        if p2pool.DEBUG:
            print len(decorated_tails), 'tails:'
            for score, tail_hash in decorated_tails:
                print format_hash(tail_hash), score
        best_tail_score, best_tail = decorated_tails[
            -1] if decorated_tails else (None, None)

        # 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.items[h].peer_addr is None,
                -self.items[h].should_punish_reason(previous_block, bits, self,
                                                    known_txs)[0],
                -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.items[head_hash].previous_hash), score
        best_head_score, best = decorated_heads[-1] if decorated_heads else (
            None, None)

        if best is not None:
            best_share = self.items[best]
            punish, punish_reason = best_share.should_punish_reason(
                previous_block, bits, self, known_txs)
            if punish > 0:
                print 'Punishing share for %r! Jumping from %s to %s!' % (
                    punish_reason, format_hash(best),
                    format_hash(best_share.previous_hash))
                best = best_share.previous_hash

            timestamp_cutoff = min(int(time.time()),
                                   best_share.timestamp) - 3600
            target_cutoff = int(
                2**256 //
                (self.net.SHARE_PERIOD * best_tail_score[1] + 1) * 2 +
                .5) if best_tail_score[1] is not None else 2**256 - 1
        else:
            timestamp_cutoff = int(time.time()) - 24 * 60 * 60
            target_cutoff = 2**256 - 1

        if p2pool.DEBUG:
            print 'Desire %i shares. Cutoff: %s old diff>%.2f' % (
                len(desired), math.format_dt(time.time() - timestamp_cutoff),
                dash_data.target_to_difficulty(target_cutoff))
            for peer_addr, hash, ts, targ in desired:
                print '   ', None if peer_addr is None else '%s:%i' % peer_addr, format_hash(
                    hash), math.format_dt(time.time(
                    ) - ts), dash_data.target_to_difficulty(
                        targ), ts >= timestamp_cutoff, targ <= target_cutoff

        return best, [(peer_addr, hash)
                      for peer_addr, hash, ts, targ in desired
                      if ts >= timestamp_cutoff
                      ], decorated_heads, bad_peer_addresses