mmgen-blocks-info: reduce to one class, reorder methods

This commit is contained in:
The MMGen Project 2021-03-13 17:01:45 +00:00
commit 3d898a895c
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2

View file

@ -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()