Skip to content

Commit

Permalink
use getwork only on explicit 'http';
Browse files Browse the repository at this point in the history
moved patch() from util to OpenCLMiner;
explicit use of '<' throughout
  • Loading branch information
m0mchil committed Mar 20, 2013
1 parent 886c4ab commit a5ab744
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 89 deletions.
4 changes: 2 additions & 2 deletions BFLMiner.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def put_job(self):
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)])
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
Expand Down Expand Up @@ -139,7 +139,7 @@ def nonce_generator(self, nonces):
for nonce in nonces.split(b','):
if len(nonce) != 8: continue
try:
yield unpack('I', nonce.decode('hex')[::-1])[0]
yield unpack('<I', nonce.decode('hex')[::-1])[0]
except error:
pass

Expand Down
2 changes: 1 addition & 1 deletion GetworkSource.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ def getwork(self, data=None):
say_exception()

def send_internal(self, result, nonce):
data = ''.join([result.header.encode('hex'), pack('III', long(result.time), long(result.difficulty), long(nonce)).encode('hex'), '000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000'])
data = ''.join([result.header.encode('hex'), pack('<3I', long(result.time), long(result.difficulty), long(nonce)).encode('hex'), '000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000'])
accepted = self.getwork(data)
if accepted != None:
self.switch.report(result.miner, nonce, accepted)
Expand Down
104 changes: 68 additions & 36 deletions OpenCLMiner.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
from hashlib import md5
from log import say_line
from sha256 import partial, calculateF
from struct import pack
from struct import pack, unpack, error
from threading import Lock
from time import sleep, time
from util import if_else, uint32, Object, bytereverse, patch, tokenize, bytearray_to_uint32
from util import if_else, uint32, Object, bytereverse, tokenize, \
bytearray_to_uint32
import sys


Expand Down Expand Up @@ -70,6 +71,7 @@ def shutdown():

def initialize(options):
if not OPENCL:
options.no_ocl = True
return []

options.worksize = tokenize(options.worksize, 'worksize')
Expand Down Expand Up @@ -183,30 +185,30 @@ def mining_thread(self):
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(0, pack('I', state[0]))
self.kernel.set_arg(1, pack('I', state[1]))
self.kernel.set_arg(2, pack('I', state[2]))
self.kernel.set_arg(3, pack('I', state[3]))
self.kernel.set_arg(4, pack('I', state[4]))
self.kernel.set_arg(5, pack('I', state[5]))
self.kernel.set_arg(6, pack('I', state[6]))
self.kernel.set_arg(7, pack('I', state[7]))

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

self.kernel.set_arg(15, pack('I', f[0]))
self.kernel.set_arg(16, pack('I', f[1]))
self.kernel.set_arg(17, pack('I', f[2]))
self.kernel.set_arg(18, pack('I', f[3]))
self.kernel.set_arg(19, pack('I', f[4]))
self.kernel.set_arg(0, pack('<I', state[0]))
self.kernel.set_arg(1, pack('<I', state[1]))
self.kernel.set_arg(2, pack('<I', state[2]))
self.kernel.set_arg(3, pack('<I', state[3]))
self.kernel.set_arg(4, pack('<I', state[4]))
self.kernel.set_arg(5, pack('<I', state[5]))
self.kernel.set_arg(6, pack('<I', state[6]))
self.kernel.set_arg(7, pack('<I', state[7]))

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

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

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

