def long_poll_thread(self, long_poll_id_available): long_poll_id_available.wait() while True: if self.should_stop or self.authorization_failed: return try: self.long_poll_active = True template = self.getblocktemplate( long_poll_id=self.long_poll_id, timeout=self.long_poll_timeout) self.long_poll_active = False if template: work = self.work_from_template(template) self.queue_work(work) if self.options.verbose: say_line('long poll: new block %s%s', (work['data'][56:64].decode('ascii'), work['data'][48:56].decode('ascii'))) if 'longpollid' in template: self.long_poll_id = template['longpollid'] except (IOError, http.client.HTTPException, ValueError, socks.ProxyError, NotAuthorized, RPCError): say_exception('long poll IO error') self.close_lp_connection() sleep(.5) except Exception: say_exception()
def proposeblock(self, block_data, work_id=None): try: self.connection = \ self.ensure_connected(self.connection, self.server().proto, self.server().host)[0] param = {'mode': 'proposal', 'data': block_data} if work_id: param['workid'] = work_id postdata = { 'method': 'getblocktemplate', 'id': 'json', 'params': (param, ) } with open('last_submission.txt', 'w') as submission_file: submission_file.write(dumps(postdata)) (self.connection, result) = self.request(self.connection, '/', self.headers, dumps(postdata)) self.switch.connection_ok() reject_reason = result['result'] say_line('proposal response: %s', reject_reason) return result['result'] except (IOError, http.client.HTTPException, ValueError, socks.ProxyError, NotAuthorized, RPCError): say_exception() self.stop() except Exception: say_exception()
def submitblock(self, block_data, work_id=None): try: self.connection = \ self.ensure_connected(self.connection, self.server().proto, self.server().host)[0] if work_id: params = (block_data, {'workid': work_id}) else: params = (block_data,) postdata = { 'method': 'submitblock', 'id': 'json', 'params': params } (self.connection, result) = self.request(self.connection, '/', self.headers, dumps(postdata)) self.switch.connection_ok() return result['result'] except (IOError, http.client.HTTPException, ValueError, socks.ProxyError, NotAuthorized, RPCError): say_exception() self.stop() except Exception: say_exception()
def long_poll_thread(self, long_poll_id_available): long_poll_id_available.wait() while True: if self.should_stop or self.authorization_failed: return try: self.long_poll_active = True template = self.getblocktemplate(long_poll_id=self.long_poll_id, timeout=self.long_poll_timeout) self.long_poll_active = False if template: work = self.work_from_template(template) self.queue_work(work) if self.options.verbose: say_line('long poll: new block %s%s', (work['data'][56:64].decode('ascii'), work['data'][48:56].decode('ascii'))) if 'longpollid' in template: self.long_poll_id = template['longpollid'] except (IOError, http.client.HTTPException, ValueError, socks.ProxyError, NotAuthorized, RPCError): say_exception('long poll IO error') self.close_lp_connection() sleep(.5) except Exception: say_exception()
def loop(self): if self.authorization_failed: return super(GetworkSource, self).loop() thread = Thread(target=self.long_poll_thread) thread.daemon = True thread.start() while True: if self.should_stop: return if self.check_failback(): return True try: with self.switch.lock: miner = self.switch.updatable_miner() while miner: work = self.getwork() self.queue_work(work, miner) miner = self.switch.updatable_miner() self.process_result_queue() sleep(1) except Exception: say_exception("Unexpected error:") break
def submitblock(self, block_data, work_id=None): try: self.connection = \ self.ensure_connected(self.connection, self.server().proto, self.server().host)[0] if work_id: params = (block_data, {'workid': work_id}) else: params = (block_data, ) postdata = { 'method': 'submitblock', 'id': 'json', 'params': params } (self.connection, result) = self.request(self.connection, '/', self.headers, dumps(postdata)) self.switch.connection_ok() return result['result'] except (IOError, http.client.HTTPException, ValueError, socks.ProxyError, NotAuthorized, RPCError): say_exception() self.stop() except Exception: say_exception()
def tokenize(option, name, default=[0], cast=int): if option: try: return [cast(x) for x in option.split(',')] except ValueError: say_exception('Invalid %s(s) specified: %s\n\n' % (name, option)) sys.exit() return default
def loop(self): super(StratumSource, self).loop() self.switch.update_time = True while True: if self.should_stop: return if self.current_job: miner = self.switch.updatable_miner() while miner: self.current_job = self.refresh_job(self.current_job) self.queue_work(self.current_job, miner) miner = self.switch.updatable_miner() if self.check_failback(): return True if not self.handler: try: # socket = ssl.wrap_socket(socket) address, port = self.server().host.split(':', 1) if not self.options.proxy: self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.connect((address, int(port))) else: self.socket = socks.socksocket() p = self.options.proxy self.socket.setproxy(p.type, p.host, p.port, True, p.user, p.pwd) try: self.socket.connect((address, int(port))) except socks.Socks5AuthError: say_exception('Proxy error:') self.stop() self.handler = Handler(self.socket, self.channel_map, self) thread = Thread(target=self.asyncore_thread) thread.daemon = True thread.start() if not self.subscribe(): say_line('Failed to subscribe') self.stop() elif not self.authorize(): self.stop() except socket.error: say_exception() self.stop() continue with self.send_lock: self.process_result_queue() sleep(1)
def check(port, likely=True): result = False try: device = open_device(port) response = init_device(device) device.close() result = is_good_init(response) except SerialException: if likely: say_exception() if not likely and result: say_line('Found BitFORCE on %s', port) elif likely and not result: say_line('No valid response from BitFORCE on %s', port) return result
def long_poll_thread(self): last_host = None while True: if self.should_stop or self.authorization_failed: return url = self.long_poll_url if url != '': proto = self.server().proto host = self.server().host parsedUrl = urlsplit(url) if parsedUrl.scheme != '': proto = parsedUrl.scheme if parsedUrl.netloc != '': host = parsedUrl.netloc url = url[url.find(host) + len(host):] if url == '': url = '/' try: if host != last_host: self.close_lp_connection() self.lp_connection, changed = self.ensure_connected( self.lp_connection, proto, host) if changed: say_line("LP connected to %s", self.server().name) last_host = host self.long_poll_active = True response = self.request(self.lp_connection, url, self.headers, timeout=self.long_poll_timeout) self.long_poll_active = False if response: (self.lp_connection, result) = response self.queue_work(result['result']) if self.options.verbose: say_line('long poll: new block %s%s', (result['result']['data'][56:64], result['result']['data'][48:56])) except (IOError, http.client.HTTPException, ValueError, socks.ProxyError, NotAuthorized, RPCError): say_exception('long poll IO error') self.close_lp_connection() sleep(.5) except Exception: say_exception()
def long_poll_thread(self): last_host = None while True: if self.should_stop or self.authorization_failed: return url = self.long_poll_url if url != '': proto = self.server().proto host = self.server().host parsedUrl = urlsplit(url) if parsedUrl.scheme != '': proto = parsedUrl.scheme if parsedUrl.netloc != '': host = parsedUrl.netloc url = url[url.find(host) + len(host):] if url == '': url = '/' try: if host != last_host: self.close_lp_connection() self.lp_connection, changed = self.ensure_connected( self.lp_connection, proto, host) if changed: say_line("LP connected to %s", self.server().name) last_host = host self.long_poll_active = True response = self.request(self.lp_connection, url, self.headers, timeout=self.long_poll_timeout) self.long_poll_active = False if response: (self.lp_connection, result) = response self.queue_work(result['result']) if self.options.verbose: say_line('long poll: new block %s%s', ( result['result']['data'][56:64], result['result']['data'][48:56])) except ( IOError, http.client.HTTPException, ValueError, socks.ProxyError, NotAuthorized, RPCError): say_exception('long poll IO error') self.close_lp_connection() sleep(.5) except Exception: say_exception()
def getwork(self, data=None): try: self.connection = \ self.ensure_connected(self.connection, self.server().proto, self.server().host)[0] self.postdata['params'] = [data] if data else [] (self.connection, result) = self.request(self.connection, '/', self.headers, dumps(self.postdata)) self.switch.connection_ok() return result['result'] except (IOError, http.client.HTTPException, ValueError, socks.ProxyError, NotAuthorized, RPCError): self.stop() except Exception: say_exception()
def send_message(self, message): data = dumps(message) + '\n' data = data.encode('utf-8') try: # self.handler.push(data) # there is some bug with asyncore's send mechanism # so we send data 'manually' # note that this is not thread safe if not self.handler: return False while data: sent = self.handler.send(data) data = data[sent:] return True except AttributeError: self.stop() except Exception: say_exception() self.stop()
def loop(self): if self.authorization_failed: return super().loop() long_poll_id_available = Event() thread = Thread( target=self.long_poll_thread, args=(long_poll_id_available,), daemon=True ) thread.start() while True: if self.should_stop: return if self.check_failback(): return True try: with self.switch.lock: miner = self.switch.updatable_miner() while miner: template = self.getblocktemplate() if template: work = self.work_from_template(template) self.queue_work(work, miner) miner = self.switch.updatable_miner() if 'longpollid' in template: self.long_poll_id = template['longpollid'] self.long_poll_url = template.get('longpolluri', '') long_poll_id_available.set() self.switch.update_time = ('time' in template.get('mutable', ())) self.process_result_queue() sleep(1) except Exception: say_exception("Unexpected error:") break
def loop(self): if self.authorization_failed: return super().loop() long_poll_id_available = Event() thread = Thread(target=self.long_poll_thread, args=(long_poll_id_available, ), daemon=True) thread.start() while True: if self.should_stop: return if self.check_failback(): return True try: with self.switch.lock: miner = self.switch.updatable_miner() while miner: template = self.getblocktemplate() if template: work = self.work_from_template(template) self.queue_work(work, miner) miner = self.switch.updatable_miner() if 'longpollid' in template: self.long_poll_id = template['longpollid'] self.long_poll_url = template.get( 'longpolluri', '') long_poll_id_available.set() self.switch.update_time = ('time' in template.get( 'mutable', ())) self.process_result_queue() sleep(1) except Exception: say_exception("Unexpected error:") break
def ensure_connected(self, connection, proto, host): if connection != None and connection.sock != None: return connection, False if proto == 'https': connector = http.client.HTTPSConnection else: connector = http.client.HTTPConnection if not self.options.proxy: return connector(host), True host, port = host.split(':') connection = connector(host) connection.sock = socks.socksocket() p = self.options.proxy connection.sock.setproxy(p.type, p.host, p.port, True, p.user, p.pwd) try: connection.sock.connect((host, int(port))) except socks.Socks5AuthError: say_exception('Proxy error:') self.stop() return connection, True
def __init__(self, options, options_encoding): self.lock = RLock() self.miners = [] self.options = options self.options_encoding = options_encoding self.last_work = 0 self.update_time = True self.max_update_time = options.max_update_time self.backup_server_index = 1 self.errors = 0 self.failback_attempt_count = 0 self.server_index = -1 self.last_server = None self.server_map = {} self.user_agent = 'apoclypsebm/' + options.version self.difficulty = 0 self.true_target = None self.last_block = '' self.sent = {} if self.options.proxy: self.options.proxy = self.parse_server(self.options.proxy, False) self.parse_proxy(self.options.proxy) self.servers = [] for server in self.options.servers: try: self.servers.append(self.parse_server(server)) except ValueError: if self.options.verbose: say_exception() say_line("Ignored invalid server entry: %s", server) continue
def proposeblock(self, block_data, work_id=None): try: self.connection = \ self.ensure_connected(self.connection, self.server().proto, self.server().host)[0] param = { 'mode': 'proposal', 'data': block_data } if work_id: param['workid'] = work_id postdata = { 'method': 'getblocktemplate', 'id': 'json', 'params': (param,) } with open('last_submission.txt', 'w') as submission_file: submission_file.write(dumps(postdata)) (self.connection, result) = self.request(self.connection, '/', self.headers, dumps(postdata)) self.switch.connection_ok() reject_reason = result['result'] say_line(f'proposal response: %s', reject_reason) return result['result'] except (IOError, http.client.HTTPException, ValueError, socks.ProxyError, NotAuthorized, RPCError): say_exception() self.stop() except Exception: say_exception()
def mining_thread(self): say_line('started BFL miner on %s', (self.id())) while not self.should_stop: try: self.device = open_device(self.port) response = init_device(self.device) if not is_good_init(response): say_line( 'Failed to initialize %s (response: %s), retrying...', (self.id(), response)) self.device.close() self.device = None sleep(1) continue last_rated = time() iterations = 0 self.job = None self.busy = False while not self.should_stop: if (not self.job) or (not self.work_queue.empty()): try: self.job = self.work_queue.get(True, 1) except Empty: if not self.busy: continue else: if not self.job and not self.busy: continue targetQ = self.job.targetQ self.job.original_time = self.job.time self.job.time_delta = uint32( int(time())) - bytereverse(self.job.time) if not self.busy: self.put_job() else: result = self.check_result() if result: now = time() self.busy = False r = self.last_job job_duration = now - self.job_started self.put_job() self.min_interval = min(self.min_interval, job_duration) iterations += 4294967296 t = now - last_rated if t > self.options.rate: self.update_rate(now, iterations, t, targetQ) last_rated = now; iterations = 0 if result != b'NO-NONCE\n': r.nonces = result self.switch.put(r) sleep(self.min_interval - (CHECK_INTERVAL * 2)) else: if result is None: self.check_interval = min( self.check_interval * 2, 1) sleep(self.check_interval) except Exception: say_exception() if self.device: self.device.close() self.device = None sleep(1)
def getblocktemplate(self, long_poll_id=None, timeout=None): param = { 'capabilities': ('longpoll', 'coinbasetxn', 'coinbasevalue', 'workid'), 'rules': ('segwit',) } try: if long_poll_id: param['longpollid'] = long_poll_id url = self.long_poll_url parsedUrl = urlsplit(url) proto = parsedUrl.scheme or self.server().proto if parsedUrl.netloc != '': host = parsedUrl.netloc url = url[url.find(host) + len(host):] if url == '': url = '/' else: host = self.server().host if host != self.long_poll_last_host: self.close_lp_connection() self.lp_connection, changed = self.ensure_connected( self.lp_connection, proto, host) connection = self.lp_connection if changed: say_line(f"LP connected to {host}") self.long_poll_last_host = host else: url = '/' self.connection, changed = \ self.ensure_connected(self.connection, self.server().proto, self.server().host) connection = self.connection if changed: say_line( f"Connected to {self.server().host}") postdata = { 'method': 'getblocktemplate', 'id': 'json', 'params': (param,) } connection, result = self.request(connection, url, self.headers, dumps(postdata), timeout=timeout or 0) self.switch.connection_ok() return result['result'] except ConnectionResetError: # Connection resets are normal if the server hasn't heard from us # in a while. if long_poll_id: self.close_lp_connection() else: self.close_connection() except (IOError, http.client.HTTPException, ValueError, socks.ProxyError, NotAuthorized, RPCError): self.stop() except Exception: say_exception()
def mining_thread(self): say_line('started BFL miner on %s', (self.id())) while not self.should_stop: try: self.device = open_device(self.port) response = init_device(self.device) if not is_good_init(response): say_line( 'Failed to initialize %s (response: %s), retrying...', (self.id(), response)) self.device.close() self.device = None sleep(1) continue last_rated = time() iterations = 0 self.job = None self.busy = False while not self.should_stop: if (not self.job) or (not self.work_queue.empty()): try: self.job = self.work_queue.get(True, 1) except Empty: if not self.busy: continue else: if not self.job and not self.busy: continue targetQ = self.job.targetQ self.job.original_time = self.job.time self.job.time_delta = uint32(int( time())) - bytereverse(self.job.time) if not self.busy: self.put_job() else: result = self.check_result() if result: now = time() self.busy = False r = self.last_job job_duration = now - self.job_started self.put_job() self.min_interval = min(self.min_interval, job_duration) iterations += 4294967296 t = now - last_rated if t > self.options.rate: self.update_rate(now, iterations, t, targetQ) last_rated = now iterations = 0 if result != b'NO-NONCE\n': r.nonces = result self.switch.put(r) sleep(self.min_interval - (CHECK_INTERVAL * 2)) else: if result is None: self.check_interval = min( self.check_interval * 2, 1) sleep(self.check_interval) except Exception: say_exception() if self.device: self.device.close() self.device = None sleep(1)
def getblocktemplate(self, long_poll_id=None, timeout=None): param = { 'capabilities': ('longpoll', 'coinbasetxn', 'coinbasevalue', 'workid'), 'rules': ('segwit', ) } try: if long_poll_id: param['longpollid'] = long_poll_id url = self.long_poll_url parsedUrl = urlsplit(url) proto = parsedUrl.scheme or self.server().proto if parsedUrl.netloc != '': host = parsedUrl.netloc url = url[url.find(host) + len(host):] if url == '': url = '/' else: host = self.server().host if host != self.long_poll_last_host: self.close_lp_connection() self.lp_connection, changed = self.ensure_connected( self.lp_connection, proto, host) connection = self.lp_connection if changed: say_line(f'LP connected to {host}') self.long_poll_last_host = host else: url = '/' self.connection, changed = \ self.ensure_connected(self.connection, self.server().proto, self.server().host) connection = self.connection if changed: say_line(f'Connected to {self.server().host}') postdata = { 'method': 'getblocktemplate', 'id': 'json', 'params': (param, ) } connection, result = self.request(connection, url, self.headers, dumps(postdata), timeout=timeout or 0) self.switch.connection_ok() return result['result'] except ConnectionResetError: # Connection resets are normal if the server hasn't heard from us # in a while. if long_poll_id: self.close_lp_connection() else: self.close_connection() except (IOError, http.client.HTTPException, ValueError, socks.ProxyError, NotAuthorized, RPCError): self.stop() except Exception: say_exception()