various fixes and cleanups throughout

This commit is contained in:
The MMGen Project 2020-02-12 10:36:15 +00:00
commit 70675956b8
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
13 changed files with 68 additions and 50 deletions

View file

@ -52,15 +52,6 @@
# Set the maximum transaction fee for BTC:
# btc_max_tx_fee 0.003
# Set the maximum transaction fee for BCH:
# bch_max_tx_fee 0.1
# Set the maximum transaction fee for LTC:
# ltc_max_tx_fee 0.3
# Set the maximum transaction fee for ETH:
# eth_max_tx_fee 0.005
# Set the transaction fee adjustment factor. Auto-calculated fees are
# multiplied by this value:
# tx_fee_adj 1.0
@ -71,15 +62,28 @@
# Set the maximum input size - applies both to files and standard input:
# max_input_size 1048576
# Uncomment to suppress non-ASCII character password warning for MSWin / MSYS2
# mswin_pw_warning false
###################
# Altcoin options #
###################
# Set the maximum transaction fee for BCH:
# bch_max_tx_fee 0.1
# Set the maximum transaction fee for LTC:
# ltc_max_tx_fee 0.3
# Set the maximum transaction fee for ETH:
# eth_max_tx_fee 0.005
# Set the Ethereum mainnet name
# eth_mainnet_chain_name foundation
# Set the Ethereum testnet name
# eth_testnet_chain_name kovan
# Uncomment to suppress non-ASCII character password warning for MSWin / MSYS2
# mswin_pw_warning false
#####################################################################
# The following options are probably of interest only to developers #
#####################################################################

View file

@ -795,8 +795,8 @@ class PasswordList(AddrList):
# password. The label may contain any printable ASCII symbol.
#
""".strip().format(n=TwComment.max_screen_width,pnm=pnm),
'file_header_bip39': """
# {pnm} BIP39 password file
'file_header_mn': """
# {pnm} {{}} password file
#
# This file is editable.
# Everything following a hash symbol '#' is a comment and ignored by {pnm}.
@ -856,7 +856,7 @@ Record this checksum: it will be used to verify the password file in the future
self.data = self.generate(seed,pw_idxs)
if self.pw_fmt == 'bip39':
self.msgs['file_header'] = self.msgs['file_header_bip39']
self.msgs['file_header'] = self.msgs['file_header_mn'].format(self.pw_fmt.upper())
self.num_addrs = len(self.data)
self.fmt_data = ''

View file

@ -37,7 +37,7 @@ class baseconv(object):
'b6d': ('base6d (die roll)', 'base6 data using the digits from one to six'),
'tirosh':('Tirosh mnemonic', 'base1626 mnemonic using truncated Tirosh wordlist'), # not used by wallet
'mmgen': ('MMGen native mnemonic',
'MMGen native mnemonic seed phrase data created using old Electrum wordlist and simple base conversion'),
'MMGen native mnemonic seed phrase created using old Electrum wordlist and simple base conversion'),
}
# https://en.wikipedia.org/wiki/Base32#RFC_4648_Base32_alphabet
# https://tools.ietf.org/html/rfc4648

View file

@ -32,7 +32,7 @@ class Daemon(MMGenObject):
debug = False
wait = True
use_pidfile = True
conf_file = None
cfg_file = None
def subclass_init(self): pass
@ -97,8 +97,8 @@ class Daemon(MMGenObject):
msg(m.format(self.net_desc,self.desc,self.pid))
else:
os.makedirs(self.datadir,exist_ok=True)
if self.conf_file:
open('{}/{}'.format(self.datadir,self.conf_file),'w').write(self.cfg_file_hdr)
if self.cfg_file:
open('{}/{}'.format(self.datadir,self.cfg_file),'w').write(self.cfg_file_hdr)
if self.use_pidfile and os.path.exists(self.pidfile):
# Parity just overwrites the data in an existing pidfile, leading to
# interesting consequences.
@ -125,7 +125,7 @@ class Daemon(MMGenObject):
return True
time.sleep(0.2)
else:
die(2,'Daemon wait timeout for {} {} exceeded'.format(self.coin,self.network))
die(2,'Daemon wait timeout for {} {} exceeded'.format(self.daemon_id.upper(),self.network))
@property
def is_ready(self):
@ -361,11 +361,11 @@ class EthereumDaemon(CoinDaemon):
@property
def stop_cmd(self):
return ['kill','-Wf',self.pid] if g.platform == 'win' else ['kill',self.pid]
return ['kill','-Wf',self.pid] if self.platform == 'win' else ['kill',self.pid]
@property
def pid(self): # TODO: distinguish between ETH and ETC
if g.platform == 'win':
if self.platform == 'win':
cp = self.run_cmd(['ps','-Wl'],silent=True,check=False)
for line in cp.stdout.decode().splitlines():
if 'parity.exe' in line:

View file

@ -357,7 +357,7 @@ def setup():
opt.quiet = True
opt.in_fmt = 'words'
ss_in = SeedSource()
opt.out_fmt = 'mmdat'
opt.out_fmt = 'wallet'
opt.usr_randchars = 0
opt.hash_preset = '1'
opt.set_by_user = ['hash_preset']

View file

@ -15,12 +15,17 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# ------------------------------------------------------------------------------
# MMGen note: this is a sorted version of the wordlist.
# The original can be found at:
# The unsorted original can be found at:
# https://github.com/spesmilo/electrum/blob/1.9.5/lib/mnemonic.py
# Electrum - lightweight Bitcoin client. Copyright (C) 2011 thomasv@gitorious
# Also available at:
# https://github.com/monero-project/monero/blob/master/src/mnemonics/english_old.h
words = tuple("""
able
about