nonces_left -= global_threads
Expand Down Expand Up @@ -272,17 +274,17 @@ def mining_thread(self):
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, pack('I', state2[1]))
self.kernel.set_arg(9, pack('I', state2[2]))
self.kernel.set_arg(10, pack('I', state2[3]))
self.kernel.set_arg(11, pack('I', state2[5]))
self.kernel.set_arg(12, pack('I', state2[6]))
self.kernel.set_arg(13, pack('I', state2[7]))
self.kernel.set_arg(15, pack('I', f[0]))
self.kernel.set_arg(16, pack('I', f[1]))
self.kernel.set_arg(17, pack('I', f[2]))
self.kernel.set_arg(18, pack('I', f[3]))
self.kernel.set_arg(19, pack('I', f[4]))
self.kernel.set_arg(8, pack('<I', state2[1]))
self.kernel.set_arg(9, pack('<I', state2[2]))
self.kernel.set_arg(10, pack('<I', state2[3]))
self.kernel.set_arg(11, pack('<I', state2[5]))
self.kernel.set_arg(12, pack('<I', state2[6]))
self.kernel.set_arg(13, pack('<I', state2[7]))
self.kernel.set_arg(15, pack('<I', f[0]))
self.kernel.set_arg(16, pack('<I', f[1]))
self.kernel.set_arg(17, pack('<I', f[2]))
self.kernel.set_arg(18, pack('<I', f[3]))
self.kernel.set_arg(19, pack('<I', f[4]))
last_n_time = now
self.update_time_counter += 1
if self.update_time_counter >= self.switch.max_update_time:
Expand Down Expand Up @@ -321,7 +323,7 @@ def load_kernel(self):
except (IOError, cl.LogicError):
self.program = cl.Program(self.context, kernel).build(self.defines)
if (self.defines.find('-DBFI_INT') != -1):
patchedBinary = patch(self.program.binaries[0])
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])
Expand Down Expand Up @@ -382,3 +384,33 @@ def get_adapter_info(self):
adapter_info.append(AdapterInfoArray[device.AdapterIndex])

return adapter_info

def patch(self, data):
pos = data.find('\x7fELF', 1)
if pos != -1 and data.find('\x7fELF', pos+1) == -1:
data2 = data[pos:]
try:
(id, a, b, c, d, e, f, offset, g, h, i, j, entrySize, count, index) = unpack('QQHHIIIIIHHHHHH', data2[:52])
if id == 0x64010101464c457f and offset != 0:
(a, b, c, d, nameTableOffset, size, e, f, g, h) = unpack('IIIIIIIIII', data2[offset+index * entrySize : offset+(index+1) * entrySize])
header = data2[offset : offset+count * entrySize]
firstText = True
for i in xrange(count):
entry = header[i * entrySize : (i+1) * entrySize]
(nameIndex, a, b, c, offset, size, d, e, f, g) = unpack('IIIIIIIIII', entry)
nameOffset = nameTableOffset + nameIndex
name = data2[nameOffset : data2.find('\x00', nameOffset)]
if name == '.text':
if firstText: firstText = False
else:
data2 = data2[offset : offset + size]
patched = ''
for i in xrange(len(data2) / 8):
instruction, = unpack('Q', data2[i * 8 : i * 8 + 8])
if (instruction&0x9003f00002001000) == 0x0001a00000000000:
instruction ^= (0x0001a00000000000 ^ 0x0000c00000000000)
patched += pack('Q', instruction)
return ''.join([data[:pos+offset], patched, data[pos + offset + size:]])
except error:
pass
return data
8 changes: 3 additions & 5 deletions StratumSource.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,8 @@ def stop(self):
def refresh_job(self, j):
j.extranonce2 = self.increment_nonce(j.extranonce2)
coinbase = j.coinbase1 + self.extranonce + j.extranonce2 + j.coinbase2
coinbase_hash = sha256(sha256(unhexlify(coinbase)).digest()).digest()
merkle_root = sha256(sha256(unhexlify(coinbase)).digest()).digest()

merkle_root = coinbase_hash
for hash_ in j.merkle_branch:
merkle_root = sha256(sha256(merkle_root + unhexlify(hash_)).digest()).digest()
merkle_root_reversed = ''
Expand All @@ -146,7 +145,6 @@ def refresh_job(self, j):
j.block_header = ''.join([j.version, j.prevhash, merkle_root, j.ntime, j.nbits])
j.time = time()
return j


def increment_nonce(self, nonce):
next_nonce = long(nonce, 16) + 1
Expand Down Expand Up @@ -266,8 +264,8 @@ def send_internal(self, result, nonce):
if not job_id in self.jobs:
return True
extranonce2 = result.extranonce2
ntime = pack('I', long(result.time)).encode('hex')
hex_nonce = pack('I', long(nonce)).encode('hex')
ntime = pack('<I', long(result.time)).encode('hex')
hex_nonce = pack('<I', long(nonce)).encode('hex')
id_ = job_id + hex_nonce
self.submits[id_] = (result.miner, nonce, time())
return self.send_message({'params': [self.server().user, job_id, extranonce2, ntime, hex_nonce], 'id': id_, 'method': u'mining.submit'})
Expand Down
27 changes: 13 additions & 14 deletions Switch.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@

