Esempio n. 1
0
def detect_stratum_proxy(host):
    s = None
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
        s.sendto(
            dumps({
                "id": 0,
                "method": "mining.get_upstream",
                "params": []
            }), ('239.3.3.3', 3333))

        say_line('Searching stratum proxy for %s', host)

        s.settimeout(2)

        try:
            while True:
                response, address = s.recvfrom(128)
                try:
                    response = loads(response)
                    response_host = response['result'][0][0] + ':' + str(
                        response['result'][0][1])
                    if response_host == host:
                        proxy_address = address[0] + ':' + str(
                            response['result'][1])
                        say_line('Using stratum proxy at %s', proxy_address)
                        return proxy_address
                except ValueError:
                    pass
        except socket.timeout:
            pass

    finally:
        if s != None:
            s.close()
Esempio n. 2
0
 def set_server_index(self, server_index):
     self.server_index = server_index
     user = self.servers[server_index].user
     name = self.servers[server_index].name
     # say_line('Setting server %s (%s @ %s)', (name, user, host))
     say_line('Setting server (%s @ %s)', (user, name))
     log.server = name
Esempio n. 3
0
def detect_stratum_proxy(host):
    s = None
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
        s.sendto(
            dumps({"id": 0, "method": "mining.get_upstream", "params": []}),
            ('239.3.3.3', 3333))

        say_line('Searching stratum proxy for %s', host)

        s.settimeout(2)

        try:
            while True:
                response, address = s.recvfrom(128)
                try:
                    response = loads(response)
                    response_host = response['result'][0][0] + ':' + str(
                        response['result'][0][1])
                    if response_host == host:
                        proxy_address = address[0] + ':' + str(
                            response['result'][1])
                        say_line('Using stratum proxy at %s', proxy_address)
                        return proxy_address
                except ValueError:
                    pass
        except socket.timeout:
            pass

    finally:
        if s != None:
            s.close()
Esempio n. 4
0
    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()
Esempio n. 5
0
    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()
Esempio n. 6
0
 def get_temperature(self):
     response = request(self.device, b'ZLX')
     if len(response) < 23 or response[0] != b'T' or response[-1:] != b'\n':
         say_line('%s: bad response for temperature: %s',
                  (self.id(), response))
         return 0
     return float(response[23:-1])
Esempio n. 7
0
    def generation_tx_for_template(self, template):
        template_tx = template.get('coinbasetxn')
        # In segwit mode, we need another merkle root that has hashed witness
        # portions of txes:
        witness_commitment = unhexlify(template['default_witness_commitment'])
        # TODO: use the 'hash' attrs if this is missing
        coinbase_msg = self.options.coinbase_msg.encode('utf-8')
        if template_tx:
            if self.options.address:
                if 'coinbase' in template.get('mutable', ('coinbase',)):
                    return tx_make_generation(coinbase_msg, self.options.address,
                                              template['coinbasevalue'],
                                              template['height'],
                                              witness_commitment=witness_commitment)
                else:
                    say_line(
                        f'Warning: address {self.options.address} ignored, not allowed by work source.')
        else:
            if self.options.address:
                return tx_make_generation(coinbase_msg, self.options.address,
                                          template['coinbasevalue'],
                                          template['height'],
                                          witness_commitment=witness_commitment)
            else:
                raise Exception('Address not supplied by user and no coinbase tx supplied by work source.')

        return (
            unhexlify(template_tx['data']),
            unhexlify(template_tx['txid']),
            unhexlify(template_tx['hash']),
        )
Esempio n. 8
0
    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()
Esempio n. 9
0
 def get_temperature(self):
     response = request(self.device, b'ZLX')
     if len(response) < 23 or response[0] != b'T' or response[-1:] != b'\n':
         say_line('%s: bad response for temperature: %s',
                  (self.id(), response))
         return 0
     return float(response[23:-1])
Esempio n. 10
0
 def check_result(self):
     response = request(self.device, b'ZFX')
     if response.startswith(b'B'): return False
     if response == b'NO-NONCE\n': return response
     if response[:12] != 'NONCE-FOUND:' or response[-1:] != '\n':
         say_line('%s: bad response checking result: %s',
                  (self.id(), response))
         return None
     return response[12:-1]
Esempio n. 11
0
 def check_result(self):
     response = request(self.device, b'ZFX')
     if response.startswith(b'B'): return False
     if response == b'NO-NONCE\n': return response
     if response[:12] != 'NONCE-FOUND:' or response[-1:] != '\n':
         say_line('%s: bad response checking result: %s',
                  (self.id(), response))
         return None
     return response[12:-1]
Esempio n. 12
0
 def report(self, miner, nonce, accepted):
     is_block, hash6, hash5 = self.sent[nonce]
     miner.share_count[1 if accepted else 0] += 1
     hash_ = hash6 + hash5 if is_block else hash6
     if self.options.verbose or is_block:
         say_line('%s %s%s, %s', (
         miner.id(), 'block ' if is_block else '', hash_,
         'accepted' if accepted else '_rejected_'))
     del self.sent[nonce]
Esempio n. 13
0
    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)
Esempio n. 14
0
    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)
