2020-05-11 18:07:58 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
|
|
# Demonstrates use of the MMGen asyncio/aiohttp JSON-RPC interface
|
|
|
|
|
# https://github.com/mmgen/mmgen
|
|
|
|
|
|
|
|
|
|
import time
|
|
|
|
|
from decimal import Decimal
|
|
|
|
|
from mmgen.common import *
|
|
|
|
|
|
2020-06-02 13:00:18 +00:00
|
|
|
opts.init({
|
|
|
|
|
'text': {
|
|
|
|
|
'desc': 'Estimate date of next Bitcoin halving',
|
|
|
|
|
'usage':'[opts]',
|
|
|
|
|
'options': """
|
|
|
|
|
-h, --help Print this help message
|
|
|
|
|
--, --longhelp Print help message for long options (common options)
|
|
|
|
|
-s, --sample-size=N Specify sample block range for block discovery time
|
|
|
|
|
estimate
|
|
|
|
|
""",
|
|
|
|
|
'notes': """
|
|
|
|
|
Requires a running Bitcoin Core node
|
|
|
|
|
If necessary, invoke with --rpc-host/--rpc-port/--rpc-user/--rpc-password
|
|
|
|
|
Specify aiohttp backend with --rpc-backend=aiohttp (Linux only)
|
|
|
|
|
"""
|
|
|
|
|
}
|
|
|
|
|
})
|
2020-05-11 18:07:58 +00:00
|
|
|
|
|
|
|
|
HalvingInterval = 210000 # src/chainparams.cpp
|
|
|
|
|
|
|
|
|
|
def date(t):
|
|
|
|
|
return '{}-{:02}-{:02} {:02}:{:02}:{:02}'.format(*time.gmtime(t)[:6])
|
|
|
|
|
|
|
|
|
|
def dhms(t):
|
|
|
|
|
return f'{t//60//60//24} days, {t//60//60%24:02}:{t//60%60:02}:{t%60:02} h/m/s'
|
|
|
|
|
|
|
|
|
|
def time_diff_warning(t_diff):
|
|
|
|
|
if abs(t_diff) > 60*60:
|
2020-05-12 16:37:59 +00:00
|
|
|
print('Warning: block tip time is {} {} clock time!'.format(
|
2020-05-11 18:07:58 +00:00
|
|
|
dhms(abs(t_diff)),
|
|
|
|
|
('behind','ahead of')[t_diff<0]))
|
|
|
|
|
|
|
|
|
|
async def main():
|
2020-06-01 20:59:34 +00:00
|
|
|
|
|
|
|
|
from mmgen.protocol import init_proto_from_opts
|
|
|
|
|
proto = init_proto_from_opts()
|
|
|
|
|
|
2020-05-11 18:07:58 +00:00
|
|
|
from mmgen.rpc import rpc_init
|
2020-06-01 20:59:34 +00:00
|
|
|
c = await rpc_init(proto)
|
|
|
|
|
|
2020-05-11 18:07:58 +00:00
|
|
|
tip = await c.call('getblockcount')
|
2020-05-12 16:37:59 +00:00
|
|
|
remaining = HalvingInterval - tip % HalvingInterval
|
2020-06-02 13:00:18 +00:00
|
|
|
sample_size = int(opt.sample_size) if opt.sample_size else max(remaining,144)
|
2020-05-11 18:07:58 +00:00
|
|
|
|
|
|
|
|
# aiohttp backend will perform these two calls concurrently:
|
|
|
|
|
cur,old = await c.gathered_call('getblockstats',((tip,),(tip - sample_size,)))
|
|
|
|
|
|
2020-05-12 16:37:59 +00:00
|
|
|
clock_time = int(time.time())
|
|
|
|
|
time_diff_warning(clock_time - cur['time'])
|
2020-05-11 18:07:58 +00:00
|
|
|
|
|
|
|
|
bdr = (cur['time'] - old['time']) / sample_size
|
|
|
|
|
t_rem = remaining * int(bdr)
|
2020-05-12 16:37:59 +00:00
|
|
|
sub = cur['subsidy'] * Decimal('0.00000001')
|
2020-05-11 18:07:58 +00:00
|
|
|
|
|
|
|
|
print(f'Current block: {tip}')
|
|
|
|
|
print(f'Next halving block: {tip + remaining}')
|
|
|
|
|
print(f'Blocks until halving: {remaining}')
|
|
|
|
|
print('Current block subsidy: {} BTC'.format(str(sub).rstrip('0')))
|
|
|
|
|
print(f'Current block discovery rate (over last {sample_size} blocks): {bdr/60:0.1f} minutes')
|
2020-05-12 16:37:59 +00:00
|
|
|
print(f'Current clock time (UTC): {date(clock_time)}')
|
2020-05-11 18:07:58 +00:00
|
|
|
print(f'Est. halving date (UTC): {date(cur["time"] + t_rem)}')
|
2020-05-12 16:37:59 +00:00
|
|
|
print(f'Est. time until halving: {dhms(cur["time"] + t_rem - clock_time)}')
|
2020-05-11 18:07:58 +00:00
|
|
|
|
2020-06-01 20:59:34 +00:00
|
|
|
run_session(main())
|