autosign: print summary of non-MMGen output addresses and amounts
To allow the user to verify that transaction outputs have not been altered by a compromised online MMGen installation, print a list of non-MMGen output addresses and amounts for all signed transactions after every autosign run. With --full-summary, print a full view of each signed transaction instead.
This commit is contained in:
parent
4a2cc07ef1
commit
d558822941
3 changed files with 61 additions and 4 deletions
|
|
@ -44,6 +44,9 @@ opts_data = {
|
|||
-m, --mountpoint=m Specify an alternate mountpoint (default: '{mp}')
|
||||
-s, --stealth-led Stealth LED mode - signal busy and error only, and only
|
||||
after successful authorization.
|
||||
-S, --full-summary Print a full summary of each signed transaction after
|
||||
each autosign run. The default list of non-MMGen outputs
|
||||
will not be printed.
|
||||
-q, --quiet Produce quieter output
|
||||
-v, --verbose Produce more verbose output
|
||||
""".format(mp=mountpoint),
|
||||
|
|
@ -191,6 +194,7 @@ def sign_tx_file(txfile):
|
|||
|
||||
if txsign(tx,wfs,None,None):
|
||||
tx.write_to_file(ask_write=False)
|
||||
txlist.append(tx)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
|
@ -241,13 +245,48 @@ def decrypt_wallets():
|
|||
|
||||
return False if fails else True
|
||||
|
||||
|
||||
def print_summary():
|
||||
|
||||
if opt.full_summary:
|
||||
bmsg('\nAutosign summary:')
|
||||
for tx in txlist:
|
||||
init_coin(tx.coin,tx.chain == 'testnet')
|
||||
msg_r(tx.format_view(terse=True))
|
||||
return
|
||||
|
||||
body = []
|
||||
for tx in txlist:
|
||||
non_mmgen = [o for o in tx.outputs if not o.mmid]
|
||||
if non_mmgen:
|
||||
body.append((tx,non_mmgen))
|
||||
|
||||
if body:
|
||||
bmsg('\nAutosign summary:')
|
||||
fs = '{} {} {}'
|
||||
t_wid,a_wid = 6,44
|
||||
msg(fs.format('TX ID ','Non-MMGen outputs'+' '*(a_wid-17),'Amount'))
|
||||
msg(fs.format('-'*t_wid, '-'*a_wid, '-'*7))
|
||||
for tx,non_mmgen in body:
|
||||
for nm in non_mmgen:
|
||||
msg(fs.format(
|
||||
tx.txid.fmt(width=t_wid,color=True) if nm is non_mmgen[0] else ' '*t_wid,
|
||||
nm.addr.fmt(width=a_wid,color=True),
|
||||
nm._amt.hl() + ' ' + yellow(tx.coin)))
|
||||
else:
|
||||
msg('No non-MMGen outputs')
|
||||
|
||||
def do_sign():
|
||||
if not opt.stealth_led: set_led('busy')
|
||||
do_mount()
|
||||
key_ok = decrypt_wallets()
|
||||
if key_ok:
|
||||
if opt.stealth_led: set_led('busy')
|
||||
global txlist
|
||||
txlist = []
|
||||
ret = sign()
|
||||
print_summary()
|
||||
txlist = []
|
||||
do_umount()
|
||||
set_led(('standby','off','error')[(not ret)*2 or bool(opt.stealth_led)])
|
||||
return ret
|
||||
|
|
|
|||
5
test/ref/25EFA3[2.34].testnet.rawtx
Normal file
5
test/ref/25EFA3[2.34].testnet.rawtx
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
3df942
|
||||
TESTNET 25EFA3 2.34 20190424_101833 433
|
||||
0200000001db9d489e2b43e30b96931364d1a4ba97bd2f5515790c82703e7b7f11e549f51a0100000000ffffffff03c0b99d06000000001976a91496235113a5c6608bdb9bc5f5e08c69458a6b17dd88acc0d45407000000001976a9148970c0a71207de041f707febfcbdac46cbd7aaf588ac702e19460200000017a914daaf772bc9d05b41f6811fa200a34fcd4d58ed2c8700000000
|
||||
[{'txid': '1af549e5117f7b3e70820c7915552fbd97baa4d1641393960be3432b9e489ddb', 'vout': 1, 'label': '', 'scriptPubKey': 'a914f199a1b4f46bd0f659287517435f4d84fda854c887', 'amt': '100', 'addr': '2NFGgt2iky94KDocUV6nE2GsGg6uvetUWzH', 'confs': 1, 'mmid': '98831F3A:S:31'}]
|
||||
[{'addr': 'muCoxgBTXA1CFb9phJqMZgqP2rm1mPrbKE', 'amt': '1.11', 'is_chg': False}, {'addr': 'mt3fwX52huqVB1aU6Y2cLts3WVG4bBeqS1', 'amt': '1.23', 'is_chg': False}, {'addr': '2NDBXVfG7uUDwrZPyEZPc8vRMyZN4dfPoY7', 'amt': '97.6599', 'is_chg': True, 'mmid': '98831F3A:S:1'}]
|
||||
|
|
@ -44,14 +44,14 @@ class TestSuiteAutosign(TestSuiteBase):
|
|||
return self.autosign(
|
||||
coins=['btc','eth'],
|
||||
txfiles=['btc','eth','mm1','etc'],
|
||||
txcount=7,
|
||||
txcount=8,
|
||||
live=live)
|
||||
|
||||
# tests everything except device detection, mount/unmount
|
||||
def autosign( self,
|
||||
coins=['btc','bch','ltc','eth'],
|
||||
txfiles=['btc','bch','ltc','eth','mm1','etc'],
|
||||
txcount=11,
|
||||
txcount=12,
|
||||
live=False):
|
||||
|
||||
if self.skip_for_win(): return
|
||||
|
|
@ -103,8 +103,9 @@ class TestSuiteAutosign(TestSuiteBase):
|
|||
fdata = [e for e in fdata_in if e[0] in txfiles]
|
||||
from test.test_py_d.ts_ref import TestSuiteRef
|
||||
tfns = [TestSuiteRef.sources['ref_tx_file'][c][1] for c,d in fdata] + \
|
||||
[TestSuiteRef.sources['ref_tx_file'][c][0] for c,d in fdata]
|
||||
tfs = [joinpath(ref_dir,d[1],fn) for d,fn in zip(fdata+fdata,tfns)]
|
||||
[TestSuiteRef.sources['ref_tx_file'][c][0] for c,d in fdata] + \
|
||||
['25EFA3[2.34].testnet.rawtx'] # TX with 2 non-MMGen outputs
|
||||
tfs = [joinpath(ref_dir,d[1],fn) for d,fn in zip(fdata+fdata+[('btc','')],tfns)]
|
||||
|
||||
for f,fn in zip(tfs,tfns):
|
||||
if fn: # use empty fn to skip file
|
||||
|
|
@ -172,13 +173,25 @@ class TestSuiteAutosign(TestSuiteBase):
|
|||
|
||||
def do_autosign(opts,mountpoint):
|
||||
make_wallet(opts)
|
||||
|
||||
copy_files(mountpoint,include_bad_tx=True)
|
||||
t = self.spawn('mmgen-autosign',opts+['--full-summary','wait'],extra_desc='(sign - full summary)')
|
||||
t.expect('{} transactions signed'.format(txcount))
|
||||
t.expect('1 transaction failed to sign')
|
||||
t.expect('Waiting')
|
||||
t.kill(2)
|
||||
t.req_exit_val = 1
|
||||
imsg('')
|
||||
t.ok()
|
||||
|
||||
copy_files(mountpoint,remove_signed_only=True)
|
||||
t = self.spawn('mmgen-autosign',opts+['wait'],extra_desc='(sign)')
|
||||
t.expect('{} transactions signed'.format(txcount))
|
||||
t.expect('1 transaction failed to sign')
|
||||
t.expect('Waiting')
|
||||
t.kill(2)
|
||||
t.req_exit_val = 1
|
||||
imsg('')
|
||||
return t
|
||||
|
||||
if live:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue