Exemple #1
0
def run():
    if not hasattr(tcp.Client, 'abortConnection'):
        print "Twisted doesn't have abortConnection! Upgrade to a newer version of Twisted to avoid memory leaks!"
        print 'Pausing for 3 seconds...'
        time.sleep(3)
    
    realnets = dict((name, net) for name, net in networks.nets.iteritems() if '_testnet' not in name)
    
    parser = fixargparse.FixedArgumentParser(description='p2pool (version %s)' % (p2pool.__version__,), fromfile_prefix_chars='@')
    parser.add_argument('--version', action='version', version=p2pool.__version__)
    parser.add_argument('--net',
        help='use specified network (default: bitcoin)',
        action='store', choices=sorted(realnets), default='bitcoin', dest='net_name')
    parser.add_argument('--testnet',
        help='''use the network's testnet''',
        action='store_const', const=True, default=False, dest='testnet')
    parser.add_argument('--debug',
        help='enable debugging mode',
        action='store_const', const=True, default=False, dest='debug')
    parser.add_argument('--bench',
        help='enable CPU performance profiling mode',
        action='store_const', const=True, default=False, dest='bench')
    parser.add_argument('--rconsole',
        help='enable rconsole debugging mode (requires rfoo)',
        action='store_const', const=True, default=False, dest='rconsole')

    parser.add_argument('-a', '--address',
        help='generate payouts to this address (default: <address requested from bitcoind>), or (dynamic)',
        type=str, action='store', default=None, dest='address')
    parser.add_argument('-i', '--numaddresses',
        help='number of bitcoin auto-generated addresses to maintain for getwork dynamic address allocation',
        type=int, action='store', default=2, dest='numaddresses')
    parser.add_argument('-t', '--timeaddresses',
        help='seconds between acquisition of new address and removal of single old (default: 2 days or 172800s)',
        type=int, action='store', default=172800, dest='timeaddresses')
    parser.add_argument('--datadir',
        help='store data in this directory (default: <directory run_p2pool.py is in>/data)',
        type=str, action='store', default=None, dest='datadir')
    parser.add_argument('--logfile',
        help='''log to this file (default: data/<NET>/log)''',
        type=str, action='store', default=None, dest='logfile')
    parser.add_argument('--web-static',
        help='use an alternative web frontend in this directory (otherwise use the built-in frontend)',
        type=str, action='store', default=None, dest='web_static')
    parser.add_argument('--merged',
        help='call getauxblock on this url to get work for merged mining (example: http://ncuser:[email protected]:10332/)',
        type=str, action='append', default=[], dest='merged_urls')
    parser.add_argument('--coinbtext',
        help='append this text to the coinbase',
        type=str, action='append', default=[], dest='coinb_texts')
    parser.add_argument('--give-author', metavar='DONATION_PERCENTAGE',
        help='donate this percentage of work towards the development of p2pool (default: 0.0)',
        type=float, action='store', default=0.0, dest='donation_percentage')
    parser.add_argument('--iocp',
        help='use Windows IOCP API in order to avoid errors due to large number of sockets being open',
        action='store_true', default=False, dest='iocp')
    parser.add_argument('--irc-announce',
        help='announce any blocks found on irc://irc.freenode.net/#p2pool',
        action='store_true', default=False, dest='irc_announce')
    parser.add_argument('--no-bugreport',
        help='disable submitting caught exceptions to the author',
        action='store_true', default=False, dest='no_bugreport')
    
    p2pool_group = parser.add_argument_group('p2pool interface')
    p2pool_group.add_argument('--p2pool-port', metavar='PORT',
        help='use port PORT to listen for connections (forward this port from your router!) (default: %s)' % ', '.join('%s:%i' % (name, net.P2P_PORT) for name, net in sorted(realnets.items())),
        type=int, action='store', default=None, dest='p2pool_port')
    p2pool_group.add_argument('-n', '--p2pool-node', metavar='ADDR[:PORT]',
        help='connect to existing p2pool node at ADDR listening on port PORT (defaults to default p2pool P2P port) in addition to builtin addresses',
        type=str, action='append', default=[], dest='p2pool_nodes')
    parser.add_argument('--disable-upnp',
        help='''don't attempt to use UPnP to forward p2pool's P2P port from the Internet to this computer''',
        action='store_false', default=True, dest='upnp')
    p2pool_group.add_argument('--max-conns', metavar='CONNS',
        help='maximum incoming connections (default: 40)',
        type=int, action='store', default=40, dest='p2pool_conns')
    p2pool_group.add_argument('--outgoing-conns', metavar='CONNS',
        help='outgoing connections (default: 6)',
        type=int, action='store', default=6, dest='p2pool_outgoing_conns')
    p2pool_group.add_argument('--external-ip', metavar='ADDR[:PORT]',
        help='specify your own public IP address instead of asking peers to discover it, useful for running dual WAN or asymmetric routing',
        type=str, action='store', default=None, dest='p2pool_external_ip')
    parser.add_argument('--disable-advertise',
        help='''don't advertise local IP address as being available for incoming connections. useful for running a dark node, along with multiple -n ADDR's and --outgoing-conns 0''',
        action='store_false', default=True, dest='advertise_ip')
    
    worker_group = parser.add_argument_group('worker interface')
    worker_group.add_argument('-w', '--worker-port', metavar='PORT or ADDR:PORT',
        help='listen on PORT on interface with ADDR for RPC connections from miners (default: all interfaces, %s)' % ', '.join('%s:%i' % (name, net.WORKER_PORT) for name, net in sorted(realnets.items())),
        type=str, action='store', default=None, dest='worker_endpoint')
    worker_group.add_argument('-f', '--fee', metavar='FEE_PERCENTAGE',
        help='''charge workers mining to their own bitcoin address (by setting their miner's username to a bitcoin address) this percentage fee to mine on your p2pool instance. Amount displayed at http://127.0.0.1:WORKER_PORT/fee (default: 0)''',
        type=float, action='store', default=0, dest='worker_fee')
    worker_group.add_argument('-s', '--share-rate', metavar='SECONDS_PER_SHARE',
        help='Auto-adjust mining difficulty on each connection to target this many seconds per pseudoshare (default: %3.0f)' % 3.,
        type=float, action='store', default=3., dest='share_rate')
    
    bitcoind_group = parser.add_argument_group('bitcoind interface')
    bitcoind_group.add_argument('--bitcoind-config-path', metavar='BITCOIND_CONFIG_PATH',
        help='custom configuration file path (when bitcoind -conf option used)',
        type=str, action='store', default=None, dest='bitcoind_config_path')
    bitcoind_group.add_argument('--bitcoind-address', metavar='BITCOIND_ADDRESS',
        help='connect to this address (default: 127.0.0.1)',
        type=str, action='store', default='127.0.0.1', dest='bitcoind_address')
    bitcoind_group.add_argument('--bitcoind-rpc-port', metavar='BITCOIND_RPC_PORT',
        help='''connect to JSON-RPC interface at this port (default: %s <read from bitcoin.conf if password not provided>)''' % ', '.join('%s:%i' % (name, net.PARENT.RPC_PORT) for name, net in sorted(realnets.items())),
        type=int, action='store', default=None, dest='bitcoind_rpc_port')
    bitcoind_group.add_argument('--bitcoind-rpc-ssl',
        help='connect to JSON-RPC interface using SSL',
        action='store_true', default=False, dest='bitcoind_rpc_ssl')
    bitcoind_group.add_argument('--bitcoind-p2p-port', metavar='BITCOIND_P2P_PORT',
        help='''connect to P2P interface at this port (default: %s <read from bitcoin.conf if password not provided>)''' % ', '.join('%s:%i' % (name, net.PARENT.P2P_PORT) for name, net in sorted(realnets.items())),
        type=int, action='store', default=None, dest='bitcoind_p2p_port')
    bitcoind_group.add_argument(metavar='BITCOIND_RPCUSERPASS',
        help='bitcoind RPC interface username, then password, space-separated (only one being provided will cause the username to default to being empty, and none will cause P2Pool to read them from bitcoin.conf)',
        type=str, action='store', default=[], nargs='*', dest='bitcoind_rpc_userpass')
    bitcoind_group.add_argument('--allow-obsolete-bitcoind',
        help='allow the use of coin daemons (bitcoind) that do not support all of the required softforks for this network (e.g. Bitcoin Core and segwit2x)',
        action='store_const', const=True, default=False, dest='allow_obsolete_bitcoind')
    
    args = parser.parse_args()
    
    if args.debug:
        p2pool.DEBUG = True
        defer.setDebugging(True)
    else:
        p2pool.DEBUG = False
    p2pool.BENCH = args.bench
    
    net_name = args.net_name + ('_testnet' if args.testnet else '')
    net = networks.nets[net_name]
    
    datadir_path = os.path.join((os.path.join(os.path.dirname(sys.argv[0]), 'data') if args.datadir is None else args.datadir), net_name)
    if not os.path.exists(datadir_path):
        os.makedirs(datadir_path)
    
    if len(args.bitcoind_rpc_userpass) > 2:
        parser.error('a maximum of two arguments are allowed')
    args.bitcoind_rpc_username, args.bitcoind_rpc_password = ([None, None] + args.bitcoind_rpc_userpass)[-2:]
    
    if args.bitcoind_rpc_password is None:
        conf_path = args.bitcoind_config_path or net.PARENT.CONF_FILE_FUNC()
        if not os.path.exists(conf_path):
            parser.error('''Bitcoin configuration file not found. Manually enter your RPC password.\r\n'''
                '''If you actually haven't created a configuration file, you should create one at %s with the text:\r\n'''
                '''\r\n'''
                '''server=1\r\n'''
                '''rpcpassword=%x\r\n'''
                '''\r\n'''
                '''Keep that password secret! After creating the file, restart Bitcoin.''' % (conf_path, random.randrange(2**128)))
        conf = open(conf_path, 'rb').read()
        contents = {}
        for line in conf.splitlines(True):
            if '#' in line:
                line = line[:line.index('#')]
            if '=' not in line:
                continue
            k, v = line.split('=', 1)
            contents[k.strip()] = v.strip()
        for conf_name, var_name, var_type in [
            ('rpcuser', 'bitcoind_rpc_username', str),
            ('rpcpassword', 'bitcoind_rpc_password', str),
            ('rpcport', 'bitcoind_rpc_port', int),
            ('port', 'bitcoind_p2p_port', int),
        ]:
            if getattr(args, var_name) is None and conf_name in contents:
                setattr(args, var_name, var_type(contents[conf_name]))
        if 'rpcssl' in contents and contents['rpcssl'] != '0':
            args.bitcoind_rpc_ssl = True
        if args.bitcoind_rpc_password is None:
            parser.error('''Bitcoin configuration file didn't contain an rpcpassword= line! Add one!''')
    
    if args.bitcoind_rpc_username is None:
        args.bitcoind_rpc_username = ''
    
    if args.bitcoind_rpc_port is None:
        args.bitcoind_rpc_port = net.PARENT.RPC_PORT
    
    if args.bitcoind_p2p_port is None:
        args.bitcoind_p2p_port = net.PARENT.P2P_PORT
    
    if args.p2pool_port is None:
        args.p2pool_port = net.P2P_PORT
    
    if args.p2pool_outgoing_conns > 10:
        parser.error('''--outgoing-conns can't be more than 10''')
    
    if args.worker_endpoint is None:
        worker_endpoint = '', net.WORKER_PORT
    elif ':' not in args.worker_endpoint:
        worker_endpoint = '', int(args.worker_endpoint)
    else:
        addr, port = args.worker_endpoint.rsplit(':', 1)
        worker_endpoint = addr, int(port)
    
    if args.address is not None and args.address != 'dynamic':
        try:
            _ = bitcoin_data.address_to_pubkey_hash(args.address, net.PARENT)
            args.pubkey_hash = True
        except Exception, e:
            parser.error('error parsing address: ' + repr(e))