Esempio n. 15
0
    def load_kernel(self):
        max_worksize = self.device.get_info(cl.device_info.MAX_WORK_GROUP_SIZE)
        if not self.worksize:
            self.worksize = max_worksize
            if self.options.verbose:
                say_line('Set worksize to %s from device info.', self.worksize)
        self.defines += f' -D WORK_GROUP_SIZE={self.worksize}'
        if self.worksize > max_worksize:
            # Exceeding the max advertised work group size
            # The overriding size will only be configure
            # at compile time isntead of at execution.
            self.execution_local_dims = None
        else:
            self.execution_local_dims = (self.worksize,)

        self.context = cl.Context([self.device], None, None)
        if self.device.extensions.find('cl_amd_media_ops') != -1:
            self.defines += ' -D BITALIGN'
            if self.device_name in ('Cedar', 'Redwood', 'Juniper', 'Cypress',
                                    'Hemlock', 'Caicos', 'Turks', 'Barts',
                                    'Cayman', 'Antilles', 'Wrestler',
                                    'Zacate', 'WinterPark', 'BeaverCreek'):
                self.defines += ' -D BFI_INT'

        kernel = pkgutil.get_data('apoclypsebm', f'{self.options.kernel}.cl')
        m = md5(
            f'{self.device.platform.name}{self.device.platform.version}'
            f'{self.device.name}{self.defines}'.encode('utf-8')
        )
        m.update(kernel)
        cache_name = f'{m.hexdigest()}.elf'

        try:
            with open(cache_name, 'rb') as binary:
                self.program = cl.Program(self.context, [self.device],
                                          [binary.read()]).build(self.defines)
        except (IOError, cl.LogicError):
            kernel = kernel.decode('ascii')
            self.program = cl.Program(self.context, kernel).build(self.defines)
            if self.defines.find('-D BFI_INT') != -1:
                patched_binary = self.patch(self.program.binaries[0])
                self.program = cl.Program(self.context, [self.device], [patched_binary]).build(self.defines)
            with open(cache_name, 'wb') as binary:
                binary.write(self.program.binaries[0])

        self.kernel = self.program.search

        if self.options.verbose:
            compiled_worksize = self.kernel.get_work_group_info(
                cl.kernel_work_group_info.COMPILE_WORK_GROUP_SIZE, self.device
            )
            say_line('Compiled work size: %s', compiled_worksize)
Esempio n. 16
0
 def add_stratum_source(self):
     if self.options.stratum_proxies:
         stratum_proxy = stratum.detect_stratum_proxy(
             self.server().host)
         if stratum_proxy:
             original_server = copy(self.server())
             original_server.source = stratum.StratumSource(self)
             self.servers.insert(self.backup_server_index, original_server)
             self.server().host = stratum_proxy
             self.server().name += '(p)'
             log.server = self.server().name
         else:
             say_line('No proxy found')
     self.server().source = stratum.StratumSource(self)
Esempio n. 17
0
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
Esempio n. 18
0
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
Esempio n. 19
0
    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()
Esempio n. 20
0
    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()
Esempio n. 21
0
 def request(self, connection, url, headers, data=None, timeout=0):
     result = response = None
     try:
         if data:
             connection.request('POST', url, data, headers)
         else:
             connection.request('GET', url, headers=headers)
         response = self.timeout_response(connection, timeout)
         if not response:
             return None
         if response.status == http.client.UNAUTHORIZED:
             say_line('Wrong username or password for %s',
                      self.server().name)
             self.authorization_failed = True
             raise NotAuthorized()
         r = self.max_redirects
         while response.status == http.client.TEMPORARY_REDIRECT:
             response.read()
             url = response.getheader('Location', '')
             if r == 0 or url == '':
                 raise http.client.HTTPException(
                     'Too much or bad redirects')
             connection.request('GET', url, headers=headers)
             response = self.timeout_response(connection, timeout)
             r -= 1
         self.long_poll_url = response.getheader('X-Long-Polling', '')
         self.switch.update_time = bool(
             response.getheader('X-Roll-NTime', ''))
         hostList = response.getheader('X-Host-List', '')
         self.stratum_header = response.getheader('x-stratum', '')
         if (not self.options.nsf) and hostList:
             self.switch.add_servers(loads(hostList))
         result = loads(response.read())
         if result['error']:
             say_line('server error: %s', result['error']['message'])
             raise RPCError(result['error']['message'])
         return (connection, result)
     finally:
         if not result or not response or (
                 response.version == 10
                 and response.getheader('connection', '') != 'keep-alive'
         ) or response.getheader('connection', '') == 'close':
             connection.close()
             connection = None
Esempio n. 22
0
 def request(self, connection, url, headers, data=None, timeout=0):
     result = response = None
     try:
         if data:
             connection.request('POST', url, data, headers)
         else:
             connection.request('GET', url, headers=headers)
         response = self.timeout_response(connection, timeout)
         if not response:
             return None
         if response.status == http.client.UNAUTHORIZED:
             say_line('Wrong username or password for %s',
                      self.server().name)
             self.authorization_failed = True
             raise NotAuthorized()
         r = self.max_redirects
         while response.status == http.client.TEMPORARY_REDIRECT:
             response.read()
             url = response.getheader('Location', '')
             if r == 0 or url == '': raise http.client.HTTPException(
                 'Too much or bad redirects')
             connection.request('GET', url, headers=headers)
             response = self.timeout_response(connection, timeout)
             r -= 1
         self.long_poll_url = response.getheader('X-Long-Polling', '')
         self.switch.update_time = bool(
             response.getheader('X-Roll-NTime', ''))
         hostList = response.getheader('X-Host-List', '')
         self.stratum_header = response.getheader('x-stratum', '')
         if (not self.options.nsf) and hostList: self.switch.add_servers(
             loads(hostList))
         result = loads(response.read())
         if result['error']:
             say_line('server error: %s', result['error']['message'])
             raise RPCError(result['error']['message'])
         return (connection, result)
     finally:
         if not result or not response or (
                 response.version == 10 and response.getheader('connection',
                                                               '') != 'keep-alive') or response.getheader(
                 'connection', '') == 'close':
             connection.close()
             connection = None
