autosign: support testnet, ERC20 tokens
This commit is contained in:
parent
8aae3a8d31
commit
4df12def5f
7 changed files with 67 additions and 17 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
26
mmgen/tx.py
26
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
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
||||
|
|
|
|||
6
test/ref/ethereum/5881D2-MM1[1.23456,50000].rawtx
Normal file
6
test/ref/ethereum/5881D2-MM1[1.23456,50000].rawtx
Normal file
|
|
@ -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
|
||||
|
|
@ -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
|
||||
13
test/test.py
13
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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue