update for MMGen v13.3.dev42
This commit is contained in:
parent
eecf8acd0d
commit
30d8a4a871
18 changed files with 147 additions and 157 deletions
|
|
@ -109,7 +109,7 @@ class BlocksInfo:
|
|||
def parse_cslist(cls,uarg,full_set,dfl_set,desc):
|
||||
|
||||
def make_list(m,func):
|
||||
groups_lc = [set(e.lower() for e in g.split(',')) for g in m.groups()]
|
||||
groups_lc = [set(e.lower() for e in gi.split(',')) for gi in m.groups()]
|
||||
for group in groups_lc:
|
||||
for e in group:
|
||||
if e not in full_set_lc:
|
||||
|
|
@ -135,7 +135,7 @@ class BlocksInfo:
|
|||
else:
|
||||
die(1,f'{uarg}: invalid parameter')
|
||||
|
||||
def __init__(self,cmd_args,opt,rpc):
|
||||
def __init__(self,cfg,cmd_args,rpc):
|
||||
|
||||
def parse_cs_uarg(uarg,full_set,dfl_set,desc):
|
||||
return (
|
||||
|
|
@ -144,10 +144,10 @@ class BlocksInfo:
|
|||
)
|
||||
|
||||
def get_fields():
|
||||
return parse_cs_uarg(opt.fields,list(self.fields),self.dfl_fields,'field')
|
||||
return parse_cs_uarg(self.cfg.fields,list(self.fields),self.dfl_fields,'field')
|
||||
|
||||
def get_stats():
|
||||
return parse_cs_uarg(opt.stats.lower(),self.all_stats,self.dfl_stats,'stat')
|
||||
return parse_cs_uarg(self.cfg.stats.lower(),self.all_stats,self.dfl_stats,'stat')
|
||||
|
||||
def parse_cmd_args(): # => (block_list, first, last, step)
|
||||
if not cmd_args:
|
||||
|
|
@ -163,8 +163,8 @@ class BlocksInfo:
|
|||
else:
|
||||
return ([self.conv_blkspec(a) for a in cmd_args],None,None,None)
|
||||
|
||||
self.cfg = cfg
|
||||
self.rpc = rpc
|
||||
self.opt = opt
|
||||
self.tip = rpc.blockcount
|
||||
|
||||
from_satoshi = self.rpc.proto.coin_amt.satoshi
|
||||
|
|
@ -198,7 +198,7 @@ class BlocksInfo:
|
|||
'di': lambda arg: '{:.2e}'.format(arg),
|
||||
}
|
||||
|
||||
if g.coin == 'BCH':
|
||||
if self.cfg.coin == 'BCH':
|
||||
self.fmt_funcs.update({
|
||||
'su': lambda arg: str(arg).rstrip('0').rstrip('.'),
|
||||
'fe': lambda arg: str(int(arg * to_satoshi)),
|
||||
|
|
@ -206,26 +206,26 @@ class BlocksInfo:
|
|||
})
|
||||
|
||||
self.fnames = tuple(
|
||||
[f for f in self.fields if self.fields[f].src == 'bh' or f == 'interval'] if opt.header_info else
|
||||
get_fields() if opt.fields else
|
||||
[f for f in self.fields if self.fields[f].src == 'bh' or f == 'interval'] if self.cfg.header_info else
|
||||
get_fields() if self.cfg.fields else
|
||||
self.dfl_fields
|
||||
)
|
||||
if opt.miner_info and 'miner' not in self.fnames:
|
||||
if self.cfg.miner_info and 'miner' not in self.fnames:
|
||||
self.fnames += ('miner',)
|
||||
|
||||
self.stats = get_stats() if opt.stats else self.dfl_stats
|
||||
self.stats = get_stats() if self.cfg.stats else self.dfl_stats
|
||||
|
||||
# Display diff stats by default only if user-requested range ends with chain tip
|
||||
if 'diff' in self.stats and not opt.stats and self.last != self.tip:
|
||||
if 'diff' in self.stats and not self.cfg.stats and self.last != self.tip:
|
||||
self.stats.remove('diff')
|
||||
|
||||
if {'avg','col_avg'} <= set(self.stats) and opt.stats_only:
|
||||
if {'avg','col_avg'} <= set(self.stats) and self.cfg.stats_only:
|
||||
self.stats.remove('col_avg')
|
||||
|
||||
if {'avg','mini_avg'} <= set(self.stats):
|
||||
self.stats.remove('mini_avg')
|
||||
|
||||
if opt.full_stats:
|
||||
if self.cfg.full_stats:
|
||||
add_fnames = {fname for sname in self.stats for fname in self.stats_deps[sname]}
|
||||
self.fnames = tuple(f for f in self.fields if f in {'block'} | set(self.fnames) | add_fnames )
|
||||
else:
|
||||
|
|
@ -397,7 +397,7 @@ class BlocksInfo:
|
|||
self.t_cur = self.prev_hdrs[n]['time']
|
||||
ret = await self.process_block(self.hdrs[n])
|
||||
self.res.append(ret)
|
||||
if self.fnames and not self.opt.stats_only:
|
||||
if self.fnames and not self.cfg.stats_only:
|
||||
self.output_block(ret,n)
|
||||
|
||||
def output_block(self,data,n):
|
||||
|
|
@ -447,7 +447,7 @@ class BlocksInfo:
|
|||
return '---'
|
||||
else:
|
||||
cb = bytes.fromhex(bd['vin'][0]['coinbase'])
|
||||
if self.opt.raw_miner_info:
|
||||
if self.cfg.raw_miner_info:
|
||||
return repr(cb)
|
||||
else:
|
||||
trmap_in = {
|
||||
|
|
@ -670,7 +670,7 @@ class BlocksInfo:
|
|||
return ( sname, (d.hdr,) + tuple(gen()) )
|
||||
|
||||
def process_stats_pre(self,i):
|
||||
if (self.fnames and not self.opt.stats_only) or i != 0:
|
||||
if (self.fnames and not self.cfg.stats_only) or i != 0:
|
||||
Msg('')
|
||||
|
||||
def finalize_output(self): pass
|
||||
|
|
@ -707,9 +707,9 @@ class BlocksInfo:
|
|||
|
||||
class JSONBlocksInfo(BlocksInfo):
|
||||
|
||||
def __init__(self,cmd_args,opt,rpc):
|
||||
super().__init__(cmd_args,opt,rpc)
|
||||
if opt.json_raw:
|
||||
def __init__(self,cfg,cmd_args,opt,rpc):
|
||||
super().__init__(cfg,cmd_args,opt,rpc)
|
||||
if self.cfg.json_raw:
|
||||
self.output_block = self.output_block_raw
|
||||
self.fmt_stat_item = self.fmt_stat_item_raw
|
||||
Msg_r('{')
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ mmgen_node_tools.PeerBlocks: List blocks in flight, disconnect stalling nodes
|
|||
|
||||
import asyncio
|
||||
from collections import namedtuple
|
||||
from mmgen.globalvars import g
|
||||
from mmgen.util import msg,msg_r,is_int
|
||||
from mmgen.term import get_term,get_terminal_size,get_char
|
||||
from mmgen.ui import line_input
|
||||
|
|
@ -30,15 +29,15 @@ class Display(PollDisplay):
|
|||
|
||||
poll_secs = 2
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self,cfg):
|
||||
|
||||
super().__init__()
|
||||
super().__init__(cfg)
|
||||
|
||||
global term,term_width
|
||||
if not term:
|
||||
term = get_term()
|
||||
term.init(noecho=True)
|
||||
term_width = g.columns or get_terminal_size().width
|
||||
term_width = self.cfg.columns or get_terminal_size().width
|
||||
msg_r(CUR_HOME+ERASE_ALL+CUR_HOME)
|
||||
|
||||
async def get_info(self,rpc):
|
||||
|
|
@ -69,7 +68,7 @@ class Display(PollDisplay):
|
|||
msg('')
|
||||
term.reset()
|
||||
# readline required for correct operation here; without it, user must re-type first digit
|
||||
ret = line_input('peer number> ',insert_txt=s,hold_protect=False)
|
||||
ret = line_input( self.cfg, 'peer number> ', insert_txt=s, hold_protect=False )
|
||||
term.init(noecho=True)
|
||||
self.enable_display = False # prevent display from updating before process_input()
|
||||
return ret
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ class PollDisplay():
|
|||
input = None
|
||||
poll_secs = 1
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self,cfg):
|
||||
self.cfg = cfg
|
||||
self.info_lock = threading.Lock() # self.info accessed by 2 threads
|
||||
self.display_kill_flag = threading.Event()
|
||||
|
||||
|
|
|
|||
|
|
@ -28,10 +28,8 @@ import sys,os,time,json,yaml
|
|||
from subprocess import run,PIPE,CalledProcessError
|
||||
from decimal import Decimal
|
||||
from collections import namedtuple
|
||||
from mmgen.opts import opt
|
||||
from mmgen.globalvars import g
|
||||
from mmgen.color import *
|
||||
from mmgen.util import die,fmt_list,msg,msg_r,Msg,vmsg,suf,fmt,stdout_or_pager
|
||||
from mmgen.util import die,fmt_list,msg,msg_r,suf,fmt
|
||||
|
||||
homedir = os.getenv('HOME')
|
||||
cachedir = os.path.join(homedir,'.cache','mmgen-node-tools')
|
||||
|
|
@ -173,23 +171,23 @@ def get_src_data(curl_cmd):
|
|||
|
||||
if cfg.btc_only:
|
||||
fn = os.path.join(cfg.cachedir,'ticker-btc.json')
|
||||
timeout = 5 if g.test_suite else btc_ratelimit
|
||||
timeout = 5 if gcfg.test_suite else btc_ratelimit
|
||||
else:
|
||||
fn = os.path.join(cfg.cachedir,'ticker.json')
|
||||
timeout = 5 if g.test_suite else ratelimit
|
||||
timeout = 5 if gcfg.test_suite else ratelimit
|
||||
|
||||
fn_rel = os.path.relpath(fn,start=homedir)
|
||||
|
||||
if not os.path.exists(fn):
|
||||
open(fn,'w').write('{}')
|
||||
|
||||
if opt.cached_data:
|
||||
if gcfg.cached_data:
|
||||
json_text = open(fn).read()
|
||||
else:
|
||||
elapsed = int(time.time() - os.stat(fn).st_mtime)
|
||||
if elapsed >= timeout:
|
||||
msg_r(f'Fetching data from {api_host}...')
|
||||
vmsg('')
|
||||
gcfg._util.vmsg('')
|
||||
try:
|
||||
cp = run(curl_cmd,check=True,stdout=PIPE)
|
||||
except CalledProcessError as e:
|
||||
|
|
@ -212,14 +210,14 @@ def get_src_data(curl_cmd):
|
|||
die(2,'Retrieved data is not valid JSON, exiting')
|
||||
|
||||
if not data:
|
||||
if opt.cached_data:
|
||||
if gcfg.cached_data:
|
||||
die(1,'No cached data! Run command without --cached-data option to retrieve data from remote host')
|
||||
else:
|
||||
die(2,'Remote host returned no data!')
|
||||
elif 'error' in data:
|
||||
die(1,data['error'])
|
||||
|
||||
if opt.cached_data:
|
||||
if gcfg.cached_data:
|
||||
msg(f'Using cached data from ~/{fn_rel}')
|
||||
else:
|
||||
open(fn,'w').write(json_text)
|
||||
|
|
@ -248,7 +246,7 @@ def main(cfg_parm,cfg_in_parm):
|
|||
'--header', 'Accept: application/json',
|
||||
] +
|
||||
(['--proxy', cfg.proxy] if cfg.proxy else []) +
|
||||
(['--silent'] if not opt.verbose else []) +
|
||||
(['--silent'] if not gcfg.verbose else []) +
|
||||
[api_url + ('/btc-bitcoin' if cfg.btc_only else '')]
|
||||
)
|
||||
|
||||
|
|
@ -264,27 +262,27 @@ def main(cfg_parm,cfg_in_parm):
|
|||
update_sample_file(cfg_in.cfg_file)
|
||||
update_sample_file(cfg_in.portfolio_file)
|
||||
|
||||
if opt.portfolio and not cfg_in.portfolio:
|
||||
if gcfg.portfolio and not cfg_in.portfolio:
|
||||
die(1,'No portfolio configured!\nTo configure a portfolio, edit the file ~/{}'.format(
|
||||
os.path.relpath(cfg_in.portfolio_file,start=homedir)))
|
||||
|
||||
curl_cmd = get_curl_cmd()
|
||||
|
||||
if opt.print_curl:
|
||||
if gcfg.print_curl:
|
||||
Msg(curl_cmd + '\n' + ' '.join(curl_cmd))
|
||||
return
|
||||
|
||||
parsed_json = [get_src_data(curl_cmd)] if cfg.btc_only else get_src_data(curl_cmd)
|
||||
|
||||
if opt.list_ids:
|
||||
if gcfg.list_ids:
|
||||
from mmgen.ui import do_pager
|
||||
do_pager('\n'.join(e['id'] for e in parsed_json))
|
||||
return
|
||||
|
||||
global now
|
||||
now = 1659465400 if g.test_suite else time.time() # 1659524400 1659445900
|
||||
now = 1659465400 if gcfg.test_suite else time.time() # 1659524400 1659445900
|
||||
|
||||
stdout_or_pager(
|
||||
gcfg._util.stdout_or_pager(
|
||||
'\n'.join(getattr(Ticker,cfg.clsname)(dict(gen_data(parsed_json))).gen_output()) + '\n'
|
||||
)
|
||||
|
||||
|
|
@ -366,12 +364,12 @@ def make_cfg(cmd_args,cfg_in):
|
|||
usr_columns )
|
||||
|
||||
def get_portfolio_assets(ret=()):
|
||||
if cfg_in.portfolio and opt.portfolio:
|
||||
if cfg_in.portfolio and gcfg.portfolio:
|
||||
ret = (parse_asset_id(e,True) for e in cfg_in.portfolio)
|
||||
return ( 'portfolio', tuple(e for e in ret if (not opt.btc) or e.symbol == 'BTC') )
|
||||
return ( 'portfolio', tuple(e for e in ret if (not gcfg.btc) or e.symbol == 'BTC') )
|
||||
|
||||
def get_portfolio():
|
||||
return {k:Decimal(v) for k,v in cfg_in.portfolio.items() if (not opt.btc) or k == 'btc-bitcoin'}
|
||||
return {k:Decimal(v) for k,v in cfg_in.portfolio.items() if (not gcfg.btc) or k == 'btc-bitcoin'}
|
||||
|
||||
def parse_add_precision(s):
|
||||
if not s:
|
||||
|
|
@ -385,8 +383,8 @@ def make_cfg(cmd_args,cfg_in):
|
|||
def create_rows():
|
||||
rows = (
|
||||
('trade_pair',) + query if (query and query.to_asset) else
|
||||
('bitcoin',parse_asset_id('btc-bitcoin')) if opt.btc else
|
||||
get_rows_from_cfg( add_data={'fiat':['usd-us-dollar']} if opt.add_columns else None )
|
||||
('bitcoin',parse_asset_id('btc-bitcoin')) if gcfg.btc else
|
||||
get_rows_from_cfg( add_data={'fiat':['usd-us-dollar']} if gcfg.add_columns else None )
|
||||
)
|
||||
|
||||
for hdr,data in (
|
||||
|
|
@ -416,8 +414,8 @@ def make_cfg(cmd_args,cfg_in):
|
|||
asset_data = namedtuple('asset_data',['symbol','id','amount','rate','rate_asset'])
|
||||
asset_tuple = namedtuple('asset_tuple',['symbol','id'])
|
||||
|
||||
usr_rows = parse_usr_asset_arg(opt.add_rows)
|
||||
usr_columns = parse_usr_asset_arg(opt.add_columns)
|
||||
usr_rows = parse_usr_asset_arg(gcfg.add_rows)
|
||||
usr_columns = parse_usr_asset_arg(gcfg.add_columns)
|
||||
query = parse_query_arg(cmd_args[0]) if cmd_args else None
|
||||
|
||||
return cfg_tuple(
|
||||
|
|
@ -425,19 +423,19 @@ def make_cfg(cmd_args,cfg_in):
|
|||
usr_rows = usr_rows,
|
||||
usr_columns = usr_columns,
|
||||
query = query,
|
||||
adjust = ( lambda x: (100 + x) / 100 if x else 1 )( Decimal(opt.adjust or 0) ),
|
||||
adjust = ( lambda x: (100 + x) / 100 if x else 1 )( Decimal(gcfg.adjust or 0) ),
|
||||
clsname = 'trading' if query else 'overview',
|
||||
btc_only = opt.btc,
|
||||
add_prec = parse_add_precision(opt.add_precision),
|
||||
cachedir = opt.cachedir or cfg_in.cfg.get('cachedir') or cachedir,
|
||||
proxy = None if opt.proxy == '' else (opt.proxy or cfg_in.cfg.get('proxy')),
|
||||
portfolio = get_portfolio() if cfg_in.portfolio and opt.portfolio and not query else None
|
||||
btc_only = gcfg.btc,
|
||||
add_prec = parse_add_precision(gcfg.add_precision),
|
||||
cachedir = gcfg.cachedir or cfg_in.cfg.get('cachedir') or cachedir,
|
||||
proxy = None if gcfg.proxy == '' else (gcfg.proxy or cfg_in.cfg.get('proxy')),
|
||||
portfolio = get_portfolio() if cfg_in.portfolio and gcfg.portfolio and not query else None
|
||||
)
|
||||
|
||||
def get_cfg_in():
|
||||
ret = namedtuple('cfg_in_data',['cfg','portfolio','cfg_file','portfolio_file'])
|
||||
cfg_file,portfolio_file = (
|
||||
[os.path.join(g.data_dir_root,'node_tools',fn) for fn in (cfg_fn,portfolio_fn)]
|
||||
[os.path.join(gcfg.data_dir_root,'node_tools',fn) for fn in (cfg_fn,portfolio_fn)]
|
||||
)
|
||||
cfg_data,portfolio_data = (
|
||||
[yaml.safe_load(open(fn).read()) if os.path.exists(fn) else None for fn in (cfg_file,portfolio_file)]
|
||||
|
|
@ -466,10 +464,10 @@ class Ticker:
|
|||
|
||||
def __init__(self,data):
|
||||
|
||||
self.comma = ',' if opt.thousands_comma else ''
|
||||
self.comma = ',' if gcfg.thousands_comma else ''
|
||||
|
||||
self.col1_wid = max(len('TOTAL'),(
|
||||
max(len(self.create_label(d['id'])) for d in data.values()) if opt.name_labels else
|
||||
max(len(self.create_label(d['id'])) for d in data.values()) if gcfg.name_labels else
|
||||
max(len(d['symbol']) for d in data.values())
|
||||
)) + 1
|
||||
|
||||
|
|
@ -482,7 +480,7 @@ class Ticker:
|
|||
|
||||
def format_last_update_col(self,cross_assets=()):
|
||||
|
||||
if opt.elapsed:
|
||||
if gcfg.elapsed:
|
||||
from mmgen.util2 import format_elapsed_hr
|
||||
fmt_func = format_elapsed_hr
|
||||
else:
|
||||
|
|
@ -627,7 +625,7 @@ class Ticker:
|
|||
amt_fmt = amt_fmt.rstrip('0').rstrip('.')
|
||||
|
||||
return self.fs_num.format(
|
||||
lbl = (self.create_label(d['id']) if opt.name_labels else d['symbol']),
|
||||
lbl = (self.create_label(d['id']) if gcfg.name_labels else d['symbol']),
|
||||
pc1 = fmt_pct(d.get('percent_change_7d')),
|
||||
pc2 = fmt_pct(d.get('percent_change_24h')),
|
||||
upd = d.get('last_updated_fmt'),
|
||||
|
|
@ -670,13 +668,13 @@ class Ticker:
|
|||
[asset.id for asset in self.usr_col_assets] +
|
||||
[a for a,b in (
|
||||
( 'btc-bitcoin', not cfg.btc_only ),
|
||||
( 'pct7d', opt.percent_change ),
|
||||
( 'pct24h', opt.percent_change ),
|
||||
( 'update_time', opt.update_time ),
|
||||
( 'pct7d', gcfg.percent_change ),
|
||||
( 'pct24h', gcfg.percent_change ),
|
||||
( 'update_time', gcfg.update_time ),
|
||||
) if b]
|
||||
)
|
||||
cols2 = list(cols)
|
||||
if opt.update_time:
|
||||
if gcfg.update_time:
|
||||
cols2.pop()
|
||||
cols2.append('amt')
|
||||
|
||||
|
|
@ -759,7 +757,7 @@ class Ticker:
|
|||
if self.show_adj:
|
||||
self.fs_str += ' {p_adj}'
|
||||
self.hl_wid += self.max_wid + 1
|
||||
if opt.update_time:
|
||||
if gcfg.update_time:
|
||||
self.fs_str += ' {upd}'
|
||||
self.hl_wid += self.upd_w + 2
|
||||
|
||||
|
|
@ -772,7 +770,7 @@ class Ticker:
|
|||
if self.show_adj else '' )
|
||||
|
||||
return self.fs_str.format(
|
||||
lbl = (self.create_label(id) if opt.name_labels else d['symbol']),
|
||||
lbl = (self.create_label(id) if gcfg.name_labels else d['symbol']),
|
||||
p_spot = green(p_spot) if id in self.hl_ids else p_spot,
|
||||
p_adj = yellow(p_adj) if id in self.hl_ids else p_adj,
|
||||
upd = d.get('last_updated_fmt'),
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
3.1.dev14
|
||||
3.1.dev15
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ def do_output_tabular(proto,addr_data,blk_hdrs):
|
|||
|
||||
fs = (
|
||||
' {n:>%s} {a} {u} {b:>%s} {t:19} {B:>%s} {T:19} {A}' % (col1w,max(5,fb_w),max(4,lb_w))
|
||||
if opt.first_block else
|
||||
if cfg.first_block else
|
||||
' {n:>%s} {a} {u} {B:>%s} {T:19} {A}' % (col1w,max(4,lb_w)) )
|
||||
|
||||
Msg('\n' + fs.format(
|
||||
|
|
@ -109,20 +109,19 @@ def do_output_tabular(proto,addr_data,blk_hdrs):
|
|||
|
||||
async def main(req_addrs):
|
||||
|
||||
from mmgen.protocol import init_proto_from_opts
|
||||
proto = init_proto_from_opts(need_amt=True)
|
||||
proto = cfg._proto
|
||||
|
||||
from mmgen.addr import CoinAddr
|
||||
addrs = [CoinAddr(proto,addr) for addr in req_addrs]
|
||||
|
||||
from mmgen.rpc import rpc_init
|
||||
rpc = await rpc_init(proto)
|
||||
rpc = await rpc_init( cfg, proto )
|
||||
|
||||
height = await rpc.call('getblockcount')
|
||||
Msg(f'{proto.coin} {proto.network.upper()} [height {height}]')
|
||||
|
||||
from mmgen.proto.btc.misc import scantxoutset
|
||||
res = await scantxoutset( rpc, [f'addr({addr})' for addr in addrs] )
|
||||
res = await scantxoutset( cfg, rpc, [f'addr({addr})' for addr in addrs] )
|
||||
|
||||
if not res['success']:
|
||||
die(1,'UTXO scanning failed or was interrupted')
|
||||
|
|
@ -155,16 +154,16 @@ async def main(req_addrs):
|
|||
blk_hashes = await rpc.batch_call('getblockhash', [(h,) for h in blk_heights])
|
||||
blk_hdrs = await rpc.batch_call('getblockheader', [(H,) for H in blk_hashes])
|
||||
|
||||
(do_output_tabular if opt.tabular else do_output)( proto, addr_data, dict(zip(blk_heights,blk_hdrs)) )
|
||||
(do_output_tabular if cfg.tabular else do_output)( proto, addr_data, dict(zip(blk_heights,blk_hdrs)) )
|
||||
|
||||
cmd_args = opts.init(opts_data,init_opts={'rpc_backend':'aiohttp'})
|
||||
cfg = opts.init(opts_data,init_opts={'rpc_backend':'aiohttp'})
|
||||
|
||||
if len(cmd_args) < 1:
|
||||
if len(cfg._args) < 1:
|
||||
die(1,'This command requires at least one coin address argument')
|
||||
|
||||
from mmgen.obj import CoinTxID,Int
|
||||
|
||||
try:
|
||||
async_run(main(cmd_args))
|
||||
async_run(main(cfg._args))
|
||||
except KeyboardInterrupt:
|
||||
sys.stderr.write('\n')
|
||||
|
|
|
|||
|
|
@ -20,7 +20,9 @@
|
|||
mmnode-blocks-info: Display information about a block or range of blocks
|
||||
"""
|
||||
|
||||
from mmgen.common import *
|
||||
import mmgen.opts as opts
|
||||
from mmgen.globalvars import gc
|
||||
from mmgen.util import async_run,fmt_list
|
||||
from .BlocksInfo import BlocksInfo,JSONBlocksInfo
|
||||
|
||||
opts_data = {
|
||||
|
|
@ -146,29 +148,26 @@ EXAMPLES:
|
|||
This program requires a txindex-enabled daemon for correct operation.
|
||||
""" },
|
||||
'code': {
|
||||
'notes': lambda proto,s: s.format(
|
||||
'notes': lambda cfg,proto,s: s.format(
|
||||
I = proto.diff_adjust_interval,
|
||||
F = fmt_list(BlocksInfo.fields,fmt='bare'),
|
||||
S = fmt_list(BlocksInfo.all_stats,fmt='bare'),
|
||||
p = g.prog_name,
|
||||
p = gc.prog_name,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
cmd_args = opts.init(opts_data)
|
||||
cfg = opts.init(opts_data)
|
||||
|
||||
async def main():
|
||||
|
||||
from mmgen.protocol import init_proto_from_opts
|
||||
from mmgen.rpc import rpc_init
|
||||
|
||||
proto = init_proto_from_opts(need_amt=True)
|
||||
cls = JSONBlocksInfo if cfg.json else BlocksInfo
|
||||
|
||||
cls = JSONBlocksInfo if opt.json else BlocksInfo
|
||||
m = cls( cfg, cfg._args, await rpc_init(cfg,cfg._proto) )
|
||||
|
||||
m = cls( cmd_args, opt, await rpc_init(proto) )
|
||||
|
||||
if m.fnames and not opt.no_header:
|
||||
if m.fnames and not cfg.no_header:
|
||||
m.print_header()
|
||||
|
||||
await m.process_blocks()
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ fee_brackets = [
|
|||
100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 2100000000000000,
|
||||
]
|
||||
|
||||
opts.init({
|
||||
cfg = opts.init({
|
||||
'sets': [
|
||||
('detail',True,'ranges',True),
|
||||
('detail',True,'show_mb_col',True),
|
||||
|
|
@ -78,17 +78,17 @@ factors.
|
|||
}
|
||||
})
|
||||
|
||||
if opt.ignore_below:
|
||||
if opt.show_empty:
|
||||
if cfg.ignore_below:
|
||||
if cfg.show_empty:
|
||||
die(1,'Conflicting options: --ignore-below, --show-empty')
|
||||
ignore_below = parse_bytespec(opt.ignore_below)
|
||||
ignore_below = parse_bytespec(cfg.ignore_below)
|
||||
|
||||
precision = (
|
||||
check_int_between(opt.precision,min_prec,max_prec,'--precision arg')
|
||||
if opt.precision else dfl_prec )
|
||||
check_int_between(cfg.precision,min_prec,max_prec,'--precision arg')
|
||||
if cfg.precision else dfl_prec )
|
||||
|
||||
from mmgen.term import get_terminal_size
|
||||
width = g.columns or get_terminal_size().width
|
||||
width = cfg.columns or get_terminal_size().width
|
||||
|
||||
class fee_bracket:
|
||||
def __init__(self,top,bottom):
|
||||
|
|
@ -103,6 +103,7 @@ def log(data,fn):
|
|||
from mmgen.rpc import json_encoder
|
||||
from mmgen.fileutil import write_data_to_file
|
||||
write_data_to_file(
|
||||
cfg = cfg,
|
||||
outfile = fn,
|
||||
data = json.dumps(data,cls=json_encoder,sort_keys=True,indent=4),
|
||||
desc = 'mempool',
|
||||
|
|
@ -130,9 +131,9 @@ def create_data(coin_amt,mempool):
|
|||
# calculate cumulative byte totals, filter rows:
|
||||
tBytes = 0
|
||||
for i in out:
|
||||
if not (i.tx_bytes or opt.show_empty):
|
||||
if not (i.tx_bytes or cfg.show_empty):
|
||||
i.skip = True
|
||||
if opt.ignore_below and i.tx_bytes < ignore_below:
|
||||
if cfg.ignore_below and i.tx_bytes < ignore_below:
|
||||
i.skip = True
|
||||
i.tx_bytes_cum = tBytes
|
||||
tBytes += i.tx_bytes
|
||||
|
|
@ -150,15 +151,15 @@ def gen_header(host,mempool,blockcount):
|
|||
TX count: {len(mempool)}
|
||||
""")).strip()
|
||||
|
||||
if opt.show_empty:
|
||||
if cfg.show_empty:
|
||||
yield('Displaying all fee brackets')
|
||||
elif opt.ignore_below:
|
||||
elif cfg.ignore_below:
|
||||
yield('Ignoring fee brackets with less than {:,} bytes ({})'.format(
|
||||
ignore_below,
|
||||
int2bytespec(ignore_below,'MB','0.6',strip=True,add_space=True),
|
||||
))
|
||||
|
||||
if opt.include_current:
|
||||
if cfg.include_current:
|
||||
yield('Including transactions in current fee bracket in Total MB amounts')
|
||||
|
||||
def fmt_mb(n):
|
||||
|
|
@ -168,11 +169,11 @@ def gen_body(data):
|
|||
tx_bytes_max = max((i.tx_bytes for i in data),default=0)
|
||||
top_max = max((i.top for i in data),default=0)
|
||||
bot_max = max((i.bottom for i in data),default=0)
|
||||
col1_w = max(len(f'{bot_max}-{top_max}') if opt.ranges else len(f'{top_max}'),6)
|
||||
col2_w = len(fmt_mb(tx_bytes_max)) if opt.show_mb_col else 0
|
||||
col1_w = max(len(f'{bot_max}-{top_max}') if cfg.ranges else len(f'{top_max}'),6)
|
||||
col2_w = len(fmt_mb(tx_bytes_max)) if cfg.show_mb_col else 0
|
||||
col3_w = len(fmt_mb(data[-1].tx_bytes_cum)) if data else 0
|
||||
col4_w = width - col1_w - col2_w - col3_w - (4 if col2_w else 3)
|
||||
if opt.show_mb_col:
|
||||
if cfg.show_mb_col:
|
||||
fs = '{a:<%i} {b:>%i} {c:>%i} {d}' % (col1_w,col2_w,col3_w)
|
||||
else:
|
||||
fs = '{a:<%i} {c:>%i} {d}' % (col1_w,col3_w)
|
||||
|
|
@ -182,9 +183,9 @@ def gen_body(data):
|
|||
|
||||
for i in data:
|
||||
if not i.skip:
|
||||
cum_bytes = i.tx_bytes_cum + i.tx_bytes if opt.include_current else i.tx_bytes_cum
|
||||
cum_bytes = i.tx_bytes_cum + i.tx_bytes if cfg.include_current else i.tx_bytes_cum
|
||||
yield(fs.format(
|
||||
a = '{}-{}'.format(i.bottom,i.top) if opt.ranges else i.top,
|
||||
a = '{}-{}'.format(i.bottom,i.top) if cfg.ranges else i.top,
|
||||
b = fmt_mb(i.tx_bytes),
|
||||
c = fmt_mb(cum_bytes),
|
||||
d = '-' * int(col4_w * ( i.tx_bytes / tx_bytes_max )) ))
|
||||
|
|
@ -197,20 +198,19 @@ def gen_body(data):
|
|||
|
||||
async def main():
|
||||
|
||||
from mmgen.protocol import init_proto_from_opts
|
||||
global proto
|
||||
proto = init_proto_from_opts(need_amt=True)
|
||||
proto = cfg._proto
|
||||
|
||||
from mmgen.rpc import rpc_init
|
||||
c = await rpc_init(proto)
|
||||
c = await rpc_init( cfg, proto )
|
||||
|
||||
mempool = await c.call('getrawmempool',True)
|
||||
|
||||
if opt.log:
|
||||
if cfg.log:
|
||||
log(mempool,'mempool.json')
|
||||
|
||||
data = create_data(proto.coin_amt,mempool)
|
||||
stdout_or_pager(
|
||||
cfg._util.stdout_or_pager(
|
||||
'\n'.join(gen_header(
|
||||
c.host,
|
||||
mempool,
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ from mmgen.common import *
|
|||
|
||||
bdr_proj = 9.95
|
||||
|
||||
opts.init({
|
||||
cfg = opts.init({
|
||||
'sets': [('mined',True,'list',True)],
|
||||
'text': {
|
||||
'desc': 'Estimate date(s) of future block subsidy halving(s)',
|
||||
|
|
@ -43,8 +43,8 @@ opts.init({
|
|||
""" }
|
||||
})
|
||||
|
||||
if opt.bdr_proj:
|
||||
bdr_proj = float(opt.bdr_proj)
|
||||
if cfg.bdr_proj:
|
||||
bdr_proj = float(cfg.bdr_proj)
|
||||
|
||||
def date(t):
|
||||
return '{}-{:02}-{:02} {:02}:{:02}:{:02}'.format(*time.gmtime(t)[:6])
|
||||
|
|
@ -61,16 +61,15 @@ def time_diff_warning(t_diff):
|
|||
|
||||
async def main():
|
||||
|
||||
from mmgen.protocol import init_proto_from_opts
|
||||
proto = init_proto_from_opts(need_amt=True)
|
||||
proto = cfg._proto
|
||||
|
||||
from mmgen.rpc import rpc_init
|
||||
c = await rpc_init(proto)
|
||||
c = await rpc_init( cfg, proto )
|
||||
|
||||
tip = await c.call('getblockcount')
|
||||
assert tip > 1, 'block tip must be > 1'
|
||||
remaining = proto.halving_interval - tip % proto.halving_interval
|
||||
sample_size = int(opt.sample_size) if opt.sample_size else min(tip-1,max(remaining,144))
|
||||
sample_size = int(cfg.sample_size) if cfg.sample_size else min(tip-1,max(remaining,144))
|
||||
|
||||
cur,old = await c.gathered_call('getblockstats',((tip,),(tip - sample_size,)))
|
||||
|
||||
|
|
@ -134,7 +133,7 @@ async def main():
|
|||
fs = (
|
||||
' {a:<7} {b:>8} {c:19}{d:2} {e:10} {f}',
|
||||
' {a:<7} {b:>8} {c:19}{d:2} {e:10} {f:17} {g:17} {h}'
|
||||
)[bool(opt.mined)]
|
||||
)[bool(cfg.mined)]
|
||||
|
||||
print(
|
||||
f'Historical/Estimated/Projected Halvings ({proto.coin}):\n\n'
|
||||
|
|
@ -174,7 +173,7 @@ async def main():
|
|||
) for n,sub,blk,mined,total_mined,bdr,t in gen_data())
|
||||
)
|
||||
|
||||
if opt.list:
|
||||
if cfg.list:
|
||||
await print_halvings()
|
||||
else:
|
||||
print_current_stats()
|
||||
|
|
|
|||
|
|
@ -34,17 +34,14 @@ opts_data = {
|
|||
}
|
||||
}
|
||||
|
||||
cmd_args = opts.init(opts_data)
|
||||
cfg = opts.init(opts_data)
|
||||
|
||||
ERASE_LINE,CUR_UP = '\033[K','\033[1A'
|
||||
|
||||
async def main():
|
||||
|
||||
from mmgen.protocol import init_proto_from_opts
|
||||
proto = init_proto_from_opts()
|
||||
|
||||
from mmgen.rpc import rpc_init
|
||||
c = await rpc_init(proto)
|
||||
c = await rpc_init( cfg, cfg._proto )
|
||||
|
||||
async def get_data():
|
||||
d = await c.call('getnettotals')
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
mmnode-peerblocks: List blocks in flight, disconnect stalling nodes
|
||||
"""
|
||||
|
||||
from mmgen.opts import init
|
||||
import mmgen.opts as opts
|
||||
from mmgen.util import async_run
|
||||
|
||||
opts_data = {
|
||||
|
|
@ -36,17 +36,14 @@ opts_data = {
|
|||
|
||||
async def main():
|
||||
|
||||
init(opts_data)
|
||||
|
||||
from mmgen.protocol import init_proto_from_opts
|
||||
proto = init_proto_from_opts()
|
||||
cfg = opts.init(opts_data)
|
||||
|
||||
from mmgen.rpc import rpc_init
|
||||
rpc = await rpc_init(proto)
|
||||
rpc = await rpc_init( cfg, cfg._proto )
|
||||
|
||||
from .PeerBlocks import BlocksDisplay,PeersDisplay
|
||||
blocks = BlocksDisplay()
|
||||
peers = PeersDisplay()
|
||||
blocks = BlocksDisplay(cfg)
|
||||
peers = PeersDisplay(cfg)
|
||||
|
||||
while True:
|
||||
await blocks.run(rpc)
|
||||
|
|
|
|||
|
|
@ -197,12 +197,15 @@ To add a portfolio, edit the file
|
|||
}
|
||||
}
|
||||
|
||||
cmd_args = opts.init(opts_data,do_post_init=True)
|
||||
gcfg = opts.init(opts_data,do_post_init=True)
|
||||
|
||||
import mmgen_node_tools.Ticker as Ticker
|
||||
Ticker.gcfg = gcfg
|
||||
|
||||
cfg_in = get_cfg_in()
|
||||
|
||||
cfg = make_cfg(cmd_args,cfg_in)
|
||||
cfg = make_cfg(gcfg._args,cfg_in)
|
||||
|
||||
opts.post_init()
|
||||
opts.post_init(gcfg)
|
||||
|
||||
main(cfg,cfg_in)
|
||||
|
|
|
|||
|
|
@ -58,14 +58,11 @@ async def main(txid):
|
|||
if len(txid) != 64 or not is_hex_str(txid):
|
||||
die(2,f'{txid}: invalid transaction ID')
|
||||
|
||||
if opt.verbose:
|
||||
if cfg.verbose:
|
||||
msg(f'TxID: {txid}')
|
||||
|
||||
from mmgen.protocol import init_proto_from_opts
|
||||
proto = init_proto_from_opts()
|
||||
|
||||
from mmgen.rpc import rpc_init
|
||||
c = await rpc_init(proto)
|
||||
c = await rpc_init(cfg._proto)
|
||||
|
||||
exitval = 0
|
||||
try:
|
||||
|
|
@ -85,11 +82,11 @@ async def main(txid):
|
|||
|
||||
return exitval
|
||||
|
||||
cmd_args = opts.init(opts_data)
|
||||
cfg = opts.init(opts_data)
|
||||
|
||||
msgs = msg_data['quiet' if opt.quiet else 'normal']
|
||||
msgs = msg_data['quiet' if cfg.quiet else 'normal']
|
||||
|
||||
if len(cmd_args) != 1:
|
||||
if len(cfg._args) != 1:
|
||||
die(1,'One transaction ID must be specified')
|
||||
|
||||
sys.exit(async_run(main(cmd_args[0])))
|
||||
sys.exit(async_run(main(cfg._args[0])))
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ python_requires = >=3.7
|
|||
include_package_data = True
|
||||
|
||||
install_requires =
|
||||
mmgen>=13.3.dev20
|
||||
mmgen>=13.3.dev42
|
||||
|
||||
packages =
|
||||
mmgen_node_tools
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ class TestSuiteMain(TestSuiteBase):
|
|||
f'mmnode-peerblocks',
|
||||
args,
|
||||
pexpect_spawn = pexpect_spawn )
|
||||
if opt.exact_output: # disable echoing of input
|
||||
if cfg.exact_output: # disable echoing of input
|
||||
t.p.logfile = None
|
||||
t.p.logfile_read = sys.stdout
|
||||
if expect_list:
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ class TestSuiteScripts(TestSuiteBase):
|
|||
|
||||
@property
|
||||
def nt_datadir(self):
|
||||
return os.path.join( g.data_dir_root, 'node_tools' )
|
||||
return os.path.join( cfg.data_dir_root, 'node_tools' )
|
||||
|
||||
def ticker_setup(self):
|
||||
self.spawn('',msg_only=True)
|
||||
|
|
@ -120,7 +120,7 @@ class TestSuiteScripts(TestSuiteBase):
|
|||
|
||||
def ticker2(self):
|
||||
t = self.ticker(cached=False)
|
||||
if not opt.skipping_deps:
|
||||
if not cfg.skipping_deps:
|
||||
t.expect('Creating')
|
||||
t.expect('Creating')
|
||||
t.expect('proxy host could not be resolved')
|
||||
|
|
|
|||
|
|
@ -13,8 +13,6 @@ test.test_py_d.ts_regtest: Regtest tests for the test.py test suite
|
|||
"""
|
||||
|
||||
import os
|
||||
from mmgen.globalvars import g
|
||||
from mmgen.opts import opt
|
||||
from mmgen.util import die,gmsg
|
||||
from mmgen.protocol import init_proto
|
||||
from mmgen.proto.btc.regtest import MMGenRegtest
|
||||
|
|
@ -28,7 +26,7 @@ args2 = ['--bob','--rpc-backend=http']
|
|||
|
||||
def gen_addrs(proto,network,keys):
|
||||
from mmgen.tool.api import tool_api
|
||||
tool = tool_api()
|
||||
tool = tool_api(cfg)
|
||||
tool.init_coin(proto.coin,'regtest')
|
||||
tool.addrtype = proto.mmtypes[-1]
|
||||
return [tool.privhex2addr('{:064x}'.format(key)) for key in keys]
|
||||
|
|
@ -105,9 +103,9 @@ class TestSuiteRegtest(TestSuiteBase):
|
|||
return
|
||||
if self.proto.testnet:
|
||||
die(2,'--testnet and --regtest options incompatible with regtest test suite')
|
||||
self.proto = init_proto(self.proto.coin,network='regtest',need_amt=True)
|
||||
self.proto = init_proto( cfg, self.proto.coin, network='regtest', need_amt=True )
|
||||
self.addrs = gen_addrs(self.proto,'regtest',[1,2,3,4,5])
|
||||
self.regtest = MMGenRegtest(self.proto.coin)
|
||||
self.regtest = MMGenRegtest(cfg,self.proto.coin)
|
||||
|
||||
def setup(self):
|
||||
stop_test_daemons(self.proto.network_id,force=True,remove_datadir=True)
|
||||
|
|
@ -128,7 +126,7 @@ class TestSuiteRegtest(TestSuiteBase):
|
|||
return self.halving_calculator(['--help'],['USAGE:'])
|
||||
|
||||
def halving_calculator2(self):
|
||||
return self.halving_calculator([],['Current block: 393',f'Current block subsidy: 12.5 {g.coin}'])
|
||||
return self.halving_calculator([],['Current block: 393',f'Current block subsidy: 12.5 {cfg.coin}'])
|
||||
|
||||
def halving_calculator3(self):
|
||||
return self.halving_calculator(['--list'],['33 4950','0'])
|
||||
|
|
@ -158,7 +156,7 @@ class TestSuiteRegtest(TestSuiteBase):
|
|||
return self.addrbal(
|
||||
args2 + [self.addrs[0]],
|
||||
[
|
||||
f'Balance: 0.357 {g.coin}',
|
||||
f'Balance: 0.357 {cfg.coin}',
|
||||
'2 unspent outputs in 2 blocks',
|
||||
'394','0.123',
|
||||
'395','0.234'
|
||||
|
|
@ -246,7 +244,7 @@ class TestSuiteRegtest(TestSuiteBase):
|
|||
])
|
||||
|
||||
def blocks_info4(self):
|
||||
n1,i1,o1,n2,i2,o2 = (2,1,3,6,3,9) if g.coin == 'BCH' else (2,1,4,6,3,12)
|
||||
n1,i1,o1,n2,i2,o2 = (2,1,3,6,3,9) if cfg.coin == 'BCH' else (2,1,4,6,3,12)
|
||||
return self.blocks_info( args1 + ['--miner-info','--fields=all','--stats=all','+3'], [
|
||||
'Averages',
|
||||
f'nTx: {n1}',
|
||||
|
|
@ -267,7 +265,7 @@ class TestSuiteRegtest(TestSuiteBase):
|
|||
from mmgen.tool.api import tool_api
|
||||
from collections import namedtuple
|
||||
|
||||
t = tool_api()
|
||||
t = tool_api(cfg)
|
||||
t.init_coin(self.proto.coin,self.proto.network)
|
||||
t.addrtype = 'compressed' if self.proto.coin == 'BCH' else 'bech32'
|
||||
wp = namedtuple('wifaddrpair',['wif','addr'])
|
||||
|
|
@ -384,7 +382,7 @@ class TestSuiteRegtest(TestSuiteBase):
|
|||
return self._feeview([])
|
||||
|
||||
def stop(self):
|
||||
if opt.no_daemon_stop:
|
||||
if cfg.no_daemon_stop:
|
||||
self.spawn('',msg_only=True)
|
||||
msg_r('(leaving daemon running by user request)')
|
||||
return 'ok'
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ from mmgen.common import *
|
|||
from mmgen.exception import *
|
||||
from mmgen_node_tools.BlocksInfo import BlocksInfo
|
||||
|
||||
from ..include.common import cfg,vmsg
|
||||
|
||||
tip = 50000
|
||||
range_vecs = (
|
||||
# First Last FromTip nBlocks Step First Last BlockList
|
||||
|
|
@ -70,12 +72,13 @@ class dummyRPC:
|
|||
class coin_amt:
|
||||
satoshi = 0.00000001
|
||||
|
||||
class dummyOpt:
|
||||
class dummyCfg:
|
||||
fields = None
|
||||
stats = None
|
||||
miner_info = None
|
||||
header_info = None
|
||||
full_stats = None
|
||||
coin = 'BTC'
|
||||
|
||||
class unit_tests:
|
||||
|
||||
|
|
@ -91,7 +94,7 @@ class unit_tests:
|
|||
|
||||
def parse_rangespec(self,name,ut):
|
||||
|
||||
b = BlocksInfo(0,dummyOpt(),dummyRPC())
|
||||
b = BlocksInfo(dummyCfg(),None,dummyRPC())
|
||||
|
||||
def test(spec,chk,foo):
|
||||
ret = b.parse_rangespec(spec)
|
||||
|
|
@ -108,8 +111,8 @@ class unit_tests:
|
|||
|
||||
def test(spec,foo,chk):
|
||||
b = BlocksInfo(
|
||||
dummyCfg(),
|
||||
spec if type(spec) == tuple else [spec],
|
||||
dummyOpt(),
|
||||
dummyRPC() )
|
||||
ret = (b.first,b.last,b.block_list)
|
||||
vmsg('{:13} => {}'.format(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue