minor fixes and cleanups
This commit is contained in:
parent
2e1f3b93e4
commit
3823e8cdc9
11 changed files with 63 additions and 60 deletions
|
|
@ -94,7 +94,7 @@ class TwAddrData(AddrData,metaclass=AsyncInit):
|
|||
out[al_id].append(AddrListEntry(self.proto,idx=obj.idx,addr=addr_array[0],label=l.comment))
|
||||
i += 1
|
||||
|
||||
vmsg(f'{i} {g.prog_name} addresses found, {len(twd)} accounts total')
|
||||
vmsg(f'{i} {g.proj_name} addresses found, {len(twd)} accounts total')
|
||||
|
||||
for al_id in out:
|
||||
self.add(AddrList(self.proto,al_id=al_id,adata=AddrListData(sorted(out[al_id],key=lambda a: a.idx))))
|
||||
|
|
|
|||
|
|
@ -56,12 +56,10 @@ def create_hdseed(proto):
|
|||
def cliargs_convert(args):
|
||||
def gen():
|
||||
for arg in args:
|
||||
if arg.lower() in ('true','false'):
|
||||
yield (True,False)[arg.lower() == 'false']
|
||||
elif len(str(arg)) < 20 and re.match(r'[0-9]+',arg):
|
||||
yield int(arg)
|
||||
else:
|
||||
yield arg
|
||||
try:
|
||||
yield json.loads(arg) # list, dict, bool, int, null
|
||||
except:
|
||||
yield arg # arbitrary string
|
||||
|
||||
return tuple(gen())
|
||||
|
||||
|
|
|
|||
|
|
@ -258,7 +258,7 @@ class BitcoinRPCClient(RPCClient,metaclass=AsyncInit):
|
|||
'getmempoolentry',
|
||||
'getrawtransaction',
|
||||
'gettransaction',
|
||||
'importaddress',
|
||||
'importaddress', # address (address or script) label rescan p2sh (Add P2SH version of the script)
|
||||
'listaccounts',
|
||||
'listlabels',
|
||||
'listunspent',
|
||||
|
|
|
|||
|
|
@ -258,8 +258,7 @@ Actions: [q]uit, r[e]draw:
|
|||
# chain. e.g. 1 would mean the best block hash. Note: this is not used
|
||||
# as a filter, but only affects [lastblock] in the return value
|
||||
# 3. include_watchonly (boolean, optional, default=true for watch-only wallets, otherwise
|
||||
# false) Include transactions to watch-only addresses (see
|
||||
# 'importaddress')
|
||||
# false) Include transactions to watch-only addresses
|
||||
# 4. include_removed (boolean, optional, default=true) Show transactions that were removed
|
||||
# due to a reorg in the "removed" array (not guaranteed to work on
|
||||
# pruned nodes)
|
||||
|
|
|
|||
|
|
@ -26,31 +26,10 @@ from .common import *
|
|||
from .addrlist import AddrList,KeyAddrList
|
||||
from .tw.common import TwLabel
|
||||
|
||||
ai_msgs = lambda k: {
|
||||
'rescan': """
|
||||
WARNING: You've chosen the '--rescan' option. Rescanning the blockchain is
|
||||
necessary only if an address you're importing is already in the blockchain,
|
||||
has a balance and is not in your tracking wallet. Note that the rescanning
|
||||
process is very slow (>30 min. for each imported address on a low-powered
|
||||
computer).
|
||||
""".strip() if opt.rescan else """
|
||||
WARNING: If any of the addresses you're importing is already in the blockchain,
|
||||
has a balance and is not in your tracking wallet, you must exit the program now
|
||||
and rerun it using the '--rescan' option.
|
||||
""".strip(),
|
||||
'bad_args': f"""
|
||||
You must specify an {g.proj_name} address file, a single address with the '--address'
|
||||
option, or a list of non-{g.proj_name} addresses with the '--addrlist' option
|
||||
""".strip()
|
||||
}[k]
|
||||
|
||||
# In batch mode, daemon just rescans each address separately anyway, so make
|
||||
# --batch and --rescan incompatible.
|
||||
|
||||
opts_data = {
|
||||
'text': {
|
||||
'desc': f'Import addresses into an {g.proj_name} tracking wallet',
|
||||
'usage':'[opts] [mmgen address file]',
|
||||
'usage':'[opts] [MMGen address file]',
|
||||
'options': """
|
||||
-h, --help Print this help message
|
||||
--, --longhelp Print help message for long options (common options)
|
||||
|
|
@ -72,6 +51,23 @@ The --batch and --rescan options cannot be used together.
|
|||
}
|
||||
}
|
||||
|
||||
addrimport_msgs = {
|
||||
'rescan': """
|
||||
WARNING: You’ve chosen the ‘--rescan’ option. Rescanning the blockchain is
|
||||
necessary only if an address you’re importing is already in an output or
|
||||
outputs in the blockchain but not all transactions involving the address
|
||||
are known to the tracking wallet.
|
||||
|
||||
Rescanning is performed via the UTXO method, which is only minimally affected
|
||||
by the number of addresses imported and typically takes just a few minutes.
|
||||
""",
|
||||
'bad_args': f"""
|
||||
You must specify either an {g.proj_name} address file, a single address with
|
||||
the ‘--address’ option, or a flat list of non-{g.proj_name} addresses with
|
||||
the ‘--addrlist’ option.
|
||||
"""
|
||||
}
|
||||
|
||||
def parse_cmd_args(rpc,cmd_args):
|
||||
|
||||
def import_mmgen_list(infile):
|
||||
|
|
@ -96,7 +92,7 @@ def parse_cmd_args(rpc,cmd_args):
|
|||
al = AddrList(proto=proto,addrlist=[opt.address])
|
||||
infile = 'command line'
|
||||
else:
|
||||
die(1,ai_msgs('bad_args'))
|
||||
die(1,addrimport_msgs['bad_args'])
|
||||
|
||||
return al,infile
|
||||
|
||||
|
|
@ -105,17 +101,17 @@ def check_opts(tw):
|
|||
rescan = bool(opt.rescan)
|
||||
|
||||
if rescan and not 'rescan' in tw.caps:
|
||||
msg(f"'--rescan' ignored: not supported by {type(tw).__name__}")
|
||||
msg(f"‘--rescan’ ignored: not supported by {type(tw).__name__}")
|
||||
rescan = False
|
||||
|
||||
if rescan and not opt.quiet:
|
||||
confirm_or_raise(
|
||||
message = ai_msgs('rescan'),
|
||||
action = 'continue',
|
||||
expect = 'YES' )
|
||||
if not keypress_confirm(
|
||||
'\n{}\n\nContinue?'.format(addrimport_msgs['rescan']),
|
||||
default_yes = True ):
|
||||
die(1,'Exiting at user request')
|
||||
|
||||
if batch and not 'batch' in tw.caps:
|
||||
msg(f"'--batch' ignored: not supported by {type(tw).__name__}")
|
||||
msg(f"‘--batch’ ignored: not supported by {type(tw).__name__}")
|
||||
batch = False
|
||||
|
||||
return batch,rescan
|
||||
|
|
@ -176,6 +172,9 @@ async def main():
|
|||
from .rpc import rpc_init
|
||||
tw.rpc = await rpc_init(proto)
|
||||
|
||||
for k,v in addrimport_msgs.items():
|
||||
addrimport_msgs[k] = fmt(v,indent=' ',strip_char='\t').rstrip()
|
||||
|
||||
al,infile = parse_cmd_args(tw.rpc,cmd_args)
|
||||
|
||||
qmsg(
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ class RPCBackends:
|
|||
self.timeout = caller.timeout
|
||||
self.http_hdrs = caller.http_hdrs
|
||||
self.make_host_path = caller.make_host_path
|
||||
self.name = type(self).__name__
|
||||
|
||||
class aiohttp(base):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -161,7 +161,8 @@ class tool_cmd(tool_cmd_base):
|
|||
async def remove_address(self,mmgen_or_coin_addr:str):
|
||||
"remove an address from tracking wallet"
|
||||
from ..tw.ctl import TrackingWallet
|
||||
ret = await (await TrackingWallet(self.proto,mode='w')).remove_address(mmgen_or_coin_addr) # returns None on failure
|
||||
# returns None on failure:
|
||||
ret = await (await TrackingWallet(self.proto,mode='w')).remove_address(mmgen_or_coin_addr)
|
||||
if ret:
|
||||
from ..util import msg
|
||||
msg(f'Address {ret!r} deleted from tracking wallet')
|
||||
|
|
|
|||
|
|
@ -221,27 +221,31 @@ class TwCommon:
|
|||
async def view_and_sort(self):
|
||||
from ..opts import opt
|
||||
from ..term import get_char
|
||||
self.prompt = type(self).prompt.strip() + '\b'
|
||||
prompt = self.prompt.strip() + '\b'
|
||||
self.no_output = False
|
||||
self.oneshot_msg = None
|
||||
self.interactive = True
|
||||
immed_chars = ''.join(self.key_mappings.keys())
|
||||
|
||||
CUR_RIGHT = lambda n: f'\033[{n}C'
|
||||
CUR_HOME = '\033[H'
|
||||
ERASE_ALL = '\033[0J'
|
||||
self.cursor_to_end_of_prompt = CUR_RIGHT( len(prompt.split('\n')[-1]) - 2 )
|
||||
clear_screen = '\n\n' if (opt.no_blank or g.test_suite) else CUR_HOME + ERASE_ALL
|
||||
|
||||
while True:
|
||||
msg_r('' if self.no_output else '\n\n' if (opt.no_blank or g.test_suite) else CUR_HOME+ERASE_ALL)
|
||||
reply = get_char(
|
||||
'' if self.no_output else (
|
||||
await self.format_squeezed()
|
||||
clear_screen
|
||||
+ await self.format_squeezed()
|
||||
+ '\n'
|
||||
+ (self.oneshot_msg or '')
|
||||
+ self.prompt
|
||||
+ prompt
|
||||
),
|
||||
immed_chars = ''.join(self.key_mappings.keys())
|
||||
)
|
||||
immed_chars = immed_chars )
|
||||
self.no_output = False
|
||||
self.oneshot_msg = '' if self.oneshot_msg else None # tristate, saves previous state
|
||||
if reply not in self.key_mappings:
|
||||
if reply not in immed_chars:
|
||||
msg_r('\ninvalid keypress ')
|
||||
await asyncio.sleep(0.3)
|
||||
continue
|
||||
|
|
@ -318,8 +322,7 @@ class TwCommon:
|
|||
|
||||
def post_view(self,parent):
|
||||
if g.platform == 'linux' and parent.oneshot_msg == None:
|
||||
CUR_RIGHT = lambda n: f'\033[{n}C'
|
||||
msg_r(CUR_RIGHT(len(parent.prompt.split('\n')[-1])-2))
|
||||
msg_r(parent.cursor_to_end_of_prompt)
|
||||
parent.no_output = True
|
||||
|
||||
class item_action:
|
||||
|
|
|
|||
|
|
@ -234,9 +234,9 @@ class TrackingWallet(MMGenObject,metaclass=AsyncInit):
|
|||
coinaddr = (await TwAddrData(self.proto)).mmaddr2coinaddr(mmaddr)
|
||||
|
||||
try:
|
||||
if not is_mmgen_id(self.proto,arg1):
|
||||
assert coinaddr, f'Invalid coin address for this chain: {arg1}'
|
||||
assert coinaddr, f'{g.proj_name} address {mmaddr!r} not found in tracking wallet'
|
||||
assert coinaddr, (
|
||||
f'{g.proj_name} address {mmaddr!r} not found in tracking wallet' if mmaddr else
|
||||
f'Invalid coin address for this chain: {addrspec}' )
|
||||
assert await self.is_in_wallet(coinaddr), f'Address {coinaddr!r} not found in tracking wallet'
|
||||
except Exception as e:
|
||||
msg(str(e))
|
||||
|
|
@ -268,8 +268,8 @@ class TrackingWallet(MMGenObject,metaclass=AsyncInit):
|
|||
return False
|
||||
else:
|
||||
desc = '{} address {} in tracking wallet'.format(
|
||||
mmaddr.type.replace('mmg','MMG'),
|
||||
mmaddr.replace(self.proto.base_coin.lower()+':','') )
|
||||
res.mmaddr.type.replace('mmgen','MMGen'),
|
||||
res.mmaddr.replace(self.proto.base_coin.lower()+':','') )
|
||||
if label:
|
||||
msg(f'Added label {label!r} to {desc}')
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ def fmt_list(iterable,fmt='dfl',indent=''):
|
|||
'min': (",", "'", "'"),
|
||||
'col': ('\n'+indent, indent, '' ),
|
||||
}[fmt]
|
||||
return lq + sep.join(iterable) + rq
|
||||
return lq + sep.join(str(i) for i in iterable) + rq
|
||||
|
||||
def list_gen(*data):
|
||||
"""
|
||||
|
|
@ -464,8 +464,8 @@ def make_full_path(outdir,outfile):
|
|||
return os.path.normpath(os.path.join(outdir, os.path.basename(outfile)))
|
||||
|
||||
def confirm_or_raise(message,action,expect='YES',exit_msg='Exiting at user request'):
|
||||
if message.strip():
|
||||
msg(message.strip())
|
||||
if message:
|
||||
msg(message)
|
||||
if line_input(
|
||||
(f'{action} ' if action[0].isupper() else f'Are you sure you want to {action}?\n') +
|
||||
f'Type uppercase {expect!r} to confirm: '
|
||||
|
|
|
|||
|
|
@ -198,8 +198,8 @@ class TestSuiteRegtest(TestSuiteBase,TestSuiteShared):
|
|||
('bob_bal3', "Bob's balance"),
|
||||
('bob_pre_import', 'sending to non-imported address'),
|
||||
('generate', 'mining a block'),
|
||||
('bob_import_addr', 'importing non-MMGen address with --rescan'),
|
||||
('bob_bal4', "Bob's balance (after import with rescan)"),
|
||||
('bob_import_addr', 'importing non-MMGen address'),
|
||||
('bob_bal4', "Bob's balance (after import)"),
|
||||
('bob_import_list', 'importing flat address list'),
|
||||
('bob_import_list_rescan', 'importing flat address list with --rescan'),
|
||||
('bob_split2', "splitting Bob's funds"),
|
||||
|
|
@ -421,7 +421,9 @@ class TestSuiteRegtest(TestSuiteBase,TestSuiteShared):
|
|||
def bob_import_miner_addr(self):
|
||||
if not self.deterministic:
|
||||
return 'skip'
|
||||
return self.spawn('mmgen-addrimport', [ '--bob', '--rescan', '--quiet', f'--address={self.miner_addr}' ])
|
||||
return self.spawn(
|
||||
'mmgen-addrimport',
|
||||
[ '--bob', '--rescan', '--quiet', f'--address={self.miner_addr}' ] )
|
||||
|
||||
def fund_wallet_deterministic(self,user,addr,utxo_nums,skip_passphrase=False):
|
||||
"""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue