commit
daa024115b
@ -21,11 +21,8 @@ COINDAEMON_TRUSTED_PASSWORD = 'somepassword'
|
|||||||
# The available options are:
|
# The available options are:
|
||||||
# scrypt, sha256d, scrypt-jane and quark
|
# scrypt, sha256d, scrypt-jane and quark
|
||||||
# If the option does not meet either of these criteria stratum defaults to scrypt
|
# If the option does not meet either of these criteria stratum defaults to scrypt
|
||||||
# Until AutoReward Selecting Code has been implemented the below options are used to select the type of coin
|
|
||||||
# For Reward type there is POW and POS. please ensure you choose the currect type.
|
|
||||||
# For Coins which support TX Messages please enter yes in the TX selection
|
# For Coins which support TX Messages please enter yes in the TX selection
|
||||||
COINDAEMON_ALGO = 'scrypt'
|
COINDAEMON_ALGO = 'scrypt'
|
||||||
COINDAEMON_Reward = 'POW'
|
|
||||||
COINDAEMON_TX = 'no'
|
COINDAEMON_TX = 'no'
|
||||||
# ******************** BASIC SETTINGS ***************
|
# ******************** BASIC SETTINGS ***************
|
||||||
# Backup Coin Daemon address's (consider having at least 1 backup)
|
# Backup Coin Daemon address's (consider having at least 1 backup)
|
||||||
@ -191,3 +188,11 @@ NOTIFY_EMAIL_SERVER = 'localhost' # E-Mail Sender
|
|||||||
NOTIFY_EMAIL_USERNAME = '' # E-Mail server SMTP Logon
|
NOTIFY_EMAIL_USERNAME = '' # E-Mail server SMTP Logon
|
||||||
NOTIFY_EMAIL_PASSWORD = ''
|
NOTIFY_EMAIL_PASSWORD = ''
|
||||||
NOTIFY_EMAIL_USETLS = True
|
NOTIFY_EMAIL_USETLS = True
|
||||||
|
|
||||||
|
#### Memcache ####
|
||||||
|
# Memcahce is a requirement. Enter the settings below
|
||||||
|
MEMCACHE_HOST = "localhost" # hostname or IP that runs memcached
|
||||||
|
MEMCACHE_PORT = 11211 # Port
|
||||||
|
MEMCACHE_TIMEOUT = 900 # Key timeout
|
||||||
|
MEMCACHE_PREFIX = "stratum_" # Prefix for keys
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,8 @@ import struct
|
|||||||
import util
|
import util
|
||||||
import merkletree
|
import merkletree
|
||||||
import halfnode
|
import halfnode
|
||||||
|
from coinbasetx import CoinbaseTransactionPOW
|
||||||
|
from coinbasetx import CoinbaseTransactionPOS
|
||||||
from coinbasetx import CoinbaseTransaction
|
from coinbasetx import CoinbaseTransaction
|
||||||
import lib.logger
|
import lib.logger
|
||||||
log = lib.logger.get_logger('block_template')
|
log = lib.logger.get_logger('block_template')
|
||||||
@ -55,10 +57,10 @@ class BlockTemplate(halfnode.CBlock):
|
|||||||
txhashes = [None] + [ util.ser_uint256(int(t['hash'], 16)) for t in data['transactions'] ]
|
txhashes = [None] + [ util.ser_uint256(int(t['hash'], 16)) for t in data['transactions'] ]
|
||||||
mt = merkletree.MerkleTree(txhashes)
|
mt = merkletree.MerkleTree(txhashes)
|
||||||
if settings.COINDAEMON_Reward == 'POW':
|
if settings.COINDAEMON_Reward == 'POW':
|
||||||
coinbase = self.coinbase_transaction_class(self.timestamper, self.coinbaser, data['coinbasevalue'], data['coinbaseaux']['flags'], data['height'],
|
coinbase = CoinbaseTransactionPOW(self.timestamper, self.coinbaser, data['coinbasevalue'], data['coinbaseaux']['flags'], data['height'],
|
||||||
settings.COINBASE_EXTRAS)
|
settings.COINBASE_EXTRAS)
|
||||||
else:
|
else:
|
||||||
coinbase = self.coinbase_transaction_class(self.timestamper, self.coinbaser, data['coinbasevalue'], data['coinbaseaux']['flags'], data['height'],
|
coinbase = CoinbaseTransactionPOS(self.timestamper, self.coinbaser, data['coinbasevalue'], data['coinbaseaux']['flags'], data['height'],
|
||||||
settings.COINBASE_EXTRAS, data['curtime'])
|
settings.COINBASE_EXTRAS, data['curtime'])
|
||||||
|
|
||||||
self.height = data['height']
|
self.height = data['height']
|
||||||
|
|||||||
@ -6,8 +6,8 @@ import settings
|
|||||||
import lib.logger
|
import lib.logger
|
||||||
log = lib.logger.get_logger('coinbasetx')
|
log = lib.logger.get_logger('coinbasetx')
|
||||||
|
|
||||||
if settings.COINDAEMON_Reward == 'POW':
|
#if settings.COINDAEMON_Reward == 'POW':
|
||||||
class CoinbaseTransaction(halfnode.CTransaction):
|
class CoinbaseTransactionPOW(halfnode.CTransaction):
|
||||||
'''Construct special transaction used for coinbase tx.
|
'''Construct special transaction used for coinbase tx.
|
||||||
It also implements quick serialization using pre-cached
|
It also implements quick serialization using pre-cached
|
||||||
scriptSig template.'''
|
scriptSig template.'''
|
||||||
@ -17,8 +17,8 @@ if settings.COINDAEMON_Reward == 'POW':
|
|||||||
extranonce_size = struct.calcsize(extranonce_type)
|
extranonce_size = struct.calcsize(extranonce_type)
|
||||||
|
|
||||||
def __init__(self, timestamper, coinbaser, value, flags, height, data):
|
def __init__(self, timestamper, coinbaser, value, flags, height, data):
|
||||||
super(CoinbaseTransaction, self).__init__()
|
super(CoinbaseTransactionPOW, self).__init__()
|
||||||
log.debug("Got to CoinBaseTX")
|
log.debug("Got to CoinBaseTX")
|
||||||
#self.extranonce = 0
|
#self.extranonce = 0
|
||||||
|
|
||||||
if len(self.extranonce_placeholder) != self.extranonce_size:
|
if len(self.extranonce_placeholder) != self.extranonce_size:
|
||||||
@ -45,7 +45,7 @@ if settings.COINDAEMON_Reward == 'POW':
|
|||||||
self.vout.append(tx_out)
|
self.vout.append(tx_out)
|
||||||
|
|
||||||
# Two parts of serialized coinbase, just put part1 + extranonce + part2 to have final serialized tx
|
# Two parts of serialized coinbase, just put part1 + extranonce + part2 to have final serialized tx
|
||||||
self._serialized = super(CoinbaseTransaction, self).serialize().split(self.extranonce_placeholder)
|
self._serialized = super(CoinbaseTransactionPOW, self).serialize().split(self.extranonce_placeholder)
|
||||||
|
|
||||||
def set_extranonce(self, extranonce):
|
def set_extranonce(self, extranonce):
|
||||||
if len(extranonce) != self.extranonce_size:
|
if len(extranonce) != self.extranonce_size:
|
||||||
@ -53,8 +53,56 @@ if settings.COINDAEMON_Reward == 'POW':
|
|||||||
|
|
||||||
(part1, part2) = self.vin[0]._scriptSig_template
|
(part1, part2) = self.vin[0]._scriptSig_template
|
||||||
self.vin[0].scriptSig = part1 + extranonce + part2
|
self.vin[0].scriptSig = part1 + extranonce + part2
|
||||||
elif settings.COINDAEMON_Reward == 'POS':
|
#elif settings.COINDAEMON_Reward == 'POS':
|
||||||
class CoinbaseTransaction(halfnode.CTransaction):
|
class CoinbaseTransactionPOS(halfnode.CTransaction):
|
||||||
|
'''Construct special transaction used for coinbase tx.
|
||||||
|
It also implements quick serialization using pre-cached
|
||||||
|
scriptSig template.'''
|
||||||
|
|
||||||
|
extranonce_type = '>Q'
|
||||||
|
extranonce_placeholder = struct.pack(extranonce_type, int('f000000ff111111f', 16))
|
||||||
|
extranonce_size = struct.calcsize(extranonce_type)
|
||||||
|
|
||||||
|
def __init__(self, timestamper, coinbaser, value, flags, height, data, ntime):
|
||||||
|
super(CoinbaseTransactionPOS, self).__init__()
|
||||||
|
log.debug("Got to CoinBaseTX")
|
||||||
|
#self.extranonce = 0
|
||||||
|
|
||||||
|
if len(self.extranonce_placeholder) != self.extranonce_size:
|
||||||
|
raise Exception("Extranonce placeholder don't match expected length!")
|
||||||
|
|
||||||
|
tx_in = halfnode.CTxIn()
|
||||||
|
tx_in.prevout.hash = 0L
|
||||||
|
tx_in.prevout.n = 2**32-1
|
||||||
|
tx_in._scriptSig_template = (
|
||||||
|
util.ser_number(height) + binascii.unhexlify(flags) + util.ser_number(int(timestamper.time())) + \
|
||||||
|
chr(self.extranonce_size),
|
||||||
|
util.ser_string(coinbaser.get_coinbase_data() + data)
|
||||||
|
)
|
||||||
|
|
||||||
|
tx_in.scriptSig = tx_in._scriptSig_template[0] + self.extranonce_placeholder + tx_in._scriptSig_template[1]
|
||||||
|
|
||||||
|
tx_out = halfnode.CTxOut()
|
||||||
|
tx_out.nValue = value
|
||||||
|
tx_out.scriptPubKey = coinbaser.get_script_pubkey()
|
||||||
|
|
||||||
|
self.nTime = ntime
|
||||||
|
if settings.COINDAEMON_SHA256_TX == 'yes':
|
||||||
|
self.strTxComment = "http://github.com/ahmedbodi/stratum-mining"
|
||||||
|
self.vin.append(tx_in)
|
||||||
|
self.vout.append(tx_out)
|
||||||
|
|
||||||
|
# Two parts of serialized coinbase, just put part1 + extranonce + part2 to have final serialized tx
|
||||||
|
self._serialized = super(CoinbaseTransactionPOS, self).serialize().split(self.extranonce_placeholder)
|
||||||
|
|
||||||
|
def set_extranonce(self, extranonce):
|
||||||
|
if len(extranonce) != self.extranonce_size:
|
||||||
|
raise Exception("Incorrect extranonce size")
|
||||||
|
|
||||||
|
(part1, part2) = self.vin[0]._scriptSig_template
|
||||||
|
self.vin[0].scriptSig = part1 + extranonce + part2
|
||||||
|
#else:
|
||||||
|
class CoinbaseTransaction(halfnode.CTransaction):
|
||||||
'''Construct special transaction used for coinbase tx.
|
'''Construct special transaction used for coinbase tx.
|
||||||
It also implements quick serialization using pre-cached
|
It also implements quick serialization using pre-cached
|
||||||
scriptSig template.'''
|
scriptSig template.'''
|
||||||
@ -86,54 +134,6 @@ elif settings.COINDAEMON_Reward == 'POS':
|
|||||||
tx_out.nValue = value
|
tx_out.nValue = value
|
||||||
tx_out.scriptPubKey = coinbaser.get_script_pubkey()
|
tx_out.scriptPubKey = coinbaser.get_script_pubkey()
|
||||||
|
|
||||||
self.nTime = ntime
|
|
||||||
if settings.COINDAEMON_SHA256_TX == 'yes':
|
|
||||||
self.strTxComment = "http://github.com/ahmedbodi/stratum-mining"
|
|
||||||
self.vin.append(tx_in)
|
|
||||||
self.vout.append(tx_out)
|
|
||||||
|
|
||||||
# Two parts of serialized coinbase, just put part1 + extranonce + part2 to have final serialized tx
|
|
||||||
self._serialized = super(CoinbaseTransaction, self).serialize().split(self.extranonce_placeholder)
|
|
||||||
|
|
||||||
def set_extranonce(self, extranonce):
|
|
||||||
if len(extranonce) != self.extranonce_size:
|
|
||||||
raise Exception("Incorrect extranonce size")
|
|
||||||
|
|
||||||
(part1, part2) = self.vin[0]._scriptSig_template
|
|
||||||
self.vin[0].scriptSig = part1 + extranonce + part2
|
|
||||||
else:
|
|
||||||
class CoinbaseTransaction(halfnode.CTransaction):
|
|
||||||
'''Construct special transaction used for coinbase tx.
|
|
||||||
It also implements quick serialization using pre-cached
|
|
||||||
scriptSig template.'''
|
|
||||||
|
|
||||||
extranonce_type = '>Q'
|
|
||||||
extranonce_placeholder = struct.pack(extranonce_type, int('f000000ff111111f', 16))
|
|
||||||
extranonce_size = struct.calcsize(extranonce_type)
|
|
||||||
|
|
||||||
def __init__(self, timestamper, coinbaser, value, flags, height, data, ntime):
|
|
||||||
super(CoinbaseTransaction, self).__init__()
|
|
||||||
log.debug("Got to CoinBaseTX")
|
|
||||||
#self.extranonce = 0
|
|
||||||
|
|
||||||
if len(self.extranonce_placeholder) != self.extranonce_size:
|
|
||||||
raise Exception("Extranonce placeholder don't match expected length!")
|
|
||||||
|
|
||||||
tx_in = halfnode.CTxIn()
|
|
||||||
tx_in.prevout.hash = 0L
|
|
||||||
tx_in.prevout.n = 2**32-1
|
|
||||||
tx_in._scriptSig_template = (
|
|
||||||
util.ser_number(height) + binascii.unhexlify(flags) + util.ser_number(int(timestamper.time())) + \
|
|
||||||
chr(self.extranonce_size),
|
|
||||||
util.ser_string(coinbaser.get_coinbase_data() + data)
|
|
||||||
)
|
|
||||||
|
|
||||||
tx_in.scriptSig = tx_in._scriptSig_template[0] + self.extranonce_placeholder + tx_in._scriptSig_template[1]
|
|
||||||
|
|
||||||
tx_out = halfnode.CTxOut()
|
|
||||||
tx_out.nValue = value
|
|
||||||
tx_out.scriptPubKey = coinbaser.get_script_pubkey()
|
|
||||||
|
|
||||||
self.nTime = ntime
|
self.nTime = ntime
|
||||||
self.vin.append(tx_in)
|
self.vin.append(tx_in)
|
||||||
self.vout.append(tx_out)
|
self.vout.append(tx_out)
|
||||||
|
|||||||
@ -21,27 +21,27 @@ log = lib.logger.get_logger('halfnode')
|
|||||||
log.debug("Got to Halfnode")
|
log.debug("Got to Halfnode")
|
||||||
|
|
||||||
if settings.COINDAEMON_ALGO == 'scrypt':
|
if settings.COINDAEMON_ALGO == 'scrypt':
|
||||||
log.debug("########################################### Loading LTC Scrypt #########################################################")
|
log.debug("########################################### Loading LTC Scrypt #########################################################")
|
||||||
import ltc_scrypt
|
import ltc_scrypt
|
||||||
elif settings.COINDAEMON_ALGO == 'quark':
|
elif settings.COINDAEMON_ALGO == 'quark':
|
||||||
log.debug("########################################### Loading Quark Support #########################################################")
|
log.debug("########################################### Loading Quark Support #########################################################")
|
||||||
import quark_hash
|
import quark_hash
|
||||||
else:
|
else:
|
||||||
log.debug("########################################### Loading SHA256 Support ######################################################")
|
log.debug("########################################### Loading SHA256 Support ######################################################")
|
||||||
|
|
||||||
if settings.COINDAEMON_Reward == 'POS':
|
#if settings.COINDAEMON_Reward == 'POS':
|
||||||
log.debug("########################################### Loading POS Support #########################################################")
|
# log.debug("########################################### Loading POS Support #########################################################")
|
||||||
pass
|
# pass
|
||||||
else:
|
#else:
|
||||||
log.debug("########################################### Loading POW Support ######################################################")
|
# log.debug("########################################### Loading POW Support ######################################################")
|
||||||
pass
|
# pass
|
||||||
|
|
||||||
if settings.COINDAEMON_TX == 'yes':
|
if settings.COINDAEMON_TX == 'yes':
|
||||||
log.debug("########################################### Loading SHA256 Transaction Message Support #########################################################")
|
log.debug("########################################### Loading SHA256 Transaction Message Support #########################################################")
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
log.debug("########################################### NOT Loading SHA256 Transaction Message Support ######################################################")
|
log.debug("########################################### NOT Loading SHA256 Transaction Message Support ######################################################")
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
MY_VERSION = 31402
|
MY_VERSION = 31402
|
||||||
|
|||||||
24
lib/util.py
24
lib/util.py
@ -211,15 +211,15 @@ def ser_number(n):
|
|||||||
s.append(n)
|
s.append(n)
|
||||||
return bytes(s)
|
return bytes(s)
|
||||||
|
|
||||||
if settings.COINDAEMON_Reward == 'POW':
|
#if settings.COINDAEMON_Reward == 'POW':
|
||||||
def script_to_address(addr):
|
def script_to_address(addr):
|
||||||
d = address_to_pubkeyhash(addr)
|
d = address_to_pubkeyhash(addr)
|
||||||
if not d:
|
if not d:
|
||||||
raise ValueError('invalid address')
|
raise ValueError('invalid address')
|
||||||
(ver, pubkeyhash) = d
|
(ver, pubkeyhash) = d
|
||||||
return b'\x76\xa9\x14' + pubkeyhash + b'\x88\xac'
|
return b'\x76\xa9\x14' + pubkeyhash + b'\x88\xac'
|
||||||
else:
|
#else:
|
||||||
def script_to_pubkey(key):
|
def script_to_pubkey(key):
|
||||||
if len(key) == 66: key = binascii.unhexlify(key)
|
if len(key) == 66: key = binascii.unhexlify(key)
|
||||||
if len(key) != 33: raise Exception('Invalid Address')
|
if len(key) != 33: raise Exception('Invalid Address')
|
||||||
return b'\x21' + key + b'\xac'
|
return b'\x21' + key + b'\xac'
|
||||||
|
|||||||
24
mining/Cache.py
Normal file
24
mining/Cache.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
''' A simple wrapper for pylibmc. It can be overwritten with simple hashing if necessary '''
|
||||||
|
import lib.settings as settings
|
||||||
|
import lib.logger
|
||||||
|
log = lib.logger.get_logger('Cache')
|
||||||
|
|
||||||
|
import pylibmc
|
||||||
|
|
||||||
|
class Cache():
|
||||||
|
def __init__(self):
|
||||||
|
# Open a new connection
|
||||||
|
self.mc = pylibmc.Client([settings.MEMCACHE_HOST + ":" + str(settings.MEMCACHE_PORT)], binary=True)
|
||||||
|
log.info("Caching initialized")
|
||||||
|
|
||||||
|
def set(self, key, value, time=settings.MEMCACHE_TIMEOUT):
|
||||||
|
return self.mc.set(settings.MEMCACHE_PREFIX + str(key), value, time)
|
||||||
|
|
||||||
|
def get(self, key):
|
||||||
|
return self.mc.get(settings.MEMCACHE_PREFIX + str(key))
|
||||||
|
|
||||||
|
def delete(self, key):
|
||||||
|
return self.mc.delete(settings.MEMCACHE_PREFIX + str(key))
|
||||||
|
|
||||||
|
def exists(self, key):
|
||||||
|
return str(key) in self.mc.get(settings.MEMCACHE_PREFIX + str(key))
|
||||||
@ -3,6 +3,7 @@ import time
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import Queue
|
import Queue
|
||||||
import signal
|
import signal
|
||||||
|
import Cache
|
||||||
|
|
||||||
import lib.settings as settings
|
import lib.settings as settings
|
||||||
|
|
||||||
@ -19,8 +20,7 @@ class DBInterface():
|
|||||||
self.q = Queue.Queue()
|
self.q = Queue.Queue()
|
||||||
self.queueclock = None
|
self.queueclock = None
|
||||||
|
|
||||||
self.usercache = {}
|
self.cache = Cache.Cache()
|
||||||
self.clearusercache()
|
|
||||||
|
|
||||||
self.nextStatsUpdate = 0
|
self.nextStatsUpdate = 0
|
||||||
|
|
||||||
@ -67,11 +67,6 @@ class DBInterface():
|
|||||||
return DB_None.DB_None()
|
return DB_None.DB_None()
|
||||||
|
|
||||||
|
|
||||||
def clearusercache(self):
|
|
||||||
log.debug("DBInterface.clearusercache called")
|
|
||||||
self.usercache = {}
|
|
||||||
self.usercacheclock = reactor.callLater(settings.DB_USERCACHE_TIME , self.clearusercache)
|
|
||||||
|
|
||||||
def scheduleImport(self):
|
def scheduleImport(self):
|
||||||
# This schedule's the Import
|
# This schedule's the Import
|
||||||
if settings.DATABASE_DRIVER == "sqlite":
|
if settings.DATABASE_DRIVER == "sqlite":
|
||||||
@ -163,19 +158,16 @@ class DBInterface():
|
|||||||
# Force username and password to be strings
|
# Force username and password to be strings
|
||||||
username = str(username)
|
username = str(username)
|
||||||
password = str(password)
|
password = str(password)
|
||||||
wid = username + ":-:" + password
|
if not settings.USERS_CHECK_PASSWORD and self.user_exists(username):
|
||||||
|
|
||||||
if wid in self.usercache:
|
|
||||||
return True
|
return True
|
||||||
elif not settings.USERS_CHECK_PASSWORD and self.user_exists(username):
|
elif self.cache.get(username) == password:
|
||||||
self.usercache[wid] = 1
|
|
||||||
return True
|
return True
|
||||||
elif self.dbi.check_password(username, password):
|
elif self.dbi.check_password(username, password):
|
||||||
self.usercache[wid] = 1
|
self.cache.set(username, password)
|
||||||
return True
|
return True
|
||||||
elif settings.USERS_AUTOADD == True:
|
elif settings.USERS_AUTOADD == True:
|
||||||
self.insert_user(username, password)
|
self.insert_user(username, password)
|
||||||
self.usercache[wid] = 1
|
self.cache.set(username, password)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
log.info("Authentication for %s failed" % username)
|
log.info("Authentication for %s failed" % username)
|
||||||
@ -188,6 +180,8 @@ class DBInterface():
|
|||||||
return self.dbi.get_user(id)
|
return self.dbi.get_user(id)
|
||||||
|
|
||||||
def user_exists(self, username):
|
def user_exists(self, username):
|
||||||
|
if self.cache.get(username) is not None:
|
||||||
|
return True
|
||||||
user = self.dbi.get_user(username)
|
user = self.dbi.get_user(username)
|
||||||
return user is not None
|
return user is not None
|
||||||
|
|
||||||
@ -195,11 +189,13 @@ class DBInterface():
|
|||||||
return self.dbi.insert_user(username, password)
|
return self.dbi.insert_user(username, password)
|
||||||
|
|
||||||
def delete_user(self, username):
|
def delete_user(self, username):
|
||||||
|
self.mc.delete(username)
|
||||||
self.usercache = {}
|
self.usercache = {}
|
||||||
return self.dbi.delete_user(username)
|
return self.dbi.delete_user(username)
|
||||||
|
|
||||||
def update_user(self, username, password):
|
def update_user(self, username, password):
|
||||||
self.usercache = {}
|
self.mc.delete(username)
|
||||||
|
self.mc.set(username, password)
|
||||||
return self.dbi.update_user(username, password)
|
return self.dbi.update_user(username, password)
|
||||||
|
|
||||||
def update_worker_diff(self, username, diff):
|
def update_worker_diff(self, username, diff):
|
||||||
|
|||||||
@ -60,6 +60,72 @@ class DB_Mysql_Vardiff(DB_Mysql.DB_Mysql):
|
|||||||
|
|
||||||
self.dbh.commit()
|
self.dbh.commit()
|
||||||
|
|
||||||
|
def found_block(self, data):
|
||||||
|
# for database compatibility we are converting our_worker to Y/N format
|
||||||
|
if data[5]:
|
||||||
|
data[5] = 'Y'
|
||||||
|
else:
|
||||||
|
data[5] = 'N'
|
||||||
|
|
||||||
|
# Check for the share in the database before updating it
|
||||||
|
# Note: We can't use DUPLICATE KEY because solution is not a key
|
||||||
|
|
||||||
|
self.execute(
|
||||||
|
"""
|
||||||
|
Select `id` from `shares`
|
||||||
|
WHERE `solution` = %(solution)s
|
||||||
|
LIMIT 1
|
||||||
|
""",
|
||||||
|
{
|
||||||
|
"solution": data[2]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
shareid = self.dbc.fetchone()
|
||||||
|
|
||||||
|
if shareid[0] > 0:
|
||||||
|
# Note: difficulty = -1 here
|
||||||
|
self.execute(
|
||||||
|
"""
|
||||||
|
UPDATE `shares`
|
||||||
|
SET `upstream_result` = %(result)s
|
||||||
|
WHERE `solution` = %(solution)s
|
||||||
|
AND `id` = %(id)s
|
||||||
|
LIMIT 1
|
||||||
|
""",
|
||||||
|
{
|
||||||
|
"result": data[5],
|
||||||
|
"solution": data[2],
|
||||||
|
"id": shareid[0]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.dbh.commit()
|
||||||
|
else:
|
||||||
|
self.execute(
|
||||||
|
"""
|
||||||
|
INSERT INTO `shares`
|
||||||
|
(time, rem_host, username, our_result,
|
||||||
|
upstream_result, reason, solution)
|
||||||
|
VALUES
|
||||||
|
(FROM_UNIXTIME(%(time)s), %(host)s,
|
||||||
|
%(uname)s,
|
||||||
|
%(lres)s, %(result)s, %(reason)s, %(solution)s)
|
||||||
|
""",
|
||||||
|
{
|
||||||
|
"time": v[4],
|
||||||
|
"host": v[6],
|
||||||
|
"uname": v[0],
|
||||||
|
"lres": v[5],
|
||||||
|
"result": v[5],
|
||||||
|
"reason": v[9],
|
||||||
|
"solution": v[2]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.dbh.commit()
|
||||||
|
|
||||||
|
|
||||||
def update_worker_diff(self, username, diff):
|
def update_worker_diff(self, username, diff):
|
||||||
log.debug("Setting difficulty for %s to %s", username, diff)
|
log.debug("Setting difficulty for %s to %s", username, diff)
|
||||||
|
|
||||||
|
|||||||
@ -44,17 +44,16 @@ def setup(on_startup):
|
|||||||
if isinstance(result, dict):
|
if isinstance(result, dict):
|
||||||
# litecoind implements version 1 of getblocktemplate
|
# litecoind implements version 1 of getblocktemplate
|
||||||
if result['version'] >= 1:
|
if result['version'] >= 1:
|
||||||
result = (yield bitcoin_rpc.getinfo())
|
result = (yield bitcoin_rpc.getdifficulty())
|
||||||
if isinstance(result,dict):
|
if isinstance(result,dict):
|
||||||
if 'stake' in result and settings.COINDAEMON_Reward == 'POS':
|
if 'proof-of-stake' in result:
|
||||||
log.info("CoinD looks to be a POS Coin, Config for POS looks correct")
|
settings.COINDAEMON_Reward = 'POS'
|
||||||
break
|
log.info("Coin detected as POS")
|
||||||
elif 'stake' not in result and settings.COINDAEMON_Reward == 'POW':
|
break;
|
||||||
log.info("CoinD looks to be a POW Coin, Config looks to be correct")
|
else:
|
||||||
break
|
settings.COINDAEMON_Reward = 'POW'
|
||||||
else:
|
log.info("Coin detected as POW")
|
||||||
log.error("Wrong Algo Selected, Switch to appropriate POS/POW in config.py!")
|
break;
|
||||||
reactor.stop()
|
|
||||||
else:
|
else:
|
||||||
log.error("Block Version mismatch: %s" % result['version'])
|
log.error("Block Version mismatch: %s" % result['version'])
|
||||||
|
|
||||||
|
|||||||
48
requirements.txt
Normal file
48
requirements.txt
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
# This File is used to create a list of requirements needed for testing stratum-mining or to create a clone install
|
||||||
|
BeautifulSoup==3.2.1
|
||||||
|
#Brlapi==0.5.7
|
||||||
|
#GnuPGInterface==0.3.2
|
||||||
|
MySQL-python==1.2.3
|
||||||
|
#PAM==0.4.2
|
||||||
|
#Pyste==0.9.10
|
||||||
|
#SOAPpy==0.12.0
|
||||||
|
Twisted==12.0.0
|
||||||
|
#Twisted-Conch==12.0.0
|
||||||
|
#Twisted-Core==12.0.0
|
||||||
|
#Twisted-Lore==12.0.0
|
||||||
|
#Twisted-Mail==12.0.0
|
||||||
|
#Twisted-Names==12.0.0
|
||||||
|
#Twisted-News==12.0.0
|
||||||
|
#Twisted-Runner==12.0.0
|
||||||
|
#Twisted-Web==12.0.0
|
||||||
|
#Twisted-Words==12.0.0
|
||||||
|
#apt-xapian-index==0.45
|
||||||
|
argparse==1.2.1
|
||||||
|
autobahn==0.6.5
|
||||||
|
#chardet==2.0.1
|
||||||
|
defer==1.0.6
|
||||||
|
distribute==0.6.28
|
||||||
|
ecdsa==0.10
|
||||||
|
feedparser==5.1.2
|
||||||
|
fpconst==0.7.2
|
||||||
|
httplib2==0.7.4
|
||||||
|
#louis==2.4.1
|
||||||
|
#ltc-scrypt==1.0
|
||||||
|
#numpy==1.6.2
|
||||||
|
pyOpenSSL==0.13
|
||||||
|
pyasn1==0.1.3
|
||||||
|
pycrypto==2.6
|
||||||
|
#pycurl==7.19.0
|
||||||
|
pyserial==2.5
|
||||||
|
#python-apt==0.8.8.2
|
||||||
|
#python-debian==0.1.21
|
||||||
|
#python-debianbts==1.11
|
||||||
|
python-memcached==1.48
|
||||||
|
pyxdg==0.19
|
||||||
|
#reportbug==6.4.4
|
||||||
|
simplejson==2.5.2
|
||||||
|
#stratum==0.2.13
|
||||||
|
#uTidylib==0.2
|
||||||
|
#unattended-upgrades==0.1
|
||||||
|
#wsgiref==0.1.2
|
||||||
|
zope.interface==3.6.1
|
||||||
Loading…
Reference in New Issue
Block a user