Exemplo n.º 1
0
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],
                ]))
    '''
    '''
Exemplo n.º 2
0
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))
Exemplo n.º 3
0
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],
                ]))
    '''

    '''
Exemplo n.º 4
0
    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
Exemplo n.º 5
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)
Exemplo n.º 6
0
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("-----------------------------------------------------------------------")
Exemplo n.º 7
0
 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)
Exemplo n.º 8
0
    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,
        )
Exemplo n.º 9
0
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()
Exemplo n.º 10
0
    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
Exemplo n.º 11
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))
Exemplo n.º 12
0
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("-----------------------------------------------------------------------")
Exemplo n.º 13
0
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(
        "-----------------------------------------------------------------------"
    )
Exemplo n.º 14
0
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(
        "-----------------------------------------------------------------------"
    )
Exemplo n.º 15
0
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)
Exemplo n.º 16
0
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(
        "-----------------------------------------------------------------------"
    )
Exemplo n.º 17
0
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)
Exemplo n.º 18
0
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(
        "-----------------------------------------------------------------------"
    )
Exemplo n.º 19
0
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("-----------------------------------------------------------------------")
Exemplo n.º 20
0
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(
        "-----------------------------------------------------------------------"
    )
Exemplo n.º 21
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