Exemple #2
0
def run():
    realnets = dict((name, net) for name, net in networks.nets.iteritems() if '_testnet' not in name)
    
    parser = fixargparse.FixedArgumentParser(description='p2pool (version %s)' % (p2pool.__version__,), fromfile_prefix_chars='@')
    parser.add_argument('--version', action='version', version=p2pool.__version__)
    parser.add_argument('--net',
        help='use specified network (default: bitbar)',
        action='store', choices=sorted(realnets), default='bitbar', dest='net_name')
    parser.add_argument('--testnet',
        help='''use the network's testnet''',
        action='store_const', const=True, default=False, dest='testnet')
    parser.add_argument('--debug',
        help='enable debugging mode',
        action='store_const', const=True, default=False, dest='debug')
    parser.add_argument('--datadir',
        help='store data in this directory (default: <directory run_p2pool.py is in>/data)',
        type=str, action='store', default=None, dest='datadir')
    parser.add_argument('--logfile',
        help='''log to this file (default: data/<NET>/log)''',
        type=str, action='store', default=None, dest='logfile')
    parser.add_argument('--merged',
        help='call getauxblock on this url to get work for merged mining (example: http://ncuser:[email protected]:10332/)',
        type=str, action='append', default=[], dest='merged_urls')
    parser.add_argument('--give-author', metavar='DONATION_PERCENTAGE',
        help='donate this percentage of work towards the development of p2pool (default: 0.0)',
        type=float, action='store', default=0.0, dest='donation_percentage')
    parser.add_argument('--iocp',
        help='use Windows IOCP API in order to avoid errors due to large number of sockets being open',
        action='store_true', default=False, dest='iocp')
    parser.add_argument('--irc-announce',
        help='announce any blocks found on irc://irc.freenode.net/#p2pool',
        action='store_true', default=False, dest='irc_announce')
    parser.add_argument('--no-bugreport',
        help='disable submitting caught exceptions to the author',
        action='store_true', default=False, dest='no_bugreport')
    
    p2pool_group = parser.add_argument_group('p2pool interface')
    p2pool_group.add_argument('--p2pool-port', metavar='PORT',
        help='use port PORT to listen for connections (forward this port from your router!) (default: %s)' % ', '.join('%s:%i' % (name, net.P2P_PORT) for name, net in sorted(realnets.items())),
        type=int, action='store', default=None, dest='p2pool_port')
    p2pool_group.add_argument('-n', '--p2pool-node', metavar='ADDR[:PORT]',
        help='connect to existing p2pool node at ADDR listening on port PORT (defaults to default p2pool P2P port) in addition to builtin addresses',
        type=str, action='append', default=[], dest='p2pool_nodes')
    parser.add_argument('--disable-upnp',
        help='''don't attempt to use UPnP to forward p2pool's P2P port from the Internet to this computer''',
        action='store_false', default=True, dest='upnp')
    p2pool_group.add_argument('--max-conns', metavar='CONNS',
        help='maximum incoming connections (default: 40)',
        type=int, action='store', default=40, dest='p2pool_conns')
    p2pool_group.add_argument('--outgoing-conns', metavar='CONNS',
        help='outgoing connections (default: 6)',
        type=int, action='store', default=6, dest='p2pool_outgoing_conns')
    
    worker_group = parser.add_argument_group('worker interface')
    worker_group.add_argument('-w', '--worker-port', metavar='PORT or ADDR:PORT',
        help='listen on PORT on interface with ADDR for RPC connections from miners (default: all interfaces, %s)' % ', '.join('%s:%i' % (name, net.WORKER_PORT) for name, net in sorted(realnets.items())),
        type=str, action='store', default=None, dest='worker_endpoint')
    worker_group.add_argument('-f', '--fee', metavar='FEE_PERCENTAGE',
        help='''charge workers mining to their own bitcoin address (by setting their miner's username to a bitcoin address) this percentage fee to mine on your p2pool instance. Amount displayed at http://127.0.0.1:WORKER_PORT/fee (default: 0)''',
        type=float, action='store', default=0, dest='worker_fee')
    
    bitcoind_group = parser.add_argument_group('bitcoind interface')
    bitcoind_group.add_argument('--bitcoind-address', metavar='BITCOIND_ADDRESS',
        help='connect to this address (default: 127.0.0.1)',
        type=str, action='store', default='127.0.0.1', dest='bitcoind_address')
    bitcoind_group.add_argument('--bitcoind-rpc-port', metavar='BITCOIND_RPC_PORT',
        help='''connect to JSON-RPC interface at this port (default: %s <read from bitcoin.conf if password not provided>)''' % ', '.join('%s:%i' % (name, net.PARENT.RPC_PORT) for name, net in sorted(realnets.items())),
        type=int, action='store', default=None, dest='bitcoind_rpc_port')
    bitcoind_group.add_argument('--bitcoind-rpc-ssl',
        help='connect to JSON-RPC interface using SSL',
        action='store_true', default=False, dest='bitcoind_rpc_ssl')
    bitcoind_group.add_argument('--bitcoind-p2p-port', metavar='BITCOIND_P2P_PORT',
        help='''connect to P2P interface at this port (default: %s <read from bitcoin.conf if password not provided>)''' % ', '.join('%s:%i' % (name, net.PARENT.P2P_PORT) for name, net in sorted(realnets.items())),
        type=int, action='store', default=None, dest='bitcoind_p2p_port')
    
    bitcoind_group.add_argument(metavar='BITCOIND_RPCUSERPASS',
        help='bitcoind RPC interface username, then password, space-separated (only one being provided will cause the username to default to being empty, and none will cause P2Pool to read them from bitcoin.conf)',
        type=str, action='store', default=[], nargs='*', dest='bitcoind_rpc_userpass')
    
    args = parser.parse_args()
    
    if args.debug:
        p2pool.DEBUG = True
        defer.setDebugging(True)
    else:
        p2pool.DEBUG = False
    
    net_name = args.net_name + ('_testnet' if args.testnet else '')
    net = networks.nets[net_name]
    
    datadir_path = os.path.join((os.path.join(os.path.dirname(sys.argv[0]), 'data') if args.datadir is None else args.datadir), net_name)
    if not os.path.exists(datadir_path):
        os.makedirs(datadir_path)
    
    if len(args.bitcoind_rpc_userpass) > 2:
        parser.error('a maximum of two arguments are allowed')
    args.bitcoind_rpc_username, args.bitcoind_rpc_password = ([None, None] + args.bitcoind_rpc_userpass)[-2:]
    
    if args.bitcoind_rpc_password is None:
        conf_path = net.PARENT.CONF_FILE_FUNC()
        if not os.path.exists(conf_path):
            parser.error('''Bitcoin configuration file not found. Manually enter your RPC password.\r\n'''
                '''If you actually haven't created a configuration file, you should create one at %s with the text:\r\n'''
                '''\r\n'''
                '''server=1\r\n'''
                '''rpcpassword=%x\r\n'''
                '''\r\n'''
                '''Keep that password secret! After creating the file, restart Bitcoin.''' % (conf_path, random.randrange(2**128)))
        conf = open(conf_path, 'rb').read()
        contents = {}
        for line in conf.splitlines(True):
            if '#' in line:
                line = line[:line.index('#')]
            if '=' not in line:
                continue
            k, v = line.split('=', 1)
            contents[k.strip()] = v.strip()
        for conf_name, var_name, var_type in [
            ('rpcuser', 'bitcoind_rpc_username', str),
            ('rpcpassword', 'bitcoind_rpc_password', str),
            ('rpcport', 'bitcoind_rpc_port', int),
            ('port', 'bitcoind_p2p_port', int),
        ]:
            if getattr(args, var_name) is None and conf_name in contents:
                setattr(args, var_name, var_type(contents[conf_name]))
        if args.bitcoind_rpc_password is None:
            parser.error('''Bitcoin configuration file didn't contain an rpcpassword= line! Add one!''')
    
    if args.bitcoind_rpc_username is None:
        args.bitcoind_rpc_username = ''
    
    if args.bitcoind_rpc_port is None:
        args.bitcoind_rpc_port = net.PARENT.RPC_PORT
    
    if args.bitcoind_p2p_port is None:
        args.bitcoind_p2p_port = net.PARENT.P2P_PORT
    
    if args.p2pool_port is None:
        args.p2pool_port = net.P2P_PORT
    
    if args.p2pool_outgoing_conns > 10:
        parser.error('''--outgoing-conns can't be more than 10''')
    
    if args.worker_endpoint is None:
        worker_endpoint = '', net.WORKER_PORT
    elif ':' not in args.worker_endpoint:
        worker_endpoint = '', int(args.worker_endpoint)
    else:
        addr, port = args.worker_endpoint.rsplit(':', 1)
        worker_endpoint = addr, int(port)

    def separate_url(url):
        s = urlparse.urlsplit(url)
        if '@' not in s.netloc:
            parser.error('merged url netloc must contain an "@"')
        userpass, new_netloc = s.netloc.rsplit('@', 1)
        return urlparse.urlunsplit(s._replace(netloc=new_netloc)), userpass
    merged_urls = map(separate_url, args.merged_urls)
    
    if args.logfile is None:
        args.logfile = os.path.join(datadir_path, 'log')
    
    logfile = logging.LogFile(args.logfile)
    pipe = logging.TimestampingPipe(logging.TeePipe([logging.EncodeReplacerPipe(sys.stderr), logfile]))
    sys.stdout = logging.AbortPipe(pipe)
    sys.stderr = log.DefaultObserver.stderr = logging.AbortPipe(logging.PrefixPipe(pipe, '> '))
    if hasattr(signal, "SIGUSR1"):
        def sigusr1(signum, frame):
            print 'Caught SIGUSR1, closing %r...' % (args.logfile,)
            logfile.reopen()
            print '...and reopened %r after catching SIGUSR1.' % (args.logfile,)
        signal.signal(signal.SIGUSR1, sigusr1)
    task.LoopingCall(logfile.reopen).start(5)
    
    class ErrorReporter(object):
        def __init__(self):
            self.last_sent = None
        
        def emit(self, eventDict):
            if not eventDict["isError"]:
                return
            
            if self.last_sent is not None and time.time() < self.last_sent + 5:
                return
            self.last_sent = time.time()
            
            if 'failure' in eventDict:
                text = ((eventDict.get('why') or 'Unhandled Error')
                    + '\n' + eventDict['failure'].getTraceback())
            else:
                text = " ".join([str(m) for m in eventDict["message"]]) + "\n"
            
            from twisted.web import client
            client.getPage(
                url='http://u.forre.st/p2pool_error.cgi',
                method='POST',
                postdata=p2pool.__version__ + ' ' + net.NAME + '\n' + text,
                timeout=15,
            ).addBoth(lambda x: None)
    if not args.no_bugreport:
        log.addObserver(ErrorReporter().emit)
    
    reactor.callWhenRunning(main, args, net, datadir_path, merged_urls, worker_endpoint)
    reactor.run()
