Пример #1
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])
Пример #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
Пример #3
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 == httplib.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 == httplib.TEMPORARY_REDIRECT:
				response.read()
				url = response.getheader('Location', '')
				if r == 0 or url == '': raise 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
Пример #4
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]
Пример #5
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
Пример #6
0
	def __init__(self, options):
		self.lock = RLock()
		self.miners = []
		self.options = options
		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 = 'poclbm/' + 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.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
Пример #7
0
    def __init__(self, options):
        self.lock = RLock()
        self.miners = []
        self.options = options
        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 = 'poclbm/' + 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.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
Пример #8
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()
Пример #9
0
	def report(self, miner, nonce, accepted):
		is_block, hash6, hash5 = self.sent[nonce]
		miner.share_count[if_else(accepted, 1, 0)] += 1
		hash_ = if_else(is_block, hash6 + hash5, hash6)
		if self.options.verbose or is_block:
			say_line('%s %s%s, %s', (miner.id(), if_else(is_block, 'block ', ''), hash_, if_else(accepted, 'accepted', '_rejected_')))
		del self.sent[nonce]
Пример #10
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]
Пример #11
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 == httplib.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 == httplib.TEMPORARY_REDIRECT:
				response.read()
				url = response.getheader('Location', '')
				if r == 0 or url == '': raise 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
Пример #12
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 = pack('<I', long(h[6])).encode('hex')
				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 = pack('<I', long(h[6])).encode('hex')
					hash5 = pack('<I', long(h[5])).encode('hex')
					self.sent[nonce] = (is_block, hash6, hash5)
					ntime = long(pack('<I', long(result.time)).encode('hex'),16)
					resnonce = long(pack('<I', long(nonce)).encode('hex'),16)
					block = self.source.create_block_header(self.source.merkle_root, ntime, self.source.bits, resnonce)
					hash_header = hashlib.sha256(hashlib.sha256(block).digest()).digest()[::-1]
					shouldSend = int(hash_header.encode('hex_codec'), 16) < self.source.server_difficulty
					print "t->" + str(ntime) + " nonce->" + str(resnonce) + " shouldSend->" + str(shouldSend)
					if shouldSend:
						if not send_callback(result, nonce):
							return False

		return True
Пример #13
0
	def report(self, miner, nonce, accepted):
		is_block, hash6, hash5 = self.sent[nonce]
		miner.share_count[if_else(accepted, 1, 0)] += 1
		hash_ = if_else(is_block, hash6 + hash5, hash6)
		if self.options.verbose or is_block:
			say_line('%s %s%s, %s', (miner.id(), if_else(is_block, 'block ', ''), hash_, if_else(accepted, 'accepted', '_rejected_')))
		del self.sent[nonce]
Пример #14
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()
Пример #15
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()
                    elif not self.suggest_difficulty(128):
                        say_line('Failed to suggest_difficulty')

                except socket.error:
                    say_exception()
                    self.stop()
                    continue

            with self.send_lock:
                self.process_result_queue()
            sleep(1)
Пример #16
0
	def check_result(self):
		response = request(self.device, b'ZFX')
		if response[0] == 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]
Пример #17
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)
Пример #18
0
    def load_kernel(self):
        self.context = cl.Context([self.device], None, None)
        if self.device.extensions.find('cl_amd_media_ops') != -1:
            self.defines += ' -DBITALIGN'
            if self.device_name in ['Cedar',
                                    'Redwood',
                                    'Juniper',
                                    'Cypress',
                                    'Hemlock',
                                    'Caicos',
                                    'Turks',
                                    'Barts',
                                    'Cayman',
                                    'Antilles',
                                    'Wrestler',
                                    'Zacate',
                                    'WinterPark',
                                    'BeaverCreek']:
                self.defines += ' -DBFI_INT'

        kernel_file = open('skein.cl', 'r')
        kernel = kernel_file.read()
        kernel_file.close()
        m = md5(); m.update(''.join([self.device.platform.name, self.device.platform.version, self.device.name, self.defines, kernel]))
        cache_name = '%s.elf' % m.hexdigest()
        binary = None
        
        compile = False
        
        try:
            binary = open(cache_name, 'rb')
            self.program = cl.Program(self.context, [self.device], [binary.read()]).build(self.defines)
            say_line("Loaded existing compiled kernel: %s", cache_name)
        except (IOError, cl.LogicError) as e:
            say_line("Error loading compiled kernel: %s", cache_name)
            say_line("Recompiling kernel ...")
            compile = True
        finally:
            if binary: binary.close()
            
        if compile:
            self.program = cl.Program(self.context, kernel).build(self.defines)
            if self.defines.find('-DBFI_INT') != -1:
                patchedBinary = self.patch(self.program.binaries[0])
                self.program = cl.Program(self.context, [self.device], [patchedBinary]).build(self.defines)
            binaryW = open(cache_name, 'wb')
            binaryW.write(self.program.binaries[0])
            binaryW.close()
            say_line("Compiled kernel: %s", cache_name)

        self.kernel = self.program.search

        if not self.worksize:
            self.worksize = self.kernel.get_work_group_info(cl.kernel_work_group_info.WORK_GROUP_SIZE, self.device)
            say_line("Worksize: %d" % self.worksize)
Пример #19
0
	def add_stratum_source(self):
		if self.options.stratum_proxies:
			stratum_proxy = StratumSource.detect_stratum_proxy(self.server().host)
			if stratum_proxy:
				original_server = copy(self.server())
				original_server.source = StratumSource.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 = StratumSource.StratumSource(self)
Пример #20
0
	def add_stratum_source(self):
		if self.options.stratum_proxies:
			stratum_proxy = StratumSource.detect_stratum_proxy(self.server().host)
			if stratum_proxy:
				original_server = copy(self.server())
				original_server.source = StratumSource.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 = StratumSource.StratumSource(self)
Пример #21
0
 def queue_kernel_parameters(self, work):
     state = skeinhashmid(pack('>16I', *work.dataX[:16]))
     
     for i in xrange(8):
         self.kernel.set_arg(i, state[i * 8:i * 8 + 8])
         
     for i in range(16, 19):
         self.kernel.set_arg(i - 8, pack('>I', work.dataX[i]))
         
     if work.target[6] != self.target6 or work.target[7] != self.target7:
         say_line("Calling with tgt %.8x %.8x", (work.target[6], work.target[7]))
         self.target6 = work.target[6]
         self.target7 = work.target[7]
Пример #22
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
Пример #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 = pack('I', long(h[6])).encode('hex')
				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 = pack('I', long(h[6])).encode('hex')
					hash5 = pack('I', long(h[5])).encode('hex')
					self.sent[nonce] = (is_block, hash6, hash5)
					if not send_callback(result, nonce):
						return False
		return True
Пример #24
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 = pack('I', long(h[6])).encode('hex')
				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 = pack('I', long(h[6])).encode('hex')
					hash5 = pack('I', long(h[5])).encode('hex')
					self.sent[nonce] = (is_block, hash6, hash5)
					if not send_callback(result, nonce):
						return False
		return True
Пример #25
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, httplib.HTTPException, ValueError,
                        socks.ProxyError, NotAuthorized, RPCError):
                    say_exception('long poll IO error')
                    self.close_lp_connection()
                    sleep(.5)
                except Exception:
                    say_exception()
Пример #26
0
    def server_source(self):
        if not hasattr(self.server(), 'source'):
            if self.server().proto == 'stratum':
                self.add_stratum_source()
            else:
                getwork_source = GetworkSource.GetworkSource(self)
                say_line('checking for stratum...')

                stratum_host = getwork_source.detect_stratum()
                if stratum_host:
                    getwork_source.close_connection()
                    self.server().proto = 'stratum'
                    self.server().host = stratum_host
                    self.add_stratum_source()
                else:
                    self.server().source = getwork_source

        return self.server().source
Пример #27
0
	def server_source(self):
		if not hasattr(self.server(), 'source'):
			if self.server().proto == 'stratum':
				self.add_stratum_source()
			else:
				getwork_source = GetworkSource.GetworkSource(self)
				say_line('checking for stratum...')

				stratum_host = getwork_source.detect_stratum()
				if stratum_host:
					getwork_source.close_connection()
					self.server().proto = 'stratum'
					self.server().host = stratum_host
					self.add_stratum_source()
				else:
					self.server().source = getwork_source

		return self.server().source
Пример #28
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, httplib.HTTPException, ValueError, socks.ProxyError, NotAuthorized, RPCError):
					say_exception('long poll IO error')
					self.close_lp_connection()
					sleep(.5)
				except Exception:
					say_exception()
Пример #29
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)
         hx = ''.join(pack('>19I', *result.dataX))
         qh = skeinhash(''.join([hx, pack('>I', long(nonce))]))
         h = unpack('>8I', qh)
         #if h[6] & 0xf == 0:
         #    say_line('Nonce: %08x, hash: %s, h6: %08x', (nonce, qh.encode('hex'), h[6]))
         if qh[-3:] != '\x00\x00\x00':
             hash7 = pack('<I', long(h[7])).encode('hex')
             say_line('Verification failed, check hardware! (%s, %s, %08x)', (result.miner.id(), hash7, nonce))
             say_line('data %s' % ''.join([hx, pack('>I', long(nonce))]).encode('hex'))
             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 = pack('<I', long(h[6])).encode('hex')
                 hash5 = pack('<I', long(h[5])).encode('hex')
                 self.sent[nonce] = (is_block, hash6, hash5)
                 if not send_callback(result, nonce):
                     return False
     return True
Пример #30
0
    def loop(self):
        self.should_stop = False
        if not self.servers:
            print '\nAt least one server is required'
            return
        else:
            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)
Пример #31
0
	def loop(self):
		self.should_stop = False
		if not self.servers:
			print '\nAt least one server is required'
			return
		else:
			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)
Пример #32
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 == False):
                devices.append(deviceAdapter(index, adapterID, busNum, udid))

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

        return adapter_info
