proto.decode_addr(): parse version bytes more efficiently

This commit is contained in:
The MMGen Project 2022-10-03 09:59:57 +00:00
commit fdf2557d01
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
7 changed files with 32 additions and 20 deletions

View file

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

View file

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

View file

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

View file

@ -16,7 +16,7 @@ from .btc import mainnet
class mainnet(mainnet): class mainnet(mainnet):
block0 = '12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2' 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' } wif_ver_num = { 'std': 'b0' }
mmtypes = ('L','C','S','B') mmtypes = ('L','C','S','B')
coin_amt = 'LTCAmt' coin_amt = 'LTCAmt'
@ -30,7 +30,7 @@ class mainnet(mainnet):
class testnet(mainnet): class testnet(mainnet):
# addr ver nums same as Bitcoin testnet, except for 'p2sh' # 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 wif_ver_num = { 'std': 'ef' } # same as Bitcoin testnet
bech32_hrp = 'tltc' bech32_hrp = 'tltc'

View file

@ -24,7 +24,7 @@ class mainnet(CoinProtocol.DummyWIF,CoinProtocol.Base):
network_names = _nw('mainnet','stagenet',None) network_names = _nw('mainnet','stagenet',None)
base_coin = 'XMR' base_coin = 'XMR'
base_proto = 'Monero' 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 = {} wif_ver_num = {}
pubkey_types = ('monero',) pubkey_types = ('monero',)
mmtypes = ('M',) mmtypes = ('M',)
@ -77,4 +77,4 @@ class mainnet(CoinProtocol.DummyWIF,CoinProtocol.Base):
raise NotImplementedError('Monero addresses do not support pubhash2addr()') raise NotImplementedError('Monero addresses do not support pubhash2addr()')
class testnet(mainnet): # use stagenet for testnet 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'}

View file

@ -13,10 +13,11 @@ Zcash protocol
""" """
from .btc import mainnet from .btc import mainnet
from ..protocol import decoded_addr
class mainnet(mainnet): class mainnet(mainnet):
base_coin = 'ZEC' 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' } wif_ver_num = { 'std': '80', 'zcash_z': 'ab36' }
pubkey_types = ('std','zcash_z') pubkey_types = ('std','zcash_z')
mmtypes = ('L','C','Z') mmtypes = ('L','C','Z')
@ -32,6 +33,18 @@ class mainnet(mainnet):
def get_addr_len(self,addr_fmt): def get_addr_len(self,addr_fmt):
return (20,64)[addr_fmt in ('zcash_z','viewkey')] 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): def preprocess_key(self,sec,pubkey_type):
if pubkey_type == 'zcash_z': # zero the first four bits if pubkey_type == 'zcash_z': # zero the first four bits
return bytes([sec[0] & 0x0f]) + sec[1:] return bytes([sec[0] & 0x0f]) + sec[1:]
@ -49,4 +62,4 @@ class mainnet(mainnet):
class testnet(mainnet): class testnet(mainnet):
wif_ver_num = { 'std': 'ef', 'zcash_z': 'ac08' } 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' }

View file

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