Exemple #3
0
def run():
    if not hasattr(tcp.Client, 'abortConnection'):
        print "Twisted doesn't have abortConnection! Upgrade to a newer version of Twisted to avoid memory leaks!"
        print 'Pausing for 3 seconds...'
        time.sleep(3)

    realnets = dict((name, net) for name, net in networks.nets.iteritems()
                    if '_testnet' not in name)

    parser = fixargparse.FixedArgumentParser(
        description='p2pool (version %s)' % (p2pool.__version__, ),
        fromfile_prefix_chars='@')
    parser.add_argument('--version',
                        action='version',
                        version=p2pool.__version__)
    parser.add_argument('--testnet',
                        help='''use the network's testnet''',
                        action='store_const',
                        const=True,
                        default=False,
                        dest='testnet')
    parser.add_argument('--debug',
                        help='enable debugging mode',
                        action='store_const',
                        const=True,
                        default=False,
                        dest='debug')
    parser.add_argument(
        '-a',
        '--address',
        help=
        'generate payouts to this address (default: <address requested from dcrwallet> which is not a good idea?)',
        type=str,
        action='store',
        default=None,
        dest='address')
    parser.add_argument(
        '-t',
        '--timeaddresses',
        help=
        'seconds between acquisition of new address and removal of single old (default: 2 days or 172800s)',
        type=int,
        action='store',
        default=172800,
        dest='timeaddresses')
    parser.add_argument(
        '--datadir',
        help=
        'store data in this directory (default: <directory run_p2pool.py is in>/data)',
        type=str,
        action='store',
        default=None,
        dest='datadir')
    parser.add_argument('--logfile',
                        help='''log to this file (default: data/<NET>/log)''',
                        type=str,
                        action='store',
                        default=None,
                        dest='logfile')
    parser.add_argument(
        '--give-author',
        metavar='DONATION_PERCENTAGE',
        help=
        'donate this percentage of work towards the development of p2pool (default: 1.0)',
        type=float,
        action='store',
        default=1.0,
        dest='donation_percentage')
    parser.add_argument(
        '--iocp',
        help=
        'use Windows IOCP API in order to avoid errors due to large number of sockets being open',
        action='store_true',
        default=False,
        dest='iocp')
    parser.add_argument(
        '--no-bugreport',
        help='disable submitting caught exceptions to the author',
        action='store_true',
        default=False,
        dest='no_bugreport')
    p2pool_group = parser.add_argument_group('p2pool interface')
    p2pool_group.add_argument(
        '--p2pool-port',
        metavar='PORT',
        help=
        'use port PORT to listen for connections (forward this port from your router!) (default: %s)'
        % ', '.join('%s:%i' % (name, net.P2P_PORT)
                    for name, net in sorted(realnets.items())),
        type=int,
        action='store',
        default=None,
        dest='p2pool_port')
    p2pool_group.add_argument(
        '-n',
        '--p2pool-node',
        metavar='ADDR[:PORT]',
        help=
        'connect to existing p2pool node at ADDR listening on port PORT (defaults to default p2pool P2P port) in addition to builtin addresses',
        type=str,
        action='append',
        default=[],
        dest='p2pool_nodes')
    parser.add_argument(
        '--disable-upnp',
        help=
        '''don't attempt to use UPnP to forward p2pool's P2P port from the Internet to this computer''',
        action='store_false',
        default=True,
        dest='upnp')
    p2pool_group.add_argument(
        '--max-conns',
        metavar='CONNS',
        help='maximum incoming connections (default: 40)',
        type=int,
        action='store',
        default=40,
        dest='p2pool_conns')
    p2pool_group.add_argument('--outgoing-conns',
                              metavar='CONNS',
                              help='outgoing connections (default: 6)',
                              type=int,
                              action='store',
                              default=6,
                              dest='p2pool_outgoing_conns')
    p2pool_group.add_argument(
        '--external-ip',
        metavar='ADDR[:PORT]',
        help=
        'specify your own public IP address instead of asking peers to discover it, useful for running dual WAN or asymmetric routing',
        type=str,
        action='store',
        default=None,
        dest='p2pool_external_ip')
    parser.add_argument(
        '--disable-advertise',
        help=
        '''don't advertise local IP address as being available for incoming connections. useful for running a dark node, along with multiple -n ADDR's and --outgoing-conns 0''',
        action='store_false',
        default=True,
        dest='advertise_ip')

    worker_group = parser.add_argument_group('worker interface')
    worker_group.add_argument(
        '-w',
        '--worker-port',
        metavar='PORT or ADDR:PORT',
        help=
        'listen on PORT on interface with ADDR for RPC connections from miners (default: all interfaces, %s)'
        % ', '.join('%s:%i' % (name, net.WORKER_PORT)
                    for name, net in sorted(realnets.items())),
        type=str,
        action='store',
        default=None,
        dest='worker_endpoint')
    worker_group.add_argument(
        '-f',
        '--fee',
        metavar='FEE_PERCENTAGE',
        help=
        '''charge workers mining to their own decred address (by setting their miner's username to a decred address) this percentage fee to mine on your p2pool instance. Amount displayed at http://127.0.0.1:WORKER_PORT/fee (default: 0)''',
        type=float,
        action='store',
        default=0,
        dest='worker_fee')

    dcrd_group = parser.add_argument_group('dcrd interface')
    dcrd_group.add_argument(
        '--dcrd-config-path',
        metavar='DCRD_CONFIG_PATH',
        help='custom configuration file path (when dcrd -conf option used)',
        type=str,
        action='store',
        default=None,
        dest='dcrd_config_path')
    dcrd_group.add_argument(
        '--dcrd-address',
        metavar='DCRD_ADDRESS',
        help='connect to this address (default: 127.0.0.1)',
        type=str,
        action='store',
        default='127.0.0.1',
        dest='dcrd_address')
    dcrd_group.add_argument(
        '--dcrd-rpc-port',
        metavar='DCRD_RPC_PORT',
        help=
        '''connect to JSON-RPC interface at this port (default: %s <read from decred.conf if password not provided>)'''
        % ', '.join('%s:%i' % (name, net.PARENT.RPC_PORT)
                    for name, net in sorted(realnets.items())),
        type=int,
        action='store',
        default=None,
        dest='dcrd_rpc_port')
    dcrd_group.add_argument(
        '--dcrd-rpc-wallet-port',
        metavar='DCRD_RPC_WALLET_PORT',
        help=
        '''connect to JSON-RPC wallet interface at this port (default: %s <read from decred.conf if password not provided>)'''
        % ', '.join('%s:%i' % (name, net.PARENT.RPC_WALLET_PORT)
                    for name, net in sorted(realnets.items())),
        type=int,
        action='store',
        default=None,
        dest='dcrd_rpc_wallet_port')
    dcrd_group.add_argument(
        '--dcrd-no-rpc-ssl',
        help=
        'connect to JSON-RPC interface - Not using SSL',  # default to using SSL unless stated
        action='store_true',
        default=False,
        dest='dcrd_no_rpc_ssl')
    dcrd_group.add_argument(
        '--dcrd-p2p-port',
        metavar='DCRD_P2P_PORT',
        help=
        '''connect to P2P interface at this port (default: %s <read from decred.conf if password not provided>)'''
        % ', '.join('%s:%i' % (name, net.PARENT.P2P_PORT)
                    for name, net in sorted(realnets.items())),
        type=int,
        action='store',
        default=None,
        dest='dcrd_p2p_port')
    dcrd_group.add_argument(
        metavar='DCRD_RPCUSERPASS',
        help=
        'dcrd RPC interface username, then password, space-separated (only one being provided will cause the username to default to being empty, and none will cause P2Pool to read them from decred.conf)',
        type=str,
        action='store',
        default=[],
        nargs='*',
        dest='dcrd_rpc_userpass')

    args = parser.parse_args()

    if args.debug:
        p2pool.DEBUG = True
        defer.setDebugging(True)
    else:
        p2pool.DEBUG = False

    #
    # fixed values
    #
    args.irc_announce = False
    args.net_name = 'decred'
    args.numaddresses = 0

    net_name = args.net_name + ('_testnet' if args.testnet else '')
    net = networks.nets[net_name]

    datadir_path = os.path.join(
        (os.path.join(os.path.dirname(sys.argv[0]), 'data')
         if args.datadir is None else args.datadir), net_name)
    if not os.path.exists(datadir_path):
        os.makedirs(datadir_path)

    if len(args.dcrd_rpc_userpass) > 2:
        parser.error('a maximum of two arguments are allowed')
    args.dcrd_rpc_username, args.dcrd_rpc_password = (
        [None, None] + args.dcrd_rpc_userpass)[-2:]

    if args.dcrd_rpc_password is None:
        conf_path = args.dcrd_config_path or net.PARENT.CONF_FILE_FUNC()
        if not os.path.exists(conf_path):
            parser.error('''Decred (dcrd) configuration file not found.'''
                         '''Expected in:''' % (conf_path))
        conf = open(conf_path, 'rb').read()
        contents = {}
        for line in conf.splitlines(True):
            if '#' in line:
                line = line[:line.index('#')]
            if '=' not in line:
                continue
            k, v = line.split('=', 1)
            contents[k.strip()] = v.strip()
        for conf_name, var_name, var_type in [
            ('rpcuser', 'dcrd_rpc_username', str),
            ('rpcpassword', 'dcrd_rpc_password', str),
            ('rpcpass', 'dcrd_rpc_password', str),  # gf:dcrd conf
            ('rpcport', 'dcrd_rpc_port', int),
            ('port', 'dcrd_p2p_port', int),
        ]:
            if getattr(args, var_name) is None and conf_name in contents:
                setattr(args, var_name, var_type(contents[conf_name]))
