diff --git a/mmgen/main_autosign.py b/mmgen/main_autosign.py index 678d391e..a4c3b0b0 100755 --- a/mmgen/main_autosign.py +++ b/mmgen/main_autosign.py @@ -101,6 +101,7 @@ This command is currently available only on Linux-based platforms. cmd_args = opts.init(opts_data,add_opts=['mmgen_keys_from_file','in_fmt']) import mmgen.tx +import mmgen.altcoins.eth.tx from mmgen.txsign import txsign from mmgen.protocol import CoinProtocol,init_coin @@ -155,14 +156,40 @@ def do_umount(): def sign_tx_file(txfile): try: - init_coin(mmgen.tx.MMGenTX(txfile,coin_sym_only=True).coin) + g.testnet = False + g.coin = 'BTC' + tmp_tx = mmgen.tx.MMGenTX(txfile,metadata_only=True) + init_coin(tmp_tx.coin) + + if tmp_tx.chain != 'mainnet': + if tmp_tx.chain == 'testnet' or ( + hasattr(g.proto,'chain_name') and tmp_tx.chain != g.proto.chain_name): + g.testnet = True + init_coin(tmp_tx.coin) + + if hasattr(g.proto,'chain_name'): + m = 'Protocol chain name ({}) does not match chain name from TX file ({})' + assert tmp_tx.chain == g.proto.chain_name, m.format(tmp_tx.chain,g.proto.chain_name) + + g.chain = tmp_tx.chain + g.token = tmp_tx.dcoin + g.dcoin = tmp_tx.dcoin or g.coin + reload(sys.modules['mmgen.tx']) + if g.coin == 'ETH': + reload(sys.modules['mmgen.altcoins.eth.tx']) + tx = mmgen.tx.MMGenTX(txfile) + if g.proto.sign_mode == 'daemon': rpc_init(reinit=True) + txsign(tx,wfs,None,None) tx.write_to_file(ask_write=False) return True + except Exception as e: + msg('An error occurred: {}'.format(e)) + return False except: return False diff --git a/mmgen/obj.py b/mmgen/obj.py index f611a015..98345f39 100755 --- a/mmgen/obj.py +++ b/mmgen/obj.py @@ -304,6 +304,8 @@ class AddrIdxList(list,InitErrors,MMGenObject): m = "{!r}: value cannot be converted to AddrIdxList ({})" return type(self).init_fail(m.format(idx_list or fmt_str,e[0]),on_fail) +class UnknownCoinAmt(Decimal): pass + class BTCAmt(Decimal,Hilite,InitErrors): color = 'yellow' max_prec = 8 diff --git a/mmgen/tx.py b/mmgen/tx.py index 8a25241d..c5f48e5f 100755 --- a/mmgen/tx.py +++ b/mmgen/tx.py @@ -272,7 +272,7 @@ Selected non-{pnm} inputs: {{}}""".strip().format(pnm=g.proj_name,pnl=g.proj_nam desc = 'transaction outputs' member_type = 'MMGenTxOutput' - def __init__(self,filename=None,coin_sym_only=False,caller=None,silent_open=False): + def __init__(self,filename=None,metadata_only=False,caller=None,silent_open=False): self.inputs = self.MMGenTxInputList() self.outputs = self.MMGenTxOutputList() self.send_amt = g.proto.coin_amt('0') # total amt minus change @@ -293,8 +293,8 @@ Selected non-{pnm} inputs: {{}}""".strip().format(pnm=g.proj_name,pnl=g.proj_nam self.locktime = None if filename: - self.parse_tx_file(filename,coin_sym_only=coin_sym_only,silent_open=silent_open) - if coin_sym_only: return + self.parse_tx_file(filename,metadata_only=metadata_only,silent_open=silent_open) + if metadata_only: return self.check_pubkey_scripts() self.check_sigs() # marks the tx as signed @@ -1114,7 +1114,7 @@ Selected non-{pnm} inputs: {{}}""".strip().format(pnm=g.proj_name,pnl=g.proj_nam def check_txfile_hex_data(self): self.hex = HexStr(self.hex,on_fail='raise') - def parse_tx_file(self,infile,coin_sym_only=False,silent_open=False): + def parse_tx_file(self,infile,metadata_only=False,silent_open=False): def eval_io_data(raw_data,desc): from ast import literal_eval @@ -1176,19 +1176,25 @@ Selected non-{pnm} inputs: {{}}""".strip().format(pnm=g.proj_name,pnl=g.proj_nam if ':' in self.coin: self.coin,self.dcoin = self.coin.split(':') - if coin_sym_only: return - if len(metadata) == 5: t = metadata.pop(0) self.chain = (t.lower(),None)[t=='Unknown'] desc = 'metadata (4 items minimum required)' - self.txid,send_amt,self.timestamp,blockcount = metadata - desc = 'metadata' - self.txid = MMGenTxID(self.txid,on_fail='raise') - self.send_amt = g.proto.coin_amt(send_amt,on_fail='raise') + txid,send_amt,self.timestamp,blockcount = metadata + + desc = 'txid in metadata' + self.txid = MMGenTxID(txid,on_fail='raise') + desc = 'send amount in metadata' + self.send_amt = UnknownCoinAmt(send_amt) # temporary, for 'metadata_only' desc = 'block count in metadata' self.blockcount = int(blockcount) + + if metadata_only: return + + desc = 'send amount in metadata' + self.send_amt = g.proto.coin_amt(send_amt,on_fail='raise') + desc = 'transaction hex data' self.check_txfile_hex_data() # the following ops will all fail if g.coin doesn't match self.coin diff --git a/scripts/test-release.sh b/scripts/test-release.sh index 6cafe055..9fc28c57 100755 --- a/scripts/test-release.sh +++ b/scripts/test-release.sh @@ -217,7 +217,7 @@ t_eth=( f_eth='Ethereum tests completed' i_autosign='Autosign' -s_autosign='The bitcoin, bitcoin-abc and litecoin (mainnet) daemons must be running for the following test' +s_autosign='The bitcoin, bitcoin-abc and litecoin mainnet and testnet daemons must be running for the following test' t_autosign=("$test_py -On autosign") f_autosign='Autosign test complete' diff --git a/test/ref/ethereum/5881D2-MM1[1.23456,50000].rawtx b/test/ref/ethereum/5881D2-MM1[1.23456,50000].rawtx new file mode 100644 index 00000000..e6239ad2 --- /dev/null +++ b/test/ref/ethereum/5881D2-MM1[1.23456,50000].rawtx @@ -0,0 +1,6 @@ +1a6cfb +ETH:MM1 FOUNDATION 5881D2 1.23456 20180729_000000 1234567 +{"nonce": "0", "chainId": "1", "from": "0d25b006dfa012b17da252e852b6e2b5ebf5ddc8", "token_addr": "d5f051401ca478b34c80d0b5a119e437dc6d9df5", "data": "", "startGas": "0.00000000000006", "to": "6e0fbe42e1343309b3ccb9068dbad6132f86c96f", "decimals": "18", "amt": "1.23456", "gasPrice": "0.00000005"} +[{'confs': 0, 'label': u'', 'mmid': '98831F3A:E:11', 'amt': '1000', 'addr': '0d25b006dfa012b17da252e852b6e2b5ebf5ddc8'}] +[{'is_chg': False, 'mmid': '98831F3A:E:12', 'amt': '1.23456', 'addr': '6e0fbe42e1343309b3ccb9068dbad6132f86c96f'}] +TvwWgaAnrkQFpAxxjBa4PHvJ8NsJDsurtiv2HuzdnXWjQmY7LHyt6PZn5J7BNtB5VzHtBG7bUosCAMFon8yxUe2mYTZoH9e6dpoAz9E6JDZtUNYz9YnF1Z3jFND1X89RuKAk6YVBrfWseeyHR8vZDdaFzBPK5SPos diff --git a/test/ref/ethereum/6BDB25-MM1[1.23456,50000].testnet.rawtx b/test/ref/ethereum/6BDB25-MM1[1.23456,50000].testnet.rawtx new file mode 100644 index 00000000..5623f847 --- /dev/null +++ b/test/ref/ethereum/6BDB25-MM1[1.23456,50000].testnet.rawtx @@ -0,0 +1,6 @@ +334f63 +ETH:MM1 KOVAN 6BDB25 1.23456 20180729_111111 7654321 +{"nonce": "0", "chainId": "42", "from": "69b2da9c0646d79ef461c79eba14943352590e4b", "token_addr": "d5f051401ca478b34c80d0b5a119e437dc6d9df5", "data": "", "startGas": "0.00000000000006", "to": "1e94936c64ef12fd4991537b714d4946839699a4", "decimals": "18", "amt": "1.23456", "gasPrice": "0.00000005"} +[{'confs': 0, 'label': u'', 'mmid': '98831F3A:E:11', 'amt': '1000', 'addr': '69b2da9c0646d79ef461c79eba14943352590e4b'}] +[{'is_chg': False, 'mmid': '98831F3A:E:12', 'amt': '1.23456', 'addr': '1e94936c64ef12fd4991537b714d4946839699a4'}] +TvwWgaAnrkQFpAxxjBa4PHvJ8NsJDsurtiv2HuzdnXWjQmY7LHyt6PZn5J7BNtB5VzHtBG7bUosCAMFon8yxUe2mYTZoH9e6dpoAz9E6JDZtUNYz9YnF1Z3jFND1X89RuKAk6YVBrfWseeyHR8vZDdaFzBPK5SPos diff --git a/test/test.py b/test/test.py index 428c1e32..a1814e7f 100755 --- a/test/test.py +++ b/test/test.py @@ -583,7 +583,9 @@ cfgs = { 'ltc': ('AF3CDF-LTC[620.76194,1453,tl=1320969600].rawtx', 'A5A1E0-LTC[1454.64322,1453,tl=1320969600].testnet.rawtx'), 'eth': ('88FEFD-ETH[23.45495,40000].rawtx', - 'B472BD-ETH[23.45495,40000].testnet.rawtx') + 'B472BD-ETH[23.45495,40000].testnet.rawtx'), + 'erc20': ('5881D2-MM1[1.23456,50000].rawtx', + '6BDB25-MM1[1.23456,50000].testnet.rawtx') }, 'ic_wallet': u'98831F3A-5482381C-18460FB1[256,1].mmincog', 'ic_wallet_hex': u'98831F3A-1630A9F2-870376A9[256,1].mmincox', @@ -2314,9 +2316,10 @@ class MMGenTestSuite(object): def autosign(self,name): # tests everything except device detection, mount/unmount if skip_for_win(): return - fdata = (('btc',''),('bch',''),('ltc','litecoin'),('eth','ethereum')) - tfns = [cfgs['8']['ref_tx_file'][c][0] for c,d in fdata] - tfs = [os.path.join(ref_dir,d[1],fn) for d,fn in zip(fdata,tfns)] + fdata = (('btc',''),('bch',''),('ltc','litecoin'),('eth','ethereum'),('erc20','ethereum')) + tfns = [cfgs['8']['ref_tx_file'][c][1] for c,d in fdata] + \ + [cfgs['8']['ref_tx_file'][c][0] for c,d in fdata] + tfs = [os.path.join(ref_dir,d[1],fn) for d,fn in zip(fdata+fdata,tfns)] try: os.mkdir(os.path.join(cfg['tmpdir'],'tx')) except: pass for f,fn in zip(tfs,tfns): @@ -2341,7 +2344,7 @@ class MMGenTestSuite(object): t.ok() t = MMGenExpect(name,'mmgen-autosign',opts+['wait'],extra_desc='(sign)') - t.expect('4 transactions signed') + t.expect('10 transactions signed') t.expect('1 transaction failed to sign') t.expect('Waiting.') t.kill(2)