from copy import copy
from log import say_exception, say_line, say_quiet
from sha256 import hash, sha256, STATE
from struct import pack, unpack
from threading import RLock
from time import time, sleep
from util import if_else, Object, chunks, bytereverse, belowOrEquals, uint32
import GetworkSource
import StratumSource
import log
import socks
Expand Down Expand Up @@ -156,13 +154,13 @@ def decode(self, server, block_header, target, job_id = None, extranonce2 = None
job = Object()

binary_data = block_header.decode('hex')
data0 = list(unpack('16I', binary_data[:64])) + ([0] * 48)
data0 = list(unpack('<16I', binary_data[:64])) + ([0] * 48)

job.target = unpack('8I', target.decode('hex'))
job.target = unpack('<8I', target.decode('hex'))
job.header = binary_data[:68]
job.merkle_end = uint32(unpack('I', binary_data[64:68])[0])
job.time = uint32(unpack('I', binary_data[68:72])[0])
job.difficulty = uint32(unpack('I', binary_data[72:76])[0])
job.merkle_end = uint32(unpack('<I', binary_data[64:68])[0])
job.time = uint32(unpack('<I', binary_data[68:72])[0])
job.difficulty = uint32(unpack('<I', binary_data[72:76])[0])
job.state = sha256(STATE, data0)
job.targetQ = 2**256 / int(''.join(list(chunks(target, 2))[::-1]), 16)
job.job_id = job_id
Expand All @@ -179,21 +177,21 @@ def set_difficulty(self, difficulty):
bits = '%08x' % bytereverse(difficulty)
true_target = '%064x' % (int(bits[2:], 16) * 2 ** (8 * (int(bits[:2], 16) - 3)),)
true_target = ''.join(list(chunks(true_target, 2))[::-1])
self.true_target = unpack('8I', true_target.decode('hex'))
self.true_target = unpack('<8I', true_target.decode('hex'))

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')
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')
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
Expand Down Expand Up @@ -265,9 +263,8 @@ def clear_result_queue(self, server):

def server_source(self):
if not hasattr(self.server(), 'source'):
if self.server().proto == 'stratum':
self.add_stratum_source()
else:
if self.server().proto == 'http':
import GetworkSource
getwork_source = GetworkSource.GetworkSource(self)
say_line('checking for stratum...')

Expand All @@ -279,6 +276,8 @@ def server_source(self):
self.add_stratum_source()
else:
self.server().source = getwork_source
else:
self.add_stratum_source()

return self.server().source

Expand Down
31 changes: 0 additions & 31 deletions util.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from log import say_exception
from struct import pack, unpack, error
import sys

class Object(object):
Expand Down Expand Up @@ -41,33 +40,3 @@ def tokenize(option, name, default=[0], cast=int):
say_exception('Invalid %s(s) specified: %s\n\n' % (name, option))
sys.exit()
return default

def patch(data):
pos = data.find('\x7fELF', 1)
if pos != -1 and data.find('\x7fELF', pos+1) == -1:
data2 = data[pos:]
try:
(id, a, b, c, d, e, f, offset, g, h, i, j, entrySize, count, index) = unpack('QQHHIIIIIHHHHHH', data2[:52])
if id == 0x64010101464c457f and offset != 0:
(a, b, c, d, nameTableOffset, size, e, f, g, h) = unpack('IIIIIIIIII', data2[offset+index * entrySize : offset+(index+1) * entrySize])
header = data2[offset : offset+count * entrySize]
firstText = True
for i in xrange(count):
entry = header[i * entrySize : (i+1) * entrySize]
(nameIndex, a, b, c, offset, size, d, e, f, g) = unpack('IIIIIIIIII', entry)
nameOffset = nameTableOffset + nameIndex
name = data2[nameOffset : data2.find('\x00', nameOffset)]
if name == '.text':
if firstText: firstText = False
else:
data2 = data2[offset : offset + size]
patched = ''
for i in xrange(len(data2) / 8):
instruction, = unpack('Q', data2[i * 8 : i * 8 + 8])
if (instruction&0x9003f00002001000) == 0x0001a00000000000:
instruction ^= (0x0001a00000000000 ^ 0x0000c00000000000)
patched += pack('Q', instruction)
return ''.join([data[:pos+offset], patched, data[pos + offset + size:]])
except error:
pass
return data

0 comments on commit a5ab744

Please sign in to comment.