#         if 'rpcssl' in contents and contents['rpcssl'] != '0':
#             args.dcrd_rpc_ssl = True
        if args.dcrd_rpc_password is None:
            parser.error(
                '''Configuration file didn't contain an rpcpassword= or a rpcpass= line! Add one!'''
            )

    if args.dcrd_rpc_username is None:
        args.dcrd_rpc_username = ''

    if args.dcrd_rpc_port is None:
        args.dcrd_rpc_port = net.PARENT.RPC_PORT

    if args.dcrd_rpc_wallet_port is None:
        args.dcrd_rpc_wallet_port = net.PARENT.RPC_WALLET_PORT

    if args.dcrd_p2p_port is None:
        args.dcrd_p2p_port = net.PARENT.P2P_PORT

    if args.p2pool_port is None:
        args.p2pool_port = net.P2P_PORT

    if args.p2pool_outgoing_conns > 10:
        parser.error('''--outgoing-conns can't be more than 10''')

    if args.worker_endpoint is None:
        worker_endpoint = '', net.WORKER_PORT
    elif ':' not in args.worker_endpoint:
        worker_endpoint = '', int(args.worker_endpoint)
    else:
        addr, port = args.worker_endpoint.rsplit(':', 1)
        worker_endpoint = addr, int(port)

    if args.address is not None:
        try:
            args.pubkey_hash = decred_addr.address_to_pubkey_hash(
                args.address, net.PARENT)
        except Exception, e:
            parser.error('error parsing address: ' + repr(e))
