Merge pull request #3 from ahmedbodi/issue-1

Issue 1
This commit is contained in:
ahmedbodi 2013-11-20 08:18:13 -08:00
commit ed65b627b5
8 changed files with 85 additions and 42 deletions

9
.gitmodules vendored Normal file
View File

@ -0,0 +1,9 @@
[submodule "externals/stratum-mining-proxy"]
path = externals/stratum-mining-proxy
url = https://github.com/generalfault/stratum-mining-proxy
[submodule "externals/litecoin_scrypt"]
path = externals/litecoin_scrypt
url = https://github.com/Tydus/litecoin_scrypt.git
[submodule "externals/stratum"]
path = externals/stratum
url = https://github.com/slush0/stratum.git

1
externals/litecoin_scrypt vendored Submodule

@ -0,0 +1 @@
Subproject commit 967f2ef35b17e3630bc42ba3fc1313b70ee446ab

1
externals/stratum vendored Submodule

@ -0,0 +1 @@
Subproject commit 8ba1b5fd8a802b981f31dace4cf920cfb4a3907c

1
externals/stratum-mining-proxy vendored Submodule

@ -0,0 +1 @@
Subproject commit 9b893fab15df318670cd137636df758dfcffa005

View File

@ -43,12 +43,14 @@ class BitcoinRPC(object):
def submitblock(self, block_hex, block_hash_hex):
# Try submitblock if that fails, go to getblocktemplate
try:
print("Submitting Block with Submit Block ")
resp = (yield self._call('submitblock', [block_hex,]))
except Exception:
try:
print("Submit Block call failed, trying GetBlockTemplate")
resp = (yield self._call('getblocktemplate', [{'mode': 'submit', 'data': block_hex}]))
except Exception as e:
log.exception("Problem Submitting block %s" % str(e))
log.exception("Both SubmitBlock and GetBlockTemplate failed. Problem Submitting block %s" % str(e))
raise
if json.loads(resp)['result'] == None:

View File

@ -111,6 +111,12 @@ COINDAEMON_TRUSTED_PORT = 8332 # RPC port
COINDAEMON_TRUSTED_USER = 'stratum'
COINDAEMON_TRUSTED_PASSWORD = '***somepassword***'
# Coin Algorithm is the option used to determine the algortithm used by stratum
# This currently only works with POW SHA256 and Scrypt Coins
# The available options are scrypt and sha256d.
# If the option does not meet either of these criteria stratum defaults to scrypt
COINDAEMON_ALGO = 'scrypt'
# ******************** OTHER CORE SETTINGS *********************
# Use "echo -n '<yourpassword>' | sha256sum | cut -f1 -d' ' "
# for calculating SHA256 of your preferred password

View File

