Fixed Master
This commit is contained in:
commit
4f25f3c887
2
.gitmodules
vendored
2
.gitmodules
vendored
@ -6,7 +6,7 @@
|
||||
url = https://github.com/Tydus/litecoin_scrypt.git
|
||||
[submodule "externals/stratum"]
|
||||
path = externals/stratum
|
||||
url = https://github.com/slush0/stratum.git
|
||||
url = https://github.com/ahmedbodi/stratum.git
|
||||
[submodule "externals/quarkcoin-hash"]
|
||||
path = externals/quarkcoin-hash
|
||||
url = https://github.com/Neisklar/quarkcoin-hash-python
|
||||
|
||||
12
README.md
12
README.md
@ -32,9 +32,9 @@ The goal is to make a reliable stratum mining server for scrypt based coins. Ove
|
||||
* WDC: WeVFgZQsKSKXGak7NJPp9SrcUexghzTPGJ
|
||||
* Doge: DLtBRYtNCzfiZfcpUeEr8KPvy5k1aR7jca
|
||||
*
|
||||
|
||||
#Requirements
|
||||
*stratum-mining* is built in python. I have been testing it with 2.7.3, but it should work with other versions. The requirements for running the software are below.
|
||||
|
||||
* Python 2.7+
|
||||
* python-twisted
|
||||
* stratum
|
||||
@ -56,7 +56,8 @@ Other coins have been known to work with this implementation. I have tested with
|
||||
* OpenSourceCoin
|
||||
* TekCoin
|
||||
* Franko
|
||||
|
||||
* Quark
|
||||
* Securecoin
|
||||
#Installation
|
||||
|
||||
The installation of this *stratum-mining* can be found in the Repo Wiki.
|
||||
@ -64,10 +65,16 @@ The installation of this *stratum-mining* can be found in the Repo Wiki.
|
||||
#Contact
|
||||
I am available in the #MPOS, #crypto-expert, #digitalcoin, and #worldcoin channels on freenode.
|
||||
Although i am willing to provide support through IRC please file issues on the repo.
|
||||
<<<<<<< HEAD
|
||||
Issues as a direct result of stratum will be helped with as much as possible
|
||||
However issues related to a coin daemon's setup and other non stratum issues,
|
||||
Please research and attempt to debug first.
|
||||
|
||||
=======
|
||||
issues as a direct result of stratum will be helped with as much as possible
|
||||
However issues related to a coin daemon's setup and other non stratum issues,
|
||||
Please research and attempt to debug first.
|
||||
|
||||
#Credits
|
||||
|
||||
* Original version by Slush0 (original stratum code)
|
||||
@ -76,7 +83,6 @@ Please research and attempt to debug first.
|
||||
* PoS conversion done by TheSeven
|
||||
* Multi Algo, Vardiff, DB and MPOS support done by Ahmed_Bodi and Obigal
|
||||
|
||||
|
||||
#License
|
||||
This software is provides AS-IS without any warranties of any kind. Please use at your own risk.
|
||||
|
||||
|
||||
@ -26,10 +26,7 @@ COINDAEMON_TRUSTED_PASSWORD = 'somepassword'
|
||||
# For Coins which support TX Messages please enter yes in the TX selection
|
||||
COINDAEMON_ALGO = 'scrypt'
|
||||
COINDAEMON_Reward = 'POW'
|
||||
COINDAEMON_TX_MSG = 'no'
|
||||
|
||||
# If you want a TX message in the block if the coin supports it, enter it below
|
||||
Tx_Message = 'http://github.com/ahmedbodi/stratum-mining'
|
||||
COINDAEMON_TX = 'no'
|
||||
# ******************** BASIC SETTINGS ***************
|
||||
# Backup Coin Daemon address's (consider having at least 1 backup)
|
||||
# You can have up to 99
|
||||
@ -45,10 +42,10 @@ Tx_Message = 'http://github.com/ahmedbodi/stratum-mining'
|
||||
#COINDAEMON_TRUSTED_PASSWORD_2 = 'somepassword'
|
||||
|
||||
# ******************** GENERAL SETTINGS ***************
|
||||
|
||||
# Set process name of twistd, much more comfortable if you run multiple processes on one machine
|
||||
STRATUM_MINING_PROCESS_NAME= 'twistd-stratum-mining'
|
||||
|
||||
|
||||
# Enable some verbose debug (logging requests and responses).
|
||||
DEBUG = False
|
||||
|
||||
@ -96,6 +93,7 @@ PASSWORD_SALT = 'some_crazy_string'
|
||||
|
||||
DATABASE_DRIVER = 'mysql' # Options: none, sqlite, postgresql or mysql
|
||||
DATABASE_EXTEND = False # SQLite and PGSQL Only!
|
||||
|
||||
# SQLite
|
||||
DB_SQLITE_FILE = 'pooldb.sqlite'
|
||||
# Postgresql
|
||||
@ -111,7 +109,6 @@ DB_MYSQL_USER = 'pooldb'
|
||||
DB_MYSQL_PASS = '**empty**'
|
||||
DB_MYSQL_PORT = 3306 # Default port for MySQL
|
||||
|
||||
|
||||
# ******************** Adv. DB Settings *********************
|
||||
# Don't change these unless you know what you are doing
|
||||
|
||||
@ -185,7 +182,11 @@ ENABLE_WORKER_BANNING = True # enable/disable temporary worker banning
|
||||
WORKER_CACHE_TIME = 600 # How long the worker stats cache is good before we check and refresh
|
||||
WORKER_BAN_TIME = 300 # How long we temporarily ban worker
|
||||
INVALID_SHARES_PERCENT = 50 # Allow average invalid shares vary this % before we ban
|
||||
|
||||
|
||||
#Pass scrypt hash to submit block check.
|
||||
#Use if submit block is returning errors and marking submitted blocks invaild upstream, but the submitted blocks are being a accepted by the coin daemon into the block chain.
|
||||
BLOCK_CHECK_SCRYPT_HASH = False
|
||||
|
||||
# ******************** E-Mail Notification Settings *********************
|
||||
NOTIFY_EMAIL_TO = '' # Where to send Start/Found block notifications
|
||||
NOTIFY_EMAIL_TO_DEADMINER = '' # Where to send dead miner notifications
|
||||
|
||||
@ -45,7 +45,7 @@ class BitcoinRPC(object):
|
||||
# Try submitblock if that fails, go to getblocktemplate
|
||||
try:
|
||||
log.debug("Submitting Block with Submit Block ")
|
||||
log.info([block_hex,])
|
||||
log.debug([block_hex,])
|
||||
resp = (yield self._call('submitblock', [block_hex,]))
|
||||
except Exception:
|
||||
try:
|
||||
|
||||
@ -6,6 +6,8 @@ import util
|
||||
import merkletree
|
||||
import halfnode
|
||||
from coinbasetx import CoinbaseTransaction
|
||||
import lib.logger
|
||||
log = lib.logger.get_logger('block_template')
|
||||
|
||||
import lib.logger
|
||||
log = lib.logger.get_logger('block_template')
|
||||
@ -24,6 +26,7 @@ class BlockTemplate(halfnode.CBlock):
|
||||
|
||||
def __init__(self, timestamper, coinbaser, job_id):
|
||||
log.debug("Got To Block_template.py")
|
||||
log.debug("Got To Block_template.py")
|
||||
super(BlockTemplate, self).__init__()
|
||||
|
||||
self.job_id = job_id
|
||||
|
||||
@ -17,8 +17,8 @@ class BlockUpdater(object):
|
||||
'''
|
||||
|
||||
def __init__(self, registry, bitcoin_rpc):
|
||||
log.debug("Got to Block Updater")
|
||||
self.bitcoin_rpc = bitcoin_rpc
|
||||
log.debug("Got To Block Updater")
|
||||
self.bitcoin_rpc = bitcoin_rpc
|
||||
self.registry = registry
|
||||
self.clock = None
|
||||
self.schedule()
|
||||
|
||||
@ -31,58 +31,52 @@ class SimpleCoinbaser(object):
|
||||
d.addErrback(self._failure)
|
||||
|
||||
def _POW_address_check(self, result):
|
||||
if result['isvalid'] == True:
|
||||
log.debug("Is Valid = %s" % result['isvalid'])
|
||||
log.debug("Address = %s " % result['address'])
|
||||
log.debug("Is Script = %s" % result['isscript'])
|
||||
log.debug("PubKey = %s " % result['pubkey'])
|
||||
log.debug("Is Compressed = %s " % result['iscompressed'])
|
||||
log.debug("Account = %s " % result['account'])
|
||||
self.address = result['address']
|
||||
if result['isvalid'] and result['ismine']:
|
||||
self.is_valid = True
|
||||
log.info("Wallet address '%s' is valid" % self.address)
|
||||
|
||||
if not self.on_load.called:
|
||||
self.on_load.callback(True)
|
||||
|
||||
elif result['isvalid'] and settings.ALLOW_NONLOCAL_WALLET == True :
|
||||
self.is_valid = True
|
||||
log.warning("!!! Wallet address '%s' is valid BUT it is not local" % self.address)
|
||||
|
||||
if not self.on_load.called:
|
||||
self.on_load.callback(True)
|
||||
|
||||
else:
|
||||
self.is_valid = False
|
||||
log.exception("Wallet address '%s' is NOT valid!" % self.address)
|
||||
|
||||
def _POS_address_check(self, result):
|
||||
if result['isvalid'] == True:
|
||||
log.debug("Is Valid = %s" % result['isvalid'])
|
||||
log.debug("Address = %s " % result['address'])
|
||||
log.debug("Is Script = %s" % result['isscript'])
|
||||
log.debug("PubKey = %s " % result['pubkey'])
|
||||
log.debug("Is Compressed = %s " % result['iscompressed'])
|
||||
log.debug("Account = %s " % result['account'])
|
||||
self.pubkey = result['pubkey']
|
||||
if result['isvalid'] and result['ismine']:
|
||||
self.is_valid = True
|
||||
log.info("Wallet address '%s' is valid" % self.address)
|
||||
|
||||
if result['isvalid'] and result['ismine']:
|
||||
self.is_valid = True
|
||||
log.info("Coinbase address '%s' is valid" % self.address)
|
||||
if result['isvalid'] == True:
|
||||
log.debug("Is Valid = %s" % result['isvalid'])
|
||||
log.debug("Address = %s " % result['address'])
|
||||
log.debug("PubKey = %s " % result['pubkey'])
|
||||
log.debug("Is Compressed = %s " % result['iscompressed'])
|
||||
log.debug("Account = %s " % result['account'])
|
||||
self.address = result['address']
|
||||
if not self.on_load.called:
|
||||
self.on_load.callback(True)
|
||||
self.on_load.callback(True)
|
||||
|
||||
elif result['isvalid'] and settings.ALLOW_NONLOCAL_WALLET == True :
|
||||
self.is_valid = True
|
||||
log.warning("!!! Coinbase address '%s' is valid BUT it is not local" % self.address)
|
||||
if not self.on_load.called:
|
||||
self.on_load.callback(True)
|
||||
|
||||
else:
|
||||
self.is_valid = False
|
||||
log.error("Coinbase address '%s' is NOT valid!" % self.address)
|
||||
|
||||
def _POS_address_check(self, result):
|
||||
if result['isvalid'] and result['ismine']:
|
||||
self.is_valid = True
|
||||
log.info("Coinbase address '%s' is valid" % self.address)
|
||||
if result['isvalid'] == True:
|
||||
log.debug("Is Valid = %s" % result['isvalid'])
|
||||
log.debug("Address = %s " % result['address'])
|
||||
log.debug("PubKey = %s " % result['pubkey'])
|
||||
log.debug("Is Compressed = %s " % result['iscompressed'])
|
||||
log.debug("Account = %s " % result['account'])
|
||||
self.pubkey = result['pubkey']
|
||||
if not self.on_load.called:
|
||||
self.on_load.callback(True)
|
||||
|
||||
elif result['isvalid'] and settings.ALLOW_NONLOCAL_WALLET == True :
|
||||
self.is_valid = True
|
||||
log.warning("!!! Wallet address '%s' is valid BUT it is not local" % self.address)
|
||||
|
||||
if not self.on_load.called:
|
||||
self.on_load.callback(True)
|
||||
elif result['isvalid'] and settings.ALLOW_NONLOCAL_WALLET == True :
|
||||
self.is_valid = True
|
||||
log.warning("!!! Coinbase address '%s' is valid BUT it is not local" % self.address)
|
||||
self.pubkey = result['pubkey']
|
||||
if not self.on_load.called:
|
||||
self.on_load.callback(True)
|
||||
|
||||
else:
|
||||
self.is_valid = False
|
||||
log.exception("Wallet address '%s' is NOT valid!" % self.address)
|
||||
self.is_valid = False
|
||||
|
||||
#def on_new_block(self):
|
||||
# pass
|
||||
|
||||
@ -6,7 +6,6 @@ import settings
|
||||
import lib.logger
|
||||
log = lib.logger.get_logger('coinbasetx')
|
||||
|
||||
|
||||
if settings.COINDAEMON_Reward == 'POW':
|
||||
class CoinbaseTransaction(halfnode.CTransaction):
|
||||
'''Construct special transaction used for coinbase tx.
|
||||
@ -19,7 +18,7 @@ if settings.COINDAEMON_Reward == 'POW':
|
||||
|
||||
def __init__(self, timestamper, coinbaser, value, flags, height, data):
|
||||
super(CoinbaseTransaction, self).__init__()
|
||||
log.debug("Got to CoinBaseTX")
|
||||
log.debug("Got to CoinBaseTX")
|
||||
#self.extranonce = 0
|
||||
|
||||
if len(self.extranonce_placeholder) != self.extranonce_size:
|
||||
@ -40,8 +39,8 @@ if settings.COINDAEMON_Reward == 'POW':
|
||||
tx_out.nValue = value
|
||||
tx_out.scriptPubKey = coinbaser.get_script_pubkey()
|
||||
|
||||
if settings.COINDAEMON_TX_MSG == 'yes':
|
||||
self.strTxComment = settings.Tx_Message
|
||||
if settings.COINDAEMON_TX == 'yes':
|
||||
self.strTxComment = "http://github.com/ahmedbodi/stratum-mining"
|
||||
self.vin.append(tx_in)
|
||||
self.vout.append(tx_out)
|
||||
|
||||
@ -88,8 +87,8 @@ elif settings.COINDAEMON_Reward == 'POS':
|
||||
tx_out.scriptPubKey = coinbaser.get_script_pubkey()
|
||||
|
||||
self.nTime = ntime
|
||||
if settings.COINDAEMON_TX_MSG == 'yes':
|
||||
self.strTxComment = settings.Tx_Message
|
||||
if settings.COINDAEMON_SHA256_TX == 'yes':
|
||||
self.strTxComment = "http://github.com/ahmedbodi/stratum-mining"
|
||||
self.vin.append(tx_in)
|
||||
self.vout.append(tx_out)
|
||||
|
||||
@ -114,7 +113,7 @@ else:
|
||||
|
||||
def __init__(self, timestamper, coinbaser, value, flags, height, data, ntime):
|
||||
super(CoinbaseTransaction, self).__init__()
|
||||
log.debug("Got to CoinBaseTX")
|
||||
log.debug("Got to CoinBaseTX")
|
||||
#self.extranonce = 0
|
||||
|
||||
if len(self.extranonce_placeholder) != self.extranonce_size:
|
||||
|
||||
@ -2,7 +2,6 @@ import struct
|
||||
import lib.logger
|
||||
log = lib.logger.get_logger('extronance')
|
||||
|
||||
|
||||
class ExtranonceCounter(object):
|
||||
'''Implementation of a counter producing
|
||||
unique extranonce across all pool instances.
|
||||
@ -10,6 +9,7 @@ class ExtranonceCounter(object):
|
||||
but it can be changed at any time without breaking anything.'''
|
||||
|
||||
def __init__(self, instance_id):
|
||||
log.debug("Got to Extronance Counter")
|
||||
if instance_id < 0 or instance_id > 31:
|
||||
raise Exception("Current ExtranonceCounter implementation needs an instance_id in <0, 31>.")
|
||||
log.debug("Got To Extronance")
|
||||
|
||||
@ -28,7 +28,6 @@ elif settings.COINDAEMON_ALGO == 'quark':
|
||||
import quark_hash
|
||||
else:
|
||||
log.debug("########################################### Loading SHA256 Support ######################################################")
|
||||
pass
|
||||
|
||||
if settings.COINDAEMON_Reward == 'POS':
|
||||
log.debug("########################################### Loading POS Support #########################################################")
|
||||
@ -37,11 +36,11 @@ else:
|
||||
log.debug("########################################### Loading POW Support ######################################################")
|
||||
pass
|
||||
|
||||
if settings.COINDAEMON_TX_MSG == 'yes':
|
||||
log.debug("########################################### Loading Transaction Message Support #########################################################")
|
||||
log.info(settings.Tx_Message)
|
||||
if settings.COINDAEMON_TX == 'yes':
|
||||
log.debug("########################################### Loading SHA256 Transaction Message Support #########################################################")
|
||||
pass
|
||||
else:
|
||||
log.debug("########################################### NOT Loading SHA256 Transaction Message Support ######################################################")
|
||||
pass
|
||||
|
||||
|
||||
@ -159,7 +158,7 @@ class CTransaction(object):
|
||||
def __init__(self):
|
||||
if settings.COINDAEMON_Reward == 'POW':
|
||||
self.nVersion = 1
|
||||
if settings.COINDAEMON_TX_MSG == 'yes':
|
||||
if settings.COINDAEMON_TX == 'yes':
|
||||
self.nVersion = 2
|
||||
self.vin = []
|
||||
self.vout = []
|
||||
@ -167,15 +166,15 @@ class CTransaction(object):
|
||||
self.sha256 = None
|
||||
elif settings.COINDAEMON_Reward == 'POS':
|
||||
self.nVersion = 1
|
||||
if settings.COINDAEMON_TX_MSG == 'yes':
|
||||
if settings.COINDAEMON_TX == 'yes':
|
||||
self.nVersion = 2
|
||||
self.nTime = 0
|
||||
self.vin = []
|
||||
self.vout = []
|
||||
self.nLockTime = 0
|
||||
self.sha256 = None
|
||||
if settings.COINDAEMON_TX_MSG == 'yes':
|
||||
self.strTxComment = settings.Tx_Message
|
||||
if settings.COINDAEMON_TX == 'yes':
|
||||
self.strTxComment = ""
|
||||
|
||||
def deserialize(self, f):
|
||||
if settings.COINDAEMON_Reward == 'POW':
|
||||
@ -191,7 +190,7 @@ class CTransaction(object):
|
||||
self.vout = deser_vector(f, CTxOut)
|
||||
self.nLockTime = struct.unpack("<I", f.read(4))[0]
|
||||
self.sha256 = None
|
||||
if settings.COINDAEMON_TX_MSG == 'yes':
|
||||
if settings.COINDAEMON_TX == 'yes':
|
||||
self.strTxComment = deser_string(f)
|
||||
|
||||
def serialize(self):
|
||||
@ -208,7 +207,7 @@ class CTransaction(object):
|
||||
r += ser_vector(self.vin)
|
||||
r += ser_vector(self.vout)
|
||||
r += struct.pack("<I", self.nLockTime)
|
||||
if settings.COINDAEMON_TX_MSG == 'yes':
|
||||
if settings.COINDAEMON_TX == 'yes':
|
||||
r += ser_string(self.strTxComment)
|
||||
return r
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@ from lib.exceptions import SubmitException
|
||||
|
||||
import lib.logger
|
||||
log = lib.logger.get_logger('template_registry')
|
||||
|
||||
log.debug("Got to Template Registry")
|
||||
from mining.interfaces import Interfaces
|
||||
from extranonce_counter import ExtranonceCounter
|
||||
import lib.settings as settings
|
||||
@ -69,7 +69,7 @@ class TemplateRegistry(object):
|
||||
def get_last_broadcast_args(self):
|
||||
'''Returns arguments for mining.notify
|
||||
from last known template.'''
|
||||
log.debug("Getting arguments needed for mining.notify")
|
||||
log.debug("Getting Laat Template")
|
||||
return self.last_block.broadcast_args
|
||||
|
||||
def add_template(self, block,block_height):
|
||||
@ -268,23 +268,25 @@ class TemplateRegistry(object):
|
||||
log.info("We found a block candidate! %s" % scrypt_hash_hex)
|
||||
|
||||
# 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')
|
||||
|
||||
if settings.COINDAEMON_ALGO == 'scrypt' or settings.COINDAEMON_ALGO == 'sha256d':
|
||||
if settings.COINDAEMON_Reward == 'POW':
|
||||
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')
|
||||
else:
|
||||
block_hash_hex = hash_bin[::-1].encode('hex_codec')
|
||||
# 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():
|
||||
# Should not happen
|
||||
log.info("Final job validation failed!")
|
||||
log.exception("FINAL JOB VALIDATION FAILED!(Try enabling/disabling tx messages)")
|
||||
|
||||
# 7. Submit block to the network
|
||||
serialized = binascii.hexlify(job.serialize())
|
||||
if settings.BLOCK_CHECK_SCRYPT_HASH:
|
||||
if settings.BLOCK_CHECK_SCRYPT_HASH:
|
||||
on_submit = self.bitcoin_rpc.submitblock(serialized, scrypt_hash_hex)
|
||||
else:
|
||||
on_submit = self.bitcoin_rpc.submitblock(serialized, block_hash_hex)
|
||||
|
||||
if on_submit:
|
||||
self.update_block()
|
||||
|
||||
|
||||
@ -73,6 +73,7 @@ class DB_Mysql():
|
||||
log.debug(data)
|
||||
|
||||
for k, v in enumerate(data):
|
||||
log.debug(v)
|
||||
# for database compatibility we are converting our_worker to Y/N format
|
||||
if v[5]:
|
||||
v[5] = 'Y'
|
||||
@ -87,16 +88,17 @@ class DB_Mysql():
|
||||
VALUES
|
||||
(FROM_UNIXTIME(%(time)s), %(host)s,
|
||||
%(uname)s,
|
||||
%(lres)s, 'N', %(reason)s, %(solution)s, %(difficulty)s)
|
||||
%(lres)s, %(result)s, %(reason)s, %(solution)s, %(difficulty)s )
|
||||
""",
|
||||
{
|
||||
"time": v[4],
|
||||
"host": v[6],
|
||||
"uname": v[0],
|
||||
"lres": v[5],
|
||||
"reason": v[9],
|
||||
"solution": v[2],
|
||||
"difficulty": v[3]
|
||||
"time": data[4],
|
||||
"host": data[6],
|
||||
"uname": data[0],
|
||||
"lres": data[5],
|
||||
"result": data[5],
|
||||
"reason": data[9],
|
||||
"solution": data[2],
|
||||
"difficulty": data[3]
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@ -46,13 +46,14 @@ class DB_Mysql_Vardiff(DB_Mysql.DB_Mysql):
|
||||
VALUES
|
||||
(FROM_UNIXTIME(%(time)s), %(host)s,
|
||||
%(uname)s,
|
||||
%(lres)s, 'N', %(reason)s, %(solution)s, %(difficulty)s)
|
||||
%(lres)s, %(result)s, %(reason)s, %(solution)s, %(difficulty)s)
|
||||
""",
|
||||
{
|
||||
"time": v[4],
|
||||
"host": v[6],
|
||||
"uname": v[0],
|
||||
"lres": v[5],
|
||||
"result": data[5],
|
||||
"reason": v[9],
|
||||
"solution": v[2],
|
||||
"difficulty": v[3]
|
||||
|
||||
@ -105,7 +105,7 @@ class Interfaces(object):
|
||||
share_limiter = None
|
||||
timestamper = None
|
||||
template_registry = None
|
||||
|
||||
|
||||
@classmethod
|
||||
def set_worker_manager(cls, manager):
|
||||
cls.worker_manager = manager
|
||||
|
||||
@ -8,7 +8,6 @@ from interfaces import Interfaces
|
||||
from subscription import MiningSubscription
|
||||
from lib.exceptions import SubmitException
|
||||
import json
|
||||
|
||||
import lib.logger
|
||||
log = lib.logger.get_logger('mining')
|
||||
|
||||
@ -45,7 +44,7 @@ class MiningService(GenericService):
|
||||
|
||||
log.debug("Server stats request: %s" % serialized)
|
||||
return '%s' % serialized
|
||||
|
||||
|
||||
@admin
|
||||
def update_block(self):
|
||||
'''Connect this RPC call to 'litecoind -blocknotify' for
|
||||
|
||||
46
scripts/refreshconfig.sh
Normal file
46
scripts/refreshconfig.sh
Normal file
@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env python
|
||||
# Send notification to Stratum mining instance add a new litecoind instance to the pool
|
||||
|
||||
import socket
|
||||
import json
|
||||
import sys
|
||||
import argparse
|
||||
import time
|
||||
|
||||
start = time.time()
|
||||
|
||||
parser = argparse.ArgumentParser(description='Refresh the config of the Stratum instance.')
|
||||
parser.add_argument('--password', dest='password', type=str, help='use admin password from Stratum server config')
|
||||
parser.add_argument('--host', dest='host', type=str, default='localhost', help='hostname of Stratum mining instance')
|
||||
parser.add_argument('--port', dest='port', type=int, default=3333, help='port of Stratum mining instance')
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.password == None:
|
||||
parser.print_help()
|
||||
sys.exit()
|
||||
|
||||
message = {'id': 1, 'method': 'mining.refresh_config', 'params': []}
|
||||
|
||||
try:
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.connect((args.host, args.port))
|
||||
s.sendall(json.dumps(message)+"\n")
|
||||
data = s.recv(16000)
|
||||
s.close()
|
||||
except IOError:
|
||||
print "Refresh Config: Cannot connect to the pool"
|
||||
sys.exit()
|
||||
|
||||
for line in data.split("\n"):
|
||||
if not line.strip():
|
||||
# Skip last line which doesn't contain any message
|
||||
continue
|
||||
|
||||
message = json.loads(line)
|
||||
if message['id'] == 1:
|
||||
if message['result'] == True:
|
||||
print "Refresh Config: done in %.03f sec" % (time.time() - start)
|
||||
else:
|
||||
print "Refresh Config: Error during request:", message['error'][1]
|
||||
else:
|
||||
print "Refresh Config: Unexpected message from the server:", message
|
||||
Loading…
Reference in New Issue
Block a user