Exemple #4
0
def run():
    if not hasattr(tcp.Client, 'abortConnection'):
        print "Twisted doesn't have abortConnection! Upgrade to a newer version of Twisted to avoid memory leaks!"
        print 'Pausing for 3 seconds...'
        time.sleep(3)

    realnets = dict((name, net) for name, net in networks.nets.iteritems()
                    if '_testnet' not in name)

    parser = fixargparse.FixedArgumentParser(
        description='P2Pool (version %s)' % (p2pool.__version__, ),
        fromfile_prefix_chars='@')
    parser.add_argument('--version',
                        action='version',
                        version=p2pool.__version__)
    parser.add_argument('--net',
                        help='use specified network (default: phoenixcoin)',
                        action='store',
                        choices=sorted(realnets),
                        default='phoenixcoin',
                        dest='net_name')
    parser.add_argument('--testnet',
                        help='''use the network's testnet''',
                        action='store_const',
                        const=True,
                        default=False,
                        dest='testnet')
    parser.add_argument('--debug',
                        help='enable debugging mode',
                        action='store_const',
                        const=True,
                        default=False,
                        dest='debug')
    parser.add_argument(
        '-a',
        '--address',
        help=
        'generate payouts to this address (default: <address returned by the daemon>)',
        type=str,
        action='store',
        default=None,
        dest='address')
    parser.add_argument(
        '--datadir',
        help=
        'store data in this directory (default: <directory run_p2pool.py is in>/data)',
        type=str,
        action='store',
        default=None,
        dest='datadir')
    parser.add_argument('--logfile',
                        help='''log to this file (default: data/<NET>/log)''',
                        type=str,
                        action='store',
                        default=None,
                        dest='logfile')
    parser.add_argument(
        '--merged',
        help=
        'call getauxblock on this url to get work for merged mining (example: http://ncuser:[email protected]:10332/)',
        type=str,
        action='append',
        default=[],
        dest='merged_urls')
    parser.add_argument(
        '--donate',
        metavar='DONATION_PERCENTAGE',
        help=
        'donate this percentage of work towards the NeoScrypt development (default: 1.0)',
        type=float,
        action='store',
        default=1.0,
        dest='donation_percentage')
    parser.add_argument(
        '--iocp',
        help=
        'use Windows IOCP API in order to avoid errors due to large number of sockets being open',
        action='store_true',
        default=False,
        dest='iocp')
    parser.add_argument(
        '--irc-announce',
        help='announce any blocks found on irc://irc.freenode.net/#p2pool',
        action='store_true',
        default=False,
        dest='irc_announce')
    parser.add_argument(
        '--no-bugreport',
        help='disable submitting caught exceptions to the developers',
        action='store_true',
        default=False,
        dest='no_bugreport')

    p2pool_group = parser.add_argument_group('P2Pool interface')
    p2pool_group.add_argument(
        '--p2pool-port',
        metavar='PORT',
        help=
        'use port PORT to listen for connections (forward this port from your router!) (default: %s)'
        % ', '.join('%s:%i' % (name, net.P2P_PORT)
                    for name, net in sorted(realnets.items())),
        type=int,
        action='store',
        default=None,
        dest='p2pool_port')
    p2pool_group.add_argument(
        '-n',
        '--p2pool-node',
        metavar='ADDR[:PORT]',
        help=
        'connect to existing P2Pool node at ADDR listening on port PORT (defaults to default P2Pool P2P port) in addition to builtin addresses',
        type=str,
        action='append',
        default=[],
        dest='p2pool_nodes')
    parser.add_argument(
        '--disable-upnp',
        help=
        '''don't attempt to use UPnP to forward P2Pool's P2P port from the Internet to this computer''',
        action='store_false',
        default=True,
        dest='upnp')
    p2pool_group.add_argument(
        '--max-conns',
        metavar='CONNS',
        help='maximum incoming connections (default: 40)',
        type=int,
        action='store',
        default=40,
        dest='p2pool_conns')
    p2pool_group.add_argument('--outgoing-conns',
                              metavar='CONNS',
                              help='outgoing connections (default: 6)',
                              type=int,
                              action='store',
                              default=6,
                              dest='p2pool_outgoing_conns')
    parser.add_argument(
        '--disable-advertise',
        help=
        '''don't advertise local IP address as being available for incoming connections. useful for running a dark node, along with multiple -n ADDR's and --outgoing-conns 0''',
        action='store_false',
        default=True,
        dest='advertise_ip')

    worker_group = parser.add_argument_group('Worker interface')
    worker_group.add_argument(
        '-w',
        '--worker-port',
        metavar='PORT or ADDR:PORT',
        help=
        'listen on PORT on interface with ADDR for RPC connections from miners (default: all interfaces, %s)'
        % ', '.join('%s:%i' % (name, net.WORKER_PORT)
                    for name, net in sorted(realnets.items())),
        type=str,
        action='store',
        default=None,
        dest='worker_endpoint')
    worker_group.add_argument(
        '-f',
        '--fee',
        metavar='FEE_PERCENTAGE',
        help=
        '''charge workers mining to their own address by assigning this percentage of work to your P2Pool's address. Amount displayed at http://127.0.0.1:WORKER_PORT/fee (default: 0)''',
        type=float,
        action='store',
        default=0,
        dest='worker_fee')
    worker_group.add_argument(
        '--miner-share-rate',
        metavar='SHARES_PER_MINUTE',
        help='number of psuedoshares per minute for each miner',
        type=float,
        action='store',
        default=None,
        dest='miner_share_rate')
    worker_group.add_argument(
        '--address-share-rate',
        metavar='SHARES_PER_MINUTE',
        help='number of psuedoshares per minute for each address',
        type=float,
        action='store',
        default=None,
        dest='address_share_rate')
    worker_group.add_argument('--min-difficulty',
                              metavar='DIFFICULTY',
                              help='minium difficulty for miners',
                              type=float,
                              action='store',
                              default=1 / (2**16),
                              dest='min_difficulty')

    daemon_group = parser.add_argument_group('Daemon interface')
    daemon_group.add_argument(
        '--daemon-config-path',
        metavar='DAEMON_CONFIG_PATH',
        help='custom configuration file path (when daemon -conf option used)',
        type=str,
        action='store',
        default=None,
        dest='daemon_config_path')
    daemon_group.add_argument(
        '--daemon-address',
        metavar='DAEMON_ADDRESS',
        help='connect to this address (default: 127.0.0.1)',
        type=str,
        action='store',
        default='127.0.0.1',
        dest='daemon_address')
    daemon_group.add_argument(
        '--daemon-rpc-port',
        metavar='DAEMON_RPC_PORT',
        help=
        '''connect to JSON-RPC interface at this port (default: %s <read from *coin.conf if password not provided>)'''
        % ', '.join('%s:%i' % (name, net.PARENT.RPC_PORT)
                    for name, net in sorted(realnets.items())),
        type=int,
        action='store',
        default=None,
        dest='daemon_rpc_port')
    daemon_group.add_argument('--daemon-rpc-ssl',
                              help='connect to JSON-RPC interface using SSL',
                              action='store_true',
                              default=False,
                              dest='daemon_rpc_ssl')
    daemon_group.add_argument(
        '--daemon-p2p-port',
        metavar='DAEMON_P2P_PORT',
        help=
        '''connect to P2P interface at this port (default: %s <read from *coin.conf if password not provided>)'''
        % ', '.join('%s:%i' % (name, net.PARENT.P2P_PORT)
                    for name, net in sorted(realnets.items())),
        type=int,
        action='store',
        default=None,
        dest='daemon_p2p_port')
    daemon_group.add_argument(
        metavar='DAEMON_RPCUSERPASS',
        help=
        'daemon RPC interface username, then password, space-separated (only one being provided will cause the username to default to being empty, and none will cause P2Pool to read them from *coin.conf)',
        type=str,
        action='store',
        default=[],
        nargs='*',
        dest='daemon_rpc_userpass')

    args = parser.parse_args()

    if args.debug:
        p2pool.DEBUG = True
        defer.setDebugging(True)
    else:
        p2pool.DEBUG = False

    net_name = args.net_name + ('_testnet' if args.testnet else '')
    net = networks.nets[net_name]

    datadir_path = os.path.join(
        (os.path.join(os.path.dirname(sys.argv[0]), 'data')
         if args.datadir is None else args.datadir), net_name)
    if not os.path.exists(datadir_path):
        os.makedirs(datadir_path)

    if len(args.daemon_rpc_userpass) > 2:
        parser.error('a maximum of two arguments are allowed')
    args.daemon_rpc_username, args.daemon_rpc_password = (
        [None, None] + args.daemon_rpc_userpass)[-2:]

    if args.daemon_rpc_password is None:
        conf_path = args.daemon_config_path or net.PARENT.CONF_FILE_FUNC()
        if not os.path.exists(conf_path):
            parser.error(
                '''Your daemon's configuration file not found. Manually enter your RPC password.\r\n'''
                '''If you actually haven't created a configuration file, you should create one at %s with the text:\r\n'''
                '''\r\n'''
                '''server=1\r\n'''
                '''rpcpassword=%x\r\n'''
                '''\r\n'''
                '''Keep that password secret! After creating the file, restart your daemon.'''
                % (conf_path, random.randrange(2**128)))
        conf = open(conf_path, 'rb').read()
        contents = {}
        for line in conf.splitlines(True):
            if '#' in line:
                line = line[:line.index('#')]
            if '=' not in line:
                continue
            k, v = line.split('=', 1)
            contents[k.strip()] = v.strip()
        for conf_name, var_name, var_type in [
            ('rpcuser', 'daemon_rpc_username', str),
            ('rpcpassword', 'daemon_rpc_password', str),
            ('rpcport', 'daemon_rpc_port', int),
            ('port', 'daemon_p2p_port', int),
        ]:
            if getattr(args, var_name) is None and conf_name in contents:
                setattr(args, var_name, var_type(contents[conf_name]))
        if 'rpcssl' in contents and contents['rpcssl'] != '0':
            args.daemon_rpc_ssl = True
        if args.daemon_rpc_password is None:
            parser.error(
                '''Your daemon's configuration file didn't contain an rpcpassword= line! Add one!'''
            )

    if args.daemon_rpc_username is None:
        args.daemon_rpc_username = ''

    if args.daemon_rpc_port is None:
        args.daemon_rpc_port = net.PARENT.RPC_PORT

    if args.daemon_p2p_port is None:
        args.daemon_p2p_port = net.PARENT.P2P_PORT

    if args.p2pool_port is None:
        args.p2pool_port = net.P2P_PORT

    if args.p2pool_outgoing_conns > 10:
        parser.error('''--outgoing-conns can't be more than 10''')

    if args.worker_endpoint is None:
        worker_endpoint = '', net.WORKER_PORT
    elif ':' not in args.worker_endpoint:
        worker_endpoint = '', int(args.worker_endpoint)
    else:
        addr, port = args.worker_endpoint.rsplit(':', 1)
        worker_endpoint = addr, int(port)

    if args.address is not None:
        try:
            args.pubkey_hash = bitcoin_data.address_to_pubkey_hash(
                args.address, net.PARENT)
        except Exception, e:
            parser.error('error parsing address: ' + repr(e))
