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