|
@@ -46,10 +46,7 @@ class MMGenRegtest(MMGenObject):
|
|
|
rpc_password = 'hodltothemoon'
|
|
|
users = ('bob','alice','miner')
|
|
|
coins = ('btc','bch','ltc')
|
|
|
- usr_cmds = (
|
|
|
- 'bob','alice','miner','user','state',
|
|
|
- 'setup','generate','send','stop',
|
|
|
- 'balances','mempool','cli' )
|
|
|
+ usr_cmds = ('setup','generate','send','stop', 'state', 'balances','mempool','cli')
|
|
|
|
|
|
def __init__(self,coin):
|
|
|
self.coin = coin.lower()
|
|
@@ -61,14 +58,13 @@ class MMGenRegtest(MMGenObject):
|
|
|
async def generate(self,blocks=1,silent=False):
|
|
|
|
|
|
blocks = int(blocks)
|
|
|
- await self.switch_user('miner',quiet=True)
|
|
|
|
|
|
async def have_generatetoaddress():
|
|
|
- ret = await self.rpc_call('help','generatetoaddress')
|
|
|
+ ret = await self.rpc_call('help','generatetoaddress',wallet='miner')
|
|
|
return not 'unknown command:' in ret
|
|
|
|
|
|
async def get_miner_address():
|
|
|
- return await self.rpc_call('getnewaddress')
|
|
|
+ return await self.rpc_call('getnewaddress',wallet='miner')
|
|
|
|
|
|
if self.d.state == 'stopped':
|
|
|
die(1,'Regtest daemon is not running')
|
|
@@ -80,27 +76,13 @@ class MMGenRegtest(MMGenObject):
|
|
|
else:
|
|
|
cmd_args = ( 'generate', blocks )
|
|
|
|
|
|
- out = await self.rpc_call(*cmd_args)
|
|
|
+ out = await self.rpc_call(*cmd_args,wallet='miner')
|
|
|
|
|
|
if len(out) != blocks:
|
|
|
rdie(1,'Error generating blocks')
|
|
|
|
|
|
gmsg('Mined {} block{}'.format(blocks,suf(blocks)))
|
|
|
|
|
|
- async def create_tracking_wallet(self,user):
|
|
|
- try:
|
|
|
- await self.rpc_call('getbalance')
|
|
|
- except:
|
|
|
- await self.rpc_call('createwallet',
|
|
|
- user,
|
|
|
- user != 'miner',
|
|
|
- user != 'miner',
|
|
|
- '',
|
|
|
- False,
|
|
|
- False,
|
|
|
- False
|
|
|
- )
|
|
|
-
|
|
|
async def setup(self):
|
|
|
|
|
|
try: os.makedirs(self.d.datadir)
|
|
@@ -113,47 +95,46 @@ class MMGenRegtest(MMGenObject):
|
|
|
|
|
|
gmsg('Starting {} regtest setup'.format(self.coin.upper()))
|
|
|
|
|
|
- gmsg('Creating miner wallet')
|
|
|
- self.start_daemon('miner')
|
|
|
- await self.create_tracking_wallet('miner')
|
|
|
+ self.d.start(silent=True)
|
|
|
+
|
|
|
+ rpc = await rpc_init(self.proto,backend=None,daemon=self.d)
|
|
|
+ for user in ('miner','bob','alice'):
|
|
|
+ gmsg(f'Creating {capfirst(user)}’s wallet')
|
|
|
+ await rpc.icall(
|
|
|
+ 'createwallet',
|
|
|
+ wallet_name = user,
|
|
|
+ no_keys = user != 'miner',
|
|
|
+ load_on_startup = False )
|
|
|
|
|
|
await self.generate(432,silent=True)
|
|
|
- await self.rpc_call('stop')
|
|
|
- time.sleep(1.2)
|
|
|
-
|
|
|
- for user in ('alice','bob'):
|
|
|
- gmsg("Creating {}'s tracking wallet".format(user.capitalize()))
|
|
|
- self.start_daemon(user)
|
|
|
- await self.create_tracking_wallet(user)
|
|
|
- if user == 'bob' and opt.setup_no_stop_daemon:
|
|
|
- msg('Leaving daemon running with Bob as current user')
|
|
|
- else:
|
|
|
- await self.rpc_call('stop')
|
|
|
- time.sleep(0.2)
|
|
|
|
|
|
gmsg('Setup complete')
|
|
|
|
|
|
- def init_daemon(self,user,reindex=False):
|
|
|
- assert user is None or user in self.users,'{!r}: invalid user for regtest'.format(user)
|
|
|
+ if opt.setup_no_stop_daemon:
|
|
|
+ msg('Leaving regtest daemon running')
|
|
|
+ else:
|
|
|
+ msg('Stopping regtest daemon')
|
|
|
+ await self.rpc_call('stop')
|
|
|
+
|
|
|
+ def init_daemon(self,reindex=False):
|
|
|
self.d.net_desc = self.coin.upper()
|
|
|
- self.d.usr_coind_args = [f'--wallet={user}']
|
|
|
if reindex:
|
|
|
self.d.usr_coind_args.append('--reindex')
|
|
|
|
|
|
- def start_daemon(self,user,reindex=False,silent=True):
|
|
|
- self.init_daemon(user=user,reindex=reindex)
|
|
|
+ async def start_daemon(self,reindex=False,silent=True):
|
|
|
+ self.init_daemon(reindex=reindex)
|
|
|
self.d.start(silent=silent)
|
|
|
-
|
|
|
- async def rpc_call(self,*args):
|
|
|
- rpc = await rpc_init(self.proto,backend=None,daemon=self.d,caller='regtest')
|
|
|
- return await rpc.call(*args)
|
|
|
-
|
|
|
- async def current_user(self):
|
|
|
- try:
|
|
|
- return (await self.rpc_call('getwalletinfo'))['walletname']
|
|
|
- except SocketError as e:
|
|
|
- msg(str(e))
|
|
|
- return None
|
|
|
+ for user in ('miner','bob','alice'):
|
|
|
+ msg(f'Loading {capfirst(user)}’s wallet')
|
|
|
+ await self.rpc_call('loadwallet',user,start_daemon=False)
|
|
|
+
|
|
|
+ async def rpc_call(self,*args,wallet=None,start_daemon=True):
|
|
|
+
|
|
|
+ assert g.prog_name == 'mmgen-regtest', 'only mmgen-regtest util is allowed to use this method'
|
|
|
+ if start_daemon and self.d.state == 'stopped':
|
|
|
+ await self.start_daemon()
|
|
|
+ rpc = await rpc_init(self.proto,backend=None,daemon=self.d)
|
|
|
+ return await rpc.call(*args,wallet=wallet)
|
|
|
|
|
|
async def stop(self):
|
|
|
await self.rpc_call('stop')
|
|
@@ -161,27 +142,21 @@ class MMGenRegtest(MMGenObject):
|
|
|
def state(self):
|
|
|
msg(self.d.state)
|
|
|
|
|
|
- async def balances(self,*users):
|
|
|
- users = list(set(users or ['bob','alice']))
|
|
|
- cur_user = await self.current_user()
|
|
|
- if cur_user in users:
|
|
|
- users.remove(cur_user)
|
|
|
- users = [cur_user] + users
|
|
|
+ async def balances(self):
|
|
|
bal = {}
|
|
|
+ users = ('bob','alice')
|
|
|
for user in users:
|
|
|
- await self.switch_user(user,quiet=True)
|
|
|
- out = await self.rpc_call('listunspent',0)
|
|
|
+ out = await self.rpc_call('listunspent',0,wallet=user)
|
|
|
bal[user] = sum(e['amount'] for e in out)
|
|
|
|
|
|
fs = '{:<16} {:18.8f}'
|
|
|
- for user in sorted(users):
|
|
|
+ for user in users:
|
|
|
msg(fs.format(user.capitalize()+"'s balance:",bal[user]))
|
|
|
msg(fs.format('Total balance:',sum(v for k,v in bal.items())))
|
|
|
|
|
|
async def send(self,addr,amt):
|
|
|
- await self.switch_user('miner',quiet=True)
|
|
|
gmsg('Sending {} miner {} to address {}'.format(amt,self.d.daemon_id.upper(),addr))
|
|
|
- cp = await self.rpc_call('sendtoaddress',addr,str(amt))
|
|
|
+ cp = await self.rpc_call('sendtoaddress',addr,str(amt),wallet='miner')
|
|
|
await self.generate(1)
|
|
|
|
|
|
async def mempool(self):
|
|
@@ -197,36 +172,6 @@ class MMGenRegtest(MMGenObject):
|
|
|
ret = getattr(self,args[0])(*args[1:])
|
|
|
return (await ret) if type(ret).__name__ == 'coroutine' else ret
|
|
|
|
|
|
- async def user(self):
|
|
|
- ret = await self.current_user()
|
|
|
- msg(ret.capitalize() if ret else 'None')
|
|
|
-
|
|
|
- async def bob(self): await self.switch_user('bob')
|
|
|
- async def alice(self): await self.switch_user('alice')
|
|
|
- async def miner(self): await self.switch_user('miner')
|
|
|
-
|
|
|
- async def switch_user(self,user,quiet=False):
|
|
|
-
|
|
|
- if self.d.state == 'busy':
|
|
|
- self.d.wait_for_state('ready')
|
|
|
-
|
|
|
- if self.d.state == 'ready':
|
|
|
- cur_user = await self.current_user()
|
|
|
- if user == cur_user:
|
|
|
- if not quiet:
|
|
|
- msg('{} is already the current user for {}'.format(user.capitalize(),self.d.net_desc))
|
|
|
- return
|
|
|
- gmsg_r('Switching to user {} for {}'.format(user.capitalize(),self.d.net_desc))
|
|
|
- if cur_user:
|
|
|
- await self.rpc_call('unloadwallet',cur_user)
|
|
|
- await self.rpc_call('loadwallet',user)
|
|
|
- else:
|
|
|
- m = 'Starting {} {} with current user {}'
|
|
|
- gmsg_r(m.format(self.d.net_desc,self.d.desc,user.capitalize()))
|
|
|
- self.start_daemon(user,silent=True)
|
|
|
-
|
|
|
- gmsg('...done')
|
|
|
-
|
|
|
async def fork(self,coin):
|
|
|
|
|
|
proto = init_proto(coin,False)
|
|
@@ -254,7 +199,7 @@ class MMGenRegtest(MMGenObject):
|
|
|
create_data_dir(self.d.datadir)
|
|
|
os.rmdir(self.d.datadir)
|
|
|
shutil.copytree(source_data_dir,self.d.datadir,symlinks=True)
|
|
|
- self.start_daemon('miner',reindex=True)
|
|
|
+ await self.start_daemon(reindex=True)
|
|
|
await self.rpc_call('stop')
|
|
|
|
|
|
gmsg('Fork {} successfully created'.format(proto.coin))
|