fixes and cleanups throughout
This commit is contained in:
parent
1aff3980ee
commit
5409ef4c2d
11 changed files with 79 additions and 55 deletions
|
|
@ -23,6 +23,7 @@ from .color import yellow, red, orange, brown, blue
|
|||
from .wallet import Wallet, get_wallet_cls
|
||||
from .addrlist import AddrIdxList
|
||||
from .filename import find_file_in_dir
|
||||
from .fileutil import shred_file
|
||||
from .ui import keypress_confirm
|
||||
|
||||
def SwapMgr(*args, **kwargs):
|
||||
|
|
@ -239,10 +240,9 @@ class Signable:
|
|||
suf(files),
|
||||
fmt_list(map(str, files), fmt='col', indent=' ')),
|
||||
do_exit = True)
|
||||
for f in files:
|
||||
msg(f'Shredding file ‘{f}’')
|
||||
from .fileutil import shred_file
|
||||
shred_file(f)
|
||||
for fn in files:
|
||||
msg(f'Shredding file ‘{fn}’')
|
||||
shred_file(fn)
|
||||
sys.exit(0)
|
||||
|
||||
async def get_last_created(self):
|
||||
|
|
@ -276,7 +276,7 @@ class Signable:
|
|||
tx1,
|
||||
seedfiles = self.parent.wallet_files[:],
|
||||
passwdfile = str(self.parent.keyfile),
|
||||
auto = True).keys)
|
||||
autosign = True).keys)
|
||||
if tx2:
|
||||
tx2.file.write(ask_write=False, outdir=self.dir)
|
||||
return tx2
|
||||
|
|
@ -693,7 +693,6 @@ class Autosign:
|
|||
|
||||
def wipe_encryption_key(self):
|
||||
if self.keyfile.exists():
|
||||
from .fileutil import shred_file
|
||||
ymsg(f'Shredding wallet encryption key ‘{self.keyfile}’')
|
||||
shred_file(self.keyfile, verbose=self.cfg.verbose)
|
||||
else:
|
||||
|
|
@ -818,11 +817,10 @@ class Autosign:
|
|||
|
||||
def clean_old_files(self):
|
||||
|
||||
def do_shred(f):
|
||||
def do_shred(fn):
|
||||
nonlocal count
|
||||
msg_r('.')
|
||||
from .fileutil import shred_file
|
||||
shred_file(f, verbose=self.cfg.verbose)
|
||||
shred_file(fn, verbose=self.cfg.verbose)
|
||||
count += 1
|
||||
|
||||
def clean_dir(s_name):
|
||||
|
|
|
|||
|
|
@ -399,7 +399,7 @@ class Crypto:
|
|||
from .ui import get_words_from_user
|
||||
return ' '.join(get_words_from_user(self.cfg, f'Enter {pw_desc} for {data_desc}: '))
|
||||
|
||||
def mmgen_encrypt(self, data, *, desc='data', hash_preset=None):
|
||||
def mmgen_encrypt(self, data, *, passwd=None, desc='data', hash_preset=None):
|
||||
salt = self.get_random(self.mmenc_salt_len)
|
||||
iv = self.get_random(self.aesctr_iv_len)
|
||||
nonce = self.get_random(self.mmenc_nonce_len)
|
||||
|
|
@ -407,7 +407,7 @@ class Crypto:
|
|||
m = ('user-requested', 'default')[hp=='3']
|
||||
self.util.vmsg(f'Encrypting {desc}')
|
||||
self.util.qmsg(f'Using {m} hash preset of {hp!r}')
|
||||
passwd = self.get_new_passphrase(
|
||||
passwd = passwd or self.get_new_passphrase(
|
||||
data_desc = desc,
|
||||
hash_preset = hp,
|
||||
passwd_file = self.cfg.passwd_file)
|
||||
|
|
@ -416,7 +416,7 @@ class Crypto:
|
|||
enc_d = self.encrypt_data(sha256(nonce+data).digest() + nonce + data, key=key, iv=iv, desc=desc)
|
||||
return salt+iv+enc_d
|
||||
|
||||
def mmgen_decrypt(self, data, *, desc='data', hash_preset=None):
|
||||
def mmgen_decrypt(self, data, *, passwd=None, desc='data', hash_preset=None):
|
||||
self.util.vmsg(f'Preparing to decrypt {desc}')
|
||||
dstart = self.mmenc_salt_len + self.aesctr_iv_len
|
||||
salt = data[:self.mmenc_salt_len]
|
||||
|
|
@ -425,7 +425,7 @@ class Crypto:
|
|||
hp = hash_preset or self.cfg.hash_preset or self.get_hash_preset_from_user(data_desc=desc)
|
||||
m = ('user-requested', 'default')[hp=='3']
|
||||
self.util.qmsg(f'Using {m} hash preset of {hp!r}')
|
||||
passwd = self.get_passphrase(
|
||||
passwd = passwd or self.get_passphrase(
|
||||
data_desc = desc,
|
||||
passwd_file = self.cfg.passwd_file)
|
||||
key = self.make_key(passwd, salt, hp)
|
||||
|
|
|
|||
|
|
@ -202,14 +202,14 @@ if cmd not in Autosign.cmds + Autosign.util_cmds:
|
|||
die(1, f'‘{cmd}’: unrecognized command')
|
||||
|
||||
if cmd != 'setup':
|
||||
for opt in ('seed_len', 'mnemonic_fmt'):
|
||||
for opt in ('seed_len', 'mnemonic_fmt', 'keys_from_file'):
|
||||
if getattr(cfg, opt):
|
||||
die(1, f'--{opt.replace("_", "-")} makes sense only for the ‘setup’ operation')
|
||||
die(1, f'--{opt.replace("_", "-")} is valid only for the ‘setup’ operation')
|
||||
|
||||
if cmd not in ('sign', 'wait'):
|
||||
for opt in ('no_summary', 'led', 'stealth_led', 'full_summary'):
|
||||
if getattr(cfg, opt):
|
||||
die(1, f'--{opt.replace("_", "-")} makes no sense for the ‘{cmd}’ operation')
|
||||
die(1, f'--{opt.replace("_", "-")} is not valid for the ‘{cmd}’ operation')
|
||||
|
||||
asi = Autosign(cfg, cmd=cmd)
|
||||
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ class Base(MMGenObject):
|
|||
as autosigning does not support the use of key files.
|
||||
|
||||
Non-{gc.proj_name} addresses found in inputs:
|
||||
{{}}
|
||||
{{}}
|
||||
"""
|
||||
|
||||
class Input(MMGenTxIO):
|
||||
|
|
@ -212,7 +212,7 @@ class Base(MMGenObject):
|
|||
edesc = 'non-MMGen address',
|
||||
quiet = True)
|
||||
|
||||
def check_non_mmgen_inputs(self, caller, *, non_mmaddrs=None):
|
||||
def check_non_mmgen_inputs(self, *, caller, non_mmaddrs=None):
|
||||
non_mmaddrs = non_mmaddrs or self.get_non_mmaddrs('inputs')
|
||||
if non_mmaddrs:
|
||||
indent = ' '
|
||||
|
|
|
|||
|
|
@ -82,12 +82,12 @@ class TxKeys:
|
|||
keylist = None,
|
||||
keyaddrlist = None,
|
||||
passwdfile = None,
|
||||
auto = False):
|
||||
autosign = False):
|
||||
self.cfg = cfg
|
||||
self.tx = tx
|
||||
self.seedfiles = seedfiles or pop_seedfiles(cfg)
|
||||
self.keylist = None if auto else keylist or get_keylist(cfg)
|
||||
self.keyaddrlist = None if auto else keyaddrlist or get_keyaddrlist(cfg, tx.proto)
|
||||
self.keylist = keylist if autosign else keylist or get_keylist(cfg)
|
||||
self.keyaddrlist = keyaddrlist if autosign else keyaddrlist or get_keyaddrlist(cfg, tx.proto)
|
||||
self.passwdfile = passwdfile
|
||||
self.saved_seeds = {}
|
||||
|
||||
|
|
@ -95,7 +95,9 @@ class TxKeys:
|
|||
err_fs = 'ERROR: a key file must be supplied for the following non-{} address{}:{}'
|
||||
sep = '\n '
|
||||
if addrs := self.tx.get_non_mmaddrs('inputs'):
|
||||
self.tx.check_non_mmgen_inputs(caller='txsign', non_mmaddrs=addrs)
|
||||
self.tx.check_non_mmgen_inputs(
|
||||
caller = 'txsign',
|
||||
non_mmaddrs = addrs)
|
||||
kal = KeyAddrList(
|
||||
cfg = self.cfg,
|
||||
proto = self.tx.proto,
|
||||
|
|
@ -209,7 +211,7 @@ class TxKeys:
|
|||
ret = self.get_keys_for_non_mmgen_inputs()
|
||||
memo_output = self.tx.check_swap_memo() # do this for non-swap transactions too!
|
||||
|
||||
if self.cfg.mmgen_keys_from_file:
|
||||
if self.keyaddrlist:
|
||||
ret += self.add_keys('inputs', self.tx.inputs, from_keyaddrlist=True)
|
||||
self.add_keys('outputs', self.tx.outputs, from_keyaddrlist=True)
|
||||
if memo_output:
|
||||
|
|
|
|||
|
|
@ -508,7 +508,7 @@ class New(Base):
|
|||
desc)) is not None:
|
||||
break
|
||||
|
||||
self.check_non_mmgen_inputs(caller)
|
||||
self.check_non_mmgen_inputs(caller=caller)
|
||||
|
||||
self.update_change_output(funds_left)
|
||||
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ class OpCreateOffline(OpCreate):
|
|||
for f in Path(self.asi.xmr_dir).iterdir():
|
||||
if f.name.endswith(vkf.ext):
|
||||
from ...fileutil import shred_file
|
||||
msg(f"\nShredding old viewkey-address file '{f}'")
|
||||
msg(f'\nShredding old viewkey-address file ‘{f}’')
|
||||
shred_file(f, verbose=self.cfg.verbose)
|
||||
|
||||
vkf.write(outdir=self.asi.xmr_dir)
|
||||
|
|
|
|||
|
|
@ -27,6 +27,10 @@ class CmdTestAutosignAutomount(CmdTestAutosignThreaded, CmdTestRegtest):
|
|||
rt_data = {
|
||||
'rtFundAmt': {'btc':'500', 'bch':'500', 'ltc':'5500'},
|
||||
}
|
||||
bal2_chk = {
|
||||
'btc': '491.11002204',
|
||||
'bch': '498.7653392',
|
||||
'ltc': '5491.11002204'}
|
||||
|
||||
cmd_group = (
|
||||
('setup', 'regtest mode setup'),
|
||||
|
|
@ -267,9 +271,4 @@ class CmdTestAutosignAutomount(CmdTestAutosignThreaded, CmdTestRegtest):
|
|||
output_args = ['data:message for posterity', f'{self.burn_addr},7.654321', f'{sid}:C:1'])
|
||||
|
||||
def alice_bal2(self):
|
||||
bals = {
|
||||
'btc': '491.11002204',
|
||||
'ltc': '5491.11002204',
|
||||
'bch': '498.7653392',
|
||||
}
|
||||
return self.user_bal('alice', bals.get(self.coin, None))
|
||||
return self.user_bal('alice', self.bal2_chk[self.coin])
|
||||
|
|
|
|||
|
|
@ -196,7 +196,8 @@ class CmdTestAutosignBase(CmdTestBase):
|
|||
use_dfl_wallet = False,
|
||||
seed_len = None,
|
||||
usr_entry_modes = False,
|
||||
passwd = 'abc',
|
||||
wallet_passwd = None,
|
||||
add_opts = [],
|
||||
expect_args = []):
|
||||
|
||||
mn_desc = mn_type or 'default'
|
||||
|
|
@ -209,7 +210,7 @@ class CmdTestAutosignBase(CmdTestBase):
|
|||
|
||||
t = self.spawn(
|
||||
'mmgen-autosign',
|
||||
self.opts
|
||||
self.opts + add_opts
|
||||
+ ([] if mn_desc == 'default' else [f'--mnemonic-fmt={mn_type}'])
|
||||
+ ([f'--seed-len={seed_len}'] if seed_len else [])
|
||||
+ ['setup'],
|
||||
|
|
@ -217,7 +218,7 @@ class CmdTestAutosignBase(CmdTestBase):
|
|||
|
||||
if use_dfl_wallet:
|
||||
t.expect('Use default wallet for autosigning? (Y/n): ', 'y')
|
||||
t.passphrase('MMGen wallet', passwd)
|
||||
t.passphrase('MMGen wallet', wallet_passwd)
|
||||
else:
|
||||
if use_dfl_wallet is not None: # None => no dfl wallet present
|
||||
t.expect('Use default wallet for autosigning? (Y/n): ', 'n')
|
||||
|
|
@ -447,11 +448,13 @@ class CmdTestAutosignThreaded(CmdTestAutosignBase):
|
|||
self,
|
||||
user,
|
||||
progname = 'txcreate',
|
||||
input_handler = None,
|
||||
ui_handler = None,
|
||||
chg_addr = None,
|
||||
opts = [],
|
||||
output_args = [],
|
||||
exit_val = 0,
|
||||
inputs = '1',
|
||||
tweaks = [],
|
||||
expect_str = None,
|
||||
data_arg = None,
|
||||
need_rbf = False):
|
||||
|
|
@ -486,10 +489,11 @@ class CmdTestAutosignThreaded(CmdTestAutosignBase):
|
|||
if exit_val:
|
||||
return do_return()
|
||||
|
||||
t = (input_handler or self.txcreate_ui_common)(
|
||||
t = (ui_handler or self.txcreate_ui_common)(
|
||||
t,
|
||||
inputs = '1',
|
||||
inputs = inputs,
|
||||
interactive_fee = '32s',
|
||||
tweaks = tweaks,
|
||||
file_desc = 'Unsigned automount transaction')
|
||||
|
||||
return do_return()
|
||||
|
|
@ -615,6 +619,7 @@ class CmdTestAutosign(CmdTestAutosignBase):
|
|||
live = False
|
||||
simulate_led = True
|
||||
no_insert_check = True
|
||||
wallet_passwd = 'abc'
|
||||
|
||||
filedir_map = (
|
||||
('btc', ''),
|
||||
|
|
@ -719,7 +724,7 @@ class CmdTestAutosign(CmdTestAutosignBase):
|
|||
'test/ref/98831F3A.hex'
|
||||
]
|
||||
)
|
||||
t.passphrase_new('new MMGen wallet', 'abc')
|
||||
t.passphrase_new('new MMGen wallet', self.wallet_passwd)
|
||||
t.written_to_file('MMGen wallet')
|
||||
return t
|
||||
|
||||
|
|
@ -729,16 +734,16 @@ class CmdTestAutosign(CmdTestAutosignBase):
|
|||
return t
|
||||
|
||||
def bad_opt1(self):
|
||||
return self._bad_opt(['--seed-len=128'], 'makes sense')
|
||||
return self._bad_opt(['--seed-len=128'], 'is valid')
|
||||
|
||||
def bad_opt2(self):
|
||||
return self._bad_opt(['--mnemonic-fmt=bip39', 'wait'], 'makes sense')
|
||||
return self._bad_opt(['--mnemonic-fmt=bip39', 'wait'], 'is valid')
|
||||
|
||||
def bad_opt3(self):
|
||||
return self._bad_opt(['--led', 'gen_key'], 'makes no sense')
|
||||
return self._bad_opt(['--led', 'gen_key'], 'is not valid')
|
||||
|
||||
def run_setup_dfl_wallet(self):
|
||||
return self.run_setup(mn_type='default', use_dfl_wallet=True)
|
||||
return self.run_setup(mn_type='default', use_dfl_wallet=True, wallet_passwd=self.wallet_passwd)
|
||||
|
||||
def run_setup_bip39(self):
|
||||
from mmgen.cfgfile import mmgen_cfg_file
|
||||
|
|
|
|||
|
|
@ -707,7 +707,7 @@ class CmdTestRegtest(CmdTestBase, CmdTestShared):
|
|||
[f'{addr},{rtFundAmt}', self.burn_addr],
|
||||
utxo_nums,
|
||||
extra_args = [f'--keys-from-file={keyfile}'],
|
||||
tweaks = 'confirm_chg_non_mmgen',
|
||||
tweaks = ['confirm_chg_non_mmgen'],
|
||||
skip_passphrase = skip_passphrase)
|
||||
|
||||
def fund_bob_deterministic(self):
|
||||
|
|
@ -745,23 +745,27 @@ class CmdTestRegtest(CmdTestBase, CmdTestShared):
|
|||
return 'skip'
|
||||
return self.addrimport('bob', add_opts=['--rescan'])
|
||||
|
||||
def fund_wallet(self, user, mmtype, amt, sid=None, addr_range='1-5', proto=None):
|
||||
def fund_wallet(self, user, amt, *, addr=None, mmtype=None, sid=None, addr_range='1-5', proto=None):
|
||||
proto = proto or self.proto
|
||||
if self.deterministic:
|
||||
return 'skip'
|
||||
if not sid:
|
||||
sid = self._user_sid(user)
|
||||
addr = self.get_addr_from_addrlist(user, sid, mmtype, 0, addr_range=addr_range, proto=proto)
|
||||
t = self.spawn('mmgen-regtest', [f'--coin={proto.coin}', 'send', str(addr), str(amt)], no_passthru_opts=True)
|
||||
addr = addr or self.get_addr_from_addrlist(
|
||||
user, sid, mmtype, 0, addr_range=addr_range, proto=proto)
|
||||
t = self.spawn(
|
||||
'mmgen-regtest',
|
||||
[f'--coin={proto.coin}', 'send', str(addr), str(amt)],
|
||||
no_passthru_opts = True)
|
||||
t.expect(f'Sending {amt} miner {proto.coin}')
|
||||
t.expect('Mined 1 block')
|
||||
return t
|
||||
|
||||
def fund_bob(self):
|
||||
return self.fund_wallet('bob', 'C', rtFundAmt)
|
||||
return self.fund_wallet('bob', rtFundAmt, mmtype='C')
|
||||
|
||||
def fund_alice(self):
|
||||
return self.fund_wallet('alice', ('L', 'S')[self.proto.cap('segwit')], rtFundAmt)
|
||||
return self.fund_wallet('alice', rtFundAmt, mmtype=('L', 'S')[self.proto.cap('segwit')])
|
||||
|
||||
def user_twview(
|
||||
self,
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ class CmdTestSwapMethods:
|
|||
return self.addrimport('bob', mmtypes=['S', 'B'], proto=self.protos[proto_idx])
|
||||
|
||||
def _fund_bob(self, proto_idx, addrtype_code, amt):
|
||||
return self.fund_wallet('bob', addrtype_code, amt, proto=self.protos[proto_idx])
|
||||
return self.fund_wallet('bob', amt, mmtype=addrtype_code, proto=self.protos[proto_idx])
|
||||
|
||||
def _bob_bal(self, proto_idx, bal, skip_check=False):
|
||||
return self.user_bal('bob', bal, proto=self.protos[proto_idx], skip_check=skip_check)
|
||||
|
|
@ -142,6 +142,7 @@ class CmdTestSwapMethods:
|
|||
inputs = '1',
|
||||
interactive_fee = None,
|
||||
file_desc = 'Unsigned transaction',
|
||||
tweaks = [],
|
||||
reload_quote = False,
|
||||
sign_and_send = False,
|
||||
need_passphrase = True,
|
||||
|
|
@ -238,10 +239,25 @@ class CmdTestSwapMethods:
|
|||
exit_val = exit_val)
|
||||
return self._swaptxbump_ui_common(t, interactive_fee=fee, new_outputs=bool(output_args))
|
||||
|
||||
def _swaptxbump_ui_common_new_outputs(self, t, *, inputs=None, interactive_fee=None, file_desc=None):
|
||||
return self._swaptxbump_ui_common(t, interactive_fee=interactive_fee, new_outputs=True)
|
||||
def _swaptxbump_ui_common_new_outputs(
|
||||
self,
|
||||
t,
|
||||
*,
|
||||
tweaks = [],
|
||||
inputs = None,
|
||||
interactive_fee = None,
|
||||
file_desc = None):
|
||||
return self._swaptxbump_ui_common(
|
||||
t,
|
||||
inputs = inputs,
|
||||
interactive_fee = interactive_fee,
|
||||
file_desc = file_desc,
|
||||
new_outputs = True)
|
||||
|
||||
def _swaptxbump_ui_common(self, t, *,
|
||||
def _swaptxbump_ui_common(
|
||||
self,
|
||||
t,
|
||||
*,
|
||||
inputs = None,
|
||||
interactive_fee = None,
|
||||
file_desc = None,
|
||||
|
|
@ -780,7 +796,7 @@ class CmdTestSwap(CmdTestSwapMethods, CmdTestRegtest, CmdTestAutosignThreaded):
|
|||
return self._user_txcreate(
|
||||
'bob',
|
||||
progname = 'swaptxcreate',
|
||||
input_handler = self._swaptxcreate_ui_common,
|
||||
ui_handler = self._swaptxcreate_ui_common,
|
||||
output_args = ['BTC', '8.88', f'{self.sid}:S:3', 'LTC', f'{self.sid}:S:3'])
|
||||
|
||||
def autosign_swaptxsend1(self):
|
||||
|
|
@ -790,7 +806,7 @@ class CmdTestSwap(CmdTestSwapMethods, CmdTestRegtest, CmdTestAutosignThreaded):
|
|||
return self._user_txcreate(
|
||||
'bob',
|
||||
progname = 'txbump',
|
||||
input_handler = self._swaptxbump_ui_common_new_outputs,
|
||||
ui_handler = self._swaptxbump_ui_common_new_outputs,
|
||||
output_args = [f'{self.sid}:S:3'])
|
||||
|
||||
def autosign_swaptxsend2(self):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue