From 38ebf35f77cab55db590ee723e85d4ebbf82ab76 Mon Sep 17 00:00:00 2001 From: philemon Date: Sun, 27 Nov 2016 10:49:29 +0300 Subject: [PATCH] [opt/cfg]: add --rpc-port, --rpc-user, --rpc-password [mswin]: remove non-MSYS Windows support (except for bitcoin datadir) MS users must launch scripts from an MSYS environment --- data_files/mmgen.cfg | 9 +++++++++ mmgen/globalvars.py | 24 ++++++++++++++---------- mmgen/opts.py | 25 ++++++++++++++----------- mmgen/rpc.py | 12 ++++++++---- mmgen/util.py | 36 +++++++++++------------------------- 5 files changed, 56 insertions(+), 50 deletions(-) diff --git a/data_files/mmgen.cfg b/data_files/mmgen.cfg index d6c669b1..557a9687 100644 --- a/data_files/mmgen.cfg +++ b/data_files/mmgen.cfg @@ -20,6 +20,15 @@ # Set the RPC host (the host bitcoind is running on): # rpc_host localhost +# Set the RPC host's port number +# rpc_port 8332 + +# Uncomment to override 'rpcuser' in bitcoin.conf +# rpc_user myusername + +# Uncomment to override 'rpcpassword' in bitcoin.conf +# rpc_password mypassword + # Set the default hash preset: # hash_preset 3 diff --git a/mmgen/globalvars.py b/mmgen/globalvars.py index 08d1518e..54a84982 100755 --- a/mmgen/globalvars.py +++ b/mmgen/globalvars.py @@ -54,6 +54,7 @@ class g(object): tx_confs = 3 seed_len = 256 + http_timeout = 60 # Constants - some of these might be overriden, but they don't change thereafter @@ -64,7 +65,10 @@ class g(object): hold_protect = True color = (False,True)[sys.stdout.isatty()] testnet = False - rpc_host = 'localhost' + rpc_host = '' + rpc_port = 0 + rpc_user = '' + rpc_password = '' testnet_name = 'testnet3' bogus_wallet_data = '' # for debugging, used by test suite @@ -76,18 +80,18 @@ class g(object): if os.getenv('HOME'): # Linux or MSYS home_dir = os.getenv('HOME') - elif platform == 'win' and os.getenv('HOMEPATH'): # Windows native: + elif platform == 'win': # Windows native: die(1,'$HOME not set! {} for Windows must be run in MSYS environment'.format(proj_name)) else: die(2,'$HOME is not set! Unable to determine home directory') - data_dir_root = None - data_dir = None - cfg_file = None - bitcoin_data_dir = (os.path.join(home_dir,'Application Data','Bitcoin'), - os.path.join(home_dir,'.bitcoin'))[bool(os.getenv('HOME'))] + data_dir_root,data_dir,cfg_file = None,None,None + bitcoin_data_dir = os.path.join(os.getenv('APPDATA'),'Bitcoin') if platform == 'win' \ + else os.path.join(home_dir,'.bitcoin') + + # User opt sets global var: + common_opts = ('color','no_license','rpc_host','rpc_port','testnet','rpc_user','rpc_password') - common_opts = ('color','no_license','rpc_host','testnet') required_opts = ( 'quiet','verbose','debug','outdir','echo_passphrase','passwd_file','stdout', 'show_hash_presets','label','keep_passphrase','keep_hash_preset', @@ -101,8 +105,8 @@ class g(object): ('batch','rescan'), ) cfg_file_opts = ( - 'color','debug','hash_preset','http_timeout','no_license','rpc_host', - 'quiet','tx_fee','tx_fee_adj','usr_randchars','testnet' + 'color','debug','hash_preset','http_timeout','no_license','rpc_host','rpc_port', + 'quiet','tx_fee','tx_fee_adj','usr_randchars','testnet','rpc_user','rpc_password' ) env_opts = ( 'MMGEN_BOGUS_WALLET_DATA', diff --git a/mmgen/opts.py b/mmgen/opts.py index f50314b8..a813f458 100755 --- a/mmgen/opts.py +++ b/mmgen/opts.py @@ -65,14 +65,18 @@ def _show_hash_presets(): msg(fs.format("'%s'" % i, *g.hash_presets[i])) msg('N = memory usage (power of two), p = iterations (rounds)') +# most, but not all, of these set the corresponding global var common_opts_data = """ ---, --color=c Set to '0' to disable color output, '1' to enable ---, --data-dir=d Specify the location of {pnm}'s data directory ---, --no-license Suppress the GPL license prompt ---, --rpc-host=h Communicate with bitcoind running on host 'h' ---, --testnet=1 Set to '1' use testnet, '0' to force mainnet ---, --skip-cfg-file Skip reading the configuration file ---, --version Print version information and exit +--, --color=c Set to '0' to disable color output, '1' to enable +--, --data-dir=d Specify the location of {pnm}'s data directory +--, --no-license Suppress the GPL license prompt +--, --rpc-host=h Communicate with bitcoind running on host 'h' +--, --rpc-port=p Communicate with bitcoind listening on port 'p' +--, --rpc-user=u Override 'rpcuser' in bitcoin.conf +--, --rpc-password=p Override 'rpcpassword' in bitcoin.conf +--, --testnet=1 Set to '1' enable testnet, '0' to disable +--, --skip-cfg-file Skip reading the configuration file +--, --version Print version information and exit """.format(pnm=g.proj_name) def opt_preproc_debug(short_opts,long_opts,skipped_opts,uopts,args): @@ -100,7 +104,7 @@ def opt_postproc_debug(): Msg(' Global vars:') for e in [d for d in dir(g) if d[:2] != '__']: Msg(' {:<20}: {}'.format(e, getattr(g,e))) - Msg('\n=== end opts.py debug ===') + Msg('\n=== end opts.py debug ===\n') def opt_postproc_actions(): from mmgen.term import set_terminal_vars @@ -110,10 +114,8 @@ def opt_postproc_actions(): check_or_create_dir(g.data_dir) # dies on error def set_data_dir_root(): - g.data_dir_root = os.path.normpath(os.path.expanduser(opt.data_dir)) if opt.data_dir else \ - (os.path.join(g.home_dir,'Application Data',g.proj_name), - os.path.join(g.home_dir,'.'+g.proj_name.lower()))[bool(os.getenv('HOME'))] + os.path.join(g.home_dir,'.'+g.proj_name.lower()) # mainnet and testnet share cfg file, as with Core g.cfg_file = os.path.join(g.data_dir_root,'{}.cfg'.format(g.proj_name.lower())) @@ -194,6 +196,7 @@ def init(opts_data,add_opts=[],opt_filter=None): # === Interaction with global vars begins here === + # NB: user opt --data-dir is actually g.data_dir_root # cfg file is in g.data_dir_root, wallet and other data are in g.data_dir # Must set g.data_dir_root and g.cfg_file from cmdline before processing cfg file set_data_dir_root() diff --git a/mmgen/rpc.py b/mmgen/rpc.py index d7e49718..f2a6e511 100755 --- a/mmgen/rpc.py +++ b/mmgen/rpc.py @@ -36,16 +36,20 @@ class BitcoinRPCConnection(object): user=None,passwd=None,auth_cookie=None, ): + dmsg('=== BitcoinRPCConnection.__init__() debug ===') + dmsg(' host [{}] port [{}] user [{}] passwd [{}] auth_cookie [{}]\n'.format( + host,port,user,passwd,auth_cookie)) + if user and passwd: self.auth_str = '{}:{}'.format(user,passwd) elif auth_cookie: self.auth_str = auth_cookie else: msg('Error: no Bitcoin RPC authentication method found') - if passwd: die(1,"'rpcuser' entry missing in bitcoin.conf") - elif user: die(1,"'rpcpassword' entry missing in bitcoin.conf") + if passwd: die(1,"'rpcuser' entry not found in bitcoin.conf or mmgen.cfg") + elif user: die(1,"'rpcpassword' entry not found in bitcoin.conf or mmgen.cfg") else: - m1 = 'Either provide rpcuser/rpcpassword in bitcoin.conf' + m1 = 'Either provide rpcuser/rpcpassword in bitcoin.conf or mmgen.cfg' m2 = '(or, alternatively, copy the authentication cookie to Bitcoin data dir' m3 = 'if {} and Bitcoin are running as different users)'.format(g.proj_name) die(1,'\n'.join((m1,m2,m3))) @@ -79,7 +83,7 @@ class BitcoinRPCConnection(object): else: die(*args[1:]) - dmsg('=== rpc.py debug ===') + dmsg('=== request() debug ===') dmsg(' RPC POST data ==> %s\n' % p) caller = self class MyJSONEncoder(json.JSONEncoder): diff --git a/mmgen/util.py b/mmgen/util.py index 75213bcc..fcc956ea 100755 --- a/mmgen/util.py +++ b/mmgen/util.py @@ -648,24 +648,10 @@ def prompt_and_get_char(prompt,chars,enter_ok=False,verbose=False): def do_pager(text): - pagers = ['less','more'] - shell = False - -# Hack for MS Windows command line (i.e. non CygWin) environment -# When 'shell' is true, Windows aborts the calling program if executable -# not found. -# When 'shell' is false, an exception is raised, invoking the fallback -# 'print' instead of the pager. -# We risk assuming that 'more' will always be available on a stock -# Windows installation. - if g.platform == 'win': - if 'HOME' not in os.environ: # native Windows terminal - shell = True - pagers = ['more'] - else: # MSYS - os.environ['LESS'] = '-cR -#1' # disable buggy line chopping - else: - os.environ['LESS'] = '-RS -#1' # raw, chop, scroll right 1 char + pagers,shell = ['less','more'],False + # --- Non-MSYS Windows code deleted --- + # raw, chop, scroll right 1 char, disable buggy line chopping for Windows + os.environ['LESS'] = (('-RS -#1'),('-cR -#1'))[g.platform=='win'] if 'PAGER' in os.environ and os.environ['PAGER'] != pagers[0]: pagers = [os.environ['PAGER']] + pagers @@ -727,14 +713,14 @@ def get_bitcoind_auth_cookie(): return '' def bitcoin_connection(): - - port = (8332,18332)[g.testnet] - host,user,passwd = g.rpc_host,'rpcuser','rpcpassword' - cfg = get_bitcoind_cfg_options((user,passwd)) - auth_cookie = get_bitcoind_auth_cookie() - + cfg = get_bitcoind_cfg_options(('rpcuser','rpcpassword')) import mmgen.rpc c = mmgen.rpc.BitcoinRPCConnection( - host,port,cfg[user],cfg[passwd],auth_cookie=auth_cookie) + g.rpc_host or 'localhost', + g.rpc_port or (8332,18332)[g.testnet], + g.rpc_user or cfg['rpcuser'], # MMGen's rpcuser,rpcpassword override bitcoind's + g.rpc_password or cfg['rpcpassword'], + auth_cookie=get_bitcoind_auth_cookie()) + # do an RPC call to make the function fail if we can't connect c.client_version = int(c.getinfo()['version']) return c