def rpc_init_bitcoind(): def check_chainfork_mismatch(conn): block0 = conn.getblockhash(0) latest = conn.getblockcount() try: assert block0 == g.proto.block0, 'Incorrect Genesis block for {}'.format( g.proto.__name__) for fork in g.proto.forks: if fork[0] == None or latest < fork[0]: break assert conn.getblockhash(fork[0]) == fork[1], ( 'Bad block hash at fork block {}. Is this the {} chain?'. format(fork[0], fork[2].upper())) except Exception as e: die( 2, "{}\n'{c}' requested, but this is not the {c} chain!".format( e.message, c=g.coin)) def check_chaintype_mismatch(): try: if g.regtest: assert g.chain == 'regtest', '--regtest option selected, but chain is not regtest' if g.testnet: assert g.chain != 'mainnet', '--testnet option selected, but chain is mainnet' if not g.testnet: assert g.chain == 'mainnet', 'mainnet selected, but chain is not mainnet' except Exception as e: die(1, '{}\nChain is {}!'.format(e.message, g.chain)) cfg = get_daemon_cfg_options(('rpcuser', 'rpcpassword')) from mmgen.rpc import CoinDaemonRPCConnection conn = CoinDaemonRPCConnection( g.rpc_host or 'localhost', g.rpc_port or g.proto.rpc_port, g.rpc_user or cfg['rpcuser'], # MMGen's rpcuser,rpcpassword override coin daemon's g.rpc_password or cfg['rpcpassword'], auth_cookie=get_coin_daemon_auth_cookie()) if g.bob or g.alice: import regtest as rt rt.user(('alice', 'bob')[g.bob], quiet=True) conn.daemon_version = int(conn.getnetworkinfo()['version']) conn.coin_amt_type = (float, str)[conn.daemon_version >= 120000] g.chain = conn.getblockchaininfo()['chain'] if g.chain != 'regtest': g.chain += 'net' assert g.chain in g.chains check_chaintype_mismatch() if g.chain == 'mainnet': # skip this for testnet, as Genesis block may change check_chainfork_mismatch(conn) conn.caps = () for func, cap in (('setlabel', 'label_api'), ('signrawtransactionwithkey', 'sign_with_key')): if len(conn.request('help', func).split('\n')) > 3: conn.caps += (cap, ) return conn
def rpc_init(reinit=False): if not 'rpc' in g.proto.mmcaps: die(1,'Coin daemon operations not supported for coin {}!'.format(g.coin)) if g.rpch != None and not reinit: return g.rpch def check_chainfork_mismatch(conn): block0 = conn.getblockhash(0) latest = conn.getblockcount() try: assert block0 == g.proto.block0,'Incorrect Genesis block for {}'.format(g.proto.__name__) for fork in g.proto.forks: if fork[0] == None or latest < fork[0]: break assert conn.getblockhash(fork[0]) == fork[1], ( 'Bad block hash at fork block {}. Is this the {} chain?'.format(fork[0],fork[2].upper())) except Exception as e: die(2,"{}\n'{c}' requested, but this is not the {c} chain!".format(e,c=g.coin)) def check_chaintype_mismatch(): try: if g.regtest: assert g.chain == 'regtest','--regtest option selected, but chain is not regtest' if g.testnet: assert g.chain != 'mainnet','--testnet option selected, but chain is mainnet' if not g.testnet: assert g.chain == 'mainnet','mainnet selected, but chain is not mainnet' except Exception as e: die(1,'{}\nChain is {}!'.format(e,g.chain)) import mmgen.rpc if g.coin == 'ETH': conn = mmgen.rpc.EthereumRPCConnection( g.rpc_host or 'localhost', g.rpc_port or g.proto.rpc_port) if not g.daemon_version: # First call g.daemon_version = conn.parity_versionInfo()['version'] # fail immediately if daemon is geth g.chain = conn.parity_chain() else: cfg = get_daemon_cfg_options(('rpcuser','rpcpassword')) conn = mmgen.rpc.CoinDaemonRPCConnection( g.rpc_host or 'localhost', g.rpc_port or g.proto.rpc_port, g.rpc_user or cfg['rpcuser'], # MMGen's rpcuser,rpcpassword override coin daemon's g.rpc_password or cfg['rpcpassword'], auth_cookie=get_coin_daemon_auth_cookie()) if not g.daemon_version: # First call if g.bob or g.alice: import regtest as rt rt.user(('alice','bob')[g.bob],quiet=True) g.daemon_version = int(conn.getnetworkinfo()['version']) g.chain = conn.getblockchaininfo()['chain'] if g.chain != 'regtest': g.chain += 'net' assert g.chain in g.chains check_chaintype_mismatch() if g.chain == 'mainnet': # skip this for testnet, as Genesis block may change check_chainfork_mismatch(conn) g.rpch = conn return conn
def rpc_init(reinit=False): if not 'rpc' in g.proto.mmcaps: die(1,'Coin daemon operations not supported for coin {}!'.format(g.coin)) if g.rpch != None and not reinit: return g.rpch def check_chainfork_mismatch(conn): block0 = conn.getblockhash(0) latest = conn.getblockcount() try: assert block0 == g.proto.block0,'Incorrect Genesis block for {}'.format(g.proto.__name__) for fork in g.proto.forks: if fork[0] == None or latest < fork[0]: break bhash = conn.getblockhash(fork[0]) assert bhash == fork[1], ( 'Bad block hash at fork block {}. Is this the {} chain?'.format(fork[0],fork[2].upper())) except Exception as e: die(2,"{}\n'{c}' requested, but this is not the {c} chain!".format(e,c=g.coin)) def check_chaintype_mismatch(): try: if g.regtest: assert g.chain == 'regtest','--regtest option selected, but chain is not regtest' if g.testnet: assert g.chain != 'mainnet','--testnet option selected, but chain is mainnet' if not g.testnet: assert g.chain == 'mainnet','mainnet selected, but chain is not mainnet' except Exception as e: die(1,'{}\nChain is {}!'.format(e,g.chain)) cfg = get_daemon_cfg_options(('rpcuser','rpcpassword')) import mmgen.rpc conn = mmgen.rpc.CoinDaemonRPCConnection( g.rpc_host or 'localhost', g.rpc_port or g.proto.rpc_port, g.rpc_user or cfg['rpcuser'], # MMGen's rpcuser,rpcpassword override coin daemon's g.rpc_password or cfg['rpcpassword'], auth_cookie=get_coin_daemon_auth_cookie()) if not g.daemon_version: # First call if g.bob or g.alice: import regtest as rt rt.user(('alice','bob')[g.bob],quiet=True) g.daemon_version = int(conn.getnetworkinfo()['version']) g.chain = conn.getblockchaininfo()['chain'] if g.chain != 'regtest': g.chain += 'net' assert g.chain in g.chains check_chaintype_mismatch() if g.chain == 'mainnet': # skip this for testnet, as Genesis block may change check_chainfork_mismatch(conn) g.rpch = conn return conn
def rpc_connection(): def check_coin_mismatch(c): if c.getblockcount() == 0: msg('Warning: no blockchain, so skipping block mismatch check') return fb = '00000000000000000019f112ec0a9982926f1258cdcc558dd7c3b7e5dc7fa148' err = [] if c.getblockchaininfo()['blocks'] <= 478558 or c.getblockhash( 478559) == fb: if g.coin == 'BCH': err = 'BCH', 'BTC' elif g.coin == 'BTC': err = 'BTC', 'BCH' if err: ydie(2, "'{}' requested, but this is the {} chain!".format(*err)) def check_chain_mismatch(): err = None if g.regtest and g.chain != 'regtest': err = '--regtest option' elif g.testnet and g.chain == 'mainnet': err = '--testnet option' # we won't actually get here, as connect will fail first elif (not g.testnet) and g.chain != 'mainnet': err = 'mainnet' if err: die(1, '{} selected but chain is {}'.format(err, g.chain)) cfg = get_bitcoind_cfg_options(('rpcuser', 'rpcpassword')) import mmgen.rpc c = mmgen.rpc.BitcoinRPCConnection( g.rpc_host or 'localhost', g.rpc_port or g.ports[g.coin][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()) if not g.bitcoind_version: # First call if g.bob or g.alice: import regtest as rt rt.user(('alice', 'bob')[g.bob], quiet=True) g.bitcoind_version = int(c.getnetworkinfo()['version']) g.chain = c.getblockchaininfo()['chain'] if g.chain != 'regtest': g.chain += 'net' assert g.chain in g.chains if g.chain == 'mainnet': check_coin_mismatch(c) return c
def init(opts_f, add_opts=[], opt_filter=None): opts_data = opts_f() opts_data['long_options'] = common_opts_data version_info = """ {pgnm_uc} version {g.version} Part of the {pnm} suite, a Bitcoin cold-storage solution for the command line. Copyright (C) {g.Cdates} {g.author} {g.email} """.format(pnm=g.proj_name, g=g, pgnm_uc=g.prog_name.upper()).strip() uopts,args,short_opts,long_opts,skipped_opts,do_help = \ mmgen.share.Opts.parse_opts(sys.argv,opts_data,opt_filter=opt_filter,defer_help=True) if g.debug: opt_preproc_debug(short_opts, long_opts, skipped_opts, uopts, args) # Save this for usage() global usage_txt usage_txt = opts_data['usage'] # Transfer uopts into opt, setting program's opts + required opts to None if not set by user for o in tuple([s.rstrip('=') for s in long_opts] + add_opts + skipped_opts) + \ g.required_opts + g.common_opts: setattr(opt, o, uopts[o] if o in uopts else None) if opt.version: Die(0, version_info) # === 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() if not opt.skip_cfg_file: cfg_data = get_data_from_config_file() override_from_cfg_file(cfg_data) override_from_env() # User opt sets global var - do these here, before opt is set from g.global_sets_opt for k in g.common_opts: val = getattr(opt, k) if val != None: setattr(g, k, set_for_type(val, getattr(g, k), '--' + k)) if g.regtest: g.testnet = True # These are equivalent for now # Global vars are now final, including g.testnet, so we can set g.data_dir g.data_dir = os.path.normpath( os.path.join(g.data_dir_root, ('', g.testnet_name)[g.testnet])) # If user opt is set, convert its type based on value in mmgen.globalvars (g) # If unset, set it to default value in mmgen.globalvars (g) setattr(opt, 'set_by_user', []) for k in g.global_sets_opt: if k in opt.__dict__ and getattr(opt, k) != None: # _typeconvert_from_dfl(k) setattr(opt, k, set_for_type(getattr(opt, k), getattr(g, k), '--' + k)) opt.set_by_user.append(k) else: setattr(opt, k, g.__dict__[k]) # Check user-set opts without modifying them if not check_opts(uopts): sys.exit(1) if opt.show_hash_presets: _show_hash_presets() sys.exit(0) if opt.verbose: opt.quiet = None die_on_incompatible_opts(g.incompatible_opts) opt_postproc_initializations() if do_help: # print help screen only after global vars are initialized opts_data = opts_f() opts_data['long_options'] = common_opts_data mmgen.share.Opts.parse_opts(sys.argv, opts_data, opt_filter=opt_filter) # We don't need this data anymore del mmgen.share.Opts del opts_f for k in ('prog_name', 'desc', 'usage', 'options', 'notes'): if k in opts_data: del opts_data[k] if g.bob or g.alice: import regtest as rt rt.user(('alice', 'bob')[g.bob], quiet=True) g.testnet = True g.rpc_host = 'localhost' g.rpc_port = rt.rpc_port g.rpc_user = rt.rpc_user g.rpc_password = rt.rpc_password g.data_dir = os.path.join(g.home_dir, '.' + g.proj_name.lower(), 'regtest') if g.debug: opt_postproc_debug() return args