Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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