View file

@ -489,7 +489,9 @@ class BTCAmt(Decimal,Hilite,InitErrors):
class BCHAmt(BTCAmt): pass
class B2XAmt(BTCAmt): pass
class LTCAmt(BTCAmt): max_amt = 84000000
class XMRAmt(BTCAmt): min_coin_unit = Decimal('0.000000000001')
class XMRAmt(BTCAmt):
min_coin_unit = Decimal('0.000000000001')
units = ('min_coin_unit',)
from mmgen.altcoins.eth.obj import ETHAmt,ETHNonce

View file

@ -29,7 +29,7 @@ def dmsg_rpc(fs,data=None,is_json=False):
if g.debug_rpc:
msg(fs if data == None else fs.format(pp_fmt(json.loads(data) if is_json else data)))
class CoinDaemonRPCConnection(MMGenObject):
class RPCConnection(MMGenObject):
auth = True
db_fs = ' host [{h}] port [{p}] user [{u}] passwd [{pw}] auth_cookie [{c}]\n'
@ -217,7 +217,7 @@ class CoinDaemonRPCConnection(MMGenObject):
'walletpassphrase',
)
class EthereumRPCConnection(CoinDaemonRPCConnection):
class EthereumRPCConnection(RPCConnection):
auth = False
db_fs = ' host [{h}] port [{p}]\n'
@ -335,7 +335,7 @@ def init_daemon_bitcoind():
cfg = get_daemon_cfg_options(('rpcuser','rpcpassword'))
conn = CoinDaemonRPCConnection(
conn = RPCConnection(
g.rpc_host or 'localhost',
g.rpc_port or g.proto.rpc_port,
g.rpc_user or cfg['rpcuser'], # MMGen's rpcuser,rpcpassword override coin daemon's

View file

@ -241,7 +241,7 @@ class MMGenToolCmdBase(object):
@classmethod
def _user_commands(cls):
return [e for e in dir(cls) if e[0] != '_' and getattr(cls,e).__doc__]
return [e for e in dir(cls) if e[0] != '_' and getattr(cls,e).__doc__ and callable(getattr(cls,e))]
class MMGenToolCmdMisc(MMGenToolCmdBase):
@ -393,7 +393,7 @@ class MMGenToolCmdCoin(MMGenToolCmdBase):
def hex2wif(self,privhex:'sstr'):
"convert a private key from hex to WIF format"
init_generators('at')
return g.proto.hex2wif(privhex,pubkey_type=at.pubkey_type,compressed=at.compressed)
return PrivKey(bytes.fromhex(privhex),pubkey_type=at.pubkey_type,compressed=at.compressed).wif
def wif2addr(self,wifkey:'sstr'):
"generate a coin address from a key in WIF format"
@ -487,9 +487,10 @@ class MMGenToolCmdMnemonic(MMGenToolCmdBase):
"""
def _do_random_mn(self,nbytes:int,fmt:str):
assert nbytes in (16,24,32), 'nbytes must be 16, 24 or 32'
hexrand = get_random(nbytes).hex()
Vmsg('Seed: {}'.format(hexrand))
return self.hex2mn(hexrand,fmt=fmt)
randbytes = get_random(nbytes)
if opt.verbose:
msg('Seed: {}'.format(randbytes.hex()))
return self.hex2mn(randbytes.hex(),fmt=fmt)
def mn_rand128(self, fmt:mn_opts_disp = dfl_mnemonic_fmt ):
"generate random 128-bit mnemonic seed phrase"
@ -512,17 +513,21 @@ class MMGenToolCmdMnemonic(MMGenToolCmdBase):
def hex2mn( self, hexstr:'sstr', fmt:mn_opts_disp = dfl_mnemonic_fmt ):
"convert a 16, 24 or 32-byte hexadecimal number to a mnemonic seed phrase"
opt.out_fmt = self._get_mnemonic_fmt(fmt)
from mmgen.seed import SeedSource
s = SeedSource(seed_bin=bytes.fromhex(hexstr))
s._format()
return ' '.join(s.ssdata.mnemonic)
if fmt == 'bip39':
from mmgen.bip39 import bip39
return ' '.join(bip39.fromhex(hexstr,fmt))
else:
bytestr = bytes.fromhex(hexstr)
return baseconv.frombytes(bytestr,fmt,'seed',tostr=True)
def mn2hex( self, seed_mnemonic:'sstr', fmt:mn_opts_disp = dfl_mnemonic_fmt ):
"convert a 12, 18 or 24-word mnemonic seed phrase to a hexadecimal number"
in_fmt = self._get_mnemonic_fmt(fmt)
opt.quiet = True
from mmgen.seed import SeedSource
return SeedSource(in_data=seed_mnemonic,in_fmt=in_fmt).seed.hexdata
if fmt == 'bip39':
from mmgen.bip39 import bip39
return bip39.tohex(seed_mnemonic.split(),fmt)
else:
return baseconv.tohex(seed_mnemonic.split(),fmt,'seed')
def mn_stats(self, fmt:mn_opts_disp = dfl_mnemonic_fmt ):
"show stats for mnemonic wordlist"

View file

@ -42,7 +42,7 @@ opts_data = {
-v, --verbose Produce more verbose output
""",
'notes': """
Valid commands: 'coin','pw'
If no command is given, the whole suite of tests is run.
"""
}
@ -141,8 +141,9 @@ def do_passwd_tests():
start_time = int(time.time())
do_coin_tests()
do_passwd_tests()
cmds = cmd_args or ('coin','pw')
for cmd in cmds:
{'coin': do_coin_tests, 'pw': do_passwd_tests }[cmd]()
t = int(time.time()) - start_time
m = 'All requested tests finished OK, elapsed time: {:02}:{:02}'

View file

@ -526,6 +526,8 @@ class CmdGroupMgr(object):
if is3seed:
for n,(i,j) in enumerate(zip(cls.tmpdir_nums,(128,192,256))):
k = '{}_{}'.format(a,n+1)
if hasattr(cls,'skip_cmds') and k in cls.skip_cmds:
continue
sdeps = get_shared_deps(k,i)
if type(b) == str:
cdata.append( (k, (i,'{} ({}-bit)'.format(b,j),[[[]+sdeps,i]])) )

View file

@ -381,12 +381,12 @@ class TestSuiteRef3Addr(TestSuiteRef3Seed):
ea = ['--accept-defaults']
return self.pwgen('passhex','фубар@crypto.org','hex','h',ea,stdout=True)
def bip39pwgen(self,req_pw_len,pwfmt='bip39',stdout=False):
def mn_pwgen(self,req_pw_len,pwfmt,ftype='passbip39',stdout=False):
pwlen = min(req_pw_len,{'1':12,'2':18,'3':24}[self.test_name[-1]])
ea = ['--accept-defaults']
return self.pwgen('passbip39','фубар@crypto.org',pwfmt,pwlen,ea,stdout=stdout)
return self.pwgen(ftype,'фубар@crypto.org',pwfmt,pwlen,ea,stdout=stdout)
def ref_bip39_12_passwdgen(self): return self.bip39pwgen(12,stdout=True)
def ref_bip39_18_passwdgen(self): return self.bip39pwgen(18,stdout=True)
def ref_bip39_24_passwdgen(self): return self.bip39pwgen(24)
def ref_hex2bip39_24_passwdgen(self): return self.bip39pwgen(24,'hex2bip39')
def ref_bip39_12_passwdgen(self): return self.mn_pwgen(12,'bip39',stdout=True)
def ref_bip39_18_passwdgen(self): return self.mn_pwgen(18,'bip39',stdout=True)
def ref_bip39_24_passwdgen(self): return self.mn_pwgen(24,'bip39')
def ref_hex2bip39_24_passwdgen(self): return self.mn_pwgen(24,'hex2bip39')

View file

@ -75,7 +75,6 @@ If no command is given, the whole suite of tests is run.
}
}
sample_text_hexdump = (
'000000: 5468 6520 5469 6d65 7320 3033 2f4a 616e{n}' +
'000010: 2f32 3030 3920 4368 616e 6365 6c6c 6f72{n}' +