From 3d898a895c3207ad3580100d5a7a8f5f804983d2 Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Sat, 13 Mar 2021 17:01:45 +0000 Subject: [PATCH] mmgen-blocks-info: reduce to one class, reorder methods --- mmnode-blocks-info | 197 ++++++++++++++++++++------------------------- 1 file changed, 87 insertions(+), 110 deletions(-) diff --git a/mmnode-blocks-info b/mmnode-blocks-info index dbb7ed8..b0e6718 100755 --- a/mmnode-blocks-info +++ b/mmnode-blocks-info @@ -32,88 +32,6 @@ class BlocksInfo: first = None last = None nblocks = None - - def __init__(self): - self.get_block_range() - self.post_init() - - def get_block_range(self): - - if not cmd_args: - first = last = c.blockcount - else: - arg = cmd_args[0] - if arg.startswith('+') and is_int(arg[1:]): - last = c.blockcount - first = last - int(arg[1:]) + 1 - elif is_int(arg): - first = last = int(arg) - else: - try: - first,last = [int(ep) for ep in arg.split('-')] - except: - opts.usage() - - if first > last: - die(2,f'{first}-{last}: invalid block range') - - if last > c.blockcount: - die(2,f'Requested block number ({last}) greater than current block height') - - self.first = first - self.last = last - self.nblocks = last - first + 1 - - def post_init(self): pass - - async def run(self): - - heights = range(self.first,self.last+1) - hashes = await c.gathered_call('getblockhash',[(height,) for height in heights]) - hdrs = await c.gathered_call('getblockheader',[(H,) for H in hashes]) - - for height in heights: - await self.process_block(height,hashes.pop(0),hdrs.pop(0)) - - def print_header(self): - hdr1 = [v.hdr1 for v in self.fvals] - hdr2 = [v.hdr2 for v in self.fvals] - if opt.miner_info: - hdr1.append(' ') - hdr2.append('Miner') - Msg(self.fs.format(*hdr1)) - Msg(self.fs.format(*hdr2)) - - async def print_summary(self): - from mmgen.util import secs_to_hms - tip = c.blockcount - rel = tip % 2016 - - if rel: - HA,HB = await c.gathered_call('getblockhash',([tip-rel],[tip])) - hA,hB = await c.gathered_call('getblockheader',([HA],[HB])) - bdi = (hB['time']-hA['time']) / rel - adj_pct = ((600 / bdi) - 1) * 100 - Msg_r(fmt(f""" - Current height: {tip} - Next diff adjust: {tip-rel+2016} (in {2016-rel} blocks [{((2016-rel)*bdi)/86400:.2f} days]) - BDI (cur period): {bdi/60:.2f} min - Est. diff adjust: {adj_pct:+.2f}% - """)) - else: - Msg_r(fmt(f""" - Current height: {tip} - Next diff adjust: {tip-rel+2016} (in {2016-rel} blocks) - """)) - - Msg('\nRange: {}-{} ({} blocks [{}])'.format( - self.first, - self.last, - self.nblocks, - secs_to_hms(self.t_cur - self.t_start) )) - -class BlocksInfoOverview(BlocksInfo): - total_bytes = 0 total_weight = 0 t_start = None @@ -158,9 +76,10 @@ class BlocksInfoOverview(BlocksInfo): 'su': lambda self,loc: str(loc.bs['subsidy'] * Decimal('0.00000001')).rstrip('0'), } + def __init__(self): - super().__init__() + self.get_block_range() if opt.fields: fnames = opt.fields.split(',') @@ -192,20 +111,41 @@ class BlocksInfoOverview(BlocksInfo): else: self.miner_pats = None - async def get_miner_string(self,H): - tx0 = (await c.call('getblock',H))['tx'][0] - bd = await c.call('getrawtransaction',tx0,1) - if type(bd) == tuple: - return '---' + def get_block_range(self): + + if not cmd_args: + first = last = c.blockcount else: - cb = bytes.fromhex(bd['vin'][0]['coinbase']) - if opt.raw_miner_info: - return repr(cb) + arg = cmd_args[0] + if arg.startswith('+') and is_int(arg[1:]): + last = c.blockcount + first = last - int(arg[1:]) + 1 + elif is_int(arg): + first = last = int(arg) else: - for pat in self.miner_pats: - m = pat.search(cb) - if m: - return ''.join(chr(b) for b in m[1] if 31 < b < 127).strip('^').strip('/').replace('/',' ') + try: + first,last = [int(ep) for ep in arg.split('-')] + except: + opts.usage() + + if first > last: + die(2,f'{first}-{last}: invalid block range') + + if last > c.blockcount: + die(2,f'Requested block number ({last}) greater than current block height') + + self.first = first + self.last = last + self.nblocks = last - first + 1 + + async def run(self): + + heights = range(self.first,self.last+1) + hashes = await c.gathered_call('getblockhash',[(height,) for height in heights]) + hdrs = await c.gathered_call('getblockheader',[(H,) for H in hashes]) + + for height in heights: + await self.process_block(height,hashes.pop(0),hdrs.pop(0)) async def process_block(self,height,H,hdr): loc = local_vars() @@ -251,9 +191,59 @@ class BlocksInfoOverview(BlocksInfo): Msg(self.fs.format(*gen())) + async def get_miner_string(self,H): + tx0 = (await c.call('getblock',H))['tx'][0] + bd = await c.call('getrawtransaction',tx0,1) + if type(bd) == tuple: + return '---' + else: + cb = bytes.fromhex(bd['vin'][0]['coinbase']) + if opt.raw_miner_info: + return repr(cb) + else: + for pat in self.miner_pats: + m = pat.search(cb) + if m: + return ''.join(chr(b) for b in m[1] if 31 < b < 127).strip('^').strip('/').replace('/',' ') + + def print_header(self): + hdr1 = [v.hdr1 for v in self.fvals] + hdr2 = [v.hdr2 for v in self.fvals] + if opt.miner_info: + hdr1.append(' ') + hdr2.append('Miner') + Msg(self.fs.format(*hdr1)) + Msg(self.fs.format(*hdr2)) + async def print_summary(self): + from mmgen.util import secs_to_hms + tip = c.blockcount + rel = tip % 2016 + + if rel: + HA,HB = await c.gathered_call('getblockhash',([tip-rel],[tip])) + hA,hB = await c.gathered_call('getblockheader',([HA],[HB])) + bdi = (hB['time']-hA['time']) / rel + adj_pct = ((600 / bdi) - 1) * 100 + Msg_r(fmt(f""" + Current height: {tip} + Next diff adjust: {tip-rel+2016} (in {2016-rel} blocks [{((2016-rel)*bdi)/86400:.2f} days]) + BDI (cur period): {bdi/60:.2f} min + Est. diff adjust: {adj_pct:+.2f}% + """)) + else: + Msg_r(fmt(f""" + Current height: {tip} + Next diff adjust: {tip-rel+2016} (in {2016-rel} blocks) + """)) + + Msg('\nRange: {}-{} ({} blocks [{}])'.format( + self.first, + self.last, + self.nblocks, + secs_to_hms(self.t_cur - self.t_start) )) + if 'bs' in self.deps: - await super().print_summary() if self.nblocks > 1: elapsed = self.t_cur - self.t_start ac = int(elapsed / self.nblocks) @@ -265,16 +255,6 @@ class BlocksInfoOverview(BlocksInfo): Avg BDI: {ac/60:.2f} min """)) -class BlocksInfoHashes(BlocksInfo): - - def print_header(self): - Msg('{:<7} {}'.format('BLOCK','HASH')) - - async def run(self): - heights = range(self.first,self.last+1) - hashes = await c.gathered_call('getblockhash',[(height,) for height in heights]) - Msg('\n'.join('{:<7} {}'.format(height,H) for height,H in zip(heights,hashes))) - opts_data = { 'sets': [ ('raw_miner_info',True,'miner_info',True), @@ -322,10 +302,7 @@ async def main(): global c c = await rpc_init(proto) - if opt.hashes: - m = BlocksInfoHashes() - else: - m = BlocksInfoOverview() + m = BlocksInfo() if not (opt.summary or opt.no_header): m.print_header()