Esempio n. 23
0
 def send(self, result, send_callback):
     for nonce in result.miner.nonce_generator(result.nonces):
         h = hash(result.state, result.merkle_end, result.time,
                  result.difficulty, nonce)
         if h[7] != 0:
             hash6 = hexlify(pack('<I', int(h[6])))
             say_line('Verification failed, check hardware! (%s, %s)',
                      (result.miner.id(), hash6))
             return True  # consume this particular result
         else:
             self.diff1_found(bytereverse(h[6]), result.target[6])
             if belowOrEquals(h[:7], result.target[:7]):
                 is_block = belowOrEquals(h[:7], self.true_target[:7])
                 hash6 = hexlify(pack('<I', int(h[6])))
                 hash5 = hexlify(pack('<I', int(h[5])))
                 self.sent[nonce] = (is_block, hash6, hash5)
                 if not send_callback(result, nonce):
                     return False
     return True
Esempio n. 24
0
    def generation_tx_for_template(self, template):
        template_tx = template.get('coinbasetxn')
        # In segwit mode, we need another merkle root that has hashed witness
        # portions of txes:
        witness_commitment = unhexlify(template['default_witness_commitment'])
        # TODO: use the 'hash' attrs if this is missing
        coinbase_msg = self.options.coinbase_msg.encode('utf-8')
        if template_tx:
            if self.options.address:
                if 'coinbase' in template.get('mutable', ('coinbase', )):
                    return tx_make_generation(
                        coinbase_msg,
                        self.options.address,
                        template['coinbasevalue'],
                        template['height'],
                        witness_commitment=witness_commitment)
                else:
                    say_line(
                        f'Warning: address {self.options.address} ignored, not allowed by work source.'
                    )
        else:
            if self.options.address:
                return tx_make_generation(
                    coinbase_msg,
                    self.options.address,
                    template['coinbasevalue'],
                    template['height'],
                    witness_commitment=witness_commitment)
            else:
                raise Exception(
                    'Address not supplied by user and no coinbase tx supplied by work source.'
                )

        return (
            unhexlify(template_tx['data']),
            unhexlify(template_tx['txid']),
            unhexlify(template_tx['hash']),
        )
Esempio n. 25
0
    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
Esempio n. 26
0
    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()
Esempio n. 27
0
    def get_adapter_info(self):
        adapter_info = []
        num_adapters = c_int(-1)
        if ADL_Adapter_NumberOfAdapters_Get(byref(num_adapters)) != ADL_OK:
            say_line(
                "ADL_Adapter_NumberOfAdapters_Get failed, cutoff temperature"
                "disabled for %s",
                self.id()
            )
            return

        AdapterInfoArray = (AdapterInfo * num_adapters.value)()

        if ADL_Adapter_AdapterInfo_Get(cast(AdapterInfoArray, LPAdapterInfo),
                                       sizeof(AdapterInfoArray)) != ADL_OK:
            say_line(
                "ADL_Adapter_AdapterInfo_Get failed, "
                "cutoff temperature disabled for %s",
                self.id()
            )
            return

        deviceAdapter = namedtuple(
            'DeviceAdapter',
            ('AdapterIndex', 'AdapterID', 'BusNumber', 'UDID')
        )

        devices = []
        for adapter in AdapterInfoArray:
            index = adapter.iAdapterIndex
            bus_num = adapter.iBusNumber
            udid = adapter.strUDID

            adapter_id = c_int(-1)

            if ADL_Adapter_ID_Get(index, byref(adapter_id)) != ADL_OK:
                say_line(
                    "ADL_Adapter_ID_Get failed, "
                    "cutoff temperature disabled for %s",
                    self.id()
                )
                return

            found = False
            for device in devices:
                if device.AdapterID.value == adapter_id.value:
                    found = True
                    break

            if found is False:
                devices.append(deviceAdapter(index, adapter_id, bus_num, udid))

        for device in devices:
            adapter_info.append(AdapterInfoArray[device.AdapterIndex])

        return adapter_info
Esempio n. 28
0
    def server_source(self):
        if not hasattr(self.server(), 'source'):
            http_source = None
            if self.server().proto == 'http':
                from apoclypsebm.work_sources.getblocktemplate import GetblocktemplateSource
                http_source = GetblocktemplateSource(self)
            elif self.server().proto == 'getwork+http':
                from apoclypsebm.work_sources.getwork import GetworkSource
                http_source = GetworkSource(self)
            else:
                self.add_stratum_source()

            if http_source:
                say_line('checking for stratum...')
                stratum_host = http_source.detect_stratum()
                if stratum_host:
                    http_source.close_connection()
                    self.server().proto = 'stratum'
                    self.server().host = stratum_host
                    self.add_stratum_source()
                else:
                    self.server().source = http_source

        return self.server().source
Esempio n. 29
0
    def get_adapter_info(self):
        adapter_info = []
        num_adapters = c_int(-1)
        if ADL_Adapter_NumberOfAdapters_Get(byref(num_adapters)) != ADL_OK:
            say_line(
                "ADL_Adapter_NumberOfAdapters_Get failed, cutoff temperature"
                "disabled for %s",
                self.id()
            )
            return

        AdapterInfoArray = (AdapterInfo * num_adapters.value)()

        if ADL_Adapter_AdapterInfo_Get(cast(AdapterInfoArray, LPAdapterInfo),
                                       sizeof(AdapterInfoArray)) != ADL_OK:
            say_line(
                "ADL_Adapter_AdapterInfo_Get failed, "
                "cutoff temperature disabled for %s",
                self.id()
            )
            return

        deviceAdapter = namedtuple(
            'DeviceAdapter',
            ('AdapterIndex', 'AdapterID', 'BusNumber', 'UDID'))

        devices = []
        for adapter in AdapterInfoArray:
            index = adapter.iAdapterIndex
            busNum = adapter.iBusNumber
            udid = adapter.strUDID

            adapterID = c_int(-1)

            if ADL_Adapter_ID_Get(index, byref(adapterID)) != ADL_OK:
                say_line(
                    "ADL_Adapter_ID_Get failed, "
                    "cutoff temperature disabled for %s",
                    self.id()
                )
                return

            found = False
            for device in devices:
                if device.AdapterID.value == adapterID.value:
                    found = True
                    break

            if found is False:
                devices.append(deviceAdapter(index, adapterID, busNum, udid))

        for device in devices:
            adapter_info.append(AdapterInfoArray[device.AdapterIndex])

        return adapter_info
Esempio n. 30
0
    def loop(self):
        self.should_stop = False
        self.set_server_index(0)

        while True:
            if self.should_stop: return

            failback = self.server_source().loop()

            sleep(1)

            if failback:
                say_line("Attempting to fail back to primary server")
                self.last_server = self.server_index
                self.set_server_index(0)
                continue

            if self.last_server:
                self.failback_attempt_count += 1
                self.set_server_index(self.last_server)
                say_line(
                    'Still unable to reconnect to primary server (attempt %s), failing over',
                    self.failback_attempt_count)
                self.last_server = None
                continue

            self.errors += 1
            say_line('IO errors - %s, tolerance %s',
                     (self.errors, self.options.tolerance))

            if self.errors > self.options.tolerance:
                self.errors = 0
                if self.backup_server_index >= len(self.servers):
                    say_line(
                        "No more backup servers left. Using primary and starting over.")
                    new_server_index = 0
                    self.backup_server_index = 1
                else:
                    new_server_index = self.backup_server_index
                    self.backup_server_index += 1
                self.set_server_index(new_server_index)
Esempio n. 31
0
    def put_job(self):
        if self.busy: return

        temperature = self.get_temperature()
        if temperature < self.cutoff_temp:
            response = request(self.device, b'ZDX')
            if self.is_ok(response):
                if self.switch.update_time:
                    self.job.time = bytereverse(
                        uint32(int(time())) - self.job.time_delta)
                data = b''.join([
                    pack('<8I', *self.job.state),
                    pack('<3I', self.job.merkle_end, self.job.time,
                         self.job.difficulty)
                ])
                response = request(self.device,
                                   b''.join([b'>>>>>>>>', data, b'>>>>>>>>']))
                if self.is_ok(response):
                    self.busy = True
                    self.job_started = time()

                    self.last_job = Object()
                    self.last_job.header = self.job.header
                    self.last_job.merkle_end = self.job.merkle_end
                    self.last_job.time = self.job.time
                    self.last_job.difficulty = self.job.difficulty
                    self.last_job.target = self.job.target
                    self.last_job.state = self.job.state
                    self.last_job.job_id = self.job.job_id
                    self.last_job.extranonce2 = self.job.extranonce2
                    self.last_job.server = self.job.server
                    self.last_job.miner = self

                    self.check_interval = CHECK_INTERVAL
                    if not self.switch.update_time or bytereverse(
                            self.job.time) - bytereverse(
                                self.job.original_time) > 55:
                        self.update = True
                        self.job = None
                else:
                    say_line('%s: bad response when sending block data: %s',
                             (self.id(), response))
            else:
                say_line('%s: bad response when submitting job (ZDX): %s',
                         (self.id(), response))
        else:
            say_line('%s: temperature exceeds cutoff, waiting...', self.id())
Esempio n. 32
0
    def put_job(self):
        if self.busy: return

        temperature = self.get_temperature()
        if temperature < self.cutoff_temp:
            response = request(self.device, b'ZDX')
            if self.is_ok(response):
                if self.switch.update_time:
                    self.job.time = bytereverse(
                        uint32(int(time())) - self.job.time_delta)
                data = b''.join([pack('<8I', *self.job.state),
                                 pack('<3I', self.job.merkle_end, self.job.time,
                                      self.job.difficulty)])
                response = request(self.device,
                                   b''.join([b'>>>>>>>>', data, b'>>>>>>>>']))
                if self.is_ok(response):
                    self.busy = True
                    self.job_started = time()

                    self.last_job = Object()
                    self.last_job.header = self.job.header
                    self.last_job.merkle_end = self.job.merkle_end
                    self.last_job.time = self.job.time
                    self.last_job.difficulty = self.job.difficulty
                    self.last_job.target = self.job.target
                    self.last_job.state = self.job.state
                    self.last_job.job_id = self.job.job_id
                    self.last_job.extranonce2 = self.job.extranonce2
                    self.last_job.server = self.job.server
                    self.last_job.miner = self

                    self.check_interval = CHECK_INTERVAL
                    if not self.switch.update_time or bytereverse(
                            self.job.time) - bytereverse(
                            self.job.original_time) > 55:
                        self.update = True
                        self.job = None
                else:
                    say_line('%s: bad response when sending block data: %s',
                             (self.id(), response))
            else:
                say_line('%s: bad response when submitting job (ZDX): %s',
                         (self.id(), response))
        else:
            say_line('%s: temperature exceeds cutoff, waiting...', self.id())
