minor fixes and cleanups

This commit is contained in:
The MMGen Project 2021-07-29 14:20:44 +00:00
commit bab1242817
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
11 changed files with 74 additions and 54 deletions

View file

@ -82,19 +82,19 @@
############################
# Ignore Bitcoin Core version:
# btc_ignore_daemon_version
# btc_ignore_daemon_version false
# Ignore Litecoin Core version:
# ltc_ignore_daemon_version
# ltc_ignore_daemon_version false
# Ignore Bitcoin Cash Node version:
# bch_ignore_daemon_version
# bch_ignore_daemon_version false
# Ignore OpenEthereum version for ETH:
# eth_ignore_daemon_version
# eth_ignore_daemon_version false
# Ignore OpenEthereum version for ETC:
# etc_ignore_daemon_version
# etc_ignore_daemon_version false
#####################
## Altcoin options ##

View file

@ -128,20 +128,23 @@ class CfgFileSample(CfgFile):
self.parse_var(' '.join(last_line[1:]),n) if parse_vars else None,
)
def get_chunks(lines):
def gen_chunks(lines):
hdr = True
chunk = []
in_chunk = False
for n,line in enumerate(lines,1):
for lineno,line in enumerate(lines,1):
if line.startswith('##'):
hdr = False
continue
if hdr:
continue
if line == '':
in_chunk = False
elif line.startswith('# '):
elif line.startswith('#'):
if in_chunk == False:
if chunk:
yield process_chunk(chunk,last_nonblank)
@ -149,14 +152,14 @@ class CfgFileSample(CfgFile):
in_chunk = True
else:
chunk.append(line)
last_nonblank = n
last_nonblank = lineno
else:
die(2,'parse error in file {!r}, line {}'.format(self.fn,n))
raise CfgFileParseError('Parse error in file {!r}, line {}'.format(self.fn,lineno))
if chunk:
yield process_chunk(chunk,last_nonblank)
return list(get_chunks(self.data))
return list(gen_chunks(self.data))
class CfgFileUsr(CfgFile):
desc = 'user configuration file'

View file

