def polling_thread(self): try: lastshares = [] errorcount = [0] * (self.device.maximum_multiplier + 1) errorweight = [0] * (self.device.maximum_multiplier + 1) maxerrorrate = [0] * (self.device.maximum_multiplier + 1) errorlimit = 0.05 errorhysteresis = 0.1 counter = 0 while not self.shutdown: counter += 1 # Poll for nonces now = time.time() nonces = self.device.read_nonces() exhausted = False with self.wakeup: if nonces[0][1] < self.lastnonce: self.lastnonce = nonces[0][1] exhausted = True if exhausted: self.send("keyspace_exhausted") for nonce in nonces: if nonce[0] != -self.device.nonce_offset and not nonce[0] in lastshares: if self.job: self.send("nonce_found", time.time(), struct.pack("<I", nonce[0])) lastshares.append(nonce[0]) while len(lastshares) > len(nonces): lastshares.pop(0) # Verify proper operation and adjust clocking if neccessary if now > self.checklockout and self.job: errorcount[self.multiplier] *= 0.995 errorweight[self.multiplier] = errorweight[self.multiplier] * 0.995 + 1 for nonce in nonces: invalid = True for offset in (0, 1, -1, 2, -2): hash = Job.calculate_hash(self.job[:76] + struct.pack("<I", nonce[1] + offset)) if struct.unpack("!I", hash[-4:])[0] == (nonce[2] + 0x5be0cd19) & 0xffffffff: invalid = False break if invalid: errorcount[self.multiplier] += 1. / len(nonces) certainty = min(1, errorweight[self.multiplier] / 100) errorrate = errorcount[self.multiplier] / errorweight[self.multiplier] maxerrorrate[self.multiplier] = max(maxerrorrate[self.multiplier], errorrate * certainty) for i in range(len(maxerrorrate) - 1): if maxerrorrate[i + 1] * i < maxerrorrate[i] * (i + 20): maxerrorrate[i + 1] = maxerrorrate[i] * (1 + 20.0 / i) limit = 0 while limit < self.device.default_multiplier and maxerrorrate[limit + 1] < errorlimit: limit += 1 while limit < self.device.maximum_multiplier and errorweight[limit] > 150 and maxerrorrate[limit + 1] < errorlimit: limit += 1 multiplier = 0 best = 0 for i in range(limit + 1): effective = (i + 1 + (errorhysteresis if i == self.multiplier else 0)) * (1 - maxerrorrate[i]) if effective > best: best = effective multiplier = i self._set_multiplier(multiplier) if counter >= 10: counter = 0 try: self.send("error_rate", errorcount[self.multiplier] / errorweight[self.multiplier]) except: pass with self.wakeup: self.wakeup.wait(self.pollinterval) except Exception as e: self.error = e # Unblock main thread self.send("ping")
def polling_thread(self): try: lastshares = [] errorcount = [0] * (self.device.maximum_multiplier + 1) errorweight = [0] * (self.device.maximum_multiplier + 1) maxerrorrate = [0] * (self.device.maximum_multiplier + 1) errorlimit = 0.05 errorhysteresis = 0.1 counter = 0 while not self.shutdown: counter += 1 # Poll for nonces now = time.time() nonces = self.device.read_nonces() exhausted = False with self.wakeup: if nonces[0][1] < self.lastnonce: self.lastnonce = nonces[0][1] exhausted = True if exhausted: self.send("keyspace_exhausted") for nonce in nonces: if nonce[0] != -self.device.nonce_offset and not nonce[ 0] in lastshares: if self.job: self.send("nonce_found", time.time(), struct.pack("<I", nonce[0])) lastshares.append(nonce[0]) while len(lastshares) > len(nonces): lastshares.pop(0) # Verify proper operation and adjust clocking if neccessary if now > self.checklockout and self.job: errorcount[self.multiplier] *= 0.995 errorweight[ self. multiplier] = errorweight[self.multiplier] * 0.995 + 1 for nonce in nonces: invalid = True for offset in (0, 1, -1, 2, -2): hash = Job.calculate_hash( self.job[:76] + struct.pack("<I", nonce[1] + offset)) if struct.unpack( "!I", hash[-4:])[0] == (nonce[2] + 0x5be0cd19) & 0xffffffff: invalid = False break if invalid: errorcount[self.multiplier] += 1. / len(nonces) certainty = min(1, errorweight[self.multiplier] / 100) errorrate = errorcount[self.multiplier] / errorweight[ self.multiplier] maxerrorrate[self.multiplier] = max( maxerrorrate[self.multiplier], errorrate * certainty) for i in range(len(maxerrorrate) - 1): if maxerrorrate[i + 1] * i < maxerrorrate[i] * (i + 20): maxerrorrate[i + 1] = maxerrorrate[i] * (1 + 20.0 / i) limit = 0 while limit < self.device.default_multiplier and maxerrorrate[ limit + 1] < errorlimit: limit += 1 while limit < self.device.maximum_multiplier and errorweight[ limit] > 150 and maxerrorrate[limit + 1] < errorlimit: limit += 1 multiplier = 0 best = 0 for i in range(limit + 1): effective = (i + 1 + (errorhysteresis if i == self.multiplier else 0)) * (1 - maxerrorrate[i]) if effective > best: best = effective multiplier = i self._set_multiplier(multiplier) if counter >= 10: counter = 0 try: self.send( "error_rate", errorcount[self.multiplier] / errorweight[self.multiplier]) except: pass with self.wakeup: self.wakeup.wait(self.pollinterval) except Exception as e: self.log("Exception caught: %s" % traceback.format_exc(), 100, "r") self.error = e # Unblock main thread self.send("ping")