Browse Source

Ethereum autosigning

MMGen 6 years ago
parent
commit
2c97f61ea4
5 changed files with 26 additions and 10 deletions
  1. 6 2
      mmgen/main_autosign.py
  2. 2 0
      mmgen/protocol.py
  3. 8 5
      mmgen/tx.py
  4. 5 0
      test/ref/ethereum/BC79AB-ETH[0.123].rawtx
  5. 5 3
      test/test.py

+ 6 - 2
mmgen/main_autosign.py

@@ -29,6 +29,8 @@ part_label   = u'MMGEN_TX'
 wallet_dir   = u'/dev/shm/autosign'
 wallet_dir   = u'/dev/shm/autosign'
 key_fn       = u'autosign.key'
 key_fn       = u'autosign.key'
 
 
+no_daemon_coins = ('ETH',)
+
 from mmgen.common import *
 from mmgen.common import *
 prog_name = os.path.basename(sys.argv[0])
 prog_name = os.path.basename(sys.argv[0])
 opts_data = lambda: {
 opts_data = lambda: {
@@ -119,6 +121,7 @@ def check_daemons_running():
 		coins = ['BTC']
 		coins = ['BTC']
 
 
 	for coin in coins:
 	for coin in coins:
+		if coin in no_daemon_coins: continue
 		g.proto = CoinProtocol(coin,g.testnet)
 		g.proto = CoinProtocol(coin,g.testnet)
 		vmsg('Checking {} daemon'.format(coin))
 		vmsg('Checking {} daemon'.format(coin))
 		try:
 		try:
@@ -153,10 +156,11 @@ def do_umount():
 
 
 def sign_tx_file(txfile):
 def sign_tx_file(txfile):
 	try:
 	try:
-		init_coin(mmgen.tx.MMGenTX(txfile,md_only=True).coin)
+		init_coin(mmgen.tx.MMGenTX(txfile,coin_sym_only=True).coin)
 		reload(sys.modules['mmgen.tx'])
 		reload(sys.modules['mmgen.tx'])
 		tx = mmgen.tx.MMGenTX(txfile)
 		tx = mmgen.tx.MMGenTX(txfile)
-		rpc_init(reinit=True)
+		if tx.coin not in no_daemon_coins:
+			rpc_init(reinit=True)
 		txsign(tx,wfs,None,None)
 		txsign(tx,wfs,None,None)
 		tx.write_to_file(ask_write=False)
 		tx.write_to_file(ask_write=False)
 		return True
 		return True

+ 2 - 0
mmgen/protocol.py

@@ -90,6 +90,7 @@ class BitcoinProtocol(MMGenObject):
 	witness_vernum_hex = '00'
 	witness_vernum_hex = '00'
 	witness_vernum     = int(witness_vernum_hex,16)
 	witness_vernum     = int(witness_vernum_hex,16)
 	bech32_hrp         = 'bc'
 	bech32_hrp         = 'bc'
+	chain_aliases      = {}
 
 
 	@classmethod
 	@classmethod
 	def is_testnet(cls):
 	def is_testnet(cls):
@@ -303,6 +304,7 @@ class EthereumProtocol(DummyWIF,BitcoinProtocolAddrgen):
 	rpc_port    = 8545
 	rpc_port    = 8545
 	mmcaps      = ('key','addr','rpc')
 	mmcaps      = ('key','addr','rpc')
 	coin_amt    = ETHAmt
 	coin_amt    = ETHAmt
+	chain_aliases = {'mainnet':['foundation'],'testnet':['kovan']}
 
 
 
 
 	@classmethod
 	@classmethod

+ 8 - 5
mmgen/tx.py

@@ -275,7 +275,7 @@ class MMGenTX(MMGenObject):
 			cls = EthereumMMGenTX
 			cls = EthereumMMGenTX
 		return MMGenObject.__new__(cls,*args,**kwargs)
 		return MMGenObject.__new__(cls,*args,**kwargs)
 
 
-	def __init__(self,filename=None,md_only=False,caller=None,silent_open=False):
+	def __init__(self,filename=None,coin_sym_only=False,caller=None,silent_open=False):
 		self.inputs      = self.MMGenTxInputList()
 		self.inputs      = self.MMGenTxInputList()
 		self.outputs     = self.MMGenTxOutputList()
 		self.outputs     = self.MMGenTxOutputList()
 		self.send_amt    = g.proto.coin_amt('0')  # total amt minus change
 		self.send_amt    = g.proto.coin_amt('0')  # total amt minus change
@@ -295,8 +295,8 @@ class MMGenTX(MMGenObject):
 		self.locktime    = None
 		self.locktime    = None
 
 
 		if filename:
 		if filename:
-			self.parse_tx_file(filename,md_only=md_only,silent_open=silent_open)
-			if md_only: return
+			self.parse_tx_file(filename,coin_sym_only=coin_sym_only,silent_open=silent_open)
+			if coin_sym_only: return
 			self.check_sigs() # marks the tx as signed
 			self.check_sigs() # marks the tx as signed
 
 
 		# repeat with sign and send, because coin daemon could be restarted
 		# repeat with sign and send, because coin daemon could be restarted
@@ -306,6 +306,8 @@ class MMGenTX(MMGenObject):
 		assert on_fail in ('return','die'),"'{}': invalid value for 'on_fail'".format(on_fail)
 		assert on_fail in ('return','die'),"'{}': invalid value for 'on_fail'".format(on_fail)
 		m = 'Transaction is for {}, but current chain is {}!'.format(self.chain,g.chain)
 		m = 'Transaction is for {}, but current chain is {}!'.format(self.chain,g.chain)
 		bad = self.chain and g.chain and self.chain != g.chain
 		bad = self.chain and g.chain and self.chain != g.chain
+		if bad and g.chain in g.proto.chain_aliases:
+			bad = self.chain not in g.proto.chain_aliases[g.chain]
 		if bad:
 		if bad:
 			msg(m) if on_fail == 'return' else die(2,m)
 			msg(m) if on_fail == 'return' else die(2,m)
 		return not bad
 		return not bad
@@ -1089,7 +1091,7 @@ class MMGenTX(MMGenObject):
 	def check_tx_hex_data(self):
 	def check_tx_hex_data(self):
 		self.hex = HexStr(self.hex,on_fail='raise')
 		self.hex = HexStr(self.hex,on_fail='raise')
 
 
-	def parse_tx_file(self,infile,md_only=False,silent_open=False):
+	def parse_tx_file(self,infile,coin_sym_only=False,silent_open=False):
 
 
 		def eval_io_data(raw_data,desc):
 		def eval_io_data(raw_data,desc):
 			from ast import literal_eval
 			from ast import literal_eval
@@ -1147,6 +1149,7 @@ class MMGenTX(MMGenObject):
 				self.locktime = int(metadata.pop()[3:])
 				self.locktime = int(metadata.pop()[3:])
 
 
 			self.coin = metadata.pop(0) if len(metadata) == 6 else 'BTC'
 			self.coin = metadata.pop(0) if len(metadata) == 6 else 'BTC'
+			if coin_sym_only: return
 
 
 			if len(metadata) == 5:
 			if len(metadata) == 5:
 				t = metadata.pop(0)
 				t = metadata.pop(0)
@@ -1161,7 +1164,7 @@ class MMGenTX(MMGenObject):
 			self.blockcount = int(blockcount)
 			self.blockcount = int(blockcount)
 			desc = 'transaction hex data'
 			desc = 'transaction hex data'
 			self.check_tx_hex_data()
 			self.check_tx_hex_data()
-			if md_only: return # the following ops will all fail if g.coin doesn't match self.coin
+			# the following ops will all fail if g.coin doesn't match self.coin
 			desc = 'coin type in metadata'
 			desc = 'coin type in metadata'
 			assert self.coin == g.coin,'invalid coin type'
 			assert self.coin == g.coin,'invalid coin type'
 			desc = 'inputs data'
 			desc = 'inputs data'

+ 5 - 0
test/ref/ethereum/BC79AB-ETH[0.123].rawtx

@@ -0,0 +1,5 @@
+59b070
+ETH FOUNDATION BC79AB 0.123 20180530_125230 7513928
+{"nonce": "0", "chainId": "0x1", "from": "e704b6cfd9f0edb2e6cfbd0c913438d37ede7b35", "to": "62ff8e4dbd251b98102e3fb5e4b14119e24cadde", "amt": "0.123", "gasPrice": "0.000000050"}
+[{'confs': 0, 'addr': 'e704b6cfd9f0edb2e6cfbd0c913438d37ede7b35', 'vout': 0, 'txid': '0000000000000000000000000000000000000000000000000000000000000000', 'label': u'', 'amt': '1.234567', 'mmid': '98831F3A:E:1'}]
+[{'mmid': '98831F3A:E:31', 'amt': '0.123', 'addr': '62ff8e4dbd251b98102e3fb5e4b14119e24cadde'}]

+ 5 - 3
test/test.py

@@ -166,6 +166,7 @@ tn_ext = ('','.testnet')[g.testnet]
 
 
 coin_sel = g.coin.lower()
 coin_sel = g.coin.lower()
 # if g.coin == 'B2X': coin_sel = 'btc'
 # if g.coin == 'B2X': coin_sel = 'btc'
+if g.coin == 'ETH': coin_sel = 'btc' # TODO
 
 
 fork       = {'bch':'btc','btc':'btc','ltc':'ltc'}[coin_sel]
 fork       = {'bch':'btc','btc':'btc','ltc':'ltc'}[coin_sel]
 tx_fee     = {'btc':'0.0001','bch':'0.001','ltc':'0.01'}[coin_sel]
 tx_fee     = {'btc':'0.0001','bch':'0.001','ltc':'0.01'}[coin_sel]
@@ -550,6 +551,7 @@ cfgs = {
 			'bch': '99BE60-BCH[106.6789]{}.rawtx',
 			'bch': '99BE60-BCH[106.6789]{}.rawtx',
 			'b2x': '6A52BC-B2X[106.6789,tl=1320969600]{}.rawtx',
 			'b2x': '6A52BC-B2X[106.6789,tl=1320969600]{}.rawtx',
 			'ltc': '75F455-LTC[106.6789]{}.rawtx',
 			'ltc': '75F455-LTC[106.6789]{}.rawtx',
+			'eth': 'BC79AB-ETH[0.123]{}.rawtx',
 		},
 		},
 		'ic_wallet':       u'98831F3A-5482381C-18460FB1[256,1].mmincog',
 		'ic_wallet':       u'98831F3A-5482381C-18460FB1[256,1].mmincog',
 		'ic_wallet_hex':   u'98831F3A-1630A9F2-870376A9[256,1].mmincox',
 		'ic_wallet_hex':   u'98831F3A-1630A9F2-870376A9[256,1].mmincox',
@@ -2117,7 +2119,7 @@ class MMGenTestSuite(object):
 	# Miscellaneous tests
 	# Miscellaneous tests
 	def autosign(self,name): # tests everything except device detection, mount/unmount
 	def autosign(self,name): # tests everything except device detection, mount/unmount
 		if skip_for_win(): return
 		if skip_for_win(): return
-		fdata = (('btc',''),('bch',''),('ltc','litecoin'))
+		fdata = (('btc',''),('bch',''),('ltc','litecoin'),('eth','ethereum'))
 		tfns = [cfgs['8']['ref_tx_file'][c].format('') for c,d in fdata]
 		tfns = [cfgs['8']['ref_tx_file'][c].format('') for c,d in fdata]
 		tfs = [os.path.join(ref_dir,d[1],fn) for d,fn in zip(fdata,tfns)]
 		tfs = [os.path.join(ref_dir,d[1],fn) for d,fn in zip(fdata,tfns)]
 		try: os.mkdir(os.path.join(cfg['tmpdir'],'tx'))
 		try: os.mkdir(os.path.join(cfg['tmpdir'],'tx'))
@@ -2127,7 +2129,7 @@ class MMGenTestSuite(object):
 		# make a bad tx file
 		# make a bad tx file
 		with open(os.path.join(cfg['tmpdir'],'tx','bad.rawtx'),'w') as f:
 		with open(os.path.join(cfg['tmpdir'],'tx','bad.rawtx'),'w') as f:
 			f.write('bad tx data')
 			f.write('bad tx data')
-		opts = ['--mountpoint='+cfg['tmpdir'],'--coins=btc,bch,ltc']
+		opts = ['--mountpoint='+cfg['tmpdir'],'--coins=btc,bch,ltc,eth']
 		mn_fn = os.path.join(ref_dir,cfgs['8']['seed_id']+'.mmwords')
 		mn_fn = os.path.join(ref_dir,cfgs['8']['seed_id']+'.mmwords')
 		mn = read_from_file(mn_fn).strip().split()
 		mn = read_from_file(mn_fn).strip().split()
 
 
@@ -2144,7 +2146,7 @@ class MMGenTestSuite(object):
 		t.ok()
 		t.ok()
 
 
 		t = MMGenExpect(name,'mmgen-autosign',opts+['wait'],extra_desc='(sign)')
 		t = MMGenExpect(name,'mmgen-autosign',opts+['wait'],extra_desc='(sign)')
-		t.expect('3 transactions signed')
+		t.expect('4 transactions signed')
 		t.expect('1 transaction failed to sign')
 		t.expect('1 transaction failed to sign')
 		t.expect('Waiting.')
 		t.expect('Waiting.')
 		t.kill(2)
 		t.kill(2)