@ -95,7 +95,7 @@ class Daemon(MMGenObject):
# TODO: assumes only one running instance of given daemon
cp = self.run_cmd(['ps','-Wl'],silent=True,check=False)
for line in cp.stdout.decode().splitlines():
if self.exec_fn_mswin in line:
if f'{self.exec_fn}.exe' in line:
return line.split()[3] # use Windows, not Cygwin, PID
die(2,'PID for {!r} not found in ps output'.format(ss))
elif self.use_pidfile:
@ -125,7 +125,7 @@ class Daemon(MMGenObject):
if not silent:
m = '{} {} already running with pid {}'
msg(m.format(self.net_desc,self.desc,self.pid))
return
return True
self.wait_for_state('stopped')
@ -162,6 +162,7 @@ class Daemon(MMGenObject):
else:
if not silent:
msg('{} {} on port {} not running'.format(self.net_desc,self.desc,self.rpc_port))
return True
def restart(self,silent=False):
self.stop(silent=silent)
@ -225,7 +226,6 @@ class MoneroWalletDaemon(Daemon):
daemon_id = 'xmr'
network = 'wallet RPC'
new_console_mswin = True
exec_fn_mswin = 'monero-wallet-rpc.exe'
ps_pid_mswin = True
def __init__(self, wallet_dir,
@ -335,8 +335,8 @@ class CoinDaemon(Daemon):
'cls_pfx',
'coind_name',
'coind_version', 'coind_version_str', # latest tested version
'coind_exec',
'cli_exec',
'exec_fn',
'cli_fn',
'cfg_file',
'testnet_dir',
'dfl_rpc',
@ -444,7 +444,7 @@ class CoinDaemon(Daemon):
else:
network_id = network_id.lower()
assert network_id in cls.network_ids, f'{network_id!r}: invalid network ID'
from mmgen.protocol import CoinProtocol
from .protocol import CoinProtocol
daemon_id,network = CoinProtocol.Base.parse_network_id(network_id)
me = Daemon.__new__(globals()[cls.daemon_ids[daemon_id].cls_pfx+'Daemon'])
@ -534,13 +534,13 @@ class CoinDaemon(Daemon):
@property
def start_cmd(self):
return ([self.coind_exec]
return ([self.exec_fn]
+ self.coind_args
+ self.shared_args
+ self.usr_coind_args )
def cli_cmd(self,*cmds):
return ([self.cli_exec]
return ([self.cli_fn]
+ self.shared_args
+ list(cmds) )
@ -553,7 +553,7 @@ class BitcoinDaemon(CoinDaemon):
if self.platform == 'win' and self.daemon_id == 'bch':
self.use_pidfile = False
from mmgen.regtest import MMGenRegtest
from .regtest import MMGenRegtest
self.shared_args = list_gen(
[f'--datadir={self.datadir}'],
[f'--rpcport={self.rpc_port}'],
@ -604,7 +604,6 @@ class BitcoinDaemon(CoinDaemon):
class MoneroDaemon(CoinDaemon):
exec_fn_mswin = 'monerod.exe'
ps_pid_mswin = True
new_console_mswin = True
host = 'localhost' # FIXME
@ -643,7 +642,7 @@ class MoneroDaemon(CoinDaemon):
if not self.test_socket(self.host,self.rpc_port):
return 'stopped'
cp = self.run_cmd(
[self.coind_exec]
[self.exec_fn]
+ self.shared_args
+ ['status'],
silent=True,
@ -655,11 +654,10 @@ class MoneroDaemon(CoinDaemon):
if self.platform == 'win':
return ['kill','-Wf',self.pid]
else:
return [self.coind_exec] + self.shared_args + ['exit']
return [self.exec_fn] + self.shared_args + ['exit']
class EthereumDaemon(CoinDaemon):
exec_fn_mswin = 'openethereum.exe'
ps_pid_mswin = True
def subclass_init(self):
@ -667,17 +665,20 @@ class EthereumDaemon(CoinDaemon):
# linux: $HOME/.local/share/io.parity.ethereum/chains/DevelopmentChain
# win: $LOCALAPPDATA/Parity/Ethereum/chains/DevelopmentChain
chaindir = os.path.join(self.datadir,'devchain')
shutil.rmtree(chaindir,ignore_errors=True)
base_path = os.path.join(self.datadir,'devchain')
shutil.rmtree(base_path,ignore_errors=True)
ld = self.platform == 'linux' and not 'no_daemonize' in self.opts
self.coind_args = list_gen(
['--no-ws'],
['--no-ipc'],
['--no-secretstore'],
[f'--ports-shift={self.port_shift}'],
[f'--base-path={chaindir}'],
[f'--base-path={base_path}'],
['--config=dev'],
['--mode=offline',self.test_suite],
['--log-file='+os.path.join(self.datadir,'openethereum.log')],
['daemon', ld],
['daemon', ld],
[self.pidfile, ld],
)

View file

@ -35,7 +35,7 @@ def help_notes_func(proto,k):
def coind_exec():
from .daemon import CoinDaemon
return (
CoinDaemon(proto.coin).coind_exec if proto.coin.lower() in CoinDaemon.daemon_ids else
CoinDaemon(proto.coin).exec_fn if proto.coin.lower() in CoinDaemon.coins else
'bitcoind' )
class help_notes:

View file

@ -1226,7 +1226,7 @@ class MMGenTX:
self.check_pubkey_scripts()
qmsg(f'Passing {len(keys)} key{suf(keys)} to {self.rpc.daemon.coind_exec}')
qmsg(f'Passing {len(keys)} key{suf(keys)} to {self.rpc.daemon.exec_fn}')
if self.has_segwit_inputs():
from .addr import KeyGenerator,AddrGenerator

View file

@ -54,7 +54,11 @@ opts_data = {
cmd_args = opts.init(opts_data)
if len(cmd_args): opts.usage()
if g.platform == 'linux' and os.getenv('USER') != 'root':
die(1,'This program must be run as root')
if len(cmd_args):
opts.usage()
mod_dir = os.path.split(normalize_path(modpath_save))[0]
mod_pardir = os.path.split(mod_dir)[0]

View file

@ -16,7 +16,8 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys,os,subprocess
import sys,os
from subprocess import run,PIPE
from shutil import copy2
sys_ver = sys.version_info[:2]
@ -24,11 +25,13 @@ req_ver = (3,6)
ver2f = lambda t: float('{}.{:03}'.format(*t))
if ver2f(sys_ver) < ver2f(req_ver):
m = '{}.{}: wrong Python version. MMGen requires Python {}.{} or greater\n'
m = '{}.{}: incorrect Python version. MMGen requires Python {}.{} or greater\n'
sys.stderr.write(m.format(*sys_ver,*req_ver))
sys.exit(1)
have_msys2 = subprocess.check_output(['uname','-s']).strip()[:7] == b'MSYS_NT'
have_msys2 = run(['uname','-s'],stdout=PIPE,check=True).stdout.startswith(b'MSYS_NT')
if have_msys2:
print('MSYS2 system detected')
from distutils.core import setup,Extension
from distutils.command.build_ext import build_ext
@ -50,7 +53,7 @@ class my_build_ext(build_ext):
ext_dest = os.path.join('mmgen',os.path.basename(ext_src))
try: os.unlink(ext_dest)
except: pass
os.chmod(ext_src,0o755)
os.chmod(ext_src,0o755) # required if user has non-standard umask
print('copying {} to {}'.format(ext_src,ext_dest))
copy2(ext_src,ext_dest)
copy_owner(cwd,ext_dest)
@ -66,7 +69,7 @@ def link_or_copy(tdir,a,b):
class my_install_data(install_data):
def run(self):
for f in 'mmgen.cfg','mnemonic.py','mn_wordlist.c':
os.chmod(os.path.join('data_files',f),0o644)
os.chmod(os.path.join('data_files',f),0o644) # required if user has non-standard umask
install_data.run(self)
class my_build_py(build_py):

View file

@ -191,18 +191,19 @@ def stop_test_daemons(*network_ids):
return test_daemons_ops(*network_ids,op='stop')
def restart_test_daemons(*network_ids,remove_datadir=False):
stop_test_daemons(*network_ids)
if not stop_test_daemons(*network_ids):
return False
return start_test_daemons(*network_ids,remove_datadir=remove_datadir)
def test_daemons_ops(*network_ids,op,remove_datadir=False):
if not opt.no_daemon_autostart:
from mmgen.daemon import CoinDaemon
silent = not opt.verbose and not getattr(opt,'exact_output',False)
ret = False
for network_id in network_ids:
if network_id.lower() not in CoinDaemon.network_ids: # silently ignore invalid IDs
continue
d = CoinDaemon(network_id,test_suite=True)
if remove_datadir:
d.stop(silent=True)
d.remove_datadir()
d.cmd(op,silent=silent)
ret = d.cmd(op,silent=silent)
return ret

View file

@ -6,21 +6,27 @@ from mmgen.common import *
cmd_args = opts.init()
from mmgen.cfg import cfg_file
cu = cfg_file('usr')
cS = cfg_file('sys')
cs = cfg_file('sample')
msg('usr cfg: {}'.format(cu.fn))
msg('sys cfg: {}'.format(cS.fn))
msg('sample cfg: {}'.format(cs.fn))
cf_usr = cfg_file('usr')
cf_sys = cfg_file('sys')
cf_sample = cfg_file('sample')
msg('Usr cfg file: {}'.format(cf_usr.fn))
msg('Sys cfg file: {}'.format(cf_sys.fn))
msg('Sample cfg file: {}'.format(cf_sample.fn))
if cmd_args:
if cmd_args[0] == 'parse_test':
ps = cs.parse(parse_vars=True)
ps = cf_sample.parse(parse_vars=True)
msg('parsed chunks: {}'.format(len(ps)))
pu = cu.parse()
pu = cf_usr.parse()
msg('usr cfg: {}'.format(' '.join(['{}={}'.format(i.name,i.value) for i in pu])))
elif cmd_args[0] == 'coin_specific_vars':
from mmgen.protocol import init_proto_from_opts
proto = init_proto_from_opts()
for varname in cmd_args[1:]:
print(f'{type(proto).__name__}.{varname}:',getattr(proto,varname))
print('{}.{}: {}'.format(
type(proto).__name__,
varname,
getattr(proto,varname)
))

View file

@ -5,6 +5,8 @@ from include.tests_header import repo_root
from mmgen.common import *
from mmgen.daemon import CoinDaemon
network_ids = CoinDaemon.network_ids
action = g.prog_name.split('-')[0]
opts_data = {
@ -30,7 +32,7 @@ Valid network IDs: {nid}, all, or no_xmr
},
'code': {
'options': lambda s: s.format(a=action.capitalize(),pn=g.prog_name),
'notes': lambda s: s.format(nid=', '.join(CoinDaemon.network_ids))
'notes': lambda s: s.format(nid=', '.join(network_ids))
}
}
@ -40,7 +42,7 @@ if 'all' in cmd_args or 'no_xmr' in cmd_args:
if len(cmd_args) != 1:
die(1,"'all' or 'no_xmr' must be the sole argument")
else:
ids = list(CoinDaemon.network_ids)
ids = list(network_ids)
if cmd_args[0] == 'no_xmr':
ids.remove('xmr')
else:
@ -48,7 +50,7 @@ else:
if not ids:
opts.usage()
for i in ids:
if i not in CoinDaemon.network_ids:
if i not in network_ids:
die(1,f'{i!r}: invalid network ID')
if 'eth' in ids and 'etc' in ids:
@ -63,7 +65,7 @@ for network_id in ids:
opts = ['no_daemonize'] if opt.no_daemonize else None,
port_shift = int(opt.port_shift or 0),
datadir = opt.datadir )
d.debug = opt.debug
d.debug = d.debug or opt.debug
d.wait = not opt.no_wait
if opt.get_state:
print('{} {} (port {}) is {}'.format(d.net_desc,d.desc,d.rpc_port,d.state))

View file

@ -60,7 +60,7 @@ class TestSuiteCfg(TestSuiteBase):
for i in (1,2,3,4,5):
t.expect(errstr)
for k in ('usr','sys','sample'):
t.expect('{} cfg: {}'.format(k,self.path(k)))
t.expect('{} cfg file:\s+{}'.format(capfirst(k),self.path(k)),regex=True)
assert not os.path.exists(self.path(k)), self.path(k)
t.read()
return t