@ -15,7 +15,14 @@ from Crypto.Hash import SHA256
from twisted.internet.protocol import Protocol
from util import *
import ltc_scrypt
import settings
if settings.COINDAEMON_ALGO == 'scrypt':
print("########################################### Loading LTC Scrypt Module #########################################################")
import ltc_scrypt
else:
print("########################################### NOT Loading LTC Scrypt Module ######################################################")
pass
import lib.logger
log = lib.logger.get_logger('halfnode')
@ -174,7 +181,9 @@ class CBlock(object):
self.nNonce = 0
self.vtx = []
self.sha256 = None
self.scrypt = None
if settings.COINDAEMON_ALGO == 'scrypt':
self.scrypt = None
else: pass
def deserialize(self, f):
self.nVersion = struct.unpack("<i", f.read(4))[0]
self.hashPrevBlock = deser_uint256(f)
@ -193,37 +202,45 @@ class CBlock(object):
r.append(struct.pack("<I", self.nNonce))
r.append(ser_vector(self.vtx))
return ''.join(r)
def calc_sha256(self):
if self.sha256 is None:
r = []
r.append(struct.pack("<i", self.nVersion))
r.append(ser_uint256(self.hashPrevBlock))
r.append(ser_uint256(self.hashMerkleRoot))
r.append(struct.pack("<I", self.nTime))
r.append(struct.pack("<I", self.nBits))
r.append(struct.pack("<I", self.nNonce))
self.sha256 = uint256_from_str(SHA256.new(SHA256.new(''.join(r)).digest()).digest())
return self.sha256
def calc_scrypt(self):
if self.scrypt is None:
r = []
r.append(struct.pack("<i", self.nVersion))
r.append(ser_uint256(self.hashPrevBlock))
r.append(ser_uint256(self.hashMerkleRoot))
r.append(struct.pack("<I", self.nTime))
r.append(struct.pack("<I", self.nBits))
r.append(struct.pack("<I", self.nNonce))
self.scrypt = uint256_from_str(ltc_scrypt.getPoWHash(''.join(r)))
return self.scrypt
if settings.COINDAEMON_ALGO == 'scrypt':
def calc_scrypt(self):
if self.scrypt is None:
r = []
r.append(struct.pack("<i", self.nVersion))
r.append(ser_uint256(self.hashPrevBlock))
r.append(ser_uint256(self.hashMerkleRoot))
r.append(struct.pack("<I", self.nTime))
r.append(struct.pack("<I", self.nBits))
r.append(struct.pack("<I", self.nNonce))
self.scrypt = uint256_from_str(ltc_scrypt.getPoWHash(''.join(r)))
return self.scrypt
else:
def calc_sha256(self):
if self.sha256 is None:
r = []
r.append(struct.pack("<i", self.nVersion))
r.append(ser_uint256(self.hashPrevBlock))
r.append(ser_uint256(self.hashMerkleRoot))
r.append(struct.pack("<I", self.nTime))
r.append(struct.pack("<I", self.nBits))
r.append(struct.pack("<I", self.nNonce))
self.sha256 = uint256_from_str(SHA256.new(SHA256.new(''.join(r)).digest()).digest())
return self.sha256
def is_valid(self):
#self.calc_sha256()
self.calc_scrypt()
if settings.COINDAEMON_ALGO == 'scrypt':
self.calc_scrypt()
else:
self.calc_sha256()
target = uint256_from_compact(self.nBits)
#if self.sha256 > target:
if self.scrypt > target:
return False
if settings.COINDAEMON_ALGO == 'scrypt':
if self.scrypt > target:
return false
else:
if self.sha256 > target:
return False
hashes = []
for tx in self.vtx:
tx.sha256 = None

View File

@ -2,8 +2,10 @@ import weakref
import binascii
import util
import StringIO
import ltc_scrypt
import settings
if settings.COINDAEMON_ALGO == 'scrypt':
import ltc_scrypt
else: pass
from twisted.internet import defer
from lib.exceptions import SubmitException
@ -140,9 +142,10 @@ class TemplateRegistry(object):
def diff_to_target(self, difficulty):
'''Converts difficulty to target'''
#diff1 = 0x00000000ffff0000000000000000000000000000000000000000000000000000
diff1 = 0x0000ffff00000000000000000000000000000000000000000000000000000000
return diff1 / difficulty
if settings.COINDAEMON_ALGO == 'scrypt':
diff1 = 0x0000ffff00000000000000000000000000000000000000000000000000000000
else: diff1 = 0x00000000ffff0000000000000000000000000000000000000000000000000000
return diff1 / difficulty
def get_job(self, job_id):
'''For given job_id returns BlockTemplate instance or None'''
@ -223,12 +226,15 @@ class TemplateRegistry(object):
header_bin = job.serialize_header(merkle_root_int, ntime_bin, nonce_bin)
# 4. Reverse header and compare it with target of the user
hash_bin = ltc_scrypt.getPoWHash(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ]))
if settings.COINDAEMON_ALGO == 'scrypt':
hash_bin = ltc_scrypt.getPoWHash(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ]))
else: hash_bin = util.doublesha(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ]))
hash_int = util.uint256_from_str(hash_bin)
scrypt_hash_hex = "%064x" % hash_int
header_hex = binascii.hexlify(header_bin)
header_hex = header_hex+"000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000"
if settings.COINDAEMON_ALGO == 'scrypt':
header_hex = header_hex+"000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000"
else: pass
target_user = self.diff_to_target(difficulty)
if hash_int > target_user and \
@ -245,16 +251,16 @@ class TemplateRegistry(object):
share_diff = int(self.diff_to_target(hash_int))
# 5. Compare hash with target of the network
# 5. Compare hash with target of the network
if hash_int <= job.target:
# Yay! It is block candidate!
# Yay! It is block candidate!
log.info("We found a block candidate! %s" % scrypt_hash_hex)
# Reverse the header and get the potential block hash (for scrypt only)
# Reverse the header and get the potential block hash (for scrypt only)
block_hash_bin = util.doublesha(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ]))
block_hash_hex = block_hash_bin[::-1].encode('hex_codec')
# 6. Finalize and serialize block object
# 6. Finalize and serialize block object
job.finalize(merkle_root_int, extranonce1_bin, extranonce2_bin, int(ntime, 16), int(nonce, 16))
if not job.is_valid():