def main(): debug = False # Try to connect to remote server d = defer.Deferred() hostname = 'california.stratum.bitcoin.cz' #hostname = 'localhost' f = SocketTransportClientFactory(hostname, 3333, allow_trusted=True, allow_untrusted=False, debug=debug, signing_key=None, signing_id=None, on_connect=d, event_handler=ServiceEventHandler) yield d # Wait to on_connect event (event, subscription_key) = (yield f.subscribe('example.pubsub.subscribe', [ 1, ])) print("Subscribed:", event, subscription_key) reactor.callLater(3, unsubscribe, f, event, subscription_key) print(yield f.rpc('discovery.list_services', [])) #print (yield f.rpc('discovery.list_methods', ['example'])) #print (yield f.rpc('discovery.list_params', ['example.ping'])) print(yield f.rpc('example.ping', ['testing payload'])) ''' s = time.time() x = 10 for x in range(x): (yield f.rpc('node.ping', ['hi',])) print float(x) / (time.time() - s) ''' #print (yield f.rpc('blockchain.transaction.broadcast', ['01000000016e71be76a49eac1d1f55113e4a581ea21a33e94a17453f6a0f3624db0b43b101000000008b48304502207e1fd0a8a8051fb21561df5d9d0e3ad0f3ced2b51e90ff1cebc85406a654cfaf022100bc7d3cf9a93959ff80953272d45fbd5cbdb8800874db0858783547ecef19c2ce014104e6a069738d8e8491a8abd3bed7d303c9b2dc3792173a18483653036fd74a5100fc6ee327b6a82b3df79005f101b88496988fa414af32df11fff3e96d53d26d03ffffffff0180969800000000001976a914e1c9b052561cf0a1da9ee3175df7d5a2d7ff7dd488ac00000000'])) ''' print (yield f.rpc_multi([ ['blockchain.block[Electrum].get_blocknum', [], False], ['node.get_peers', [], False], ['firstbits.create', ['1MarekMKDKRb6PEeHeVuiCGayk9avyBGBB',], False], ['firstbits.create', ['1MarekMKDKRb6PEeHeVuiCGayk9avyBGBB',], False], ['node.ping', ['test'], False], ])) ''' '''
def GetworkProxy_main(cb): log.info("Stratum proxy version %s Connecting to Pool..." % version.VERSION) # Connect to Stratum pool f = SocketTransportClientFactory(settings.HOSTNAME, settings.LISTEN_SOCKET_TRANSPORT, debug=False, proxy=None, event_handler=client_service.ClientMiningService) job_registry = jobs.JobRegistry(f, cmd='', no_midstate=settings.GW_DISABLE_MIDSTATE, real_target=settings.GW_SEND_REAL_TARGET) client_service.ClientMiningService.job_registry = job_registry client_service.ClientMiningService.reset_timeout() workers = worker_registry.WorkerRegistry(f) f.on_connect.addCallback(on_connect, workers, job_registry) f.on_disconnect.addCallback(on_disconnect, workers, job_registry) # Cleanup properly on shutdown reactor.addSystemEventTrigger('before', 'shutdown', on_shutdown, f) # Block until proxy connects to the pool yield f.on_connect # Setup getwork listener gw_site = Site(getwork_listener.Root(job_registry, workers, stratum_host=settings.HOSTNAME, stratum_port=settings.LISTEN_SOCKET_TRANSPORT, custom_lp=False, custom_stratum=False, custom_user=False, custom_password=False )) gw_site.noisy = False reactor.listenTCP(settings.GW_PORT, gw_site, interface='0.0.0.0') log.info("Getwork Proxy is online, Port: %d" % (settings.GW_PORT))
def main(): debug = False # Try to connect to remote server d = defer.Deferred() hostname = 'california.stratum.bitcoin.cz' #hostname = 'localhost' f = SocketTransportClientFactory(hostname, 3333, allow_trusted=True, allow_untrusted=False, debug=debug, signing_key=None, signing_id=None, on_connect=d, event_handler=ServiceEventHandler) yield d # Wait to on_connect event (event, subscription_key) = (yield f.subscribe('example.pubsub.subscribe', [1,])) print "Subscribed:", event, subscription_key reactor.callLater(3, unsubscribe, f, event, subscription_key) print (yield f.rpc('discovery.list_services', [])) #print (yield f.rpc('discovery.list_methods', ['example'])) #print (yield f.rpc('discovery.list_params', ['example.ping'])) print (yield f.rpc('example.ping', ['testing payload'])) ''' s = time.time() x = 10 for x in range(x): (yield f.rpc('node.ping', ['hi',])) print float(x) / (time.time() - s) ''' #print (yield f.rpc('blockchain.transaction.broadcast', ['01000000016e71be76a49eac1d1f55113e4a581ea21a33e94a17453f6a0f3624db0b43b101000000008b48304502207e1fd0a8a8051fb21561df5d9d0e3ad0f3ced2b51e90ff1cebc85406a654cfaf022100bc7d3cf9a93959ff80953272d45fbd5cbdb8800874db0858783547ecef19c2ce014104e6a069738d8e8491a8abd3bed7d303c9b2dc3792173a18483653036fd74a5100fc6ee327b6a82b3df79005f101b88496988fa414af32df11fff3e96d53d26d03ffffffff0180969800000000001976a914e1c9b052561cf0a1da9ee3175df7d5a2d7ff7dd488ac00000000'])) ''' print (yield f.rpc_multi([ ['blockchain.block[Electrum].get_blocknum', [], False], ['node.get_peers', [], False], ['firstbits.create', ['1MarekMKDKRb6PEeHeVuiCGayk9avyBGBB',], False], ['firstbits.create', ['1MarekMKDKRb6PEeHeVuiCGayk9avyBGBB',], False], ['node.ping', ['test'], False], ])) ''' '''
def _connect(self, login, passwd): if self._con_factory or self._subscription: raise Exception('Factory or subscription already present') # Try to connect to remote server self._con_factory = SocketTransportClientFactory(POOL_HOST, POOL_PORT, allow_trusted=True, allow_untrusted=False, debug=DEBUG, signing_key=None, signing_id=None, event_handler=self) self.out("connecting... ") try: yield self._con_factory.on_connect # Wait to on_connect event except: self.out('ERR: connection failed') raise auth_result = (yield self._con_factory.subscribe('mining.authorize', [login, passwd])) self.out("authorized %s %s" % (login, str(auth_result))) (_, extranonce1, extranonce2_size) = (yield self._con_factory.subscribe( 'mining.subscribe', [ 'minersim-1.0', ]))[:3] self._subscription = { 'login': login, 'difficulty': 1, 'difficulty_new': 1, 'job_id': None, 'ntime': time.time(), 'extranonce2_size': extranonce2_size, 'job_specified': defer.Deferred() } self.out("subscribed, waiting for a job") yield self._subscription['job_specified'] self.START = time.time() self.COUNTER = 0
def __init__(self, host, port, user, passw): self.difficulty = 1 self.last_broadcast = None self.use_set_extranonce = False log.info("Connecting to Stratum pool at %s:%d" % (host, port)) self.host = host self.port = int(port) self._detect_set_extranonce() self.job_registry = jobs.JobRegistry() self.auth = (user, passw) self.connected = defer.Deferred() self.authorized = False self.f = SocketTransportClientFactory( host, port, debug=True, event_handler=client_service.ClientMiningService) self.f.on_connect.addCallbacks(self.on_connect, self.on_timeout) self.f.on_disconnect.addCallback(self.on_disconnect)
def main(): reactor.disconnectAll() failover = False if settings.POOL_FAILOVER_ENABLE: failover = settings.failover_pool settings.failover_pool = not settings.failover_pool pool_host = settings.POOL_HOST pool_port = settings.POOL_PORT if failover and settings.POOL_FAILOVER_ENABLE: pool_host = settings.POOL_HOST_FAILOVER pool_port = settings.POOL_PORT_FAILOVER log.warning("Monero Stratum proxy version: %s" % version.VERSION) log.warning("Trying to connect to Stratum pool at %s:%d" % (pool_host, pool_port)) # Connect to Stratum pool, main monitoring connection f = SocketTransportClientFactory(pool_host, pool_port, debug=settings.DEBUG, proxy=None, event_handler=client_service.ClientMiningService) job_registry = jobs.JobRegistry(f) client_service.ClientMiningService.job_registry = job_registry client_service.ClientMiningService.reset_timeout() f.on_connect.addCallback(on_connect) f.on_disconnect.addCallback(on_disconnect) # Cleanup properly on shutdown reactor.addSystemEventTrigger('before', 'shutdown', on_shutdown, f) # Block until proxy connect to the pool try: yield f.on_connect except TransportException: log.warning("First pool server must be online first time to start failover") return # Setup stratum listener stratum_listener.StratumProxyService._set_upstream_factory(f) stratum_listener.StratumProxyService._set_custom_user(settings.CUSTOM_USER, settings.CUSTOM_PASSWORD, settings.ENABLE_WORKER_ID, settings.WORKER_ID_FROM_IP) reactor.listenTCP(settings.STRATUM_PORT, SocketTransportFactory(debug=settings.DEBUG, event_handler=ServiceEventHandler), interface=settings.STRATUM_HOST) # Setup multicast responder reactor.listenMulticast(3333, multicast_responder.MulticastResponder((pool_host, pool_port), settings.STRATUM_PORT), listenMultiple=True) log.warning("-----------------------------------------------------------------------") if settings.STRATUM_HOST == '0.0.0.0': log.warning("PROXY IS LISTENING ON ALL IPs ON PORT %d (stratum)" % settings.STRATUM_PORT) else: log.warning("LISTENING FOR MINERS ON stratum+tcp://%s:%d (stratum)" % \ (settings.STRATUM_HOST, settings.STRATUM_PORT)) log.warning("-----------------------------------------------------------------------")
def set_pool(self, host, port, user, passw, timeout=120): self.log.warning( "Trying to connect to Stratum pool at %s:%d" % (host, port)) self.host = host self.port = int(port) self._detect_set_extranonce() self.cservice = client_service.ClientMiningService self.f = SocketTransportClientFactory( host, port, debug=True, event_handler=self.cservice) self.jobreg = jobs.JobRegistry(self.f, scrypt_target=True) self.cservice.job_registry = self.jobreg self.cservice.use_dirty_ping = False self.pool_timeout = timeout self.cservice.reset_timeout() self.cservice.auth = (user, passw) self.sharestats = share_stats.ShareStats() self.cservice.f = self.f self.f.on_connect.addCallback(self.on_connect) self.f.on_disconnect.addCallback(self.on_disconnect)
def _connect(self, hostname, port, on_connect, on_disconnect): from stratum.socket_transport import SocketTransportClientFactory # Try to connect to remote server return SocketTransportClientFactory( hostname, port, allow_trusted=True, allow_untrusted=False, debug=False, signing_key=None, signing_id=None, on_connect=on_connect, on_disconnect=on_disconnect, is_reconnecting=False, )
def main(args): if args.pid_file: fp = file(args.pid_file, 'w') fp.write(str(os.getpid())) fp.close() log.warning("Trying to connect to Stratum pool at %s:%d" % (args.host, args.port)) # Connect to Stratum pool f = SocketTransportClientFactory( args.host, args.port, debug=args.verbose, proxy=None, event_handler=client_service.ClientMiningService) job_registry = jobs.JobRegistry(f, cmd=args.blocknotify_cmd, scrypt_target=args.scrypt_target, no_midstate=args.no_midstate, real_target=args.real_target, use_old_target=args.old_target) client_service.ClientMiningService.job_registry = job_registry client_service.ClientMiningService.reset_timeout() workers = worker_registry.WorkerRegistry(f) f.on_connect.addCallback(on_connect, workers, job_registry) f.on_disconnect.addCallback(on_disconnect, workers, job_registry) if args.test: f.on_connect.addCallback(test_launcher, job_registry) # Cleanup properly on shutdown reactor.addSystemEventTrigger('before', 'shutdown', on_shutdown, f) # Block until connect to the pool yield f.on_connect # thread thread = threading.Thread(target=mine, args=[args, job_registry, workers]) #thread.daemon = True thread.start()
def _connect(self, login, passwd): if self._con_factory or self._subscription: raise Exception('Factory or subscription already present') # Try to connect to remote server self._con_factory = SocketTransportClientFactory(POOL_HOST, POOL_PORT, allow_trusted=True, allow_untrusted=False, debug=DEBUG, signing_key=None, signing_id=None, event_handler=self) self.out("connecting... ") try: yield self._con_factory.on_connect # Wait to on_connect event except: self.out('ERR: connection failed') raise auth_result = (yield self._con_factory.subscribe('mining.authorize', [login, passwd])) self.out("authorized %s %s" % (login, str(auth_result))) (_, extranonce1, extranonce2_size) = (yield self._con_factory.subscribe('mining.subscribe', ['minersim-1.0',]))[:3] self._subscription = {'login': login, 'difficulty': 1, 'difficulty_new': 1, 'job_id': None, 'ntime': time.time(), 'extranonce2_size': extranonce2_size, 'job_specified': defer.Deferred()} self.out("subscribed, waiting for a job") yield self._subscription['job_specified'] self.START = time.time() self.COUNTER = 0
class StratumProxy(): set_extranonce_pools = ['nicehash.com'] def __init__(self, host, port, user, passw): self.difficulty = 1 self.last_broadcast = None self.use_set_extranonce = False log.info("Connecting to Stratum pool at %s:%d" % (host, port)) self.host = host self.port = int(port) self._detect_set_extranonce() self.job_registry = jobs.JobRegistry() self.auth = (user, passw) self.connected = defer.Deferred() self.authorized = False self.f = SocketTransportClientFactory( host, port, debug=True, event_handler=client_service.ClientMiningService) self.f.on_connect.addCallbacks(self.on_connect, self.on_timeout) self.f.on_disconnect.addCallback(self.on_disconnect) def _detect_set_extranonce(self): self.use_set_extranonce = False for pool in self.set_extranonce_pools: if self.host.find(pool) > 0: self.use_set_extranonce = True def on_timeout(self, e): log.info('on timeout..................... %s' % (self)) self.f.on_connect.addCallbacks(self.on_connect, self.on_timeout) @defer.inlineCallbacks def on_connect(self, f): log.info('on connect..................... %s' % (self)) # Callback when proxy get connected to the pool f.on_connect.addCallbacks(self.on_connect, self.on_timeout) # Set the pool proxy into table StratumServer._set_pool_proxy(id(f.client.factory), self) # Broadcast connect event control.PoolConnectSubscription.emit(id(f)) # Subscribe proxy log.info("Subscribing for mining jobs %s" % (self)) try: (_, extranonce1, extranonce2_size) = (yield self.f.rpc('mining.subscribe', [settings.USER_AGENT]))[:3] self.job_registry.set_extranonce(extranonce1, extranonce2_size) except Exception as e: log.info('on connect subscription failed..................%s %s' % (e, self)) return # Set extranonce if self.use_set_extranonce: log.info("Enable extranonce subscription method %s" % (self)) try: f.rpc('mining.extranonce.subscribe', []) except Exception as e: log.info('extranonce subscription failed..............%s %s' % (e, self)) return # Authorize proxy log.info("Authorizing user %s, password %s, proxy %s" % (self.auth[0], self.auth[1], self)) try: self.authorized = (yield f.rpc('mining.authorize', [self.auth[0], self.auth[1]])) except Exception as e: log.info('on connect authorization failed.................%s %s' % (e, self)) if not self.authorized: log.info('on connect authorization failed...................%s' % (self)) log.info('.....................on connect %s' % (self)) # Proxy connected self.connected.callback(self) def on_disconnect(self, f): log.info('on disconnect................. %s' % (self)) # Callback when proxy get disconnected from the pool f.on_disconnect.addCallback(self.on_disconnect) # Broadcast disconnect event control.PoolDisconnectSubscription.emit(id(f)) # Reset connected deferred if self.connected.called: self.connected = defer.Deferred() # Connect miners stratum_listener.MiningSubscription.reconnect_all(self) log.info('..................on disconnect %s' % (self))
def main(): reactor.disconnectAll() log.warning("Ethereum Stratum proxy version: %s" % version.VERSION) # Connect to Stratum pool, main monitoring connection log.warning("Trying to connect to Stratum pool at %s:%d" % (settings.POOL_HOST, settings.POOL_PORT)) f = SocketTransportClientFactory(settings.POOL_HOST, settings.POOL_PORT, debug=settings.DEBUG, proxy=None, event_handler=client_service.ClientMiningService) f.is_failover = False ff = None if settings.POOL_FAILOVER_ENABLE: log.warning("Trying to connect to failover Stratum pool at %s:%d" % (settings.POOL_HOST_FAILOVER, settings.POOL_PORT_FAILOVER)) ff = SocketTransportClientFactory(settings.POOL_HOST_FAILOVER, settings.POOL_PORT_FAILOVER, debug=settings.DEBUG, proxy=None, event_handler=client_service.ClientMiningService) ff.is_failover = True job_registry = jobs.JobRegistry(f,ff) client_service.ClientMiningService.job_registry = job_registry client_service.ClientMiningService.reset_timeout() f.on_connect.addCallback(on_connect) f.on_disconnect.addCallback(on_disconnect) # Cleanup properly on shutdown reactor.addSystemEventTrigger('before', 'shutdown', on_shutdown, f) if ff: ff.on_connect.addCallback(on_connect) ff.on_disconnect.addCallback(on_disconnect) reactor.addSystemEventTrigger('before', 'shutdown', on_shutdown, ff) # Block until proxy connect to the pool try: yield f.on_connect except TransportException: log.warning("First pool server must be online first time during start") return conn = reactor.listenTCP(settings.PORT, Site(getwork_listener.Root(job_registry, settings.ENABLE_WORKER_ID)), interface=settings.HOST) try: conn.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # Enable keepalive packets conn.socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 60) # Seconds before sending keepalive probes conn.socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, 1) # Interval in seconds between keepalive probes conn.socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT, 5) # Failed keepalive probles before declaring other end dead except: pass # Some socket features are not available on all platforms (you can guess which one) log.warning("-----------------------------------------------------------------------") if settings.HOST == '0.0.0.0': log.warning("PROXY IS LISTENING ON ALL IPs ON PORT %d" % settings.PORT) else: log.warning("LISTENING FOR MINERS ON http://%s:%d" % (settings.HOST, settings.PORT)) log.warning("-----------------------------------------------------------------------") log.warning("Wallet: %s" % settings.WALLET) log.warning("Worker ID enabled: %s" % settings.ENABLE_WORKER_ID) if settings.MONITORING: log.warning("Email monitoring on %s" % settings.MONITORING_EMAIL) else: log.warning("Email monitoring disabled") log.warning("Failover enabled: %s" % settings.POOL_FAILOVER_ENABLE) log.warning("-----------------------------------------------------------------------")
def main(args): if args.pid_file: fp = file(args.pid_file, 'w') fp.write(str(os.getpid())) fp.close() if args.port != 3333: '''User most likely provided host/port for getwork interface. Let's try to detect Stratum host/port of given getwork pool.''' try: new_host = (yield utils.detect_stratum(args.host, args.port)) except: log.exception("Stratum host/port autodetection failed") new_host = None if new_host != None: args.host = new_host[0] args.port = new_host[1] log.warning("Stratum proxy version: %s" % version.VERSION) # Setup periodic checks for a new version #test_update() if args.tor: log.warning("Configuring Tor connection") args.proxy = '127.0.0.1:9050' args.host = 'pool57wkuu5yuhzb.onion' args.port = 3333 if args.proxy: proxy = args.proxy.split(':') if len(proxy) < 2: proxy = (proxy, 9050) else: proxy = (proxy[0], int(proxy[1])) log.warning("Using proxy %s:%d" % proxy) else: proxy = None log.warning("Trying to connect to Stratum pool at %s:%d" % (args.host, args.port)) # Connect to Stratum pool f = SocketTransportClientFactory( args.host, args.port, debug=args.verbose, proxy=proxy, event_handler=client_service.ClientMiningService) job_registry = jobs.JobRegistry(f, cmd=args.blocknotify_cmd, scrypt_target=args.scrypt_target, no_midstate=args.no_midstate, real_target=args.real_target, use_old_target=args.old_target) client_service.ClientMiningService.job_registry = job_registry client_service.ClientMiningService.reset_timeout() workers = worker_registry.WorkerRegistry(f) f.on_connect.addCallback(on_connect, workers, job_registry) f.on_disconnect.addCallback(on_disconnect, workers, job_registry) if args.test: f.on_connect.addCallback(test_launcher, job_registry) # Cleanup properly on shutdown reactor.addSystemEventTrigger('before', 'shutdown', on_shutdown, f) # Block until proxy connect to the pool yield f.on_connect # Setup getwork listener if args.getwork_port > 0: conn = reactor.listenTCP( args.getwork_port, Site( getwork_listener.Root(job_registry, workers, stratum_host=args.stratum_host, stratum_port=args.stratum_port, custom_lp=args.custom_lp, custom_stratum=args.custom_stratum, custom_user=args.custom_user, custom_password=args.custom_password)), interface=args.getwork_host) try: conn.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # Enable keepalive packets conn.socket.setsockopt( socket.SOL_TCP, socket.TCP_KEEPIDLE, 60) # Seconds before sending keepalive probes conn.socket.setsockopt( socket.SOL_TCP, socket.TCP_KEEPINTVL, 1) # Interval in seconds between keepalive probes conn.socket.setsockopt( socket.SOL_TCP, socket.TCP_KEEPCNT, 5) # Failed keepalive probles before declaring other end dead except: pass # Some socket features are not available on all platforms (you can guess which one) # Setup stratum listener #if args.stratum_port > 0: # stratum_listener.StratumProxyService._set_upstream_factory(f) # stratum_listener.StratumProxyService._set_custom_user(args.custom_user, args.custom_password) # reactor.listenTCP(args.stratum_port, SocketTransportFactory(debug=False, event_handler=ServiceEventHandler), interface=args.stratum_host) # Setup multicast responder #reactor.listenMulticast(3333, multicast_responder.MulticastResponder((args.host, args.port), args.stratum_port, args.getwork_port), listenMultiple=True) log.warning( "-----------------------------------------------------------------------" ) if args.getwork_host == '0.0.0.0': log.warning("PROXY IS LISTENING ON ALL IPs ON PORT %d (getwork)" % args.getwork_port) else: log.warning("LISTENING FOR MINERS ON http://%s:%d (getwork) " % \ (args.getwork_host, args.getwork_port)) log.warning( "-----------------------------------------------------------------------" )
def main(): reactor.disconnectAll() failover = False if settings.POOL_FAILOVER_ENABLE: failover = settings.failover_pool settings.failover_pool = not settings.failover_pool pool_host = settings.POOL_HOST pool_port = settings.POOL_PORT if failover and settings.POOL_FAILOVER_ENABLE: pool_host = settings.POOL_HOST_FAILOVER pool_port = settings.POOL_PORT_FAILOVER log.warning("Monero Stratum proxy versao: %s" % version.VERSION) log.warning("Tentando se conectar a Stratum pool as %s:%d" % (pool_host, pool_port)) # Connect to Stratum pool, main monitoring connection f = SocketTransportClientFactory( pool_host, pool_port, debug=settings.DEBUG, proxy=None, event_handler=client_service.ClientMiningService) job_registry = jobs.JobRegistry(f) client_service.ClientMiningService.job_registry = job_registry client_service.ClientMiningService.reset_timeout() f.on_connect.addCallback(on_connect) f.on_disconnect.addCallback(on_disconnect) # Cleanup properly on shutdown reactor.addSystemEventTrigger('before', 'shutdown', on_shutdown, f) # Block until proxy connect to the pool try: yield f.on_connect except TransportException: log.warning( "O Pool Primaria deve estar conectada pela primeira vez para iniciar o failover" ) return # Setup stratum listener stratum_listener.StratumProxyService._set_upstream_factory(f) stratum_listener.StratumProxyService._set_custom_user( settings.CUSTOM_USER, settings.CUSTOM_PASSWORD, settings.ENABLE_WORKER_ID, settings.WORKER_ID_FROM_IP) reactor.listenTCP(settings.STRATUM_PORT, SocketTransportFactory( debug=settings.DEBUG, event_handler=ServiceEventHandler), interface=settings.STRATUM_HOST) # Setup multicast responder reactor.listenMulticast(3333, multicast_responder.MulticastResponder( (pool_host, pool_port), settings.STRATUM_PORT), listenMultiple=True) log.warning( "-----------------------------------------------------------------------" ) if settings.STRATUM_HOST == '0.0.0.0': log.warning("PROXY esta escutando todos os IPS na porta %d (stratum)" % settings.STRATUM_PORT) else: log.warning("esperando pelos mineiros/rigs em stratum+tcp://%s:%d (stratum)" % \ (settings.STRATUM_HOST, settings.STRATUM_PORT)) log.warning( "-----------------------------------------------------------------------" )
class Runner(object): START = time.time() COUNTER = 0 def __init__(self, name, commands): self._next_cmd_idx = 0 self._stop_command_flag = False self._name = name self._commands = commands self._con_factory = None self._methods = { 'mining.set_difficulty': self._on_set_difficulty, 'mining.notify': self._on_notify, 'client.reconnect': self._on_reconnect } self._subscription = None if VERBOSE: self.out("Runner created") @staticmethod def sleep(secs): d = defer.Deferred() reactor.callLater(secs, d.callback, None) return d def _report_and_reset_counter(self, reason): length = time.time() - self.START share_rate = self._subscription['difficulty'] * (self.COUNTER / length) self.out("last %d rate: %.02f / %.01fs -> cca %.01f Ghash/s %.03f sh/s (%s)" % \ (self.COUNTER, self.COUNTER / length, length, share_rate * (2**32) / (1000*1000*1000.), share_rate, reason)) self.COUNTER = 0 self.START = time.time() def _prepare_reconnect(self, login): """ Returns if it is necessary to reconnect """ if not self._con_factory: return True if self._subscription and self._subscription['login'] == login: if VERBOSE: self.out('miner already authorized') return False self._finish_job(True) return True @defer.inlineCallbacks def _connect(self, login, passwd): if self._con_factory or self._subscription: raise Exception('Factory or subscription already present') # Try to connect to remote server self._con_factory = SocketTransportClientFactory(POOL_HOST, POOL_PORT, allow_trusted=True, allow_untrusted=False, debug=DEBUG, signing_key=None, signing_id=None, event_handler=self) self.out("connecting... ") try: yield self._con_factory.on_connect # Wait to on_connect event except: self.out('ERR: connection failed') raise auth_result = (yield self._con_factory.subscribe('mining.authorize', [login, passwd])) self.out("authorized %s %s" % (login, str(auth_result))) (_, extranonce1, extranonce2_size) = (yield self._con_factory.subscribe( 'mining.subscribe', [ 'minersim-1.0', ]))[:3] self._subscription = { 'login': login, 'difficulty': 1, 'difficulty_new': 1, 'job_id': None, 'ntime': time.time(), 'extranonce2_size': extranonce2_size, 'job_specified': defer.Deferred() } self.out("subscribed, waiting for a job") yield self._subscription['job_specified'] self.START = time.time() self.COUNTER = 0 @defer.inlineCallbacks def _simulate_hashrate(self, login, hash_rate, deterministic): prev_submit = None prev_submit_time = time.time() while not self._stop_command_flag: wait_duration = Simulator.get_next_share_wait_time( hash_rate, self._subscription['difficulty'], deterministic) # Compute how far is next submit from the last one submit_time = prev_submit_time + wait_duration # How long we should wait? wait_duration = submit_time - time.time() prev_submit_time = submit_time if wait_duration <= 0.0: wait_duration = 0 # Wait for the next share yield self.sleep(wait_duration) if prev_submit: # Wait for a response before next submit is made yield prev_submit prev_submit = None if not self._subscription['job_id']: continue self.COUNTER += 1 length = time.time() - self.START if length >= 50 or self.COUNTER >= 100: self._report_and_reset_counter('regular') # Generate a random nonce which is NOT interpreted as a new block while True: nonce = "%08x" % random.randint(0, 0xffffffff) if nonce != SIMULATED_BLOCK_NONCE: break prev_submit = self._submit(login, nonce) def _submit(self, login, nonce): submit = self._con_factory.rpc('mining.submit', [ login, self._subscription['job_id'], "01" * self._subscription['extranonce2_size'], "%x" % (self._subscription['ntime'] + 1), nonce ]) submit.addErrback(self._submission_err) return submit def _submission_err(self, failure): if failure.type == RemoteServiceException: error_msg = failure.value.args[1] if error_msg in ('Stale share', ) or \ re.match("Job '[a-fA-F0-9]+' not found", error_msg): self.out("Submission error ignored: %s" % error_msg) return None self.out("Submission error") return failure def _block_accepted(self, d): self.out('block accepted') def _finish_job(self, disconnect): if disconnect: self.out('disconnecting') if self._con_factory: if self._con_factory.client: self._con_factory.client.transport.abortConnection() if self._con_factory: self._con_factory.stopTrying() self._con_factory = None self._subscription = None def out(self, arg): line = "%s [%s] %s\n" % (datetime.datetime.now().strftime( "%Y-%m-%d %H:%M:%S"), self._name, arg) sys.stdout.write(line) def _handle_event(self, msg_method, msg_params, connection): self._methods[msg_method](*msg_params) return ServiceFactory.call(msg_method, msg_params, connection_ref=connection) def _on_set_difficulty(self, difficulty): self._subscription['difficulty_new'] = difficulty self._report_and_reset_counter('diff changed') if VERBOSE: self.out("Received difficulty %d" % difficulty) def _on_reconnect(self, *args): self.out('received RECONNECT from the server') def _on_notify(self, job_id, prev_hash, coinb1, coinb2, merkle_branch, version, nbits, ntime, clean_jobs, *args): # self.out('CALLED on_notify %s' % str((job_id, prev_hash, coinb1, coinb2, merkle_branch, version, nbits, ntime, clean_jobs, args)) try: job_id.lower() except: self.out("non string job_id %s received" % str(job_id)) self._subscription['job_id'] = job_id self._subscription['ntime'] = int(ntime, 16) if self._subscription['job_specified']: self._subscription['job_specified'].callback(True) self._subscription['job_specified'] = None if clean_jobs and self._subscription[ 'difficulty'] != self._subscription['difficulty_new']: self._subscription['difficulty'] = self._subscription[ 'difficulty_new'] self.COUNTER = 0 self.START = time.time() else: # print "Job update", SUBSCRIPTION['job_id'], "clean", clean_jobs pass def __call__(self, *args, **kwargs): """ It is used as an EventHandler class. Instantiation is by-passed by this method. """ return self def change_speed(self, lower, upper, period): self.__speed = math.exp( math.log(lower) + (random.random()**1.5 * (math.log(upper) - math.log(lower)))) if period: reactor.callLater(period, self.change_speed, lower, upper, period) self._report_and_reset_counter('speed change') self.out("SPEED changed to %0.02f Gh/s %0.03f sh/s" % (self.__speed, self.__speed * (1000 * 1000 * 1000.0) / (2**32))) def _cmd_loop(self, cmd_index=0): self._next_cmd_idx = cmd_index def _cmd_disconnect(self): self._finish_job(True) def _cmd_sim(self, login, passwd, hashrate, duration): return self._simulate_cmd_common(login, passwd, hashrate, duration, False) def _cmd_simd(self, login, passwd, hashrate, duration): return self._simulate_cmd_common(login, passwd, hashrate, duration, True) @defer.inlineCallbacks def _cmd_block(self, login, passwd): if self._prepare_reconnect(login): yield self._connect(login, passwd) self.out("submitting BLOCK") submit = self._submit(login, SIMULATED_BLOCK_NONCE) submit.addCallback(self._block_accepted) yield submit @defer.inlineCallbacks def _simulate_cmd_common(self, login, passwd, hashrate, duration, deterministic): if duration > 0: self._plan_stop_command(duration) if self._prepare_reconnect(login): yield self._connect(login, passwd) yield self._simulate_hashrate(login, hashrate, deterministic) @staticmethod def _get_interval_integer(interval): vals = interval.split('-', 1) if len(vals) > 1: return random.randint(int(vals[0]), int(vals[1])) return int(vals[0]) @defer.inlineCallbacks def _cmd_wait(self, seconds): seconds = self._get_interval_integer(seconds) yield self.sleep(seconds) @defer.inlineCallbacks def _cmd_sync(self, seconds): to_wait = seconds - (time.time() % seconds) yield self.sleep(to_wait) def _stop_command(self): self._stop_command_flag = True def _plan_stop_command(self, delay): reactor.callLater(delay, self._stop_command) @defer.inlineCallbacks def run_all(self): self._next_cmd_idx = 0 while self._next_cmd_idx < len(self._commands): cmd = self._commands[self._next_cmd_idx] self._next_cmd_idx += 1 try: self._stop_command_flag = False yield self._run_command(cmd) except: self.out(traceback.format_exc()) self._finish_job(True) self.out("Out of jobs") defer.returnValue(None) @classmethod def make_command(cls, cmd_name, args): if cmd_name == 'loop': cmd_idx = (int(args), ) if args else () return Command('loop', cmd_idx) if cmd_name in ('sim', 'simd'): login, hash_rate, duration = args.split(':') login, passwd = login.split("=", 1) hash_rate = float(hash_rate) if len(duration.strip()): duration = float(duration) else: duration = 0 return Command(cmd_name, (login, passwd, hash_rate, duration)) if cmd_name == 'block': login, passwd = args.split("=", 1) return Command('block', (login, passwd)) if cmd_name == 'wait': if not re.match('[0-9]+(-[0-9]+)?', args): raise Exception("Invalid format for wait time: %s" % str(args)) return Command('wait', (args, )) if cmd_name == 'sync': if not re.match('[0-9]+', args): raise Exception("Invalid format for sync: %s" % str(args)) return Command('wait', (int(args), )) if cmd_name == 'disconnect': if not args is None: raise Exception("Disconnect doesn't take any parameters: %s" % str(args)) return Command('disconnect', ()) raise Exception("Unknown command %s" % str(cmd_name)) @defer.inlineCallbacks def _run_command(self, cmd): func = self.__getattribute__('_cmd_%s' % cmd.name) if VERBOSE: self.out('executing: %s %s' % (cmd.name, cmd.args)) yield func(*cmd.args)
def main(): reactor.disconnectAll() log.warning("Ethereum Stratum proxy version: %s" % version.VERSION) # Connect to Stratum pool, main monitoring connection log.warning("Trying to connect to Stratum pool at %s:%d" % (mainpool, mainport)) f = SocketTransportClientFactory( mainpool, mainport, debug=settings.DEBUG, proxy=None, event_handler=client_service.ClientMiningService) f1 = None f2 = None f3 = None if settings.POOL_FAILOVER_ENABLE: if not (backuppool1 is None): log.warning( "Trying to connect to failover Stratum pool-1 at %s:%d" % (backuppool1, backupport1)) f1 = SocketTransportClientFactory( backuppool1, backupport1, debug=settings.DEBUG, proxy=None, event_handler=client_service.ClientMiningService) f1.is_failover = True if not (backuppool2 is None): log.warning( "Trying to connect to failover Stratum pool-2 at %s:%d" % (backuppool2, backupport2)) f2 = SocketTransportClientFactory( backuppool2, backupport2, debug=settings.DEBUG, proxy=None, event_handler=client_service.ClientMiningService) f2.is_failover = True if not (backuppool3 is None): log.warning( "Trying to connect to failover Stratum pool-3 at %s:%d" % (backuppool3, backupport3)) f3 = SocketTransportClientFactory( backuppool3, backupport3, debug=settings.DEBUG, proxy=None, event_handler=client_service.ClientMiningService) f3.is_failover = True job_registry = jobs.JobRegistry(f, f1, f2, f3) client_service.ClientMiningService.job_registry = job_registry client_service.ClientMiningService.reset_timeout() f.on_connect.addCallback(on_connect) f.on_disconnect.addCallback(on_disconnect) # Cleanup properly on shutdown reactor.addSystemEventTrigger('before', 'shutdown', on_shutdown, f) if f1: f1.on_connect.addCallback(on_connect) f1.on_disconnect.addCallback(on_disconnect) reactor.addSystemEventTrigger('before', 'shutdown', on_shutdown, f1) if f2: f2.on_connect.addCallback(on_connect) f2.on_disconnect.addCallback(on_disconnect) reactor.addSystemEventTrigger('before', 'shutdown', on_shutdown, f2) if f3: f3.on_connect.addCallback(on_connect) f3.on_disconnect.addCallback(on_disconnect) reactor.addSystemEventTrigger('before', 'shutdown', on_shutdown, f3) # Block until proxy connect to the pool try: yield f.on_connect except TransportException: log.error( "First pool server must be online during proxy startup. Dying Gracefully." ) reactor.stop() reactor.removeAll() return if len(proxywallet) != 42 and len(proxywallet) != 40: conn = reactor.listenTCP( settings.PORT, Site(getwork_listener.Root(job_registry, False)), interface=settings.HOST) else: conn = reactor.listenTCP( settings.PORT, Site(getwork_listener.Root(job_registry, settings.ENABLE_WORKER_ID)), interface=settings.HOST) try: conn.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # Enable keepalive packets conn.socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 60) # Seconds before sending keepalive probes conn.socket.setsockopt( socket.SOL_TCP, socket.TCP_KEEPINTVL, 1) # Interval in seconds between keepalive probes conn.socket.setsockopt( socket.SOL_TCP, socket.TCP_KEEPCNT, 5) # Failed keepalive probles before declaring other end dead except: pass # Some socket features are not available on all platforms (you can guess which one) log.warning( "-----------------------------------------------------------------------" ) if settings.HOST == '0.0.0.0': log.warning("PROXY IS LISTENING ON ALL IPs ON PORT %d" % settings.PORT) else: log.warning("LISTENING FOR MINERS ON http://%s:%d" % (settings.HOST, settings.PORT)) log.warning( "-----------------------------------------------------------------------" ) log.warning("Wallet: %s" % proxywallet) if len(proxywallet) != 42 and len(proxywallet) != 40: log.warning( "Wallet is not 40/42 Characters in Length, WORKER ID DISABLED") log.warning("OK if using non-eth address based pool authentication") log.warning("Otherwise - BAD ETH WALLET") else: log.warning("Worker ID enabled: %s" % settings.ENABLE_WORKER_ID) if settings.MONITORING: log.warning("Email monitoring on %s" % settings.MONITORING_EMAIL) else: log.warning("Email monitoring disabled") log.warning("Failover enabled: %s" % settings.POOL_FAILOVER_ENABLE) log.warning( "-----------------------------------------------------------------------" )
class Runner(object): START = time.time() COUNTER = 0 def __init__(self, name, commands): self._next_cmd_idx = 0 self._stop_command_flag = False self._name = name self._commands = commands self._con_factory = None self._methods = { 'mining.set_difficulty': self._on_set_difficulty, 'mining.notify': self._on_notify, 'client.reconnect': self._on_reconnect } self._subscription = None if VERBOSE: self.out("Runner created") @staticmethod def sleep(secs): d = defer.Deferred() reactor.callLater(secs, d.callback, None) return d def _report_and_reset_counter(self, reason): length = time.time() - self.START share_rate = self._subscription['difficulty'] * (self.COUNTER / length) self.out("last %d rate: %.02f / %.01fs -> cca %.01f Ghash/s %.03f sh/s (%s)" % \ (self.COUNTER, self.COUNTER / length, length, share_rate * (2**32) / (1000*1000*1000.), share_rate, reason)) self.COUNTER = 0 self.START = time.time() def _prepare_reconnect(self, login): """ Returns if it is necessary to reconnect """ if not self._con_factory: return True if self._subscription and self._subscription['login'] == login: if VERBOSE: self.out('miner already authorized') return False self._finish_job(True) return True @defer.inlineCallbacks def _connect(self, login, passwd): if self._con_factory or self._subscription: raise Exception('Factory or subscription already present') # Try to connect to remote server self._con_factory = SocketTransportClientFactory(POOL_HOST, POOL_PORT, allow_trusted=True, allow_untrusted=False, debug=DEBUG, signing_key=None, signing_id=None, event_handler=self) self.out("connecting... ") try: yield self._con_factory.on_connect # Wait to on_connect event except: self.out('ERR: connection failed') raise auth_result = (yield self._con_factory.subscribe('mining.authorize', [login, passwd])) self.out("authorized %s %s" % (login, str(auth_result))) (_, extranonce1, extranonce2_size) = (yield self._con_factory.subscribe('mining.subscribe', ['minersim-1.0',]))[:3] self._subscription = {'login': login, 'difficulty': 1, 'difficulty_new': 1, 'job_id': None, 'ntime': time.time(), 'extranonce2_size': extranonce2_size, 'job_specified': defer.Deferred()} self.out("subscribed, waiting for a job") yield self._subscription['job_specified'] self.START = time.time() self.COUNTER = 0 @defer.inlineCallbacks def _simulate_hashrate(self, login, hash_rate, deterministic): prev_submit = None prev_submit_time = time.time() while not self._stop_command_flag: wait_duration = Simulator.get_next_share_wait_time(hash_rate, self._subscription['difficulty'], deterministic) # Compute how far is next submit from the last one submit_time = prev_submit_time + wait_duration # How long we should wait? wait_duration = submit_time - time.time() prev_submit_time = submit_time if wait_duration <= 0.0: wait_duration = 0 # Wait for the next share yield self.sleep(wait_duration) if prev_submit: # Wait for a response before next submit is made yield prev_submit prev_submit = None if not self._subscription['job_id']: continue self.COUNTER += 1 length = time.time() - self.START if length >= 50 or self.COUNTER >= 100: self._report_and_reset_counter('regular') # Generate a random nonce which is NOT interpreted as a new block while True: nonce = "%08x" % random.randint(0, 0xffffffff) if nonce != SIMULATED_BLOCK_NONCE: break prev_submit = self._submit(login, nonce) def _submit(self, login, nonce): submit = self._con_factory.rpc('mining.submit', [login, self._subscription['job_id'], "01" * self._subscription['extranonce2_size'], "%x" % (self._subscription['ntime'] + 1), nonce]) submit.addErrback(self._submission_err) return submit def _submission_err(self, failure): if failure.type == RemoteServiceException: error_msg = failure.value.args[1] if error_msg in ('Stale share', ) or \ re.match("Job '[a-fA-F0-9]+' not found", error_msg): self.out("Submission error ignored: %s" % error_msg) return None self.out("Submission error") return failure def _block_accepted(self, d): self.out('block accepted') def _finish_job(self, disconnect): if disconnect: self.out('disconnecting') if self._con_factory: if self._con_factory.client: self._con_factory.client.transport.abortConnection() if self._con_factory: self._con_factory.stopTrying() self._con_factory = None self._subscription = None def out(self, arg): line = "%s [%s] %s\n" % (datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), self._name, arg) sys.stdout.write(line) def _handle_event(self, msg_method, msg_params, connection): self._methods[msg_method](*msg_params) return ServiceFactory.call(msg_method, msg_params, connection_ref=connection) def _on_set_difficulty(self, difficulty): self._subscription['difficulty_new'] = difficulty self._report_and_reset_counter('diff changed') if VERBOSE: self.out("Received difficulty %d" % difficulty) def _on_reconnect(self, *args): self.out('received RECONNECT from the server') def _on_notify(self, job_id, prev_hash, coinb1, coinb2, merkle_branch, version, nbits, ntime, clean_jobs, *args): # self.out('CALLED on_notify %s' % str((job_id, prev_hash, coinb1, coinb2, merkle_branch, version, nbits, ntime, clean_jobs, args)) try: job_id.lower() except: self.out("non string job_id %s received" % str(job_id)) self._subscription['job_id'] = job_id self._subscription['ntime'] = int(ntime, 16) if self._subscription['job_specified']: self._subscription['job_specified'].callback(True) self._subscription['job_specified'] = None if clean_jobs and self._subscription['difficulty'] != self._subscription['difficulty_new']: self._subscription['difficulty'] = self._subscription['difficulty_new'] self.COUNTER = 0 self.START = time.time() else: # print "Job update", SUBSCRIPTION['job_id'], "clean", clean_jobs pass def __call__(self, *args, **kwargs): """ It is used as an EventHandler class. Instantiation is by-passed by this method. """ return self def change_speed(self, lower, upper, period): self.__speed = math.exp(math.log(lower) + (random.random() ** 1.5 * (math.log(upper) - math.log(lower)))) if period: reactor.callLater(period, self.change_speed, lower, upper, period) self._report_and_reset_counter('speed change') self.out("SPEED changed to %0.02f Gh/s %0.03f sh/s" % (self.__speed, self.__speed * (1000*1000*1000.0)/(2**32))) def _cmd_loop(self, cmd_index=0): self._next_cmd_idx = cmd_index def _cmd_disconnect(self): self._finish_job(True) def _cmd_sim(self, login, passwd, hashrate, duration): return self._simulate_cmd_common(login, passwd, hashrate, duration, False) def _cmd_simd(self, login, passwd, hashrate, duration): return self._simulate_cmd_common(login, passwd, hashrate, duration, True) @defer.inlineCallbacks def _cmd_block(self, login, passwd): if self._prepare_reconnect(login): yield self._connect(login, passwd) self.out("submitting BLOCK") submit = self._submit(login, SIMULATED_BLOCK_NONCE) submit.addCallback(self._block_accepted) yield submit @defer.inlineCallbacks def _simulate_cmd_common(self, login, passwd, hashrate, duration, deterministic): if duration > 0: self._plan_stop_command(duration) if self._prepare_reconnect(login): yield self._connect(login, passwd) yield self._simulate_hashrate(login, hashrate, deterministic) @staticmethod def _get_interval_integer(interval): vals = interval.split('-', 1) if len(vals) > 1: return random.randint(int(vals[0]), int(vals[1])) return int(vals[0]) @defer.inlineCallbacks def _cmd_wait(self, seconds): seconds = self._get_interval_integer(seconds) yield self.sleep(seconds) @defer.inlineCallbacks def _cmd_sync(self, seconds): to_wait = seconds - (time.time() % seconds) yield self.sleep(to_wait) def _stop_command(self): self._stop_command_flag = True def _plan_stop_command(self, delay): reactor.callLater(delay, self._stop_command) @defer.inlineCallbacks def run_all(self): self._next_cmd_idx = 0 while self._next_cmd_idx < len(self._commands): cmd = self._commands[self._next_cmd_idx] self._next_cmd_idx += 1 try: self._stop_command_flag = False yield self._run_command(cmd) except: self.out(traceback.format_exc()) self._finish_job(True) self.out("Out of jobs") defer.returnValue(None) @classmethod def make_command(cls, cmd_name, args): if cmd_name == 'loop': cmd_idx = (int(args),) if args else () return Command('loop', cmd_idx) if cmd_name in ('sim', 'simd'): login, hash_rate, duration = args.split(':') login, passwd = login.split("=", 1) hash_rate = float(hash_rate) if len(duration.strip()): duration = float(duration) else: duration = 0 return Command(cmd_name, (login, passwd, hash_rate, duration)) if cmd_name == 'block': login, passwd = args.split("=", 1) return Command('block', (login, passwd)) if cmd_name == 'wait': if not re.match('[0-9]+(-[0-9]+)?', args): raise Exception("Invalid format for wait time: %s" % str(args)) return Command('wait', (args,)) if cmd_name == 'sync': if not re.match('[0-9]+', args): raise Exception("Invalid format for sync: %s" % str(args)) return Command('wait', (int(args),)) if cmd_name == 'disconnect': if not args is None: raise Exception("Disconnect doesn't take any parameters: %s" % str(args)) return Command('disconnect', ()) raise Exception("Unknown command %s" % str(cmd_name)) @defer.inlineCallbacks def _run_command(self, cmd): func = self.__getattribute__('_cmd_%s' % cmd.name) if VERBOSE: self.out('executing: %s %s' % (cmd.name, cmd.args)) yield func(*cmd.args)
def main(): reactor.disconnectAll() log.warning("Ethereum Stratum proxy version: %s" % version.VERSION) # Connect to Stratum pool, main monitoring connection log.warning("Trying to connect to Stratum pool at %s:%d" % (settings.POOL_HOST, settings.POOL_PORT)) f = SocketTransportClientFactory( settings.POOL_HOST, settings.POOL_PORT, debug=settings.DEBUG, proxy=None, event_handler=client_service.ClientMiningService) f1 = None f2 = None f3 = None if settings.POOL_FAILOVER_ENABLE: log.warning( "Trying to connect to failover Stratum pool-1 at %s:%d" % (settings.POOL_HOST_FAILOVER1, settings.POOL_PORT_FAILOVER1)) f1 = SocketTransportClientFactory( settings.POOL_HOST_FAILOVER1, settings.POOL_PORT_FAILOVER1, debug=settings.DEBUG, proxy=None, event_handler=client_service.ClientMiningService) f1.is_failover = True log.warning( "Trying to connect to failover Stratum pool-2 at %s:%d" % (settings.POOL_HOST_FAILOVER2, settings.POOL_PORT_FAILOVER2)) f2 = SocketTransportClientFactory( settings.POOL_HOST_FAILOVER2, settings.POOL_PORT_FAILOVER2, debug=settings.DEBUG, proxy=None, event_handler=client_service.ClientMiningService) f2.is_failover = True log.warning( "Trying to connect to failover Stratum pool-3 at %s:%d" % (settings.POOL_HOST_FAILOVER3, settings.POOL_PORT_FAILOVER3)) f3 = SocketTransportClientFactory( settings.POOL_HOST_FAILOVER3, settings.POOL_PORT_FAILOVER3, debug=settings.DEBUG, proxy=None, event_handler=client_service.ClientMiningService) f3.is_failover = True job_registry = jobs.JobRegistry(f, f1, f2, f3) client_service.ClientMiningService.job_registry = job_registry client_service.ClientMiningService.reset_timeout() f.on_connect.addCallback(on_connect) f.on_disconnect.addCallback(on_disconnect) # Cleanup properly on shutdown reactor.addSystemEventTrigger('before', 'shutdown', on_shutdown, f) if f1: f1.on_connect.addCallback(on_connect) f1.on_disconnect.addCallback(on_disconnect) reactor.addSystemEventTrigger('before', 'shutdown', on_shutdown, f1) if f2: f2.on_connect.addCallback(on_connect) f2.on_disconnect.addCallback(on_disconnect) reactor.addSystemEventTrigger('before', 'shutdown', on_shutdown, f2) if f3: f3.on_connect.addCallback(on_connect) f3.on_disconnect.addCallback(on_disconnect) reactor.addSystemEventTrigger('before', 'shutdown', on_shutdown, f3) # Block until proxy connect to the pool try: yield f.on_connect except TransportException: log.warning("First pool server must be online first time during start") return conn = reactor.listenTCP( settings.PORT, Site(getwork_listener.Root(job_registry, settings.ENABLE_WORKER_ID)), interface=settings.HOST) try: conn.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # Enable keepalive packets conn.socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 60) # Seconds before sending keepalive probes conn.socket.setsockopt( socket.SOL_TCP, socket.TCP_KEEPINTVL, 1) # Interval in seconds between keepalive probes conn.socket.setsockopt( socket.SOL_TCP, socket.TCP_KEEPCNT, 5) # Failed keepalive probles before declaring other end dead except: pass # Some socket features are not available on all platforms (you can guess which one) log.warning( "-----------------------------------------------------------------------" ) if settings.HOST == '0.0.0.0': log.warning("PROXY IS LISTENING ON ALL IPs ON PORT %d" % settings.PORT) else: log.warning("LISTENING FOR MINERS ON http://%s:%d" % (settings.HOST, settings.PORT)) log.warning( "-----------------------------------------------------------------------" ) log.warning("Wallet: %s" % settings.WALLET) log.warning("Worker ID enabled: %s" % settings.ENABLE_WORKER_ID) if settings.MONITORING: log.warning("Email monitoring on %s" % settings.MONITORING_EMAIL) else: log.warning("Email monitoring disabled") log.warning("Failover enabled: %s" % settings.POOL_FAILOVER_ENABLE) log.warning( "-----------------------------------------------------------------------" )
def main(): reactor.disconnectAll() log.warning("Ethereum Stratum proxy version: %s" % version.VERSION) # Connect to Stratum pool, main monitoring connection log.warning("Trying to connect to Stratum pool at %s:%d" % (mainpool, mainport)) f = SocketTransportClientFactory(mainpool, mainport, debug=settings.DEBUG, proxy=None, event_handler=client_service.ClientMiningService) f1 = None f2 = None f3 = None if settings.POOL_FAILOVER_ENABLE: if not (backuppool1 is None): log.warning("Trying to connect to failover Stratum pool-1 at %s:%d" % (backuppool1, backupport1)) f1 = SocketTransportClientFactory(backuppool1, backupport1, debug=settings.DEBUG, proxy=None, event_handler=client_service.ClientMiningService) f1.is_failover = True if not (backuppool2 is None): log.warning("Trying to connect to failover Stratum pool-2 at %s:%d" % (backuppool2, backupport2)) f2 = SocketTransportClientFactory(backuppool2, backupport2, debug=settings.DEBUG, proxy=None, event_handler=client_service.ClientMiningService) f2.is_failover = True if not (backuppool3 is None): log.warning("Trying to connect to failover Stratum pool-3 at %s:%d" % (backuppool3, backupport3)) f3 = SocketTransportClientFactory(backuppool3, backupport3, debug=settings.DEBUG, proxy=None, event_handler=client_service.ClientMiningService) f3.is_failover = True job_registry = jobs.JobRegistry(f,f1,f2,f3) client_service.ClientMiningService.job_registry = job_registry client_service.ClientMiningService.reset_timeout() f.on_connect.addCallback(on_connect) f.on_disconnect.addCallback(on_disconnect) # Cleanup properly on shutdown reactor.addSystemEventTrigger('before', 'shutdown', on_shutdown, f) if f1: f1.on_connect.addCallback(on_connect) f1.on_disconnect.addCallback(on_disconnect) reactor.addSystemEventTrigger('before', 'shutdown', on_shutdown, f1) if f2: f2.on_connect.addCallback(on_connect) f2.on_disconnect.addCallback(on_disconnect) reactor.addSystemEventTrigger('before', 'shutdown', on_shutdown, f2) if f3: f3.on_connect.addCallback(on_connect) f3.on_disconnect.addCallback(on_disconnect) reactor.addSystemEventTrigger('before', 'shutdown', on_shutdown, f3) # Block until proxy connect to the pool try: yield f.on_connect except TransportException: log.error("First pool server must be online during proxy startup. Dying Gracefully.") reactor.stop() reactor.removeAll() return if len(proxywallet)!=42 and len(proxywallet)!=40: conn = reactor.listenTCP(settings.PORT, Site(getwork_listener.Root(job_registry, False)), interface=settings.HOST) else: conn = reactor.listenTCP(settings.PORT, Site(getwork_listener.Root(job_registry, settings.ENABLE_WORKER_ID)), interface=settings.HOST) try: conn.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # Enable keepalive packets conn.socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 60) # Seconds before sending keepalive probes conn.socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, 1) # Interval in seconds between keepalive probes conn.socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT, 5) # Failed keepalive probles before declaring other end dead except: pass # Some socket features are not available on all platforms (you can guess which one) log.warning("-----------------------------------------------------------------------") if settings.HOST == '0.0.0.0': log.warning("PROXY IS LISTENING ON ALL IPs ON PORT %d" % settings.PORT) else: log.warning("LISTENING FOR MINERS ON http://%s:%d" % (settings.HOST, settings.PORT)) log.warning("-----------------------------------------------------------------------") log.warning("Wallet: %s" % proxywallet) if len(proxywallet)!=42 and len(proxywallet)!=40: log.warning("Wallet is not 40/42 Characters in Length, WORKER ID DISABLED") log.warning("OK if using non-eth address based pool authentication") log.warning("Otherwise - BAD ETH WALLET") else: log.warning("Worker ID enabled: %s" % settings.ENABLE_WORKER_ID) if settings.MONITORING: log.warning("Email monitoring on %s" % settings.MONITORING_EMAIL) else: log.warning("Email monitoring disabled") log.warning("Failover enabled: %s" % settings.POOL_FAILOVER_ENABLE) log.warning("-----------------------------------------------------------------------")
def main(args): if args.pid_file: fp = file(args.pid_file, 'w') fp.write(str(os.getpid())) fp.close() if args.port != 3333: '''User most likely provided host/port for getwork interface. Let's try to detect Stratum host/port of given getwork pool.''' try: new_host = (yield utils.detect_stratum(args.host, args.port)) except: log.exception("Stratum host/port autodetection failed") new_host = None if new_host != None: args.host = new_host[0] args.port = new_host[1] log.warning("Stratum proxy version: %s" % version.VERSION) if args.tor: log.warning("Configuring Tor connection") args.proxy = '127.0.0.1:9050' args.host = 'pool57wkuu5yuhzb.onion' args.port = 3333 if args.proxy: proxy = args.proxy.split(':') if len(proxy) < 2: proxy = (proxy, 9050) else: proxy = (proxy[0], int(proxy[1])) log.warning("Using proxy %s:%d" % proxy) else: proxy = None log.warning("Trying to connect to Stratum pool at %s:%d" % (args.host, args.port)) # Connect to Stratum pool f = SocketTransportClientFactory( args.host, args.port, debug=args.verbose, proxy=proxy, event_handler=client_service.ClientMiningService) job_registry = jobs.JobRegistry(f, cmd=args.blocknotify_cmd, no_midstate=args.no_midstate, real_target=args.real_target) client_service.ClientMiningService.job_registry = job_registry client_service.ClientMiningService.reset_timeout() workers = worker_registry.WorkerRegistry(f) f.on_connect.addCallback(on_connect, workers, job_registry) f.on_disconnect.addCallback(on_disconnect, workers, job_registry) if args.test: f.on_connect.addCallback(test_launcher, job_registry) # Cleanup properly on shutdown reactor.addSystemEventTrigger('before', 'shutdown', on_shutdown, f) # Block until proxy connect to the pool yield f.on_connect # Setup getwork listener if args.getwork_port > 0: reactor.listenTCP(args.getwork_port, Site( getwork_listener.Root( job_registry, workers, stratum_host=args.stratum_host, stratum_port=args.stratum_port, custom_lp=args.custom_lp, custom_stratum=args.custom_stratum, custom_user=args.custom_user, custom_password=args.custom_password)), interface=args.getwork_host) # Setup stratum listener if args.stratum_port > 0: stratum_listener.StratumProxyService._set_upstream_factory(f) reactor.listenTCP( args.stratum_port, SocketTransportFactory(debug=False, event_handler=ServiceEventHandler)) # Setup multicast responder reactor.listenMulticast(3333, multicast_responder.MulticastResponder( (args.host, args.port), args.stratum_port, args.getwork_port), listenMultiple=True) log.warning( "-----------------------------------------------------------------------" ) if args.getwork_host == '0.0.0.0' and args.stratum_host == '0.0.0.0': log.warning( "PROXY IS LISTENING ON ALL IPs ON PORT %d (stratum) AND %d (getwork)" % (args.stratum_port, args.getwork_port)) else: log.warning("LISTENING FOR MINERS ON http://%s:%d (getwork) and stratum+tcp://%s:%d (stratum)" % \ (args.getwork_host, args.getwork_port, args.stratum_host, args.stratum_port)) log.warning( "-----------------------------------------------------------------------" )
class StratumProxy(): f = None jobreg = None cservice = None sharestats = None use_set_extranonce = False set_extranonce_pools = ['nicehash.com'] disconnect_counter = 0 pool_timeout = 0 backup = [] using_backup = False origin_pool = [] connecting = False def __init__(self, stl): self.log = stratum.logger.get_logger('proxy') self.stl = stl def _detect_set_extranonce(self): self.use_set_extranonce = False for pool in self.set_extranonce_pools: if self.host.find(pool) > 0: self.use_set_extranonce = True def set_pool(self, host, port, user, passw, timeout=120): self.log.warning( "Trying to connect to Stratum pool at %s:%d" % (host, port)) self.host = host self.port = int(port) self._detect_set_extranonce() self.cservice = client_service.ClientMiningService self.f = SocketTransportClientFactory( host, port, debug=True, event_handler=self.cservice) self.jobreg = jobs.JobRegistry(self.f, scrypt_target=True) self.cservice.job_registry = self.jobreg self.cservice.use_dirty_ping = False self.pool_timeout = timeout self.cservice.reset_timeout() self.cservice.auth = (user, passw) self.sharestats = share_stats.ShareStats() self.cservice.f = self.f self.f.on_connect.addCallback(self.on_connect) self.f.on_disconnect.addCallback(self.on_disconnect) def reconnect(self, host=None, port=None, user=None, passw=None): if host: self.host = host if port: self.port = int(port) self._detect_set_extranonce() cuser, cpassw = self.cservice.auth if not user: user = cuser if not passw: passw = cpassw self.cservice.auth = (user, passw) self.cservice.controlled_disconnect = True self.log.info("Trying reconnection with pool") if not self.f.client: self.log.info("Client was not connected before!") self.f.on_connect.addCallback(self.on_connect) self.f.on_disconnect.addCallback(self.on_disconnect) self.f.new_host = (self.host, self.port) self.f.connect() else: self.f.reconnect(host, port, None) def connect(self): self.connecting = True yield self.f.on_connect self.connecting = False @defer.inlineCallbacks def on_connect(self, f): '''Callback when proxy get connected to the pool''' # Hook to on_connect again f.on_connect.addCallback(self.on_connect) # Subscribe for receiving jobs self.log.info("Subscribing for mining jobs") (_, extranonce1, extranonce2_size) = (yield self.f.rpc('mining.subscribe', []))[:3] self.jobreg.set_extranonce(extranonce1, extranonce2_size) if self.use_set_extranonce: self.log.info("Enable extranonce subscription method") f.rpc('mining.extranonce.subscribe', []) self.log.warning( "Authorizing user %s, password %s" % self.cservice.auth) self.cservice.authorize(self.cservice.auth[0], self.cservice.auth[1]) # Set controlled disconnect to False self.cservice.controlled_disconnect = False self.disconnect_counter = 0 defer.returnValue(f) def on_disconnect(self, f): '''Callback when proxy get disconnected from the pool''' f.on_disconnect.addCallback(self.on_disconnect) if not self.cservice.controlled_disconnect: self.log.error( "Uncontroled disconnect detected for pool %s:%d" % self.f.main_host) if self.backup and self.disconnect_counter > 1: self.log.error( "Two or more connection lost, switching to backup pool: %s" % self.backup) f.new_host = (self.backup[0], self.backup[1]) self.origin_pool = [self.host, self.port] self.host = self.backup[0] self.port = self.backup[1] self.using_backup = True else: self.log.info("Controlled disconnect detected") self.cservice.controlled_disconnect = False self.stl.MiningSubscription.reconnect_all() self.disconnect_counter += 1 return f