LTC support/testing fixes
- examples/halving-calculator.py: support LTC and BCH - test/test.py regtest: support Litecoin Core v0.18.1 - test/unit_tests.py: add LTC test
This commit is contained in:
parent
d1d7132a7c
commit
cfa8d19cd0
6 changed files with 31 additions and 24 deletions
|
|
@ -9,7 +9,7 @@ from mmgen.common import *
|
||||||
|
|
||||||
opts.init({
|
opts.init({
|
||||||
'text': {
|
'text': {
|
||||||
'desc': 'Estimate date of next Bitcoin halving',
|
'desc': 'Estimate date of next block subsidy halving',
|
||||||
'usage':'[opts]',
|
'usage':'[opts]',
|
||||||
'options': """
|
'options': """
|
||||||
-h, --help Print this help message
|
-h, --help Print this help message
|
||||||
|
|
@ -18,20 +18,20 @@ opts.init({
|
||||||
estimate
|
estimate
|
||||||
""",
|
""",
|
||||||
'notes': """
|
'notes': """
|
||||||
Requires a running Bitcoin Core node
|
Requires a running coin daemon
|
||||||
|
Specify coin with --coin=btc (default)/--coin=bch/--coin=ltc
|
||||||
If necessary, invoke with --rpc-host/--rpc-port/--rpc-user/--rpc-password
|
If necessary, invoke with --rpc-host/--rpc-port/--rpc-user/--rpc-password
|
||||||
Specify aiohttp backend with --rpc-backend=aiohttp (Linux only)
|
Specify aiohttp backend with --rpc-backend=aiohttp (Linux only)
|
||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
HalvingInterval = 210000 # src/chainparams.cpp
|
|
||||||
|
|
||||||
def date(t):
|
def date(t):
|
||||||
return '{}-{:02}-{:02} {:02}:{:02}:{:02}'.format(*time.gmtime(t)[:6])
|
return '{}-{:02}-{:02} {:02}:{:02}:{:02}'.format(*time.gmtime(t)[:6])
|
||||||
|
|
||||||
def dhms(t):
|
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'
|
t,neg = (-t,'-') if t < 0 else (t,' ')
|
||||||
|
return f'{neg}{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):
|
def time_diff_warning(t_diff):
|
||||||
if abs(t_diff) > 60*60:
|
if abs(t_diff) > 60*60:
|
||||||
|
|
@ -48,8 +48,9 @@ async def main():
|
||||||
c = await rpc_init(proto)
|
c = await rpc_init(proto)
|
||||||
|
|
||||||
tip = await c.call('getblockcount')
|
tip = await c.call('getblockcount')
|
||||||
remaining = HalvingInterval - tip % HalvingInterval
|
assert tip > 1, 'block tip must be > 1'
|
||||||
sample_size = int(opt.sample_size) if opt.sample_size else max(remaining,144)
|
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))
|
||||||
|
|
||||||
# aiohttp backend will perform these two calls concurrently:
|
# aiohttp backend will perform these two calls concurrently:
|
||||||
cur,old = await c.gathered_call('getblockstats',((tip,),(tip - sample_size,)))
|
cur,old = await c.gathered_call('getblockstats',((tip,),(tip - sample_size,)))
|
||||||
|
|
@ -64,10 +65,10 @@ async def main():
|
||||||
print(f'Current block: {tip}')
|
print(f'Current block: {tip}')
|
||||||
print(f'Next halving block: {tip + remaining}')
|
print(f'Next halving block: {tip + remaining}')
|
||||||
print(f'Blocks until halving: {remaining}')
|
print(f'Blocks until halving: {remaining}')
|
||||||
print('Current block subsidy: {} BTC'.format(str(sub).rstrip('0')))
|
print('Current block subsidy: {} {}'.format(str(sub).rstrip('0'),proto.coin))
|
||||||
print(f'Current block discovery rate (over last {sample_size} blocks): {bdr/60:0.1f} minutes')
|
print(f'Current block discovery rate (over last {sample_size} blocks): {bdr/60:0.1f} minutes')
|
||||||
print(f'Current clock time (UTC): {date(clock_time)}')
|
print(f'Current clock time (UTC): {date(clock_time)}')
|
||||||
print(f'Est. halving date (UTC): {date(cur["time"] + t_rem)}')
|
print(f'Est. halving date (UTC): {date(cur["time"] + t_rem)}')
|
||||||
print(f'Est. time until halving: {dhms(cur["time"] + t_rem - clock_time)}')
|
print(f'Est. time until halving: {dhms(cur["time"] + t_rem - clock_time)}')
|
||||||
|
|
||||||
run_session(main())
|
run_session(main())
|
||||||
|
|
|
||||||
|
|
@ -457,7 +457,7 @@ class BitcoinDaemon(CoinDaemon):
|
||||||
elif self.daemon_id == 'bch':
|
elif self.daemon_id == 'bch':
|
||||||
self.coin_specific_coind_args = ['--usecashaddr=0']
|
self.coin_specific_coind_args = ['--usecashaddr=0']
|
||||||
elif self.daemon_id == 'ltc':
|
elif self.daemon_id == 'ltc':
|
||||||
self.coin_specific_coind_args = ['--mempoolreplacement=1']
|
self.coin_specific_coind_args = ['--mempoolreplacement=1','--txindex=1']
|
||||||
|
|
||||||
if self.network == 'testnet':
|
if self.network == 'testnet':
|
||||||
self.lockfile = os.path.join(self.datadir,self.testnet_dir,'.cookie')
|
self.lockfile = os.path.join(self.datadir,self.testnet_dir,'.cookie')
|
||||||
|
|
|
||||||
|
|
@ -231,6 +231,7 @@ class CoinProtocol(MMGenObject):
|
||||||
bech32_hrp = 'bc'
|
bech32_hrp = 'bc'
|
||||||
sign_mode = 'daemon'
|
sign_mode = 'daemon'
|
||||||
avg_bdi = int(9.7 * 60) # average block discovery interval (historical)
|
avg_bdi = int(9.7 * 60) # average block discovery interval (historical)
|
||||||
|
halving_interval = 210000
|
||||||
|
|
||||||
def hex2wif(self,hexpriv,pubkey_type,compressed): # input is preprocessed hex
|
def hex2wif(self,hexpriv,pubkey_type,compressed): # input is preprocessed hex
|
||||||
sec = bytes.fromhex(hexpriv)
|
sec = bytes.fromhex(hexpriv)
|
||||||
|
|
@ -366,6 +367,7 @@ class CoinProtocol(MMGenObject):
|
||||||
forks = []
|
forks = []
|
||||||
bech32_hrp = 'ltc'
|
bech32_hrp = 'ltc'
|
||||||
avg_bdi = 150
|
avg_bdi = 150
|
||||||
|
halving_interval = 840000
|
||||||
|
|
||||||
class LitecoinTestnet(Litecoin):
|
class LitecoinTestnet(Litecoin):
|
||||||
# addr ver nums same as Bitcoin testnet, except for 'p2sh'
|
# addr ver nums same as Bitcoin testnet, except for 'p2sh'
|
||||||
|
|
|
||||||
11
mmgen/rpc.py
11
mmgen/rpc.py
|
|
@ -329,7 +329,7 @@ class BitcoinRPCClient(RPCClient,metaclass=aInitMeta):
|
||||||
async def __ainit__(self,proto,daemon,backend):
|
async def __ainit__(self,proto,daemon,backend):
|
||||||
|
|
||||||
self.proto = proto
|
self.proto = proto
|
||||||
self.daemon_data_dir = daemon.datadir
|
self.daemon = daemon
|
||||||
|
|
||||||
super().__init__(
|
super().__init__(
|
||||||
host = 'localhost' if g.test_suite else (g.rpc_host or 'localhost'),
|
host = 'localhost' if g.test_suite else (g.rpc_host or 'localhost'),
|
||||||
|
|
@ -387,14 +387,13 @@ class BitcoinRPCClient(RPCClient,metaclass=aInitMeta):
|
||||||
|
|
||||||
def get_daemon_cfg_fn(self):
|
def get_daemon_cfg_fn(self):
|
||||||
# Use dirname() to remove 'bob' or 'alice' component
|
# Use dirname() to remove 'bob' or 'alice' component
|
||||||
cfg_dir = os.path.dirname(g.data_dir) if self.proto.regtest else self.daemon_data_dir
|
|
||||||
return os.path.join(
|
return os.path.join(
|
||||||
cfg_dir,
|
(os.path.dirname(g.data_dir) if self.proto.regtest else self.daemon.datadir),
|
||||||
(self.proto.is_fork_of or self.proto.name).lower() + '.conf' )
|
self.daemon.cfg_file )
|
||||||
|
|
||||||
def get_daemon_auth_cookie_fn(self):
|
def get_daemon_auth_cookie_fn(self):
|
||||||
return os.path.join(
|
return os.path.join(
|
||||||
self.daemon_data_dir,
|
self.daemon.datadir,
|
||||||
self.proto.daemon_data_subdir,
|
self.proto.daemon_data_subdir,
|
||||||
'.cookie' )
|
'.cookie' )
|
||||||
|
|
||||||
|
|
@ -482,7 +481,7 @@ class EthereumRPCClient(RPCClient,metaclass=aInitMeta):
|
||||||
|
|
||||||
async def __ainit__(self,proto,daemon,backend):
|
async def __ainit__(self,proto,daemon,backend):
|
||||||
self.proto = proto
|
self.proto = proto
|
||||||
self.daemon_data_dir = daemon.datadir
|
self.daemon = daemon
|
||||||
|
|
||||||
super().__init__(
|
super().__init__(
|
||||||
host = 'localhost' if g.test_suite else (g.rpc_host or 'localhost'),
|
host = 'localhost' if g.test_suite else (g.rpc_host or 'localhost'),
|
||||||
|
|
|
||||||
|
|
@ -285,7 +285,7 @@ class TestSuiteRegtest(TestSuiteBase,TestSuiteShared):
|
||||||
return t
|
return t
|
||||||
|
|
||||||
def halving_calculator_bob(self):
|
def halving_calculator_bob(self):
|
||||||
t = self.spawn('halving-calculator.py',['--bob','--sample-size=144'],cmd_dir='examples')
|
t = self.spawn('halving-calculator.py',['--bob'],cmd_dir='examples')
|
||||||
t.expect('time until halving')
|
t.expect('time until halving')
|
||||||
t.read()
|
t.read()
|
||||||
return t
|
return t
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,11 @@ from mmgen.daemon import CoinDaemon,MoneroWalletDaemon
|
||||||
def auth_test(proto,d):
|
def auth_test(proto,d):
|
||||||
d.stop()
|
d.stop()
|
||||||
if g.platform != 'win':
|
if g.platform != 'win':
|
||||||
qmsg(f'\n Testing authentication with credentials from bitcoin.conf:')
|
qmsg(f'\n Testing authentication with credentials from {d.cfg_file}:')
|
||||||
d.remove_datadir()
|
d.remove_datadir()
|
||||||
os.makedirs(d.datadir)
|
os.makedirs(d.datadir)
|
||||||
|
|
||||||
cf = os.path.join(d.datadir,'bitcoin.conf')
|
cf = os.path.join(d.datadir,d.cfg_file)
|
||||||
open(cf,'a').write('\nrpcuser = ut_rpc\nrpcpassword = ut_rpc_passw0rd\n')
|
open(cf,'a').write('\nrpcuser = ut_rpc\nrpcpassword = ut_rpc_passw0rd\n')
|
||||||
|
|
||||||
d.add_flag('keep_cfg_file')
|
d.add_flag('keep_cfg_file')
|
||||||
|
|
@ -25,7 +25,7 @@ def auth_test(proto,d):
|
||||||
|
|
||||||
async def do():
|
async def do():
|
||||||
rpc = await rpc_init(proto)
|
rpc = await rpc_init(proto)
|
||||||
assert rpc.auth.user == 'ut_rpc', 'user is not ut_rpc!'
|
assert rpc.auth.user == 'ut_rpc', f'{rpc.auth.user}: user is not ut_rpc!'
|
||||||
|
|
||||||
run_session(do())
|
run_session(do())
|
||||||
d.stop()
|
d.stop()
|
||||||
|
|
@ -54,6 +54,8 @@ class init_test:
|
||||||
rpc = await rpc_init(proto,backend)
|
rpc = await rpc_init(proto,backend)
|
||||||
do_msg(rpc)
|
do_msg(rpc)
|
||||||
|
|
||||||
|
ltc = bch
|
||||||
|
|
||||||
async def eth(proto,backend):
|
async def eth(proto,backend):
|
||||||
rpc = await rpc_init(proto,backend)
|
rpc = await rpc_init(proto,backend)
|
||||||
do_msg(rpc)
|
do_msg(rpc)
|
||||||
|
|
@ -76,14 +78,17 @@ def run_test(coin,auth):
|
||||||
|
|
||||||
class unit_tests:
|
class unit_tests:
|
||||||
|
|
||||||
altcoin_deps = ('bch','eth','xmr_wallet')
|
altcoin_deps = ('ltc','bch','eth','xmr_wallet')
|
||||||
|
|
||||||
def bch(self,name,ut):
|
|
||||||
return run_test('bch',auth=True)
|
|
||||||
|
|
||||||
def btc(self,name,ut):
|
def btc(self,name,ut):
|
||||||
return run_test('btc',auth=True)
|
return run_test('btc',auth=True)
|
||||||
|
|
||||||
|
def ltc(self,name,ut):
|
||||||
|
return run_test('ltc',auth=True)
|
||||||
|
|
||||||
|
def bch(self,name,ut):
|
||||||
|
return run_test('bch',auth=True)
|
||||||
|
|
||||||
def eth(self,name,ut):
|
def eth(self,name,ut):
|
||||||
return run_test('eth',auth=False)
|
return run_test('eth',auth=False)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue