From b1a30fab2e9dad9b01174d9e6d1a23085047ec9f Mon Sep 17 00:00:00 2001 From: MMGen Date: Wed, 3 Jul 2019 17:39:05 +0000 Subject: [PATCH] rpc_init(): move daemon init functions to rpc.py --- mmgen/rpc.py | 105 +++++++++++++++++++++++++++++++++++++++++++++++++- mmgen/util.py | 95 +-------------------------------------------- 2 files changed, 106 insertions(+), 94 deletions(-) diff --git a/mmgen/rpc.py b/mmgen/rpc.py index 74a0de58..00942906 100755 --- a/mmgen/rpc.py +++ b/mmgen/rpc.py @@ -261,4 +261,107 @@ class EthereumRPCConnection(CoinDaemonRPCConnection): def rpc_error(ret): return type(ret) is tuple and ret and ret[0] == 'rpcfail' -def rpc_errmsg(ret): return ret[1][2] +def init_daemon_parity(): + + def resolve_token_arg(token_arg): + from mmgen.obj import CoinAddr + from mmgen.altcoins.eth.tw import EthereumTrackingWallet + from mmgen.altcoins.eth.contract import Token + + tw = EthereumTrackingWallet(no_rpc=True) + + try: addr = CoinAddr(token_arg,on_fail='raise') + except: addr = tw.sym2addr(token_arg) + + if not addr: + m = "'{}': unrecognized token symbol" + raise UnrecognizedTokenSymbol(m.format(token_arg)) + + sym = tw.addr2sym(addr) # throws exception on failure + vmsg('ERC20 token resolved: {} ({})'.format(addr,sym)) + + return addr,sym + + from mmgen.rpc import EthereumRPCConnection + conn = EthereumRPCConnection( + g.rpc_host or 'localhost', + g.rpc_port or g.proto.rpc_port) + + conn.daemon_version = conn.parity_versionInfo()['version'] # fail immediately if daemon is geth + conn.coin_amt_type = str + g.chain = conn.parity_chain().replace(' ','_') + + conn.caps = () + try: + conn.request('eth_chainId') + conn.caps += ('eth_chainId',) + except RPCFailure: + pass + + if conn.request('parity_nodeKind')['capability'] == 'full': + conn.caps += ('full_node',) + + if g.token: + g.rpch = conn # set g.rpch so rpc_init() will return immediately + (g.token,g.dcoin) = resolve_token_arg(g.token) + + return conn + +def init_daemon_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.args[0],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.args[0],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: + from . 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 = ('full_node',) + 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 init_daemon(name): + return globals()['init_daemon_'+name]() + +def rpc_errmsg(ret): + return ret[1][2] diff --git a/mmgen/util.py b/mmgen/util.py index 930442b2..a62808a1 100755 --- a/mmgen/util.py +++ b/mmgen/util.py @@ -879,103 +879,12 @@ def get_coin_daemon_auth_cookie(): f = os.path.join(g.proto.daemon_data_dir,g.proto.daemon_data_subdir,'.cookie') return get_lines_from_file(f,'')[0] if file_is_readable(f) else '' -def rpc_init_parity(): - - def resolve_token_arg(token_arg): - from mmgen.tw import TrackingWallet - from mmgen.obj import CoinAddr - from mmgen.altcoins.eth.contract import Token - - try: addr = CoinAddr(token_arg,on_fail='raise') - except: addr = TrackingWallet().sym2addr(token_arg) - else: Token(addr) # test for presence in blockchain - - if not addr: - m = "'{}': unrecognized token symbol" - raise UnrecognizedTokenSymbol(m.format(token_arg)) - - sym = Token(addr).symbol().upper() - vmsg('ERC20 token resolved: {} ({})'.format(addr,sym)) - return addr,sym - - from mmgen.rpc import EthereumRPCConnection - g.rpch = EthereumRPCConnection( - g.rpc_host or 'localhost', - g.rpc_port or g.proto.rpc_port) - - g.rpch.daemon_version = g.rpch.parity_versionInfo()['version'] # fail immediately if daemon is geth - g.rpch.coin_amt_type = str - g.chain = g.rpch.parity_chain().replace(' ','_') - if g.token: - (g.token,g.dcoin) = resolve_token_arg(g.token) - - g.rpch.caps = () - try: - g.rpch.request('eth_chainId') - g.rpch.caps += ('eth_chainId',) - except RPCFailure: - pass - - return g.rpch - -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.args[0],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.args[0],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: - from . 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 - g.rpch = globals()['rpc_init_'+g.proto.daemon_family]() + from mmgen.rpc import init_daemon + g.rpch = init_daemon(g.proto.daemon_family) return g.rpch def format_par(s,indent=0,width=80,as_list=False):