Guest User

Untitled

a guest
Jan 16th, 2011
374
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 24.14 KB | None | 0 0
  1. diff --git a/BitcoinMiner.py b/BitcoinMiner.py
  2. index 728c0fa..638e11d 100644
  3. --- a/BitcoinMiner.py
  4. +++ b/BitcoinMiner.py
  5. @@ -1,11 +1,13 @@
  6.  import sys
  7.  import numpy as np
  8.  import pyopencl as cl
  9. +import socket
  10. +import bitcoin
  11.  
  12.  from struct import *
  13.  from Queue import Queue
  14.  from Queue import Empty
  15. -from threading import Thread
  16. +from threading import Thread, Event
  17.  from time import sleep, time
  18.  from datetime import datetime
  19.  from jsonrpc import ServiceProxy
  20. @@ -31,7 +33,7 @@ def if_else(condition, trueVal, falseVal):
  21.         return falseVal
  22.  
  23.  class BitcoinMiner(Thread):
  24. -   def __init__(self, platform, context, host, user, password, port=8332, frames=60, rate=1, askrate=5, worksize=-1, vectors=False):
  25. +   def __init__(self, platform, context, device, host, user, password, port=8332, frames=60, rate=1, askrate=5, worksize=-1, vectors=False):
  26.         Thread.__init__(self)
  27.         (defines, self.rateDivisor) = if_else(vectors, ('-DVECTORS', 500), ('', 1000))
  28.  
  29. @@ -41,10 +43,13 @@ class BitcoinMiner(Thread):
  30.         self.askrate = min(self.askrate, 10)
  31.         self.worksize = int(worksize)
  32.         self.frames = max(frames, 1)
  33. +       self.device = device
  34. +       self.hostname = socket.gethostname()
  35. +       self.logfile = "%s-%i.log" % (self.hostname, self.device)
  36. +       self.statusfile = "%s-%i.hashrate" % (self.hostname, self.device)
  37. +       self.sh = open(self.statusfile, "w")
  38. +       self.hashrate = None
  39.  
  40. -       if (self.context.devices[0].extensions.find('cl_amd_media_ops') != -1):
  41. -           defines += ' -DBITALIGN'
  42. -          
  43.         kernelFile = open('BitcoinMiner.cl', 'r')
  44.         self.miner = cl.Program(self.context, kernelFile.read()).build(defines)
  45.         kernelFile.close()
  46. @@ -56,6 +61,11 @@ class BitcoinMiner(Thread):
  47.         self.resultQueue = Queue()
  48.  
  49.         self.bitcoin = ServiceProxy('http://%s:%s@%s:%s' % (user, password, host, port))
  50. +       self.node = Node(host, 8333)
  51. +
  52. +       self.node.newblock.set()
  53. +
  54. +       self.node.start()
  55.  
  56.     def say(self, format, args=()):
  57.         sys.stdout.write('\r                                        \r' + format % args)
  58. @@ -63,6 +73,11 @@ class BitcoinMiner(Thread):
  59.  
  60.     def sayLine(self, format, args=()):
  61.         self.say(format + '\n', args)
  62. +       formatted_line = format % args
  63. +       line = "%s-%i %s\n" % (self.hostname, self.device, formatted_line)
  64. +       fh = open(self.logfile, "a")
  65. +       fh.write(line)
  66. +       fh.close()
  67.  
  68.     def blockFound(self, hash, accepted):
  69.         # designed to be overridden
  70. @@ -70,6 +85,7 @@ class BitcoinMiner(Thread):
  71.  
  72.     def getwork(self, data=None):
  73.         try:
  74. +           print "\ngetwork"
  75.             if data:
  76.                 return self.bitcoin.getwork(data)
  77.             else:
  78. @@ -94,7 +110,8 @@ class BitcoinMiner(Thread):
  79.                 except Empty:
  80.                     pass
  81.  
  82. -               if result or (time() - lastWork > self.askrate):
  83. +               if result or self.node.newblock.isSet():
  84. +                   self.node.newblock.clear()
  85.                     self.workQueue.put(work)
  86.                     lastWork = time()
  87.                     work = None
  88. @@ -108,6 +125,12 @@ class BitcoinMiner(Thread):
  89.             print '\nbye'
  90.             sleep(1.1)
  91.  
  92. +   def dumpHashrate(self):
  93. +       self.sh.seek(0)
  94. +       self.sh.write(self.hashrate)
  95. +       self.sh.truncate(len(self.hashrate))
  96. +       self.sh.flush()
  97. +
  98.     def run(self):
  99.         frame = float(1)/float(self.frames)
  100.         window = frame/30
  101. @@ -124,6 +147,7 @@ class BitcoinMiner(Thread):
  102.         output_buf = cl.Buffer(self.context, cl.mem_flags.WRITE_ONLY | cl.mem_flags.USE_HOST_PTR, hostbuf=output)
  103.  
  104.         work = None
  105. +       hashstring = None
  106.         while True:
  107.             if (not work) or (not self.workQueue.empty()):
  108.                 try:
  109. @@ -134,6 +158,8 @@ class BitcoinMiner(Thread):
  110.                     if not work:
  111.                         continue
  112.                     elif work == 'stop':
  113. +                       self.node.stop()
  114. +                       self.node.join()
  115.                         return
  116.                     try:
  117.                         data   = np.array(unpack('IIIIIIIIIIIIIIII', work['data'][128:].decode('hex')), dtype=np.uint32)
  118. @@ -153,10 +179,14 @@ class BitcoinMiner(Thread):
  119.                                 state[0], state[1], state[2], state[3], state[4], state[5], state[6], state[7],
  120.                                 state2[1], state2[2], state2[3], state2[5], state2[6], state2[7],
  121.                                 target[6], target[7], pack('I', base), output_buf)
  122. +
  123.             cl.enqueue_read_buffer(queue, output_buf, output)
  124.  
  125.             if (time() - lastRate > self.rate):
  126. -               self.say('%s khash/s', int((threadsRun / (time() - lastRate)) / self.rateDivisor))
  127. +               hashrate = int((threadsRun / (time() - lastRate)) / self.rateDivisor)
  128. +               self.hashrate = "%i khash/s" % hashrate
  129. +               self.say(self.hashrate)
  130. +               Thread(target = self.dumpHashrate).start()
  131.                 threadsRun = 0
  132.                 lastRate = time()
  133.  
  134. @@ -179,4 +209,17 @@ class BitcoinMiner(Thread):
  135.                 result['hash'] = output[0]
  136.                 self.resultQueue.put(result)
  137.                 output[0] = 0
  138. -               cl.enqueue_write_buffer(queue, output_buf, output)
  139. \ No newline at end of file
  140. +               cl.enqueue_write_buffer(queue, output_buf, output)
  141. +
  142. +class Node(bitcoin.BitcoinNode):
  143. +   def __init__(self, dstaddr, dstport):
  144. +       self.__parent = super(Node, self)
  145. +       self.__parent.__init__(dstaddr, dstport)
  146. +       self.newblock = Event()
  147. +
  148. +   def do_tx(self, message):
  149. +       self.newblock.set()
  150. +
  151. +   def do_block(self, message):
  152. +       self.newblock.set()
  153. +
  154. diff --git a/bitcoin.py b/bitcoin.py
  155. new file mode 100755
  156. index 0000000..5ac1e44
  157. --- /dev/null
  158. +++ b/bitcoin.py
  159. @@ -0,0 +1,673 @@
  160. +#!/usr/bin/python
  161. +# Public Domain
  162. +
  163. +import struct
  164. +import threading
  165. +import select
  166. +import socket
  167. +import asyncore
  168. +import binascii
  169. +import time
  170. +import sys
  171. +import random
  172. +import cStringIO
  173. +from Crypto.Hash import SHA256
  174. +
  175. +MY_VERSION = 312
  176. +MY_SUBVERSION = ".4"
  177. +
  178. +Cs = 0
  179. +
  180. +def deser_string(f):
  181. +   nit = struct.unpack("<B", f.read(1))[0]
  182. +   if nit == 253:
  183. +       nit = struct.unpack("<H", f.read(2))[0]
  184. +   elif nit == 254:
  185. +       nit = struct.unpack("<I", f.read(4))[0]
  186. +   elif nit == 255:
  187. +       nit = struct.unpack("<Q", f.read(8))[0]
  188. +   return f.read(nit)
  189. +
  190. +def ser_string(s):
  191. +   if len(s) < 253:
  192. +       return chr(len(s)) + s
  193. +   elif len(s) < 0x10000:
  194. +       return chr(253) + struct.pack("<H", len(s)) + s
  195. +   elif len(s) < 0x100000000L:
  196. +       return chr(254) + struct.pack("<I", len(s)) + s
  197. +   return chr(255) + struct.pack("<Q", len(s)) + s
  198. +
  199. +def deser_uint256(f):
  200. +   r = 0L
  201. +   for i in xrange(8):
  202. +       t = struct.unpack("<I", f.read(4))[0]
  203. +       r += t << (i * 32)
  204. +   return r
  205. +
  206. +def ser_uint256(u):
  207. +   rs = ""
  208. +   for i in xrange(8):
  209. +       rs += struct.pack("<I", u & 0xFFFFFFFFL)
  210. +       u >>= 32
  211. +   return rs
  212. +
  213. +def uint256_from_str(s):
  214. +   r = 0L
  215. +   t = struct.unpack("<IIIIIIII", s[:32])
  216. +   for i in xrange(8):
  217. +       r += t[i] << (i * 32)
  218. +   return r
  219. +
  220. +def uint256_from_compact(c):
  221. +   nbytes = (c >> 24) & 0xFF
  222. +   v = (c & 0xFFFFFFL) << (8 * (nbytes - 3))
  223. +   return v
  224. +
  225. +def deser_vector(f, c):
  226. +   nit = struct.unpack("<B", f.read(1))[0]
  227. +   if nit == 253:
  228. +       nit = struct.unpack("<H", f.read(2))[0]
  229. +   elif nit == 254:
  230. +       nit = struct.unpack("<I", f.read(4))[0]
  231. +   elif nit == 255:
  232. +       nit = struct.unpack("<Q", f.read(8))[0]
  233. +   r = []
  234. +   for i in xrange(nit):
  235. +       t = c()
  236. +       t.deserialize(f)
  237. +       r.append(t)
  238. +   return r
  239. +
  240. +def ser_vector(l):
  241. +   r = ""
  242. +   if len(l) < 253:
  243. +       r = chr(len(l))
  244. +   elif len(l) < 0x10000:
  245. +       r = chr(253) + struct.pack("<H", len(l))
  246. +   elif len(l) < 0x100000000L:
  247. +       r = chr(254) + struct.pack("<I", len(l))
  248. +   else:
  249. +       r = chr(255) + struct.pack("<Q", len(l))
  250. +   for i in l:
  251. +       r += i.serialize()
  252. +   return r
  253. +
  254. +def deser_uint256_vector(f):
  255. +   nit = struct.unpack("<B", f.read(1))[0]
  256. +   if nit == 253:
  257. +       nit = struct.unpack("<H", f.read(2))[0]
  258. +   elif nit == 254:
  259. +       nit = struct.unpack("<I", f.read(4))[0]
  260. +   elif nit == 255:
  261. +       nit = struct.unpack("<Q", f.read(8))[0]
  262. +   r = []
  263. +   for i in xrange(nit):
  264. +       t = deser_uint256(f)
  265. +       r.append(t)
  266. +   return r
  267. +
  268. +def ser_uint256_vector(l):
  269. +   r = ""
  270. +   if len(l) < 253:
  271. +       r = chr(len(l))
  272. +   elif len(s) < 0x10000:
  273. +       r = chr(253) + struct.pack("<H", len(l))
  274. +   elif len(s) < 0x100000000L:
  275. +       r = chr(254) + struct.pack("<I", len(l))
  276. +   else:
  277. +       r = chr(255) + struct.pack("<Q", len(l))
  278. +   for i in l:
  279. +       r += ser_uint256(i)
  280. +   return r
  281. +
  282. +class CAddress(object):
  283. +   def __init__(self):
  284. +       self.nServices = 1
  285. +       self.pchReserved = "\x00" * 10 + "\xff" * 2
  286. +       self.ip = "0.0.0.0"
  287. +       self.port = 0
  288. +   def deserialize(self, f):
  289. +       self.nServices = struct.unpack("<Q", f.read(8))[0]
  290. +       self.pchReserved = f.read(12)
  291. +       self.ip = socket.inet_ntoa(f.read(4))
  292. +       self.port = struct.unpack(">H", f.read(2))[0]
  293. +   def serialize(self):
  294. +       r = ""
  295. +       r += struct.pack("<Q", self.nServices)
  296. +       r += self.pchReserved
  297. +       r += socket.inet_aton(self.ip)
  298. +       r += struct.pack(">H", self.port)
  299. +       return r
  300. +   def __repr__(self):
  301. +       return "CAddress(nServices=%i ip=%s port=%i)" % (self.nServices, self.ip, self.port)
  302. +
  303. +class CInv(object):
  304. +   typemap = {
  305. +       0: "Error",
  306. +       1: "TX",
  307. +       2: "Block"}
  308. +   def __init__(self):
  309. +       self.type = 0
  310. +       self.hash = 0L
  311. +   def deserialize(self, f):
  312. +       self.type = struct.unpack("<i", f.read(4))[0]
  313. +       self.hash = deser_uint256(f)
  314. +   def serialize(self):
  315. +       r = ""
  316. +       r += struct.pack("<i", self.type)
  317. +       r += ser_uint256(self.hash)
  318. +       return r
  319. +   def __repr__(self):
  320. +       return "CInv(type=%s hash=%064x)" % (self.typemap[self.type], self.hash)
  321. +
  322. +class CBlockLocator(object):
  323. +   def __init__(self):
  324. +       self.nVersion = MY_VERSION
  325. +       self.vHave = []
  326. +   def deserialize(self, f):
  327. +       self.nVersion = struct.unpack("<i", f.read(4))[0]
  328. +       self.vHave = deser_uint256_vector(f)
  329. +   def serialize(self):
  330. +       r = ""
  331. +       r += struct.pack("<i", self.nVersion)
  332. +       r += ser_uint256_vector(self.vHave)
  333. +       return r
  334. +   def __repr__(self):
  335. +       return "CBlockLocator(nVersion=%i vHave=%s)" % (self.nVersion, repr(self.vHave))
  336. +
  337. +class COutPoint(object):
  338. +   def __init__(self):
  339. +       self.hash = 0
  340. +       self.n = 0
  341. +   def deserialize(self, f):
  342. +       self.hash = deser_uint256(f)
  343. +       self.n = struct.unpack("<I", f.read(4))[0]
  344. +   def serialize(self):
  345. +       r = ""
  346. +       r += ser_uint256(self.hash)
  347. +       r += struct.pack("<I", self.n)
  348. +       return r
  349. +   def __repr__(self):
  350. +       return "COutPoint(hash=%064x n=%i)" % (self.hash, self.n)
  351. +
  352. +class CTxIn(object):
  353. +   def __init__(self):
  354. +       self.prevout = COutPoint()
  355. +       self.scriptSig = ""
  356. +       self.nSequence = 0
  357. +   def deserialize(self, f):
  358. +       self.prevout = COutPoint()
  359. +       self.prevout.deserialize(f)
  360. +       self.scriptSig = deser_string(f)
  361. +       self.nSequence = struct.unpack("<I", f.read(4))[0]
  362. +   def serialize(self):
  363. +       r = ""
  364. +       r += self.prevout.serialize()
  365. +       r += ser_string(self.scriptSig)
  366. +       r += struct.pack("<I", self.nSequence)
  367. +       return r
  368. +   def __repr__(self):
  369. +       return "CTxIn(prevout=%s scriptSig=%s nSequence=%i)" % (repr(self.prevout), binascii.hexlify(self.scriptSig), self.nSequence)
  370. +
  371. +class CTxOut(object):
  372. +   def __init__(self):
  373. +       self.nValue = 0
  374. +       self.scriptPubKey = ""
  375. +   def deserialize(self, f):
  376. +       self.nValue = struct.unpack("<q", f.read(8))[0]
  377. +       self.scriptPubKey = deser_string(f)
  378. +   def serialize(self):
  379. +       r = ""
  380. +       r += struct.pack("<q", self.nValue)
  381. +       r += ser_string(self.scriptPubKey)
  382. +       return r
  383. +   def __repr__(self):
  384. +       return "CTxOut(nValue=%i.%08i scriptPubKey=%s)" % (self.nValue // 100000000, self.nValue % 100000000, binascii.hexlify(self.scriptPubKey))
  385. +
  386. +class CTransaction(object):
  387. +   def __init__(self):
  388. +       self.nVersion = 1
  389. +       self.vin = []
  390. +       self.vout = []
  391. +       self.nLockTime = 0
  392. +       self.sha256 = None
  393. +   def deserialize(self, f):
  394. +       self.nVersion = struct.unpack("<i", f.read(4))[0]
  395. +       self.vin = deser_vector(f, CTxIn)
  396. +       self.vout = deser_vector(f, CTxOut)
  397. +       self.nLockTime = struct.unpack("<I", f.read(4))[0]
  398. +   def serialize(self):
  399. +       r = ""
  400. +       r += struct.pack("<i", self.nVersion)
  401. +       r += ser_vector(self.vin)
  402. +       r += ser_vector(self.vout)
  403. +       r += struct.pack("<I", self.nLockTime)
  404. +       return r
  405. +   def calc_sha256(self):
  406. +       if self.sha256 is None:
  407. +           self.sha256 = uint256_from_str(SHA256.new(SHA256.new(self.serialize()).digest()).digest())
  408. +   def is_valid(self):
  409. +       self.calc_sha256()
  410. +       for tout in self.vout:
  411. +           if tout.nValue < 0 or tout.nValue > 21000000L * 100000000L:
  412. +               return False
  413. +       return True
  414. +   def __repr__(self):
  415. +       return "CTransaction(nVersion=%i vin=%s vout=%s nLockTime=%i)" % (self.nVersion, repr(self.vin), repr(self.vout), self.nLockTime)
  416. +
  417. +class CBlock(object):
  418. +   def __init__(self):
  419. +       self.nVersion = 1
  420. +       self.hashPrevBlock = 0
  421. +       self.hashMerkleRoot = 0
  422. +       self.nTime = 0
  423. +       self.nBits = 0
  424. +       self.nNonce = 0
  425. +       self.vtx = []
  426. +       self.sha256 = None
  427. +   def deserialize(self, f):
  428. +       self.nVersion = struct.unpack("<i", f.read(4))[0]
  429. +       self.hashPrevBlock = deser_uint256(f)
  430. +       self.hashMerkleRoot = deser_uint256(f)
  431. +       self.nTime = struct.unpack("<I", f.read(4))[0]
  432. +       self.nBits = struct.unpack("<I", f.read(4))[0]
  433. +       self.nNonce = struct.unpack("<I", f.read(4))[0]
  434. +       self.vtx = deser_vector(f, CTransaction)
  435. +   def serialize(self):
  436. +       r = ""
  437. +       r += struct.pack("<i", self.nVersion)
  438. +       r += ser_uint256(self.hashPrevBlock)
  439. +       r += ser_uint256(self.hashMerkleRoot)
  440. +       r += struct.pack("<I", self.nTime)
  441. +       r += struct.pack("<I", self.nBits)
  442. +       r += struct.pack("<I", self.nNonce)
  443. +       r += ser_vector(self.vtx)
  444. +       return r
  445. +   def calc_sha256(self):
  446. +       if self.sha256 is None:
  447. +           r = ""
  448. +           r += struct.pack("<i", self.nVersion)
  449. +           r += ser_uint256(self.hashPrevBlock)
  450. +           r += ser_uint256(self.hashMerkleRoot)
  451. +           r += struct.pack("<I", self.nTime)
  452. +           r += struct.pack("<I", self.nBits)
  453. +           r += struct.pack("<I", self.nNonce)
  454. +           self.sha256 = uint256_from_str(SHA256.new(SHA256.new(r).digest()).digest())
  455. +   def is_valid(self):
  456. +       self.calc_sha256()
  457. +       target = uint256_from_compact(self.nBits)
  458. +       if self.sha256 > target:
  459. +           return False
  460. +       hashes = []
  461. +       for tx in self.vtx:
  462. +           if not tx.is_valid():
  463. +               return False
  464. +           tx.calc_sha256()
  465. +           hashes.append(ser_uint256(tx.sha256))
  466. +       while len(hashes) > 1:
  467. +           newhashes = []
  468. +           for i in xrange(0, len(hashes), 2):
  469. +               i2 = min(i+1, len(hashes)-1)
  470. +               newhashes.append(SHA256.new(SHA256.new(hashes[i] + hashes[i2]).digest()).digest())
  471. +           hashes = newhashes
  472. +       if uint256_from_str(hashes[0]) != self.hashMerkleRoot:
  473. +           return False
  474. +       return True
  475. +   def __repr__(self):
  476. +       return "CBlock(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x nTime=%s nBits=%08x nNonce=%08x vtx=%s)" % (self.nVersion, self.hashPrevBlock, self.hashMerkleRoot, time.ctime(self.nTime), self.nBits, self.nNonce, repr(self.vtx))
  477. +
  478. +class msg_version(object):
  479. +   command = "version"
  480. +   def __init__(self):
  481. +       self.nVersion = MY_VERSION
  482. +       self.nServices = 1
  483. +       self.nTime = time.time()
  484. +       self.addrTo = CAddress()
  485. +       self.addrFrom = CAddress()
  486. +       self.nNonce = random.getrandbits(64)
  487. +       self.strSubVer = MY_SUBVERSION
  488. +       self.nStartingHeight = -1
  489. +   def deserialize(self, f):
  490. +       self.nVersion = struct.unpack("<i", f.read(4))[0]
  491. +       if self.nVersion == 10300:
  492. +           self.nVersion = 300
  493. +       self.nServices = struct.unpack("<Q", f.read(8))[0]
  494. +       self.nTime = struct.unpack("<q", f.read(8))[0]
  495. +       self.addrTo = CAddress()
  496. +       self.addrTo.deserialize(f)
  497. +       if self.nVersion >= 106:
  498. +           self.addrFrom = CAddress()
  499. +           self.addrFrom.deserialize(f)
  500. +           self.nNonce = struct.unpack("<Q", f.read(8))[0]
  501. +           self.strSubVer = deser_string(f)
  502. +           if self.nVersion >= 209:
  503. +               self.nStartingHeight = struct.unpack("<i", f.read(4))[0]
  504. +           else:
  505. +               self.nStartingHeight = None
  506. +       else:
  507. +           self.addrFrom = None
  508. +           self.nNonce = None
  509. +           self.strSubVer = None
  510. +           self.nStartingHeight = None
  511. +   def serialize(self):
  512. +       r = ""
  513. +       r += struct.pack("<i", self.nVersion)
  514. +       r += struct.pack("<Q", self.nServices)
  515. +       r += struct.pack("<q", self.nTime)
  516. +       r += self.addrTo.serialize()
  517. +       r += self.addrFrom.serialize()
  518. +       r += struct.pack("<Q", self.nNonce)
  519. +       r += ser_string(self.strSubVer)
  520. +       r += struct.pack("<i", self.nStartingHeight)
  521. +       return r
  522. +   def __repr__(self):
  523. +       return "msg_version(nVersion=%i nServices=%i nTime=%s addrTo=%s addrFrom=%s nNonce=0x%016X strSubVer=%s nStartingHeight=%i)" % (self.nVersion, self.nServices, time.ctime(self.nTime), repr(self.addrTo), repr(self.addrFrom), self.nNonce, self.strSubVer, self.nStartingHeight)
  524. +
  525. +class msg_verack(object):
  526. +   command = "verack"
  527. +   def __init__(self):
  528. +       pass
  529. +   def deserialize(self, f):
  530. +       pass
  531. +   def serialize(self):
  532. +       return ""
  533. +   def __repr__(self):
  534. +       return "msg_verack()"
  535. +
  536. +class msg_addr(object):
  537. +   command = "addr"
  538. +   def __init__(self):
  539. +       self.addrs = []
  540. +   def deserialize(self, f):
  541. +       self.addrs = deser_vector(f, CAddress)
  542. +   def serialize(self):
  543. +       return ser_vector(self.addrs)
  544. +   def __repr__(self):
  545. +       return "msg_addr(addrs=%s)" % (repr(self.addrs))
  546. +
  547. +class msg_inv(object):
  548. +   command = "inv"
  549. +   def __init__(self):
  550. +       self.inv = []
  551. +   def deserialize(self, f):
  552. +       self.inv = deser_vector(f, CInv)
  553. +   def serialize(self):
  554. +       return ser_vector(self.inv)
  555. +   def __repr__(self):
  556. +       return "msg_inv(inv=%s)" % (repr(self.inv))
  557. +
  558. +class msg_getdata(object):
  559. +   command = "getdata"
  560. +   def __init__(self):
  561. +       self.inv = []
  562. +   def deserialize(self, f):
  563. +       self.inv = deser_vector(f, CInv)
  564. +   def serialize(self):
  565. +       return ser_vector(self.inv)
  566. +   def __repr__(self):
  567. +       return "msg_getdata(inv=%s)" % (repr(self.inv))
  568. +
  569. +class msg_getblocks(object):
  570. +   command = "getblocks"
  571. +   def __init__(self):
  572. +       self.locator = CBlockLocator()
  573. +       self.hashstop = 0L
  574. +   def deserialize(self, f):
  575. +       self.locator = CBlockLocator()
  576. +       self.locator.deserialize(f)
  577. +       self.hashstop = deser_uint256(f)
  578. +   def serialize(self):
  579. +       r = ""
  580. +       r += self.locator.serialize()
  581. +       r += ser_uint256(self.hashstop)
  582. +       return r
  583. +   def __repr__(self):
  584. +       return "msg_getblocks(locator=%s hashstop=%064x)" % (repr(self.locator), self.hashstop)
  585. +
  586. +class msg_tx(object):
  587. +   command = "tx"
  588. +   def __init__(self):
  589. +       self.tx = CTransaction()
  590. +   def deserialize(self, f):
  591. +       self.tx.deserialize(f)
  592. +   def serialize(self):
  593. +       return self.tx.serialize()
  594. +   def __repr__(self):
  595. +       return "msg_tx(tx=%s)" % (repr(self.tx))
  596. +
  597. +class msg_block(object):
  598. +   command = "block"
  599. +   def __init__(self):
  600. +       self.block = CBlock()
  601. +   def deserialize(self, f):
  602. +       self.block.deserialize(f)
  603. +   def serialize(self):
  604. +       return self.block.serialize()
  605. +   def __repr__(self):
  606. +       return "msg_block(block=%s)" % (repr(self.block))
  607. +
  608. +class msg_getaddr(object):
  609. +   command = "getaddr"
  610. +   def __init__(self):
  611. +       pass
  612. +   def deserialize(self, f):
  613. +       pass
  614. +   def serialize(self):
  615. +       return ""
  616. +   def __repr__(self):
  617. +       return "msg_getaddr()"
  618. +
  619. +#msg_checkorder
  620. +#msg_submitorder
  621. +#msg_reply
  622. +
  623. +class msg_ping(object):
  624. +   command = "ping"
  625. +   def __init__(self):
  626. +       pass
  627. +   def deserialize(self, f):
  628. +       pass
  629. +   def serialize(self):
  630. +       return ""
  631. +   def __repr__(self):
  632. +       return "msg_ping()"
  633. +
  634. +
  635. +
  636. +
  637. +
  638. +
  639. +class BitcoinNode(threading.Thread):
  640. +   messagemap = {
  641. +       "version": msg_version,
  642. +       "verack": msg_verack,
  643. +       "addr": msg_addr,
  644. +       "inv": msg_inv,
  645. +       "getdata": msg_getdata,
  646. +       "getblocks": msg_getblocks,
  647. +       "tx": msg_tx,
  648. +       "block": msg_block,
  649. +       "getaddr": msg_getaddr,
  650. +       "ping": msg_ping
  651. +   }
  652. +   def __init__(self, dstaddr, dstport):
  653. +       threading.Thread.__init__(self)
  654. +       self.dstaddr = dstaddr
  655. +       self.dstport = dstport
  656. +       self.sendbuf = ""
  657. +       self.recvbuf = ""
  658. +       self.ver_send = 0
  659. +       self.ver_recv = 0
  660. +       self.last_sent = 0
  661. +       self.state = "idle"
  662. +       self.e_stop = threading.Event()
  663. +
  664. +   def stop(self):
  665. +       self.e_stop.set()
  666. +
  667. +   def run(self):
  668. +       self.state = "connecting"
  669. +       print "connecting %s" % self.dstaddr
  670. +       self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  671. +       try:
  672. +           self.socket.settimeout(120)
  673. +           self.socket.connect((self.dstaddr, self.dstport))
  674. +       except:
  675. +           self.handle_close()
  676. +
  677. +       self.handle_connect()
  678. +
  679. +       epoll = select.epoll()
  680. +       epoll.register(self.socket.fileno(), select.EPOLLIN)
  681. +
  682. +       while self.state != "closed":
  683. +           if self.e_stop.isSet():
  684. +               break
  685. +
  686. +           events = epoll.poll(timeout=1)
  687. +           for fd, ev in events:
  688. +               if ev & select.EPOLLIN:
  689. +                   self.handle_read()
  690. +               elif ev & select.EPOLLHUP:
  691. +                   self.handle_close()
  692. +
  693. +           self.handle_write()
  694. +
  695. +       self.handle_close()
  696. +
  697. +   def handle_connect(self):
  698. +       self.state = "connected"
  699. +       print "connected"
  700. +       #send version msg
  701. +       t = msg_version()
  702. +       t.addrTo.ip = self.dstaddr
  703. +       t.addrTo.port = self.dstport
  704. +       t.addrFrom.ip = "0.0.0.0"
  705. +       t.addrFrom.port = 0
  706. +       self.send_message(t)
  707. +
  708. +   def handle_close(self):
  709. +       print "close"
  710. +       self.state = "closed"
  711. +       self.recvbuf = ""
  712. +       self.sendbuf = ""
  713. +       try:
  714. +           self.close()
  715. +       except:
  716. +           pass
  717. +   def handle_read(self):
  718. +       try:
  719. +           t = self.socket.recv(8192)
  720. +       except:
  721. +           self.handle_close()
  722. +           return
  723. +       if len(t) == 0:
  724. +           self.handle_close()
  725. +           return
  726. +       self.recvbuf += t
  727. +       self.got_data()
  728. +   def readable(self):
  729. +       return True
  730. +   def writable(self):
  731. +       return (len(self.sendbuf) > 0)
  732. +   def handle_write(self):
  733. +       try:
  734. +           sent = self.socket.send(self.sendbuf)
  735. +       except:
  736. +           self.handle_close()
  737. +           return
  738. +       self.sendbuf = self.sendbuf[sent:]
  739. +   def got_data(self):
  740. +       while True:
  741. +           if len(self.recvbuf) < 4:
  742. +               return
  743. +           if self.recvbuf[:4] != "\xf9\xbe\xb4\xd9":
  744. +               raise ValueError("got garbage %s" % repr(self.recvbuf))
  745. +           if self.ver_recv < 209:
  746. +               if len(self.recvbuf) < 4 + 12 + 4:
  747. +                   return
  748. +               command = self.recvbuf[4:4+12].split("\x00", 1)[0]
  749. +               msglen = struct.unpack("<i", self.recvbuf[4+12:4+12+4])[0]
  750. +               checksum = None
  751. +               if len(self.recvbuf) < 4 + 12 + 4 + msglen:
  752. +                   return
  753. +               msg = self.recvbuf[4+12+4:4+12+4+msglen]
  754. +               self.recvbuf = self.recvbuf[4+12+4+msglen:]
  755. +           else:
  756. +               if len(self.recvbuf) < 4 + 12 + 4 + 4:
  757. +                   return
  758. +               command = self.recvbuf[4:4+12].split("\x00", 1)[0]
  759. +               msglen = struct.unpack("<i", self.recvbuf[4+12:4+12+4])[0]
  760. +               checksum = self.recvbuf[4+12+4:4+12+4+4]
  761. +               if len(self.recvbuf) < 4 + 12 + 4 + 4 + msglen:
  762. +                   return
  763. +               msg = self.recvbuf[4+12+4+4:4+12+4+4+msglen]
  764. +               th = SHA256.new(msg).digest()
  765. +               h = SHA256.new(th).digest()
  766. +               if checksum != h[:4]:
  767. +                   raise ValueError("got bad checksum %s" % repr(self.recvbuf))
  768. +               self.recvbuf = self.recvbuf[4+12+4+4+msglen:]
  769. +           if command in self.messagemap:
  770. +               f = cStringIO.StringIO(msg)
  771. +               t = self.messagemap[command]()
  772. +               t.deserialize(f)
  773. +               self.got_message(t)
  774. +           else:
  775. +               print "UNKNOWN COMMAND", command, repr(msg)
  776. +   def send_message(self, message):
  777. +       if self.state != "connected":
  778. +           return
  779. +       #print "send %s" % repr(message)
  780. +       command = message.command
  781. +       data = message.serialize()
  782. +       tmsg = "\xf9\xbe\xb4\xd9"
  783. +       tmsg += command
  784. +       tmsg += "\x00" * (12 - len(command))
  785. +       tmsg += struct.pack("<I", len(data))
  786. +       if self.ver_send >= 209:
  787. +           th = SHA256.new(data).digest()
  788. +           h = SHA256.new(th).digest()
  789. +           tmsg += h[:4]
  790. +       tmsg += data
  791. +       self.sendbuf += tmsg
  792. +       self.last_sent = time.time()
  793. +   def got_message(self, message):
  794. +       if self.last_sent + 30 * 60 < time.time():
  795. +           self.send_message(msg_ping())
  796. +
  797. +       mname = 'do_' + message.command
  798. +       if not hasattr(self, mname):
  799. +           return
  800. +
  801. +       method = getattr(self, mname)
  802. +       method(message)
  803. +
  804. +
  805. +#      if message.command == "tx":
  806. +#          message.tx.calc_sha256()
  807. +#          sha256 = message.tx.sha256
  808. +#          pubkey = binascii.hexlify(message.tx.vout[0].scriptPubKey)
  809. +#          txlock.acquire()
  810. +#          tx.append([str(sha256), str(time.time()), str(self.dstaddr), pubkey])
  811. +#          txlock.release()
  812. +
  813. +   def do_version(self, message):
  814. +       if message.nVersion >= 209:
  815. +           self.send_message(msg_verack())
  816. +       self.ver_send = min(MY_VERSION, message.nVersion)
  817. +       if message.nVersion < 209:
  818. +           self.ver_recv = self.ver_send
  819. +
  820. +   def do_verack(self, message):
  821. +           self.ver_recv = self.ver_send
  822. +
  823. +   def do_inv(self, message):
  824. +       want = msg_getdata()
  825. +       for i in message.inv:
  826. +           if i.type == 1:
  827. +               want.inv.append(i)
  828. +           elif i.type == 2:
  829. +               want.inv.append(i)
  830. +       if len(want.inv):
  831. +           self.send_message(want)
  832. +
  833. diff --git a/poclbm.py b/poclbm.py
  834. index 267d6ef..6077a7a 100644
  835. --- a/poclbm.py
  836. +++ b/poclbm.py
  837. @@ -27,5 +27,5 @@ if (options.device == -1 or options.device >= len(devices)):
  838.     sys.exit()
  839.  
  840.  context = cl.Context([devices[options.device]], None, None)
  841. -myMiner = BitcoinMiner(platform, context, options.host, options.user, options.password, options.port, options.frames, options.rate, options.askrate, options.worksize, options.vectors)
  842. -myMiner.mine()
  843. \ No newline at end of file
  844. +myMiner = BitcoinMiner(platform, context, options.device, options.host, options.user, options.password, options.port, options.frames, options.rate, options.askrate, options.worksize, options.vectors)
  845. +myMiner.mine()
Advertisement
Add Comment
Please, Sign In to add comment