Esempio n. 33
0
    def detect_stratum(self):
        work = self.getwork()
        if self.authorization_failed:
            return False

        if work:
            if self.stratum_header:
                host = self.stratum_header
                proto = host.find('://')
                if proto != -1:
                    host = self.stratum_header[proto + 3:]
                # this doesn't work in windows/python 2.6
                # host = urlparse.urlparse(self.stratum_header).netloc
                say_line('diverted to stratum on %s', host)
                return host
            else:
                say_line('using JSON-RPC (no stratum header)')
                self.queue_work(work)
                return False

        say_line('no response to getwork, using as stratum')
        return self.server().host
Esempio n. 34
0
    def detect_stratum(self):
        work = self.getwork()
        if self.authorization_failed:
            return False

        if work:
            if self.stratum_header:
                host = self.stratum_header
                proto = host.find('://')
                if proto != -1:
                    host = self.stratum_header[proto + 3:]
                # this doesn't work in windows/python 2.6
                # host = urlparse.urlparse(self.stratum_header).netloc
                say_line('diverted to stratum on %s', host)
                return host
            else:
                say_line('using JSON-RPC (no stratum header)')
                self.queue_work(work)
                return False

        say_line('no response to getwork, using as stratum')
        return self.server().host
Esempio n. 35
0
    def handle_message(self, message):

        # Miner API
        if 'method' in message:

            # mining.notify
            if message['method'] == 'mining.notify':
                params = message['params']

                j = Object()

                j.job_id = params[0]
                j.prevhash = params[1]
                j.coinbase1 = params[2]
                j.coinbase2 = params[3]
                j.merkle_branch = params[4]
                j.version = params[5]
                j.nbits = params[6]
                j.ntime = params[7]
                clear_jobs = params[8]
                if clear_jobs:
                    self.jobs.clear()
                j.extranonce2 = self.extranonce2_size * '00'

                j = self.refresh_job(j)

                self.jobs[j.job_id] = j
                self.current_job = j

                self.queue_work(j)
                self.switch.connection_ok()

            # mining.get_version
            if message['method'] == 'mining.get_version':
                with self.send_lock:
                    self.send_message({"error": None, "id": message['id'],
                                       "result": self.user_agent})

            # mining.set_difficulty
            elif message['method'] == 'mining.set_difficulty':
                say_line("Setting new difficulty: %s", message['params'][0])
                self.server_difficulty = min(MIN_DIFFICULTY, BASE_DIFFICULTY //
                                             message['params'][0])

            # client.reconnect
            elif message['method'] == 'client.reconnect':
                address, port = self.server().host.split(':', 1)
                (new_address, new_port, timeout) = message['params'][:3]
                if new_address: address = new_address
                if new_port != None: port = new_port
                say_line("%s asked us to reconnect to %s:%d in %d seconds",
                         (self.server().name, address, port, timeout))
                self.server().host = address + ':' + str(port)
                Timer(timeout, self.reconnect).start()

            # client.add_peers
            elif message['method'] == 'client.add_peers':
                hosts = [{'host': host[0], 'port': host[1]} for host in
                         message['params'][0]]
                self.switch.add_servers(hosts)

        # responses to server API requests
        elif 'result' in message:

            # response to mining.subscribe
            # store extranonce and extranonce2_size
            if message['id'] == 's':
                self.extranonce = message['result'][1]
                self.extranonce2_size = message['result'][2]
                self.subscribed = True

            # check if this is submit confirmation (message id should be in submits dictionary)
            # cleanup if necessary
            elif message['id'] in self.submits:
                miner, nonce = self.submits[message['id']][:2]
                accepted = message['result']
                self.switch.report(miner, nonce, accepted)
                del self.submits[message['id']]
                if time() - self.last_submits_cleanup > 3600:
                    now = time()
                    for key, value in self.submits.items():
                        if now - value[2] > 3600:
                            del self.submits[key]
                    self.last_submits_cleanup = now

            # response to mining.authorize
            elif message['id'] == self.server().user:
                if not message['result']:
                    say_line('authorization failed with %s:%s@%s', (
                    self.server().user, self.server().pwd, self.server().host))
                    self.authorized = False
                else:
                    self.authorized = True
Esempio n. 36
0
 def reconnect(self):
     say_line("%s reconnecting to %s",
              (self.server().name, self.server().host))
     self.handler.close()
Esempio n. 37
0
 def diff1_found(self, hash_, target):
     if self.options.verbose and target < 0xFFFF0000:
         say_line('checking %s <= %s', (hash_, target))
Esempio n. 38
0
    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()
