Browse Source

proto.decode_addr(): parse version bytes more efficiently

The MMGen Project 3 years ago
parent
commit
fdf2557d01
7 changed files with 32 additions and 20 deletions
  1. 1 1
      mmgen/altcoin.py
  2. 1 1
      mmgen/proto/bch.py
  3. 2 2
      mmgen/proto/btc.py
  4. 2 2
      mmgen/proto/ltc.py
  5. 2 2
      mmgen/proto/xmr.py
  6. 15 2
      mmgen/proto/zec.py
  7. 9 10
      mmgen/protocol.py

+ 1 - 1
mmgen/altcoin.py

@@ -756,7 +756,7 @@ def create_altcoin_protos(data):
 				(mainnet,),
 				{
 					'base_coin': e.symbol,
-					'addr_ver_bytes': dict(
+					'addr_ver_info': dict(
 						[( num2hexstr(e.p2pkh_info[0]), 'p2pkh' )] +
 						([( num2hexstr(e.p2sh_info[0]), 'p2sh' )] if e.p2sh_info else [])
 					),

+ 1 - 1
mmgen/proto/bch.py

@@ -30,7 +30,7 @@ class mainnet(mainnet):
 	def pubhash2segwitaddr(self,pubkey):    raise NotImplementedError
 
 class testnet(mainnet):
-	addr_ver_bytes = { '6f': 'p2pkh', 'c4': 'p2sh' }
+	addr_ver_info  = { '6f': 'p2pkh', 'c4': 'p2sh' }
 	wif_ver_num    = { 'std': 'ef' }
 
 class regtest(testnet):

+ 2 - 2
mmgen/proto/btc.py

@@ -21,7 +21,7 @@ class mainnet(CoinProtocol.Secp256k1): # chainparams.cpp
 	"""
 	mod_clsname     = 'Bitcoin'
 	network_names   = _nw('mainnet','testnet','regtest')
-	addr_ver_bytes  = { '00': 'p2pkh', '05': 'p2sh' }
+	addr_ver_info   = { '00': 'p2pkh', '05': 'p2sh' }
 	addr_len        = 20
 	wif_ver_num     = { 'std': '80' }
 	mmtypes         = ('L','C','S','B')
@@ -123,7 +123,7 @@ class mainnet(CoinProtocol.Secp256k1): # chainparams.cpp
 			data = [self.witness_vernum] + bech32.convertbits(list(pubhash),8,5) )
 
 class testnet(mainnet):
-	addr_ver_bytes      = { '6f': 'p2pkh', 'c4': 'p2sh' }
+	addr_ver_info       = { '6f': 'p2pkh', 'c4': 'p2sh' }
 	wif_ver_num         = { 'std': 'ef' }
 	bech32_hrp          = 'tb'
 

+ 2 - 2
mmgen/proto/ltc.py

@@ -16,7 +16,7 @@ from .btc import mainnet
 
 class mainnet(mainnet):
 	block0          = '12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2'
-	addr_ver_bytes  = { '30': 'p2pkh', '05': 'p2sh', '32': 'p2sh' } # new p2sh ver 0x32 must come last
+	addr_ver_info   = { '30': 'p2pkh', '05': 'p2sh', '32': 'p2sh' } # new p2sh ver 0x32 must come last
 	wif_ver_num     = { 'std': 'b0' }
 	mmtypes         = ('L','C','S','B')
 	coin_amt        = 'LTCAmt'
@@ -30,7 +30,7 @@ class mainnet(mainnet):
 
 class testnet(mainnet):
 	# addr ver nums same as Bitcoin testnet, except for 'p2sh'
-	addr_ver_bytes     = { '6f':'p2pkh', 'c4':'p2sh', '3a':'p2sh' }
+	addr_ver_info      = { '6f':'p2pkh', 'c4':'p2sh', '3a':'p2sh' }
 	wif_ver_num        = { 'std': 'ef' } # same as Bitcoin testnet
 	bech32_hrp         = 'tltc'
 

+ 2 - 2
mmgen/proto/xmr.py

@@ -24,7 +24,7 @@ class mainnet(CoinProtocol.DummyWIF,CoinProtocol.Base):
 	network_names  = _nw('mainnet','stagenet',None)
 	base_coin      = 'XMR'
 	base_proto     = 'Monero'
-	addr_ver_bytes = { '12': 'monero', '2a': 'monero_sub', '13': 'monero_integrated' }
+	addr_ver_info  = { '12': 'monero', '2a': 'monero_sub', '13': 'monero_integrated' }
 	wif_ver_num    = {}
 	pubkey_types   = ('monero',)
 	mmtypes        = ('M',)
@@ -77,4 +77,4 @@ class mainnet(CoinProtocol.DummyWIF,CoinProtocol.Base):
 		raise NotImplementedError('Monero addresses do not support pubhash2addr()')
 
 class testnet(mainnet): # use stagenet for testnet
-	addr_ver_bytes = { '18': 'monero', '24': 'monero_sub', '19': 'monero_integrated' } # testnet is {'35','3f','36'}
+	addr_ver_info = { '18': 'monero', '24': 'monero_sub', '19': 'monero_integrated' } # testnet is {'35','3f','36'}

+ 15 - 2
mmgen/proto/zec.py

@@ -13,10 +13,11 @@ Zcash protocol
 """
 
 from .btc import mainnet
+from ..protocol import decoded_addr
 
 class mainnet(mainnet):
 	base_coin      = 'ZEC'
-	addr_ver_bytes = { '1cb8': 'p2pkh', '1cbd': 'p2sh', '169a': 'zcash_z', 'a8abd3': 'viewkey' }
+	addr_ver_info  = { '1cb8': 'p2pkh', '1cbd': 'p2sh', '169a': 'zcash_z', 'a8abd3': 'viewkey' }
 	wif_ver_num    = { 'std': '80', 'zcash_z': 'ab36' }
 	pubkey_types   = ('std','zcash_z')
 	mmtypes        = ('L','C','Z')
@@ -32,6 +33,18 @@ class mainnet(mainnet):
 	def get_addr_len(self,addr_fmt):
 		return (20,64)[addr_fmt in ('zcash_z','viewkey')]
 
+	def decode_addr_bytes(self,addr_bytes):
+		"""
+		vlen must be set dynamically since Zcash has variable length ver_bytes
+		"""
+		for ver_bytes,addr_fmt in self.addr_ver_bytes.items():
+			vlen = len(ver_bytes)
+			if addr_bytes[:vlen] == ver_bytes:
+				if len(addr_bytes[vlen:]) == self.get_addr_len(addr_fmt):
+					return decoded_addr( addr_bytes[vlen:], ver_bytes, addr_fmt )
+
+		return False
+
 	def preprocess_key(self,sec,pubkey_type):
 		if pubkey_type == 'zcash_z': # zero the first four bits
 			return bytes([sec[0] & 0x0f]) + sec[1:]
@@ -49,4 +62,4 @@ class mainnet(mainnet):
 
 class testnet(mainnet):
 	wif_ver_num  = { 'std': 'ef', 'zcash_z': 'ac08' }
-	addr_ver_bytes = { '1d25': 'p2pkh', '1cba': 'p2sh', '16b6': 'zcash_z', 'a8ac0c': 'viewkey' }
+	addr_ver_info = { '1d25': 'p2pkh', '1cba': 'p2sh', '16b6': 'zcash_z', 'a8ac0c': 'viewkey' }

+ 9 - 10
mmgen/protocol.py

@@ -68,8 +68,10 @@ class CoinProtocol(MMGenObject):
 				'regtest': '_rt',
 			}[network]
 
-			if hasattr(self,'addr_ver_bytes'):
-				self.addr_fmt_to_ver_bytes = {v:bytes.fromhex(k) for k,v in self.addr_ver_bytes.items()}
+			if hasattr(self,'addr_ver_info'):
+				self.addr_ver_bytes = {bytes.fromhex(k):v for k,v in self.addr_ver_info.items()}
+				self.addr_fmt_to_ver_bytes = {v:k for k,v in self.addr_ver_bytes.items()}
+				self.addr_ver_bytes_len = len(list(self.addr_ver_bytes)[0])
 
 			if 'tx' not in self.mmcaps and g.is_txprog:
 				from .util import die
@@ -139,14 +141,11 @@ class CoinProtocol(MMGenObject):
 			return self.addr_len
 
 		def decode_addr_bytes(self,addr_bytes):
-			for ver_hex,addr_fmt in self.addr_ver_bytes.items():
-				ver_bytes = bytes.fromhex(ver_hex)
-				vlen = len(ver_bytes)
-				if addr_bytes[:vlen] == ver_bytes:
-					if len(addr_bytes[vlen:]) == self.get_addr_len(addr_fmt):
-						return decoded_addr( addr_bytes[vlen:], ver_bytes, addr_fmt )
-
-			return False
+			vlen = self.addr_ver_bytes_len
+			return decoded_addr(
+				addr_bytes[vlen:],
+				addr_bytes[:vlen],
+				self.addr_ver_bytes[addr_bytes[:vlen]] )
 
 		def coin_addr(self,addr):
 			from .addr import CoinAddr