From ec83c7898ae738e743ae48ef90404ef0969e9b1b Mon Sep 17 00:00:00 2001 From: mcdmaster Date: Fri, 27 Mar 2020 07:39:52 +0900 Subject: [PATCH 1/5] Update requirements.txt --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index dfa3fc5..712938f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ -Twisted==16.1.1 +Twisted>=19.7.0 zope.interface==4.1.3 From df973b5bdf9898984fcd7b8e3ee1c5306e8bd66c Mon Sep 17 00:00:00 2001 From: mcdmaster Date: Fri, 27 Mar 2020 07:45:23 +0900 Subject: [PATCH 2/5] Update getwork_listener.py --- mining_libs/getwork_listener.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mining_libs/getwork_listener.py b/mining_libs/getwork_listener.py index 6fabd21..c521717 100644 --- a/mining_libs/getwork_listener.py +++ b/mining_libs/getwork_listener.py @@ -27,12 +27,12 @@ def json_error(self, msg_id, message): return resp def render_POST(self, request): - request.setHeader('content-type', 'application/json') + request.setHeader(b'content-type', b'application/json') data = json.loads(request.content.read()) if not self.job_registry.jobs: log.warning('Proxy is waiting for a job...') - request.write(self.json_error(data.get('id', 0), "Proxy is waiting for a job...")+'\n') + request.write((self.json_error(data.get('id', 0), "Proxy is waiting for a job...")+'\n').encode()) request.finish() return NOT_DONE_YET @@ -48,9 +48,9 @@ def render_POST(self, request): response = self.json_response(data.get('id', 0), self.job_registry.jobs.params) elif data['method'] == 'eth_submitWork' or data['method'] == 'eth_submitHashrate': if self.isWorkerID: - worker_name = request.uri[1:15].split("/")[0] + worker_name = request.uri[1:15].split(b"/")[0] if not worker_name: - ip_temp = request.getClientIP().split('.') + ip_temp = request.getClientIP().split(b'.') worker_name = str( int(ip_temp[0])*16777216 + int(ip_temp[1])*65536 + int(ip_temp[2])*256 + int(ip_temp[3]) ) else: worker_name = '' @@ -67,7 +67,7 @@ def render_POST(self, request): response = self.json_error(data.get('id'), "Unsupported method '%s'" % data['method']) try: - request.write(response+'\n') + request.write(("%s\n" % response).encode()) request.finish() return NOT_DONE_YET except Exception: @@ -89,4 +89,4 @@ def render_GET(self, request): if self.job_registry.f3: connected = "connected" if (hasattr(self.job_registry.f3, "is_connected") and self.job_registry.f3.is_connected) else "disconnected" ret_text += "Failover server3 %s:%s (%s) %s
" % (self.job_registry.f3.main_host[0], self.job_registry.f3.main_host[1], self.job_registry.f3.remote_ip, connected) - return ret_text + return "".join(ret_text).encode() From 22a6da46b2dea744276e0910e9912d46dc605715 Mon Sep 17 00:00:00 2001 From: mcdmaster Date: Fri, 27 Mar 2020 07:52:18 +0900 Subject: [PATCH 3/5] Update protocol.py --- stratum/protocol.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/stratum/protocol.py b/stratum/protocol.py index 97ed104..5797313 100644 --- a/stratum/protocol.py +++ b/stratum/protocol.py @@ -32,7 +32,7 @@ def finish(self): self.on_finish.callback(True) class Protocol(LineOnlyReceiver): - delimiter = '\n' + delimiter = b'\n' def _get_id(self): self.request_id += 1 @@ -100,27 +100,27 @@ def connectionLost(self, reason): def writeJsonRequest(self, method, params, worker, is_notification=False): request_id = None if is_notification else self._get_id() - serialized = json.dumps({'id': request_id, 'method': method, 'params': params, 'jsonrpc':'2.0', 'worker': worker}) + serialized = json.dumps({'id': request_id, 'method': method, 'params': params, 'jsonrpc':'2.0', 'worker': worker}).encode() if self.factory.debug: - log.debug("< %s" % serialized) + log.debug(b"< %b" % serialized) - self.transport_write("%s\n" % serialized) + self.transport_write(b"%b\n" % serialized) return request_id def writeJsonResponse(self, data, message_id): if not data: return - serialized = json.dumps({'id': message_id, 'result': data, 'error': None, 'jsonrpc':'2.0'}) + serialized = json.dumps({'id': message_id, 'result': data, 'error': None, 'jsonrpc':'2.0'}).encode() if self.factory.debug: - log.debug("< %s" % serialized) + log.debug(b"< %b" % serialized) - self.transport_write("%s\n" % serialized) + self.transport_write(b"%b\n" % serialized) def writeJsonError(self, code, message, traceback, message_id): - serialized = json.dumps({'id': message_id, 'result': None, 'error': (code, message, traceback)}) - self.transport_write("%s\n" % serialized) + serialized = json.dumps({'id': message_id, 'result': None, 'error': (code, message, traceback)}).encode() + self.transport_write(b"%b\n" % serialized) def writeGeneralError(self, message, code=-1): log.error(message) From ef389649b14b70eab817934244f803e911e46a37 Mon Sep 17 00:00:00 2001 From: mcdmaster Date: Fri, 27 Mar 2020 07:53:00 +0900 Subject: [PATCH 4/5] Update eth-proxy.py --- eth-proxy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eth-proxy.py b/eth-proxy.py index 1fbe785..1f895e7 100644 --- a/eth-proxy.py +++ b/eth-proxy.py @@ -166,7 +166,7 @@ def main(): log.warning("-----------------------------------------------------------------------") if __name__ == '__main__': - fp = file("eth-proxy.pid", 'w') + fp = open("eth-proxy.pid", 'w') fp.write(str(os.getpid())) fp.close() main() From bbe7a04ca63950c69561e87ec69a9e2a53791fdb Mon Sep 17 00:00:00 2001 From: mcdmaster Date: Tue, 19 Jan 2021 00:01:06 +0900 Subject: [PATCH 5/5] Enable leading user.worker:pass@ in URL --- eth-proxy.conf | 146 ++++++++++++++++---------------- mining_libs/client_service.py | 13 ++- mining_libs/getwork_listener.py | 3 + stratum/__init__.py | 2 +- stratum/connection_registry.py | 4 +- stratum/event_handler.py | 6 +- stratum/logger.py | 2 +- stratum/protocol.py | 10 +-- stratum/server.py | 10 +-- stratum/services.py | 2 +- stratum/settings.py | 12 +-- stratum/socket_transport.py | 10 +-- stratum/socksclient.py | 54 ++++++------ stratum/stats.py | 2 +- 14 files changed, 141 insertions(+), 135 deletions(-) diff --git a/eth-proxy.conf b/eth-proxy.conf index 3887604..b3ef7f5 100644 --- a/eth-proxy.conf +++ b/eth-proxy.conf @@ -1,71 +1,75 @@ -### -# Examples of command line for miners: -# -# ethminer.exe --farm-recheck 200 -G -F http://HOST:PORT/ -# ethminer.exe --farm-recheck 300 -G -F http://HOST:PORT/rig1 -# -# ethminer.exe -G -F http://127.0.0.1:8080/ -# ethminer.exe --farm-recheck 100 -G -F http://192.168.0.33:8080/rig1 -# -# farm-recheck parameter is very individual. Just test different values. -# -# You can submit shares without workername or -# You can provide workername: -# - with url like "/rig1" -# - or use automatically numbering(integer) based on IP of miner -# -# Servers: -# EU-Server: eth-eu.dwarfpool.com (France) -# US-Server: eth-us.dwarfpool.com (EastCoast: Montreal,Canada) -# US-Server: eth-us2.dwarfpool.com (WestCoast: Las Vegas) -# RU-Server: eth-ru.dwarfpool.com (Moscow) -# HK-Server: eth-hk.dwarfpool.com (Hong-Kong) -# CN-Server: eth-cn.dwarfpool.com (Shanghai) -# SG-Server: eth-sg.dwarfpool.com (Singapore) -# AU-Server: eth-au.dwarfpool.com (Melbourne) -# -### - -# Select Ethereum ETH or Expanse EXP -COIN = "ETH" - -# Host and port for your workers -HOST = "0.0.0.0" -PORT = 8080 - -# Coin address where money goes -WALLET = "XXXXXX" - -# To donate please use wallet "0xea7263feb7d8a8ab0a11eedd8f1ce04412ab0820" - -# It's useful for individually monitoring and statistic -ENABLE_WORKER_ID = False - -# On DwarfPool you have option to monitor your workers via email. -# If WORKER_ID is enabled, you can monitor every worker/rig separately. -MONITORING = False -MONITORING_EMAIL = "mail@example.com" - -# Main pool -POOL_HOST = "eth-eu.dwarfpool.com" -POOL_PORT = 8008 - -# Failover pool -POOL_FAILOVER_ENABLE = True - -POOL_HOST_FAILOVER1 = "eth-ru.dwarfpool.com" -POOL_PORT_FAILOVER1 = 8008 - -POOL_HOST_FAILOVER2 = "eth-us.dwarfpool.com" -POOL_PORT_FAILOVER2 = 8008 - -POOL_HOST_FAILOVER3 = "eth-hk.dwarfpool.com" -POOL_PORT_FAILOVER3 = 8008 - - -# Logging -LOG_TO_FILE = True - -# Enable debug -DEBUG = False - \ No newline at end of file +### +# Examples of command line for miners: +# +# ethminer.exe --farm-recheck 200 -G -F http://HOST:PORT/ +# ethminer.exe --farm-recheck 300 -G -F http://HOST:PORT/rig1 +# ethminer.exe --farm-recheck 400 -G -P stratum+tcp://user.rig1:pass@HOST:PORT +# +# ethminer.exe -G -F http://127.0.0.1:8080/ +# ethminer.exe --farm-recheck 100 -G -F http://192.168.0.33:8080/rig1 +# +# farm-recheck parameter is very individual. Just test different values. +# +# You can submit shares without workername or +# You can provide workername: +# - with url like "/rig1" +# - or use automatically numbering(integer) based on IP of miner +# +# Servers: +# EU-Server: eth-eu.dwarfpool.com (France) +# US-Server: eth-us.dwarfpool.com (EastCoast: Montreal,Canada) +# US-Server: eth-us2.dwarfpool.com (WestCoast: Las Vegas) +# RU-Server: eth-ru.dwarfpool.com (Moscow) +# HK-Server: eth-hk.dwarfpool.com (Hong-Kong) +# CN-Server: eth-cn.dwarfpool.com (Shanghai) +# SG-Server: eth-sg.dwarfpool.com (Singapore) +# AU-Server: eth-au.dwarfpool.com (Melbourne) +# +### + +# Select Ethereum ETH or Expanse EXP +COIN = "ETH" + +# Host and port for your workers +HOST = "0.0.0.0" +PORT = 8080 + +# Coin address where money goes +WALLET = "XXXXXX" + +# To donate please use wallet "0xea7263feb7d8a8ab0a11eedd8f1ce04412ab0820" + +# It's useful for individually monitoring and statistic +# Your pool user ID / password can be provided as well +ENABLE_WORKER_ID = False +# ENABLE_WORKER_ID = "rig1" +# ENABLE_WORKER_ID = "user.rig1" +# ENABLE_WORKER_ID = "user.rig1:pass" + +# On DwarfPool you have option to monitor your workers via email. +# If WORKER_ID is enabled, you can monitor every worker/rig separately. +MONITORING = False +MONITORING_EMAIL = "mail@example.com" + +# Main pool +POOL_HOST = "eth-eu.dwarfpool.com" +POOL_PORT = 8008 + +# Failover pool +POOL_FAILOVER_ENABLE = True + +POOL_HOST_FAILOVER1 = "eth-ru.dwarfpool.com" +POOL_PORT_FAILOVER1 = 8008 + +POOL_HOST_FAILOVER2 = "eth-us.dwarfpool.com" +POOL_PORT_FAILOVER2 = 8008 + +POOL_HOST_FAILOVER3 = "eth-hk.dwarfpool.com" +POOL_PORT_FAILOVER3 = 8008 + + +# Logging +LOG_TO_FILE = True + +# Enable debug +DEBUG = False \ No newline at end of file diff --git a/mining_libs/client_service.py b/mining_libs/client_service.py index 57be2a8..9d39cb6 100644 --- a/mining_libs/client_service.py +++ b/mining_libs/client_service.py @@ -1,11 +1,10 @@ from twisted.internet import reactor - from stratum.event_handler import GenericEventHandler -from jobs import Job -import version as _version +from mining_libs.jobs import Job -import stratum.logger -log = stratum.logger.get_logger('proxy') +import stratum.version as _version +from stratum import logger +log = logger.get_logger('proxy') class ClientMiningService(GenericEventHandler): job_registry = None # Reference to JobRegistry instance @@ -47,8 +46,8 @@ def handle_event(self, method, params, connection_ref): if method == 'eth_getWork': '''Proxy just received information about new mining job''' # Broadcast to getwork clients - job = Job.build_from_pool(params) - self.job_registry.replace_job(job, connection_ref) + jobpool = Job.build_from_pool(params) + self.job_registry.replace_job(jobpool, connection_ref) else: '''Pool just asked us for something which we don't support...''' diff --git a/mining_libs/getwork_listener.py b/mining_libs/getwork_listener.py index c521717..32c221e 100644 --- a/mining_libs/getwork_listener.py +++ b/mining_libs/getwork_listener.py @@ -8,6 +8,8 @@ import stratum.logger log = stratum.logger.get_logger('proxy') +from stratum.settings import ENABLE_WORKER_ID + class Root(Resource): isLeaf = True @@ -28,6 +30,7 @@ def json_error(self, msg_id, message): def render_POST(self, request): request.setHeader(b'content-type', b'application/json') + request.setHeader(b'Authorization', b'basic: %s' % ENABLE_WORKER_ID) data = json.loads(request.content.read()) if not self.job_registry.jobs: diff --git a/stratum/__init__.py b/stratum/__init__.py index 552a734..da050f4 100644 --- a/stratum/__init__.py +++ b/stratum/__init__.py @@ -1 +1 @@ -from server import setup +from stratum.server import setup diff --git a/stratum/connection_registry.py b/stratum/connection_registry.py index 5065f2c..1735bd8 100644 --- a/stratum/connection_registry.py +++ b/stratum/connection_registry.py @@ -1,6 +1,6 @@ import weakref from twisted.internet import reactor -from services import GenericService +from stratum.services import GenericService class ConnectionRegistry(object): __connections = weakref.WeakKeyDictionary() @@ -14,7 +14,7 @@ def remove_connection(cls, conn): try: del cls.__connections[conn] except: - print "Warning: Cannot remove connection from ConnectionRegistry" + print("Warning: Cannot remove connection from ConnectionRegistry") @classmethod def get_session(cls, conn): diff --git a/stratum/event_handler.py b/stratum/event_handler.py index c6ded12..de72758 100644 --- a/stratum/event_handler.py +++ b/stratum/event_handler.py @@ -1,6 +1,6 @@ -import custom_exceptions +from stratum import custom_exceptions from twisted.internet import defer -from services import wrap_result_object +from stratum.services import wrap_result_object class GenericEventHandler(object): def _handle_event(self, msg_method, msg_result, connection_ref): @@ -8,5 +8,5 @@ def _handle_event(self, msg_method, msg_result, connection_ref): def handle_event(self, msg_method, msg_params, connection_ref): '''In most cases you'll only need to overload this method.''' - print "Other side called method", msg_method, "with params", msg_params + print("Other side called method", msg_method, "with params", msg_params) raise custom_exceptions.MethodNotFoundException("Method '%s' not implemented" % msg_method) \ No newline at end of file diff --git a/stratum/logger.py b/stratum/logger.py index 5534ee3..03d6c29 100644 --- a/stratum/logger.py +++ b/stratum/logger.py @@ -4,7 +4,7 @@ import logging from twisted.python import log as twisted_log -import settings +from stratum import settings ''' class Logger(object): diff --git a/stratum/protocol.py b/stratum/protocol.py index 5797313..288010a 100644 --- a/stratum/protocol.py +++ b/stratum/protocol.py @@ -6,12 +6,12 @@ from twisted.internet import defer, reactor, error from twisted.python.failure import Failure -import stats -import custom_exceptions -import connection_registry -import settings +from stratum import stats +import stratum.custom_exceptions +from stratum import connection_registry +import stratum.settings -import logger +from stratum import logger log = logger.get_logger('protocol') class RequestCounter(object): diff --git a/stratum/server.py b/stratum/server.py index 61c9a44..123421c 100644 --- a/stratum/server.py +++ b/stratum/server.py @@ -3,12 +3,12 @@ def setup(setup_event=None): from twisted.internet import epollreactor epollreactor.install() except ImportError: - print "Failed to install epoll reactor, default reactor will be used instead." + print("Failed to install epoll reactor, default reactor will be used instead.") try: import settings except ImportError: - print "***** Is configs.py missing? Maybe you want to copy and customize config_default.py?" + print("***** Is configs.py missing? Maybe you want to copy and customize config_default.py?") from twisted.application import service application = service.Application("stratum-server") @@ -51,8 +51,8 @@ def setup_finalize(event, application): sslContext = ssl.DefaultOpenSSLContextFactory(settings.SSL_PRIVKEY, settings.SSL_CACERT) except OpenSSL.SSL.Error: sslContext = None - print "Cannot initiate SSL context, are SSL_PRIVKEY or SSL_CACERT missing?" - print "This will skip all SSL-based transports." + print("Cannot initiate SSL context, are SSL_PRIVKEY or SSL_CACERT missing?") + print("This will skip all SSL-based transports.") # Set up thread pool size for service threads reactor.suggestThreadPoolSize(settings.THREAD_POOL_SIZE) @@ -106,4 +106,4 @@ def setup_finalize(event, application): return event if __name__ == '__main__': - print "This is not executable script. Try 'twistd -ny launcher.tac instead!" \ No newline at end of file + print("This is not executable script. Try 'twistd -ny launcher.tac instead!") \ No newline at end of file diff --git a/stratum/services.py b/stratum/services.py index 9ad65aa..b5aeb76 100644 --- a/stratum/services.py +++ b/stratum/services.py @@ -4,7 +4,7 @@ import weakref import re -import custom_exceptions +import stratum.custom_exceptions VENDOR_RE = re.compile(r'\[(.*)\]') diff --git a/stratum/settings.py b/stratum/settings.py index fd7fad8..40b1e08 100644 --- a/stratum/settings.py +++ b/stratum/settings.py @@ -34,7 +34,7 @@ def read_values(cfg): value = getattr(cfg, varname) yield (varname, value) - import config_default + from stratum import config_default if os.path.isfile('eth-proxy.conf'): config = open('eth-proxy.conf','r').readlines() @@ -62,13 +62,13 @@ def read_values(cfg): module.__dict__[name] = value if module.__dict__['DEBUG'] and changes: - print "----------------" - print "Custom settings:" + print("----------------") + print("Custom settings:") for k, v in changes.items(): if 'passw' in k.lower(): - print k, ": ********" + print(k, ": ********") else: - print k, ":", v - print "----------------" + print(k, ":", v) + print("----------------") setup() diff --git a/stratum/socket_transport.py b/stratum/socket_transport.py index e9238b1..14a6d04 100644 --- a/stratum/socket_transport.py +++ b/stratum/socket_transport.py @@ -2,12 +2,12 @@ from twisted.internet.protocol import ReconnectingClientFactory from twisted.internet import reactor, defer, endpoints -import socksclient -import custom_exceptions -from protocol import Protocol, ClientProtocol -from event_handler import GenericEventHandler +from stratum import socksclient +from stratum import custom_exceptions +from stratum.protocol import Protocol, ClientProtocol +from stratum.event_handler import GenericEventHandler -import logger +from stratum import logger log = logger.get_logger('socket_transport') def sockswrapper(proxy, dest): diff --git a/stratum/socksclient.py b/stratum/socksclient.py index b82c98c..c319ed1 100644 --- a/stratum/socksclient.py +++ b/stratum/socksclient.py @@ -3,7 +3,7 @@ import socket import struct -from zope.interface import implements +from zope.interface import implementer from twisted.internet import defer from twisted.internet.interfaces import IStreamClientEndpoint from twisted.internet.protocol import Protocol, ClientFactory @@ -19,8 +19,8 @@ class SOCKSv4ClientProtocol(Protocol): buf = '' def SOCKSConnect(self, host, port): - # only socksv4a for now - ver = 4 + # socksv4a and later + ver = 5 cmd = 1 # stream connection user = '\x00' dnsname = '' @@ -77,30 +77,30 @@ def buildProtocol(self, addr): return r class SOCKSWrapper(object): - implements(IStreamClientEndpoint) - factory = SOCKSv4ClientFactory + @implementer(IStreamClientEndpoint) + class StreamClientEndpoint: - def __init__(self, reactor, host, port, endpoint): - self._host = host - self._port = port - self._reactor = reactor - self._endpoint = endpoint + def __init__(self, reactor, host, port, endpoint): + self._host = host + self._port = port + self._reactor = reactor + self._endpoint = endpoint - def connect(self, protocolFactory): - """ - Return a deferred firing when the SOCKS connection is established. - """ + def connect(self, protocolFactory): + """ + Return a deferred firing when the SOCKS connection is established. + """ - try: - # Connect with an intermediate SOCKS factory/protocol, - # which then hands control to the provided protocolFactory - # once a SOCKS connection has been established. - f = self.factory() - f.postHandshakeEndpoint = self._endpoint - f.postHandshakeFactory = protocolFactory - f.handshakeDone = defer.Deferred() - wf = _WrappingFactory(f) - self._reactor.connectTCP(self._host, self._port, wf) - return f.handshakeDone - except: - return defer.fail() \ No newline at end of file + try: + # Connect with an intermediate SOCKS factory/protocol, + # which then hands control to the provided protocolFactory + # once a SOCKS connection has been established. + f = self.factory() + f.postHandshakeEndpoint = self._endpoint + f.postHandshakeFactory = protocolFactory + f.handshakeDone = defer.Deferred() + wf = _WrappingFactory(f) + self._reactor.connectTCP(self._host, self._port, wf) + return f.handshakeDone + except: + return defer.fail() \ No newline at end of file diff --git a/stratum/stats.py b/stratum/stats.py index 63b3026..1dd4c25 100644 --- a/stratum/stats.py +++ b/stratum/stats.py @@ -1,5 +1,5 @@ import time -import logger +from stratum import logger log = logger.get_logger('stats') class PeerStats(object):