Esempio n. 39
0
    def handle_message(self, message):

        # Miner API
        if 'method' in message:

            # mining.notify
            if message['method'] == 'mining.notify':
                params = message['params']

                j = Object()

                j.job_id = params[0]
                j.prevhash = params[1]

                #john
                j.prevhash = ''.join([
                    j.prevhash[i] + j.prevhash[i + 1]
                    for i in range(0, len(j.prevhash), 2)
                ][::-1])
                prev_block_hash_words = bytearray()
                for word in chunks(unhexlify(j.prevhash), 4):
                    # Prepend because template items are in RPC byte order.
                    prev_block_hash_words[0:0] = word
                j.prevhash = ''.join(
                    ['%02x' % b for b in prev_block_hash_words])

                j.coinbase1 = params[2]
                j.coinbase2 = params[3]
                j.merkle_branch = params[4]
                j.version = params[5]
                j.nbits = params[6]
                j.ntime = params[7]
                clear_jobs = params[8]
                if clear_jobs:
                    self.jobs.clear()
                j.extranonce2 = self.extranonce2_size * '00'

                j = self.refresh_job(j)

                self.jobs[j.job_id] = j
                self.current_job = j

                self.queue_work(j)
                self.switch.connection_ok()

            # mining.get_version
            if message['method'] == 'mining.get_version':
                with self.send_lock:
                    self.send_message({
                        "error": None,
                        "id": message['id'],
                        "result": self.user_agent
                    })

            # mining.set_difficulty
            elif message['method'] == 'mining.set_difficulty':
                say_line("Setting new difficulty: %s", message['params'][0])
                self.server_difficulty = min(
                    MIN_DIFFICULTY,
                    int(BASE_DIFFICULTY // message['params'][0]))

            # client.reconnect
            elif message['method'] == 'client.reconnect':
                address, port = self.server().host.split(':', 1)
                (new_address, new_port, timeout) = message['params'][:3]
                if new_address:
                    address = new_address
                if new_port is not None:
                    port = new_port
                say_line("%s asked us to reconnect to %s:%d in %d seconds",
                         (self.server().name, address, port, timeout))
                self.server().host = address + ':' + str(port)
                Timer(timeout, self.reconnect).start()

            # client.add_peers
            elif message['method'] == 'client.add_peers':
                hosts = [{
                    'host': host[0],
                    'port': host[1]
                } for host in message['params'][0]]
                self.switch.add_servers(hosts)

        # responses to server API requests
        elif 'result' in message:

            # response to mining.subscribe
            # store extranonce and extranonce2_size
            if message['id'] == 's':
                self.extranonce = message['result'][1]
                self.extranonce2_size = message['result'][2]
                self.subscribed = True

            # check if this is submit confirmation (message id should be in submits dictionary)
            # cleanup if necessary
            elif message['id'] in self.submits:
                miner, nonce = self.submits[message['id']][:2]
                accepted = message['result']
                self.switch.report(miner, nonce, accepted)
                del self.submits[message['id']]
                if monotonic() - self.last_submits_cleanup > 3600:
                    now = monotonic()
                    for key, value in self.submits.items():
                        if now - value[2] > 3600:
                            del self.submits[key]
                    self.last_submits_cleanup = now

            # response to mining.authorize
            elif message['id'] == self.server().user:
                if not message['result']:
                    say_line('authorization failed with %s:%s@%s',
                             (self.server().user, self.server().pwd,
                              self.server().host))
                    self.authorized = False
                else:
                    self.authorized = True
Esempio n. 40
0
 def reconnect(self):
     say_line("%s reconnecting to %s",
              (self.server().name, self.server().host))
     self.handler.close()
Esempio n. 41
0
    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)
Esempio n. 42
0
    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)
