Browse Source

mmnode-blocks-info: support -o all, -o none, -o -<field_list>

- The --stats-only option has been removed, since -o none produces the
  equivalent output.

- -s -<stat_list> is also supported.
The MMGen Project 4 years ago
parent
commit
db98ef9ea1
2 changed files with 70 additions and 50 deletions
  1. 26 10
      mmgen/node_tools/BlocksInfo.py
  2. 44 40
      mmnode-blocks-info

+ 26 - 10
mmgen/node_tools/BlocksInfo.py

@@ -116,23 +116,32 @@ class BlocksInfo:
 	def __init__(self,cmd_args,opt,rpc):
 
 		def parse_cslist(uarg,full_set,dfl_set,desc):
-			usr_set = uarg.lstrip('+').split(',')
+			m = re.match('([+-]){1}',uarg)
+			pfx = m[1] if m else None
+			usr_set = set((uarg[1:] if m else uarg).split(','))
+			dfl_set = set(dfl_set)
 			for e in usr_set:
 				if e not in full_set:
 					die(1,f'{e!r}: unrecognized {desc}')
-			res = dfl_set + usr_set if uarg[0] == '+' else usr_set
+			res = (
+				dfl_set | usr_set if pfx == '+' else
+				dfl_set - usr_set if pfx == '-' else
+				usr_set
+			)
 			# display elements in order:
 			return [e for e in full_set if e in res]
 
+		def parse_cs_uarg(uarg,full_set,dfl_set,desc):
+			return (
+				full_set if uarg == 'all' else [] if uarg == 'none' else
+				parse_cslist(uarg,full_set,dfl_set,desc)
+			)
+
 		def get_fields():
-			return parse_cslist(opt.fields,self.fields,self.dfl_fields,'field')
+			return parse_cs_uarg(opt.fields,list(self.fields),self.dfl_fields,'field')
 
 		def get_stats():
-			arg = opt.stats.lower()
-			return (
-				self.all_stats if arg == 'all' else [] if arg == 'none' else
-				parse_cslist(arg,self.all_stats,self.dfl_stats,'stat')
-			)
+			return parse_cs_uarg(opt.stats.lower(),self.all_stats,self.dfl_stats,'stat')
 
 		def parse_cmd_args(): # => (block_list, first, last, step)
 			if not cmd_args:
@@ -182,6 +191,13 @@ class BlocksInfo:
 		self.block_data = namedtuple('block_data',self.fnames)
 		self.stats = get_stats() if opt.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:
+			self.stats.remove('diff')
+
+		if 'avg' in self.stats and not self.fnames:
+			self.stats.remove('avg')
+
 	def gen_fs(self,fnames,fill=[],fill_char='-',add_name=False):
 		for i in range(len(fnames)):
 			name = fnames[i]
@@ -315,7 +331,7 @@ class BlocksInfo:
 				await init(n)
 			ret = await self.process_block(heights[n],hashes[n],self.hdrs[n])
 			self.res.append(ret)
-			if not self.opt.stats_only:
+			if self.fnames:
 				self.output_block(ret,n)
 
 	def output_block(self,data,n):
@@ -490,7 +506,7 @@ class BlocksInfo:
 		return ('averages', ('Averages:', (fs, dict(gen())) ))
 
 	def process_stats_pre(self,i):
-		if not (self.opt.stats_only and i == 0):
+		if self.fnames or i != 0:
 			Msg('')
 
 	def finalize_output(self): pass

+ 44 - 40
mmnode-blocks-info

