示例#1
0
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