Esempio n. 43
0
    def mining_thread(self):
        say_line('started OpenCL miner on platform %d, device %d (%s)',
                 (self.options.platform, self.device_index, self.device_name))

        (self.defines, rate_divisor, hashspace) = (
        vectors_definition(), 500, 0x7FFFFFFF) if self.vectors else (
        '', 1000, 0xFFFFFFFF)
        self.defines += (' -DOUTPUT_SIZE=' + str(self.output_size))
        self.defines += (' -DOUTPUT_MASK=' + str(self.output_size - 1))

        self.load_kernel()
        frame = 1.0 / max(self.frames, 3)
        unit = self.worksize * 256
        global_threads = unit * 10

        queue = cl.CommandQueue(self.context)

        last_rated_pace = last_rated = last_n_time = last_temperature = time()
        base = last_hash_rate = threads_run_pace = threads_run = 0
        output = bytearray((self.output_size + 1) * 4)
        output_buffer = cl.Buffer(self.context,
                                  cl.mem_flags.WRITE_ONLY |
                                  cl.mem_flags.USE_HOST_PTR,
                                  hostbuf=output)
        self.kernel.set_arg(20, output_buffer)

        work = None
        temperature = 0
        while True:
            if self.should_stop:
                return

            sleep(self.frameSleep)

            if (not work) or (not self.work_queue.empty()):
                try:
                    work = self.work_queue.get(True, 1)
                except Empty:
                    continue
                else:
                    if not work:
                        continue
                    nonces_left = hashspace
                    state = work.state
                    f = [0] * 8
                    state2 = partial(state, work.merkle_end, work.time,
                                     work.difficulty, f)
                    calculateF(state, work.merkle_end, work.time,
                               work.difficulty, f, state2)

                    set_arg = self.kernel.set_arg
                    set_arg(0, uint32_as_bytes(state[0]))
                    set_arg(1, uint32_as_bytes(state[1]))
                    set_arg(2, uint32_as_bytes(state[2]))
                    set_arg(3, uint32_as_bytes(state[3]))
                    set_arg(4, uint32_as_bytes(state[4]))
                    set_arg(5, uint32_as_bytes(state[5]))
                    set_arg(6, uint32_as_bytes(state[6]))
                    set_arg(7, uint32_as_bytes(state[7]))

                    set_arg(8, uint32_as_bytes(state2[1]))
                    set_arg(9, uint32_as_bytes(state2[2]))
                    set_arg(10, uint32_as_bytes(state2[3]))
                    set_arg(11, uint32_as_bytes(state2[5]))
                    set_arg(12, uint32_as_bytes(state2[6]))
                    set_arg(13, uint32_as_bytes(state2[7]))

                    set_arg(15, uint32_as_bytes(f[0]))
                    set_arg(16, uint32_as_bytes(f[1]))
                    set_arg(17, uint32_as_bytes(f[2]))
                    set_arg(18, uint32_as_bytes(f[3]))
                    set_arg(19, uint32_as_bytes(f[4]))

            if temperature < self.cutoff_temp:
                self.kernel.set_arg(14, uint32_as_bytes(base))
                cl.enqueue_nd_range_kernel(queue, self.kernel,
                                           (global_threads,), (self.worksize,))

                nonces_left -= global_threads
                threads_run_pace += global_threads
                threads_run += global_threads
                base = uint32(base + global_threads)
            else:
                threads_run_pace = 0
                last_rated_pace = time()
                sleep(self.cutoff_interval)

            now = time()
            if self.adapterIndex != None:
                t = now - last_temperature
                if temperature >= self.cutoff_temp or t > 1:
                    last_temperature = now
                    with adl_lock:
                        temperature = self.get_temperature()

            t = now - last_rated_pace
            if t > 1:
                rate = (threads_run_pace / t) / rate_divisor
                last_rated_pace = now
                threads_run_pace = 0
                r = last_hash_rate / rate
                if r < 0.9 or r > 1.1:
                    global_threads = max(
                        unit * int((rate * frame * rate_divisor) / unit), unit)
                    last_hash_rate = rate

            t = now - last_rated
            if t > self.options.rate:
                self.update_rate(now, threads_run, t, work.targetQ,
                                 rate_divisor)
                last_rated = now
                threads_run = 0

            queue.finish()
            cl.enqueue_copy(queue, output_buffer, output)
            queue.finish()

            if output[-1]:
                result = Object()
                result.header = work.header
                result.merkle_end = work.merkle_end
                result.time = work.time
                result.difficulty = work.difficulty
                result.target = work.target
                result.state = list(state)
                result.nonces = output[:]
                result.job_id = work.job_id
                result.extranonce2 = work.extranonce2
                result.transactions = work.transactions
                result.server = work.server
                result.miner = self
                self.switch.put(result)
                output[:] = b'\x00' * len(output)
                cl.enqueue_copy(queue, output, output_buffer)

            if not self.switch.update_time:
                if nonces_left < 3 * global_threads * self.frames:
                    self.update = True
                    nonces_left += 0xFFFFFFFFFFFF
                elif 0xFFFFFFFFFFF < nonces_left < 0xFFFFFFFFFFFF:
                    say_line('warning: job finished, %s is idle', self.id())
                    work = None
            elif now - last_n_time > 1:
                work.time = bytereverse(bytereverse(work.time) + 1)
                state2 = partial(state, work.merkle_end, work.time,
                                 work.difficulty, f)
                calculateF(state, work.merkle_end, work.time, work.difficulty,
                           f, state2)
                set_arg = self.kernel.set_arg
                set_arg(8, uint32_as_bytes(state2[1]))
                set_arg(9, uint32_as_bytes(state2[2]))
                set_arg(10, uint32_as_bytes(state2[3]))
                set_arg(11, uint32_as_bytes(state2[5]))
                set_arg(12, uint32_as_bytes(state2[6]))
                set_arg(13, uint32_as_bytes(state2[7]))
                set_arg(15, uint32_as_bytes(f[0]))
                set_arg(16, uint32_as_bytes(f[1]))
                set_arg(17, uint32_as_bytes(f[2]))
                set_arg(18, uint32_as_bytes(f[3]))
                set_arg(19, uint32_as_bytes(f[4]))
                last_n_time = now
                self.update_time_counter += 1
                if self.update_time_counter >= self.switch.max_update_time:
                    self.update = True
                    self.update_time_counter = 1
Esempio n. 44
0
    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()
Esempio n. 45
0
    def mining_thread(self):
        say_line('started OpenCL miner on platform %d, device %d (%s)',
                 (self.options.platform, self.device_idx, self.device_name))

        self.defines, rate_divisor, hashspace = (
            '-D VECTORS', 500, 0x7FFFFFFF
        ) if self.vectors else (
            '', 1000, 0xFFFFFFFF
        )

        self.defines += (
            f' -D OUTPUT_SIZE={self.output_size}'
            f' -D OUTPUT_MASK={self.output_size - 1}'
        )

        self.load_kernel()
        frame = 1.0 / max(self.frames, 3)
        unit = self.worksize * 256
        global_threads = unit * 10

        queue = cl.CommandQueue(self.context)

        last_rated_pace = last_rated = last_n_time = last_temperature = monotonic()
        base = last_hash_rate = threads_run_pace = threads_run = 0

        blank_output = b'\x00' * ((self.output_size + 1) * 4)
        host_output = bytearray(blank_output)
        cl_output = cl.Buffer(
            self.context,
            cl.mem_flags.WRITE_ONLY,
            size=len(host_output)
        )
        cl.enqueue_copy(queue, cl_output, blank_output)
        self.kernel.set_arg(20, cl_output)

        work = None
        temperature = 0
        while True:
            if self.should_stop:
                return

            sleep(self.frame_sleep)

            if (not work) or (not self.work_queue.empty()):
                try:
                    work = self.work_queue.get(True, 1)
                except Empty:
                    continue
                else:
                    if not work:
                        continue
                    nonces_left = hashspace
                    state = work.state
                    f = [0, 0, 0, 0, 0, 0, 0, 0]
                    state2 = partial(state, work.merkle_end, work.time,
                                     work.difficulty, f)
                    calculateF(state, work.merkle_end, work.time,
                               work.difficulty, f, state2)

                    set_arg = self.kernel.set_arg
                    set_arg(0, uint32_as_bytes(state[0]))
                    set_arg(1, uint32_as_bytes(state[1]))
                    set_arg(2, uint32_as_bytes(state[2]))
                    set_arg(3, uint32_as_bytes(state[3]))
                    set_arg(4, uint32_as_bytes(state[4]))
                    set_arg(5, uint32_as_bytes(state[5]))
                    set_arg(6, uint32_as_bytes(state[6]))
                    set_arg(7, uint32_as_bytes(state[7]))

                    set_arg(8, uint32_as_bytes(state2[1]))
                    set_arg(9, uint32_as_bytes(state2[2]))
                    set_arg(10, uint32_as_bytes(state2[3]))
                    set_arg(11, uint32_as_bytes(state2[5]))
                    set_arg(12, uint32_as_bytes(state2[6]))
                    set_arg(13, uint32_as_bytes(state2[7]))

                    set_arg(15, uint32_as_bytes(f[0]))
                    set_arg(16, uint32_as_bytes(f[1]))
                    set_arg(17, uint32_as_bytes(f[2]))
                    set_arg(18, uint32_as_bytes(f[3]))
                    set_arg(19, uint32_as_bytes(f[4]))

            if temperature < self.cutoff_temp:
                self.kernel.set_arg(14, uint32_as_bytes(base))
                cl.enqueue_nd_range_kernel(queue, self.kernel,
                                           (global_threads,), self.execution_local_dims)

                nonces_left -= global_threads
                threads_run_pace += global_threads
                threads_run += global_threads
                base = uint32(base + global_threads)
            else:
                threads_run_pace = 0
                last_rated_pace = monotonic()
                sleep(self.cutoff_interval)

            now = monotonic()
            if self.adapter_idx is not None:
                t = now - last_temperature
                if temperature >= self.cutoff_temp or t > 1:
                    last_temperature = now
                    with adl_lock:
                        temperature = self.get_temperature()

            t = now - last_rated_pace
            if t > 1:
                rate = (threads_run_pace / t) / rate_divisor
                last_rated_pace = now
                threads_run_pace = 0
                r = last_hash_rate / rate
                if r < 0.9 or r > 1.1:
                    global_threads = max(
                        unit * int((rate * frame * rate_divisor) / unit), unit)
                    last_hash_rate = rate

            t = now - last_rated
            if t > self.options.rate:
                self.update_rate(now, threads_run, t, work.targetQ,
                                 rate_divisor)
                last_rated = now
                threads_run = 0

            cl.enqueue_copy(queue, host_output, cl_output)
            queue.finish()

            if host_output[-1]:
                result = Object()
                result.header = work.header
                result.merkle_end = work.merkle_end
                result.time = work.time
                result.difficulty = work.difficulty
                result.target = work.target
                result.state = tuple(state)
                result.nonces = host_output[:]
                result.job_id = work.job_id
                result.extranonce2 = work.extranonce2
                result.transactions = work.transactions
                result.server = work.server
                result.miner = self
                self.switch.put(result)
                cl.enqueue_copy(queue, cl_output, blank_output)

            if not self.switch.update_time:
                if nonces_left < 3 * global_threads * self.frames:
                    self.update = True
                    nonces_left += 0xFFFFFFFFFFFF
                elif 0xFFFFFFFFFFF < nonces_left < 0xFFFFFFFFFFFF:
                    say_line('warning: job finished, %s is idle', self.id())
                    work = None
            elif now - last_n_time > 1:
                work.time = bytereverse(bytereverse(work.time) + 1)
                state2 = partial(state, work.merkle_end, work.time,
                                 work.difficulty, f)
                calculateF(state, work.merkle_end, work.time, work.difficulty,
                           f, state2)
                set_arg = self.kernel.set_arg
                set_arg(8, uint32_as_bytes(state2[1]))
                set_arg(9, uint32_as_bytes(state2[2]))
                set_arg(10, uint32_as_bytes(state2[3]))
                set_arg(11, uint32_as_bytes(state2[5]))
                set_arg(12, uint32_as_bytes(state2[6]))
                set_arg(13, uint32_as_bytes(state2[7]))
                set_arg(15, uint32_as_bytes(f[0]))
                set_arg(16, uint32_as_bytes(f[1]))
                set_arg(17, uint32_as_bytes(f[2]))
                set_arg(18, uint32_as_bytes(f[3]))
                set_arg(19, uint32_as_bytes(f[4]))
                last_n_time = now
                self.update_time_counter += 1
                if self.update_time_counter >= self.switch.max_update_time:
                    self.update = True
                    self.update_time_counter = 1