Пример #33
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(long(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())
Пример #34
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_Active_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 == False):
				devices.append(deviceAdapter(index, adapterID, busNum, udid))

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

		return adapter_info
Пример #35
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
Пример #36
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
Пример #37
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 = (np.uint32(time()) - self.job.time_delta).byteswap()
				data = b''.join([self.job.state.tostring(), self.job.merkle_end.tostring(), self.job.time.tostring(), self.job.difficulty.tostring()])
				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 self.job.time.byteswap() - self.job.original_time.byteswap() > 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())
Пример #38
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 = np.uint32(time()) - self.job.time.byteswap()
		
					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)
Пример #39
0
	def diff1_found(self, hash_, target):
		if self.options.verbose and target < 0xFFFF0000L:
			say_line('checking %s <= %s', (hash_, target))
Пример #40
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.nodelay_socket(
                            socket.AF_INET, socket.SOCK_STREAM)
                        self.socket.connect((address, int(port)))
                    else:
                        proxy_proto, user, pwd, proxy_host = self.options.proxy[:
                                                                                4]
                        proxy_port = 9050
                        proxy_host = proxy_host.split(':')
                        if len(proxy_host) > 1:
                            proxy_port = int(proxy_host[1])
                            proxy_host = proxy_host[0]

                        self.socket = socks.socksocket()

                        proxy_type = socks.PROXY_TYPE_SOCKS5
                        if proxy_proto == 'http':
                            proxy_type = socks.PROXY_TYPE_HTTP
                        elif proxy_proto == 'socks4':
                            proxy_type = socks.PROXY_TYPE_SOCKS4

                        self.socket.setproxy(proxy_type, proxy_host,
                                             proxy_port, True, user, 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)
Пример #41
0
 def reconnect(self):
     say_line("%s reconnecting to %s",
              (self.server().name, self.server().host))
     self.handler.close()
Пример #42
0
	def get_temperature(self):
		response = request(self.device, b'ZLX')
		if response[0] != b'T' or len(response) < 23 or response[-1:] != b'\n':
			say_line('%s: bad response for temperature: %s', (self.id(), response))
			return 0
		return float(response[23:-1])
Пример #43
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 = 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
Пример #44
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) = if_else(self.vectors, ('-DVECTORS', 500, 0x7FFFFFFF), ('', 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 = np.zeros(self.output_size + 1, np.uint32)
		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
					state2 = work.state2
					f = work.f

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

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

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

			if temperature < self.cutoff_temp:
				self.kernel.set_arg(14, pack('I', 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_read_buffer(queue, output_buffer, output)
			queue.finish()

			if output[self.output_size]:
				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 = np.array(state)
				result.nonces = np.array(output)
				result.job_id = work.job_id
				result.extranonce2 = work.extranonce2
				result.server = work.server
				result.miner = self
				self.switch.put(result)
				output.fill(0)
				cl.enqueue_write_buffer(queue, output_buffer, 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)
				self.kernel.set_arg(8, state2[1])
				self.kernel.set_arg(9, state2[2])
				self.kernel.set_arg(10, state2[3])
				self.kernel.set_arg(11, state2[5])
				self.kernel.set_arg(12, state2[6])
				self.kernel.set_arg(13, state2[7])
				self.kernel.set_arg(15, f[0])
				self.kernel.set_arg(16, f[1])
				self.kernel.set_arg(17, f[2])
				self.kernel.set_arg(18, f[3])
				self.kernel.set_arg(19, 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
Пример #45
0
	def reconnect(self):
		say_line("%s reconnecting to %s", (self.server().name, self.server().host))
		self.handler.close()
Пример #46
0
 def diff1_found(self, hash_, target):
     if self.options.verbose and target < 0xFFFF0000L:
         say_line('checking %s <= %s', (hash_, target))
Пример #47
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 = 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
Пример #48
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) = ('', 1000, 0xFFFFFFFF)
        self.defines += (' -D%sOUTPUT_SIZE=%s' % (self.defspace, str(self.output_size)))
        self.defines += (' -D%sOUTPUT_MASK=%s' % (self.defspace, str(self.output_size - 1)))
        self.defines += (' -D%sENDIAN_LITTLE=%d' % (self.defspace, self.device.endian_little))
        self.defines += (' -D%sGPU_AMD=%d' % (self.defspace, self.gpu_amd))
        self.defines += (' -I%s%s' % (self.defspace, os.getcwd()))

        say_line("Compiler defines: %s", self.defines)

        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(12, 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

                    self.queue_kernel_parameters(work)

            if temperature < self.cutoff_temp:
                self.kernel.set_arg(11, pack('<I', 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 is not None:
                t = now - last_temperature
                if temperature >= self.cutoff_temp or t > 1:
                    last_temperature = now
                    with adl_lock:
                        self.temperature = self.get_temperature()
                        temperature = self.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_read_buffer(queue, output_buffer, output)
            queue.finish()

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

                for miner in self.switch.miners:
                    miner.update = True

            if not self.switch.update_time:
                if nonces_left < 6 * 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:
                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