Exemple #5
0
def run():
    realnets = dict((name, net) for name, net in networks.nets.iteritems()
                    if '_testnet' not in name)

    parser = fixargparse.FixedArgumentParser(
        description='p2pool (version %s)' % (p2pool.__version__, ),
        fromfile_prefix_chars='@')
    parser.add_argument('--version',
                        action='version',
                        version=p2pool.__version__)
    parser.add_argument('--net',
                        help='use specified network (default: bitcoin)',
                        action='store',
                        choices=sorted(realnets),
                        default='bitcoin',
                        dest='net_name')
    parser.add_argument('--testnet',
                        help='''use the network's testnet''',
                        action='store_const',
                        const=True,
                        default=False,
                        dest='testnet')
    parser.add_argument('--debug',
                        help='enable debugging mode',
                        action='store_const',
                        const=True,
                        default=False,
                        dest='debug')
    parser.add_argument(
        '-a',
        '--address',
        help=
        'generate payouts to this address (default: <address requested from bitcoind>)',
        type=str,
        action='store',
        default=None,
        dest='address')
    parser.add_argument(
        '--datadir',
        help=
        'store data in this directory (default: <directory run_p2pool.py is in>/data)',
        type=str,
        action='store',
        default=None,
        dest='datadir')
    parser.add_argument('--logfile',
                        help='''log to this file (default: data/<NET>/log)''',
                        type=str,
                        action='store',
                        default=None,
                        dest='logfile')
    parser.add_argument(
        '--merged',
        help=
        'call getauxblock on this url to get work for merged mining (example: http://ncuser:[email protected]:10332/)',
        type=str,
        action='append',
        default=[],
        dest='merged_urls')
    parser.add_argument(
        '--give-author',
        metavar='DONATION_PERCENTAGE',
        help=
        'donate this percentage of work towards the development of p2pool (default: 0.5)',
        type=float,
        action='store',
        default=0.5,
        dest='donation_percentage')
    parser.add_argument(
        '--iocp',
        help=
        'use Windows IOCP API in order to avoid errors due to large number of sockets being open',
        action='store_true',
        default=False,
        dest='iocp')
    parser.add_argument(
        '--irc-announce',
        help='announce any blocks found on irc://irc.freenode.net/#p2pool',
        action='store_true',
        default=False,
        dest='irc_announce')
    parser.add_argument(
        '--no-bugreport',
        help='disable submitting caught exceptions to the author',
        action='store_true',
        default=False,
        dest='no_bugreport')

    p2pool_group = parser.add_argument_group('p2pool interface')
    p2pool_group.add_argument(
        '--p2pool-port',
        metavar='PORT',
        help=
        'use port PORT to listen for connections (forward this port from your router!) (default: %s)'
        % ', '.join('%s:%i' % (name, net.P2P_PORT)
                    for name, net in sorted(realnets.items())),
        type=int,
        action='store',
        default=None,
        dest='p2pool_port')
    p2pool_group.add_argument(
        '-n',
        '--p2pool-node',
        metavar='ADDR[:PORT]',
        help=
        'connect to existing p2pool node at ADDR listening on port PORT (defaults to default p2pool P2P port) in addition to builtin addresses',
        type=str,
        action='append',
        default=[],
        dest='p2pool_nodes')
    parser.add_argument(
        '--disable-upnp',
        help=
        '''don't attempt to use UPnP to forward p2pool's P2P port from the Internet to this computer''',
        action='store_false',
        default=True,
        dest='upnp')
    p2pool_group.add_argument(
        '--max-conns',
        metavar='CONNS',
        help='maximum incoming connections (default: 40)',
        type=int,
        action='store',
        default=40,
        dest='p2pool_conns')
    p2pool_group.add_argument('--outgoing-conns',
                              metavar='CONNS',
                              help='outgoing connections (default: 10)',
                              type=int,
                              action='store',
                              default=10,
                              dest='p2pool_outgoing_conns')

    worker_group = parser.add_argument_group('worker interface')
    worker_group.add_argument(
        '-w',
        '--worker-port',
        metavar='PORT or ADDR:PORT',
        help=
        'listen on PORT on interface with ADDR for RPC connections from miners (default: all interfaces, %s)'
        % ', '.join('%s:%i' % (name, net.WORKER_PORT)
                    for name, net in sorted(realnets.items())),
        type=str,
        action='store',
        default=None,
        dest='worker_endpoint')
    worker_group.add_argument(
        '-f',
        '--fee',
        metavar='FEE_PERCENTAGE',
        help=
        '''charge workers mining to their own bitcoin address (by setting their miner's username to a bitcoin address) this percentage fee to mine on your p2pool instance. Amount displayed at http://127.0.0.1:WORKER_PORT/fee (default: 0)''',
        type=float,
        action='store',
        default=0,
        dest='worker_fee')

    bitcoind_group = parser.add_argument_group('bitcoind interface')
    bitcoind_group.add_argument(
        '--bitcoind-address',
        metavar='BITCOIND_ADDRESS',
        help='connect to this address (default: 127.0.0.1)',
        type=str,
        action='store',
        default='127.0.0.1',
        dest='bitcoind_address')
    bitcoind_group.add_argument(
        '--bitcoind-rpc-port',
        metavar='BITCOIND_RPC_PORT',
        help=
        '''connect to JSON-RPC interface at this port (default: %s <read from bitcoin.conf if password not provided>)'''
        % ', '.join('%s:%i' % (name, net.PARENT.RPC_PORT)
                    for name, net in sorted(realnets.items())),
        type=int,
        action='store',
        default=None,
        dest='bitcoind_rpc_port')
    bitcoind_group.add_argument('--bitcoind-rpc-ssl',
                                help='connect to JSON-RPC interface using SSL',
                                action='store_true',
                                default=False,
                                dest='bitcoind_rpc_ssl')
    bitcoind_group.add_argument(
        '--bitcoind-p2p-port',
        metavar='BITCOIND_P2P_PORT',
        help=
        '''connect to P2P interface at this port (default: %s <read from bitcoin.conf if password not provided>)'''
        % ', '.join('%s:%i' % (name, net.PARENT.P2P_PORT)
                    for name, net in sorted(realnets.items())),
        type=int,
        action='store',
        default=None,
        dest='bitcoind_p2p_port')

    bitcoind_group.add_argument(
        metavar='BITCOIND_RPCUSERPASS',
        help=
        'bitcoind RPC interface username, then password, space-separated (only one being provided will cause the username to default to being empty, and none will cause P2Pool to read them from bitcoin.conf)',
        type=str,
        action='store',
        default=[],
        nargs='*',
        dest='bitcoind_rpc_userpass')

    args = parser.parse_args()

    if args.debug:
        p2pool.DEBUG = True
        defer.setDebugging(True)

    net_name = args.net_name + ('_testnet' if args.testnet else '')
    net = networks.nets[net_name]

    datadir_path = os.path.join(
        (os.path.join(os.path.dirname(sys.argv[0]), 'data')
         if args.datadir is None else args.datadir), net_name)
    if not os.path.exists(datadir_path):
        os.makedirs(datadir_path)

    if len(args.bitcoind_rpc_userpass) > 2:
        parser.error('a maximum of two arguments are allowed')
    args.bitcoind_rpc_username, args.bitcoind_rpc_password = (
        [None, None] + args.bitcoind_rpc_userpass)[-2:]

    if args.bitcoind_rpc_password is None:
        conf_path = net.PARENT.CONF_FILE_FUNC()
        if not os.path.exists(conf_path):
            parser.error(
                '''Bitcoin configuration file not found. Manually enter your RPC password.\r\n'''
                '''If you actually haven't created a configuration file, you should create one at %s with the text:\r\n'''
                '''\r\n'''
                '''server=1\r\n'''
                '''rpcpassword=%x\r\n'''
                '''\r\n'''
                '''Keep that password secret! After creating the file, restart Bitcoin.'''
                % (conf_path, random.randrange(2**128)))
        conf = open(conf_path, 'rb').read()
        contents = {}
        for line in conf.splitlines(True):
            if '#' in line:
                line = line[:line.index('#')]
            if '=' not in line:
                continue
            k, v = line.split('=', 1)
            contents[k.strip()] = v.strip()
        for conf_name, var_name, var_type in [
            ('rpcuser', 'bitcoind_rpc_username', str),
            ('rpcpassword', 'bitcoind_rpc_password', str),
            ('rpcport', 'bitcoind_rpc_port', int),
            ('port', 'bitcoind_p2p_port', int),
        ]:
            if getattr(args, var_name) is None and conf_name in contents:
                setattr(args, var_name, var_type(contents[conf_name]))
        if args.bitcoind_rpc_password is None:
            parser.error(
                '''Bitcoin configuration file didn't contain an rpcpassword= line! Add one!'''
            )

    if args.bitcoind_rpc_username is None:
        args.bitcoind_rpc_username = ''

    if args.bitcoind_rpc_port is None:
        args.bitcoind_rpc_port = net.PARENT.RPC_PORT

    if args.bitcoind_p2p_port is None:
        args.bitcoind_p2p_port = net.PARENT.P2P_PORT

    if args.p2pool_port is None:
        args.p2pool_port = net.P2P_PORT

    if args.p2pool_outgoing_conns > 10:
        parser.error('''--outgoing-conns can't be more than 10''')

    if args.worker_endpoint is None:
        worker_endpoint = '', net.WORKER_PORT
    elif ':' not in args.worker_endpoint:
        worker_endpoint = '', int(args.worker_endpoint)
    else:
        addr, port = args.worker_endpoint.rsplit(':', 1)
        worker_endpoint = addr, int(port)

    if args.address is not None:
        try:
            args.pubkey_hash = bitcoin_data.address_to_pubkey_hash(
                args.address, net.PARENT)
        except Exception, e:
            parser.error('error parsing address: ' + repr(e))
Exemple #6
0
def run():
    if not hasattr(tcp.Client, 'abortConnection'):
        print "Twisted doesn't have abortConnection! Upgrade to a newer version of Twisted to avoid memory leaks!"
        print 'Pausing for 3 seconds...'
        time.sleep(3)

    realnets = dict((name, net) for name, net in networks.nets.iteritems()
                    if '_testnet' not in name)

    parser = fixargparse.FixedArgumentParser(
        description='p2pool (version %s)' % (p2pool.__version__, ),
        fromfile_prefix_chars='@')
    parser.add_argument('--version',
                        action='version',
                        version=p2pool.__version__)
    parser.add_argument('--net',
                        help='use specified network (default: dash)',
                        action='store',
                        choices=sorted(realnets),
                        default='dash',
                        dest='net_name')
    parser.add_argument('--testnet',
                        help='''use the network's testnet''',
                        action='store_const',
                        const=True,
                        default=False,
                        dest='testnet')
    parser.add_argument('--debug',
                        help='enable debugging mode',
                        action='store_const',
                        const=True,
                        default=False,
                        dest='debug')
    parser.add_argument('--rconsole',
                        help='enable rconsole debugging mode (requires rfoo)',
                        action='store_const',
                        const=True,
                        default=False,
                        dest='rconsole')

    parser.add_argument(
        '-a',
        '--address',
        help=
        'generate payouts to this address (default: <address requested from dashd>), or (dynamic)',
        type=str,
        action='store',
        default=None,
        dest='address')
    parser.add_argument(
        '-i',
        '--numaddresses',
        help=
        'number of dash auto-generated addresses to maintain for getwork dynamic address allocation',
        type=int,
        action='store',
        default=2,
        dest='numaddresses')
    parser.add_argument(
        '-t',
        '--timeaddresses',
        help=
        'seconds between acquisition of new address and removal of single old (default: 2 days or 172800s)',
        type=int,
        action='store',
        default=172800,
        dest='timeaddresses')
    parser.add_argument(
        '--datadir',
        help=
        'store data in this directory (default: <directory run_p2pool.py is in>/data)',
        type=str,
        action='store',
        default=None,
        dest='datadir')
    parser.add_argument('--logfile',
                        help='''log to this file (default: data/<NET>/log)''',
                        type=str,
                        action='store',
                        default=None,
                        dest='logfile')
    parser.add_argument(
        '--web-static',
        help=
        'use an alternative web frontend in this directory (otherwise use the built-in frontend)',
        type=str,
        action='store',
        default=None,
        dest='web_static')
    parser.add_argument(
        '--merged',
        help=
        'call getauxblock on this url to get work for merged mining (example: http://ncuser:[email protected]:10332/)',
        type=str,
        action='append',
        default=[],
        dest='merged_urls')
    parser.add_argument('--coinbtext',
                        help='append this text to the coinbase',
                        type=str,
                        action='append',
                        default=[],
                        dest='coinb_texts')
    parser.add_argument(
        '--give-author',
        metavar='DONATION_PERCENTAGE',
        help=
        'donate this percentage of work towards the development of p2pool (default: 1.0)',
        type=float,
        action='store',
        default=1.0,
        dest='donation_percentage')
    parser.add_argument(
        '--iocp',
        help=
        'use Windows IOCP API in order to avoid errors due to large number of sockets being open',
        action='store_true',
        default=False,
        dest='iocp')
    parser.add_argument(
        '--irc-announce',
        help='announce any blocks found on irc://irc.freenode.net/#p2pool',
        action='store_true',
        default=False,
        dest='irc_announce')
    parser.add_argument(
        '--no-bugreport',
        help='disable submitting caught exceptions to the author',
        action='store_true',
        default=False,
        dest='no_bugreport')

    p2pool_group = parser.add_argument_group('p2pool interface')
    p2pool_group.add_argument(
        '--p2pool-port',
        metavar='PORT',
        help=
        'use port PORT to listen for connections (forward this port from your router!) (default: %s)'
        % ', '.join('%s:%i' % (name, net.P2P_PORT)
                    for name, net in sorted(realnets.items())),
        type=int,
        action='store',
        default=None,
        dest='p2pool_port')
    p2pool_group.add_argument(
        '-n',
        '--p2pool-node',
        metavar='ADDR[:PORT]',
        help=
        'connect to existing p2pool node at ADDR listening on port PORT (defaults to default p2pool P2P port) in addition to builtin addresses',
        type=str,
        action='append',
        default=[],
        dest='p2pool_nodes')
    parser.add_argument(
        '--disable-upnp',
        help=
        '''don't attempt to use UPnP to forward p2pool's P2P port from the Internet to this computer''',
        action='store_false',
        default=True,
        dest='upnp')
    p2pool_group.add_argument(
        '--max-conns',
        metavar='CONNS',
        help='maximum incoming connections (default: 40)',
        type=int,
        action='store',
        default=40,
        dest='p2pool_conns')
    p2pool_group.add_argument('--outgoing-conns',
                              metavar='CONNS',
                              help='outgoing connections (default: 6)',
                              type=int,
                              action='store',
                              default=6,
                              dest='p2pool_outgoing_conns')
    p2pool_group.add_argument(
        '--external-ip',
        metavar='ADDR[:PORT]',
        help=
        'specify your own public IP address instead of asking peers to discover it, useful for running dual WAN or asymmetric routing',
        type=str,
        action='store',
        default=None,
        dest='p2pool_external_ip')
    parser.add_argument(
        '--disable-advertise',
        help=
        '''don't advertise local IP address as being available for incoming connections. useful for running a dark node, along with multiple -n ADDR's and --outgoing-conns 0''',
        action='store_false',
        default=True,
        dest='advertise_ip')

    worker_group = parser.add_argument_group('worker interface')
    worker_group.add_argument(
        '-w',
        '--worker-port',
        metavar='PORT or ADDR:PORT',
        help=
        'listen on PORT on interface with ADDR for RPC connections from miners (default: all interfaces, %s)'
        % ', '.join('%s:%i' % (name, net.WORKER_PORT)
                    for name, net in sorted(realnets.items())),
        type=str,
        action='store',
        default=None,
        dest='worker_endpoint')
    worker_group.add_argument(
        '-f',
        '--fee',
        metavar='FEE_PERCENTAGE',
        help=
        '''charge workers mining to their own dash address (by setting their miner's username to a dash address) this percentage fee to mine on your p2pool instance. Amount displayed at http://127.0.0.1:WORKER_PORT/fee (default: 0)''',
        type=float,
        action='store',
        default=0,
        dest='worker_fee')
    worker_group.add_argument(
        '--miner-share-rate',
        metavar='SHARES_PER_MINUTE',
        help='number of psuedoshares per minute for each miner',
        type=float,
        action='store',
        default=None,
        dest='miner_share_rate')
    worker_group.add_argument(
        '--address-share-rate',
        metavar='SHARES_PER_MINUTE',
        help='number of psuedoshares per minute for each address',
        type=float,
        action='store',
        default=None,
        dest='address_share_rate')
    worker_group.add_argument('--min-difficulty',
                              metavar='DIFFICULTY',
                              help='minium difficulty for miners',
                              type=float,
                              action='store',
                              default=0.01,
                              dest='min_difficulty')

    dashd_group = parser.add_argument_group('dashd interface')
    dashd_group.add_argument(
        '--dashd-config-path',
        metavar='DASHD_CONFIG_PATH',
        help='custom configuration file path (when dashd -conf option used)',
        type=str,
        action='store',
        default=None,
        dest='dashd_config_path')
    dashd_group.add_argument(
        '--dashd-address',
        metavar='DASHD_ADDRESS',
        help='connect to this address (default: 127.0.0.1)',
        type=str,
        action='store',
        default='127.0.0.1',
        dest='dashd_address')
    dashd_group.add_argument(
        '--dashd-rpc-port',
        metavar='DASHD_RPC_PORT',
        help=
        '''connect to JSON-RPC interface at this port (default: %s <read from dash.conf if password not provided>)'''
        % ', '.join('%s:%i' % (name, net.PARENT.RPC_PORT)
                    for name, net in sorted(realnets.items())),
        type=int,
        action='store',
        default=None,
        dest='dashd_rpc_port')
    dashd_group.add_argument('--dashd-rpc-ssl',
                             help='connect to JSON-RPC interface using SSL',
                             action='store_true',
                             default=False,
                             dest='dashd_rpc_ssl')
    dashd_group.add_argument(
        '--dashd-p2p-port',
        metavar='DASHD_P2P_PORT',
        help=
        '''connect to P2P interface at this port (default: %s <read from dash.conf if password not provided>)'''
        % ', '.join('%s:%i' % (name, net.PARENT.P2P_PORT)
                    for name, net in sorted(realnets.items())),
        type=int,
        action='store',
        default=None,
        dest='dashd_p2p_port')

    dashd_group.add_argument(
        metavar='DASHD_RPCUSERPASS',
        help=
        'dashd RPC interface username, then password, space-separated (only one being provided will cause the username to default to being empty, and none will cause P2Pool to read them from dash.conf)',
        type=str,
        action='store',
        default=[],
        nargs='*',
        dest='dashd_rpc_userpass')

    args = parser.parse_args()

    if args.debug:
        p2pool.DEBUG = True
        defer.setDebugging(True)
    else:
        p2pool.DEBUG = False

    net_name = args.net_name + ('_testnet' if args.testnet else '')
    net = networks.nets[net_name]

    datadir_path = os.path.join(
        (os.path.join(os.path.dirname(sys.argv[0]), 'data')
         if args.datadir is None else args.datadir), net_name)
    if not os.path.exists(datadir_path):
        os.makedirs(datadir_path)

    if len(args.dashd_rpc_userpass) > 2:
        parser.error('a maximum of two arguments are allowed')
    args.dashd_rpc_username, args.dashd_rpc_password = (
        [None, None] + args.dashd_rpc_userpass)[-2:]

    if args.dashd_rpc_password is None:
        conf_path = args.dashd_config_path or net.PARENT.CONF_FILE_FUNC()
        if not os.path.exists(conf_path):
            parser.error(
                '''dash configuration file not found. Manually enter your RPC password.\r\n'''
                '''If you actually haven't created a configuration file, you should create one at %s with the text:\r\n'''
                '''\r\n'''
                '''server=1\r\n'''
                '''rpcpassword=%x\r\n'''
                '''\r\n'''
                '''Keep that password secret! After creating the file, restart dash.'''
                % (conf_path, random.randrange(2**128)))
        conf = open(conf_path, 'rb').read()
        contents = {}
        for line in conf.splitlines(True):
            if '#' in line:
                line = line[:line.index('#')]
            if '=' not in line:
                continue
            k, v = line.split('=', 1)
            contents[k.strip()] = v.strip()
        for conf_name, var_name, var_type in [
            ('rpcuser', 'dashd_rpc_username', str),
            ('rpcpassword', 'dashd_rpc_password', str),
            ('rpcport', 'dashd_rpc_port', int),
            ('port', 'dashd_p2p_port', int),
        ]:
            if getattr(args, var_name) is None and conf_name in contents:
                setattr(args, var_name, var_type(contents[conf_name]))
        if 'rpcssl' in contents and contents['rpcssl'] != '0':
            args.dashd_rpc_ssl = True
        if args.dashd_rpc_password is None:
            parser.error(
                '''dash configuration file didn't contain an rpcpassword= line! Add one!'''
            )

    if args.dashd_rpc_username is None:
        args.dashd_rpc_username = ''

    if args.dashd_rpc_port is None:
        args.dashd_rpc_port = net.PARENT.RPC_PORT

    if args.dashd_p2p_port is None:
        args.dashd_p2p_port = net.PARENT.P2P_PORT

    if args.p2pool_port is None:
        args.p2pool_port = net.P2P_PORT

    if args.worker_endpoint is None:
        worker_endpoint = '', net.WORKER_PORT
    elif ':' not in args.worker_endpoint:
        worker_endpoint = '', int(args.worker_endpoint)
    else:
        addr, port = args.worker_endpoint.rsplit(':', 1)
        worker_endpoint = addr, int(port)

    if args.address is not None and args.address != 'dynamic':
        try:
            args.pubkey_hash = dash_data.address_to_pubkey_hash(
                args.address, net.PARENT)
        except Exception as e:
            parser.error('error parsing address: ' + repr(e))
    else:
        args.pubkey_hash = None

    def separate_url(url):
        s = urlparse.urlsplit(url)
        if '@' not in s.netloc:
            parser.error('merged url netloc must contain an "@"')
        userpass, new_netloc = s.netloc.rsplit('@', 1)
        return urlparse.urlunsplit(s._replace(netloc=new_netloc)), userpass

    merged_urls = map(separate_url, args.merged_urls)

    if args.logfile is None:
        args.logfile = os.path.join(datadir_path, 'log')

    logfile = logging.LogFile(args.logfile)
    pipe = logging.TimestampingPipe(
        logging.TeePipe([logging.EncodeReplacerPipe(sys.stderr), logfile]))
    sys.stdout = logging.AbortPipe(pipe)
    sys.stderr = log.DefaultObserver.stderr = logging.AbortPipe(
        logging.PrefixPipe(pipe, '> '))
    if hasattr(signal, "SIGUSR1"):

        def sigusr1(signum, frame):
            print 'Caught SIGUSR1, closing %r...' % (args.logfile, )
            logfile.reopen()
            print '...and reopened %r after catching SIGUSR1.' % (
                args.logfile, )

        signal.signal(signal.SIGUSR1, sigusr1)
    deferral.RobustLoopingCall(logfile.reopen).start(5)

    class ErrorReporter(object):
        def __init__(self):
            self.last_sent = None

        def emit(self, eventDict):
            if not eventDict["isError"]:
                return

            if self.last_sent is not None and time.time() < self.last_sent + 5:
                return
            self.last_sent = time.time()

            if 'failure' in eventDict:
                text = ((eventDict.get('why') or 'Unhandled Error') + '\n' +
                        eventDict['failure'].getTraceback())
            else:
                text = " ".join([str(m) for m in eventDict["message"]]) + "\n"

            from twisted.web import client
            client.getPage(
                url='http://u.forre.st/p2pool_error.cgi',
                method='POST',
                postdata=p2pool.__version__ + ' ' + net.NAME + '\n' + text,
                timeout=15,
            ).addBoth(lambda x: None)

    if not args.no_bugreport:
        log.addObserver(ErrorReporter().emit)
    if args.rconsole:
        from rfoo.utils import rconsole
        rconsole.spawn_server()

    reactor.callWhenRunning(main, args, net, datadir_path, merged_urls,
                            worker_endpoint)
    reactor.run()