@@ -27,8 +27,6 @@ opts_data = {
 	'sets': [
 		('hashes',     True,   'fields',     'block,hash'),
 		('hashes',     True,   'stats',      'none'),
-		('stats',      'none', 'stats_only', False),
-		('stats_only', True,   'no_header',  True),
 		('json_raw',   True,   'json',       True),
 		('raw_miner_info',True,'miner_info', True),
 	],
@@ -50,17 +48,19 @@ opts_data = {
 -M, --raw-miner-info  Display miner info in uninterpreted form
 -n, --no-header       Don’t print the column header
 -o, --fields=         Display the specified fields (comma-separated list).
-                      See AVAILABLE FIELDS below.  If the first character
-                      is '+', specified fields are added to the defaults.
+                      See AVAILABLE FIELDS below.  Prefix the list with '+'
+                      to add the fields to the defaults, or '-' to remove
+                      them.  The special values 'all' and 'none' select all
+                      available fields or none, respectively.
 -s, --stats=          Display the specified stats (comma-separated list).
-                      See AVAILABLE STATS below.  If the first character is
-                      '+', specified stats are added to the defaults.  Use
-                      'none' to disable, or 'all' for all available stats.
--S, --stats-only      Display stats only.  Skip display of per-block data.
+                      See AVAILABLE STATS below.  The prefixes and special
+                      values available to the --fields option are recognized.
 """,
 	'notes': """
-If no block number is specified, the current block is assumed.  The string
-'cur' can be used in place of the current block number.
+If no block number is specified, the current chain tip is assumed.
+
+The special value 'cur' can be used to designate the chain tip wherever a
+block number is expected.
 
 If the requested range ends at the current chain tip, an estimate of the next
 difficulty adjustment is also displayed. The estimate is based on the average
@@ -74,40 +74,47 @@ AVAILABLE STATS: {s}
 
 EXAMPLES:
 
-    # Display info for current block:
-    {p}
+    Display info for current block:
+    $ {p}
+
+    Display info for the Genesis Block:
+    $ {p} 0
+
+    Display info for the last 20 blocks:
+    $ {p} +20
 
-    # Display info for the Genesis Block:
-    {p} 0
+    Display specified fields for blocks 165-190
+    $ {p} -o block,date,size,inputs,nTx 165-190
 
-    # Display info for the last 20 blocks:
-    {p} +20
+    Display info for 10 blocks beginning at block 600000:
+    $ {p} 600000+10
 
-    # Display specified fields for blocks 165-190
-    {p} -o block,date,size,inputs,nTx 165-190
+    Display info for every 5th block of 50-block range beginning at 1000
+    blocks from chain tip:
+    $ {p} -- -1000+50+5
 
-    # Display info for 10 blocks beginning at block 600000:
-    {p} 600000+10
+    Display info for block 152817, adding miner field:
+    $ {p} -o +miner 152817
 
-    # Display info for every 5th block of 50-block range beginning at 1000
-    # blocks from chain tip:
-    {p} -- -1000+50+5
+    Display specified fields for listed blocks:
+    $ {p} -o block,date,hash 245798 170 624044
 
-    # Display info for block 152817, adding miner field:
-    {p} -o +miner 152817
+    Display every difficulty adjustment from Genesis Block to chain tip:
+    $ {p} -o +difficulty 0-cur+2016
 
-    # Display specified fields for listed blocks:
-    {p} -o block,date,hash 245798 170 624044
+    Display roughly a block a day over the last two weeks.  Note that
+    multiplication is allowed in the nBlocks spec:
+    $ {p} +144*14+144
 
-    # Display every difficulty adjustment from Genesis Block to chain tip:
-    {p} -o +difficulty 0-cur+2016
+    Display only range stats for the last ten blocks:
+    $ {p} -o none -s range +10
 
-    # Display roughly a block a day over the last two weeks.  Note that
-    # multiplication is allowed in the nBlocks spec:
-    {p} +144*14+144
+    Display data for the last ten blocks, skipping 'size' and 'subsidy'
+    fields and stats:
+    $ {p} -o -size,subsidy -s none +10
 
-    # Display only range stats for the last ten blocks:
-    {p} -s range -S +10
+    Display all fields and stats for the last ten blocks:
+    $ {p} -o all -s all +10
 
 This program requires a txindex-enabled daemon for correct operation.
 """.format(
@@ -130,18 +137,15 @@ async def main():
 
 	m = cls( cmd_args, opt, await rpc_init(proto) )
 
-	if not opt.no_header:
+	if m.fnames and not opt.no_header:
 		m.print_header()
 
 	await m.process_blocks()
 
 	if m.last and m.stats:
-		for i,stat in enumerate(m.stats):
-			if stat == 'diff': # Display diff stats by default only if user-requested range ends with chain tip
-				if not opt.stats and m.last != m.tip:
-					continue
+		for i,sname in enumerate(m.stats):
 			m.process_stats_pre(i)
-			await m.process_stats(stat)
+			await m.process_stats(sname)
 
 	m.finalize_output()