|
|
@@ -27,7 +27,7 @@ from mmgen.proto.btc.regtest import MMGenRegtest
|
|
|
from mmgen.proto.bch.cashaddr import b32a
|
|
|
from mmgen.proto.btc.common import b58a
|
|
|
from mmgen.color import yellow
|
|
|
-from mmgen.util import msg_r, die, gmsg, capfirst, suf, fmt_list
|
|
|
+from mmgen.util import msg_r, die, gmsg, capfirst, suf, fmt_list, is_hex_str
|
|
|
from mmgen.protocol import init_proto
|
|
|
from mmgen.addrlist import AddrList
|
|
|
from mmgen.wallet import Wallet, get_wallet_cls
|
|
|
@@ -189,14 +189,15 @@ class CmdTestRegtest(CmdTestBase, CmdTestShared):
|
|
|
('subgroup.view', ['label']),
|
|
|
('subgroup._auto_chg_deps', ['twexport', 'label']),
|
|
|
('subgroup.auto_chg', ['_auto_chg_deps']),
|
|
|
+ ('subgroup.dump_hex', ['fund_users']),
|
|
|
('stop', 'stopping regtest daemon'),
|
|
|
)
|
|
|
cmd_subgroups = {
|
|
|
'misc': (
|
|
|
'miscellaneous commands',
|
|
|
- ('daemon_version', 'mmgen-tool daemon_version'),
|
|
|
- ('halving_calculator_bob', 'halving calculator (Bob)'),
|
|
|
- ('cli_txcreate', '‘mmgen-cli createrawtransaction’'),
|
|
|
+ ('daemon_version', 'mmgen-tool daemon_version'),
|
|
|
+ ('halving_calculator_bob', 'halving calculator (Bob)'),
|
|
|
+ ('cli_createrawtransaction', '‘mmgen-cli createrawtransaction’'),
|
|
|
),
|
|
|
'init_bob': (
|
|
|
'creating Bob’s MMGen wallet and tracking wallet',
|
|
|
@@ -224,7 +225,7 @@ class CmdTestRegtest(CmdTestBase, CmdTestShared):
|
|
|
('fund_bob', 'funding Bob’s wallet'),
|
|
|
('fund_alice', 'funding Alice’s wallet'),
|
|
|
('generate', 'mining a block'),
|
|
|
- ('bob_bal1_cli', 'Bob’s balance (via ‘mmgen-cli’)'),
|
|
|
+ ('bob_bal1', 'Bob’s balance'),
|
|
|
('generate_extra_deterministic', 'generate extra blocks for deterministic run'),
|
|
|
),
|
|
|
'msg': (
|
|
|
@@ -458,6 +459,17 @@ class CmdTestRegtest(CmdTestBase, CmdTestShared):
|
|
|
'(no unused addresses)'),
|
|
|
('carol_delete_wallet', 'unloading and deleting Carol’s tracking wallet'),
|
|
|
),
|
|
|
+ 'dump_hex': (
|
|
|
+ 'sending from dumped hex',
|
|
|
+ ('bob_dump_hex_create', 'dump_hex transaction - creating'),
|
|
|
+ ('bob_dump_hex_sign', 'dump_hex transaction - signing'),
|
|
|
+ ('bob_dump_hex_dump_stdout', 'dump_hex transaction - dumping tx hex to stdout'),
|
|
|
+ ('bob_dump_hex_dump', 'dump_hex transaction - dumping tx hex to file'),
|
|
|
+ ('bob_dump_hex_test', 'dump_hex transaction - test whether TX can be sent'),
|
|
|
+ ('bob_dump_hex_send_cli', 'dump_hex transaction - sending via cli'),
|
|
|
+ ('generate', 'mining a block'),
|
|
|
+ ('bob_bal7', 'Bob’s balance'),
|
|
|
+ ),
|
|
|
}
|
|
|
|
|
|
def __init__(self, trunner, cfgs, spawn):
|
|
|
@@ -494,11 +506,12 @@ class CmdTestRegtest(CmdTestBase, CmdTestShared):
|
|
|
self.burn_addr = make_burn_addr(self.proto)
|
|
|
self.user_sids = {}
|
|
|
self.protos = (self.proto,)
|
|
|
+ self.dump_hex_subdir = os.path.join(self.tmpdir, 'nochg_tx')
|
|
|
|
|
|
def _add_comments_to_addr_file(self, proto, addrfile, outfile, use_comments=False):
|
|
|
silence()
|
|
|
gmsg(f'Adding comments to address file {addrfile!r}')
|
|
|
- a = AddrList(cfg, proto, addrfile)
|
|
|
+ a = AddrList(cfg, proto, infile=addrfile)
|
|
|
for n, idx in enumerate(a.idxs(), 1):
|
|
|
if use_comments:
|
|
|
a.set_comment(idx, get_comment())
|
|
|
@@ -548,7 +561,7 @@ class CmdTestRegtest(CmdTestBase, CmdTestShared):
|
|
|
t.expect('time until halving')
|
|
|
return t
|
|
|
|
|
|
- def cli_txcreate(self):
|
|
|
+ def cli_createrawtransaction(self):
|
|
|
txid = 'beadcafe' * 8
|
|
|
return self.spawn(
|
|
|
'mmgen-cli',
|
|
|
@@ -777,6 +790,15 @@ class CmdTestRegtest(CmdTestBase, CmdTestShared):
|
|
|
def bob_twview1(self):
|
|
|
return self.user_twview('bob', chk=('1', rtAmts[0]))
|
|
|
|
|
|
+ def _user_bal_cli(self, user, *, chk=None, chks=[]):
|
|
|
+ t = self.spawn('mmgen-cli', [f'--{user}', 'getbalance', '*', '1', 'true'])
|
|
|
+ res = t.read().splitlines()[0].rstrip('0').rstrip('.')
|
|
|
+ if chk:
|
|
|
+ assert res == chk, f'{res}: invalid balance! (expected {chk})'
|
|
|
+ else:
|
|
|
+ assert res in chks, f'{res}: invalid balance! (expected one of {chks})'
|
|
|
+ return t
|
|
|
+
|
|
|
def user_bal(self, user, bal, opts=[], args=['showempty=1'], skip_check=False, proto=None):
|
|
|
proto = proto or self.proto
|
|
|
t = self.spawn('mmgen-tool', opts + [f'--{user}', f'--coin={proto.coin}', 'listaddresses'] + args)
|
|
|
@@ -785,20 +807,16 @@ class CmdTestRegtest(CmdTestBase, CmdTestShared):
|
|
|
return t
|
|
|
|
|
|
def alice_bal1(self):
|
|
|
- return self.user_bal('alice', rtFundAmt)
|
|
|
+ return self._user_bal_cli('alice', chk=rtFundAmt)
|
|
|
|
|
|
def alice_bal2(self):
|
|
|
- return self.user_bal('alice', rtBals[8])
|
|
|
+ return self._user_bal_cli('alice', chk=rtBals[8])
|
|
|
|
|
|
- def bob_bal1_cli(self):
|
|
|
- t = self.spawn(
|
|
|
- 'mmgen-cli',
|
|
|
- ['--regtest=1', '--wallet=bob', f'--coin={self.proto.coin}', 'getbalance', '*', '0', 'true'])
|
|
|
- t.expect(rtFundAmt + '.00')
|
|
|
- return t
|
|
|
+ def bob_bal1(self):
|
|
|
+ return self._user_bal_cli('bob', chk=rtFundAmt)
|
|
|
|
|
|
def bob_bal2(self):
|
|
|
- return self.user_bal('bob', rtBals[0], self._cashaddr_opt(1))
|
|
|
+ return self._user_bal_cli('bob', chk=rtBals[0])
|
|
|
|
|
|
def bob_bal2a(self):
|
|
|
return self.user_bal('bob', rtBals[0], args=['showempty=1', 'age_fmt=confs'])
|
|
|
@@ -819,16 +837,16 @@ class CmdTestRegtest(CmdTestBase, CmdTestShared):
|
|
|
return self.user_bal('bob', rtBals[0], args=['showempty=0', 'sort=twmmid', 'reverse=1'])
|
|
|
|
|
|
def bob_bal3(self):
|
|
|
- return self.user_bal('bob', rtBals[1])
|
|
|
+ return self._user_bal_cli('bob', chk=rtBals[1])
|
|
|
|
|
|
def bob_bal4(self):
|
|
|
- return self.user_bal('bob', rtBals[2])
|
|
|
+ return self._user_bal_cli('bob', chk=rtBals[2])
|
|
|
|
|
|
def bob_bal5(self):
|
|
|
- return self.user_bal('bob', rtBals[3])
|
|
|
+ return self._user_bal_cli('bob', chk=rtBals[3])
|
|
|
|
|
|
def bob_bal6(self):
|
|
|
- return self.user_bal('bob', rtBals[7])
|
|
|
+ return self._user_bal_cli('bob', chk=rtBals[7])
|
|
|
|
|
|
def bob_subwallet_addrgen1(self):
|
|
|
return self.addrgen('bob', subseed_idx='29L', mmtypes=['C']) # 29L: 2FA7BBA8
|
|
|
@@ -1110,7 +1128,7 @@ class CmdTestRegtest(CmdTestBase, CmdTestShared):
|
|
|
sid, self.get_altcoin_pfx(proto.coin), id_str, addr_range, x='-α' if cfg.debug_utf8 else '')
|
|
|
addrfile = get_file_with_ext(self._user_dir(user), ext, no_dot=True)
|
|
|
silence()
|
|
|
- addr = AddrList(cfg, proto, addrfile).data[idx].addr
|
|
|
+ addr = AddrList(cfg, proto, infile=addrfile).data[idx].addr
|
|
|
end_silence()
|
|
|
return addr
|
|
|
|
|
|
@@ -2180,6 +2198,64 @@ class CmdTestRegtest(CmdTestBase, CmdTestShared):
|
|
|
'L',
|
|
|
'contains no unused addresses of address type')
|
|
|
|
|
|
+ def bob_dump_hex_create(self):
|
|
|
+ if not os.path.exists(self.dump_hex_subdir):
|
|
|
+ os.mkdir(self.dump_hex_subdir)
|
|
|
+ autochg_arg = self._user_sid('bob') + ':C'
|
|
|
+ return self.txcreate_ui_common(
|
|
|
+ self.spawn('mmgen-txcreate',
|
|
|
+ [
|
|
|
+ '-d',
|
|
|
+ self.dump_hex_subdir,
|
|
|
+ '-B',
|
|
|
+ '--bob',
|
|
|
+ '--fee=0.00009713',
|
|
|
+ autochg_arg
|
|
|
+ ]),
|
|
|
+ auto_chg_addr = autochg_arg)
|
|
|
+
|
|
|
+ def bob_dump_hex_sign(self):
|
|
|
+ txfile = get_file_with_ext(self.dump_hex_subdir, 'rawtx')
|
|
|
+ return self.txsign_ui_common(
|
|
|
+ self.spawn('mmgen-txsign', ['-d', self.dump_hex_subdir, '--bob', txfile]),
|
|
|
+ do_passwd = True,
|
|
|
+ passwd = rt_pw)
|
|
|
+
|
|
|
+ def _bob_dump_hex_dump(self, file):
|
|
|
+ txfile = get_file_with_ext(self.dump_hex_subdir, 'sigtx')
|
|
|
+ t = self.spawn('mmgen-txsend', ['-d', self.dump_hex_subdir, f'--dump-hex={file}', '--bob', txfile])
|
|
|
+ t.expect('view: ', '\n')
|
|
|
+ t.expect('(y/N): ', '\n') # add comment?
|
|
|
+ t.written_to_file('Sent transaction')
|
|
|
+ return t
|
|
|
+
|
|
|
+ def bob_dump_hex_dump(self):
|
|
|
+ return self._bob_dump_hex_dump('tx_dump.hex')
|
|
|
+
|
|
|
+ def bob_dump_hex_dump_stdout(self):
|
|
|
+ return self._bob_dump_hex_dump('-')
|
|
|
+
|
|
|
+ def _user_dump_hex_send_cli(self, user, *, subdir=None):
|
|
|
+ txhex = self.read_from_tmpfile('tx_dump.hex', subdir=subdir).strip()
|
|
|
+ t = self.spawn('mmgen-cli', [f'--{user}', 'sendrawtransaction', txhex])
|
|
|
+ txid = t.read().splitlines()[0]
|
|
|
+ assert is_hex_str(txid) and len(txid) == 64
|
|
|
+ return t
|
|
|
+
|
|
|
+ def bob_dump_hex_test(self):
|
|
|
+ txfile = get_file_with_ext(self.dump_hex_subdir, 'sigtx')
|
|
|
+ t = self.spawn('mmgen-txsend', ['--bob', '--test', txfile])
|
|
|
+ self.txsend_ui_common(t, bogus_send=False, test=True)
|
|
|
+ return t
|
|
|
+
|
|
|
+ def bob_dump_hex_send_cli(self):
|
|
|
+ return self._user_dump_hex_send_cli('bob', subdir='nochg_tx')
|
|
|
+
|
|
|
+ def bob_bal7(self):
|
|
|
+ if not self.coin == 'btc':
|
|
|
+ return 'skip'
|
|
|
+ return self._user_bal_cli('bob', chks=['499.99990287', '46.51845565'])
|
|
|
+
|
|
|
def stop(self):
|
|
|
self.spawn('', msg_only=True)
|
|
|
if cfg.no_daemon_stop:
|