mmgen-txcreate: warn user if change address is a used address
This commit is contained in:
parent
4b07f8fac8
commit
68caeb3130
5 changed files with 59 additions and 8 deletions
|
|
@ -242,6 +242,13 @@ class TwAddresses(TwView):
|
|||
def dump_fn_pfx(self):
|
||||
return 'listaddresses' + (f'-minconf-{self.minconf}' if self.minconf else '')
|
||||
|
||||
def is_used(self,coinaddr):
|
||||
for e in self.data:
|
||||
if e.addr == coinaddr:
|
||||
return bool(e.recvd)
|
||||
else: # addr not in tracking wallet
|
||||
return None
|
||||
|
||||
class action(TwView.action):
|
||||
|
||||
def s_amt(self,parent):
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ tx.new: new transaction class
|
|||
from ..globalvars import *
|
||||
from ..opts import opt
|
||||
from .base import Base
|
||||
from ..color import pink
|
||||
from ..color import pink,yellow
|
||||
from ..obj import get_obj,MMGenList
|
||||
from ..util import msg,qmsg,fmt,die,suf,remove_dups,get_extension
|
||||
from ..addr import is_mmgen_id,CoinAddr,is_coin_addr
|
||||
|
|
@ -235,6 +235,25 @@ class New(Base):
|
|||
self.add_mmaddrs_to_outputs(ad_w,ad_f)
|
||||
self.check_dup_addrs('outputs')
|
||||
|
||||
chg_idx = self.get_chg_output_idx()
|
||||
if chg_idx is not None:
|
||||
await self.warn_chg_addr_used(self.outputs[chg_idx])
|
||||
|
||||
async def warn_chg_addr_used(self,chg):
|
||||
from ..tw.addresses import TwAddresses
|
||||
if (await TwAddresses(self.proto,get_data=True)).is_used(chg.addr):
|
||||
from ..ui import keypress_confirm
|
||||
if not keypress_confirm(
|
||||
'{a} {b} {c}\n{d}'.format(
|
||||
a = yellow(f'Requested change address'),
|
||||
b = (chg.mmid or chg.addr).hl(),
|
||||
c = yellow('is already used!'),
|
||||
d = yellow('Address reuse harms your privacy and security. Continue anyway? (y/N): ')
|
||||
),
|
||||
complete_prompt = True,
|
||||
default_yes = False ):
|
||||
die(1,'Exiting at user request')
|
||||
|
||||
# inputs methods
|
||||
def select_unspent(self,unspent):
|
||||
prompt = 'Enter a range or space-separated list of outputs to spend: '
|
||||
|
|
|
|||
12
test/overlay/fakemods/mmgen/tx/new.py
Normal file
12
test/overlay/fakemods/mmgen/tx/new.py
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import os as overlay_fake_os
|
||||
from .new_orig import *
|
||||
|
||||
if overlay_fake_os.getenv('MMGEN_BOGUS_UNSPENT_DATA'):
|
||||
|
||||
class overlay_fake_data:
|
||||
|
||||
async def warn_chg_addr_used(foo,us):
|
||||
from ..util import ymsg
|
||||
ymsg('Bogus unspent data: skipping change address is used check')
|
||||
|
||||
New.warn_chg_addr_used = overlay_fake_data.warn_chg_addr_used
|
||||
|
|
@ -638,9 +638,13 @@ class TestSuiteRegtest(TestSuiteBase,TestSuiteShared):
|
|||
sid1 = self._get_user_subsid('bob','29L')
|
||||
sid2 = self._get_user_subsid('bob','127S')
|
||||
chg_addr = self._user_sid('bob') + (':B:1',':L:1')[self.proto.coin=='BCH']
|
||||
outputs_cl = [sid1+':C:2,0.29',sid2+':C:3,0.127',chg_addr]
|
||||
inputs = ('3','1')[self.proto.coin=='BCH']
|
||||
return self.user_txdo('bob',rtFee[1],outputs_cl,inputs,extra_args=['--subseeds=127'])
|
||||
return self.user_txdo(
|
||||
user = 'bob',
|
||||
fee = rtFee[1],
|
||||
outputs_cl = [sid1+':C:2,0.29',sid2+':C:3,0.127',chg_addr],
|
||||
outputs_list = ('3','1')[self.proto.coin=='BCH'],
|
||||
extra_args = ['--subseeds=127'],
|
||||
used_chg_addr_resp = (None,'y')[self.proto.coin=='BCH'] )
|
||||
|
||||
def bob_twview2(self):
|
||||
sid1 = self._get_user_subsid('bob','29L')
|
||||
|
|
@ -779,7 +783,8 @@ class TestSuiteRegtest(TestSuiteBase,TestSuiteShared):
|
|||
bad_locktime = False,
|
||||
full_tx_view = False,
|
||||
menu = ['M'],
|
||||
skip_passphrase = False ):
|
||||
skip_passphrase = False,
|
||||
used_chg_addr_resp = None ):
|
||||
|
||||
t = self.spawn('mmgen-txdo',
|
||||
['-d',self.tmpdir,'-B','--'+user] +
|
||||
|
|
@ -793,7 +798,9 @@ class TestSuiteRegtest(TestSuiteBase,TestSuiteShared):
|
|||
file_desc = 'Signed transaction',
|
||||
interactive_fee = (tx_fee,'')[bool(fee)],
|
||||
add_comment = tx_comment_jp,
|
||||
view = 't',save=True)
|
||||
view = 't',
|
||||
save = True,
|
||||
used_chg_addr_resp = used_chg_addr_resp )
|
||||
|
||||
if not skip_passphrase:
|
||||
t.passphrase(dfl_wcls.desc,rt_pw)
|
||||
|
|
@ -848,7 +855,8 @@ class TestSuiteRegtest(TestSuiteBase,TestSuiteShared):
|
|||
outputs_cl = self._create_tx_outputs('alice',(('L',1,',60'),('C',1,',40'))) # alice_sid:L:1, alice_sid:C:1
|
||||
outputs_cl += [self._user_sid('bob')+':'+rtBobOp3]
|
||||
return self.user_txdo('bob',rtFee[1],outputs_cl,'3',
|
||||
extra_args=([],['--rbf'])[self.proto.cap('rbf')])
|
||||
extra_args = ([],['--rbf'])[self.proto.cap('rbf')],
|
||||
used_chg_addr_resp = 'y' )
|
||||
|
||||
def bob_send_non_mmgen(self):
|
||||
outputs_cl = self._create_tx_outputs('alice',(
|
||||
|
|
|
|||
|
|
@ -46,13 +46,18 @@ class TestSuiteShared(object):
|
|||
add_comment = '',
|
||||
view = 't',
|
||||
save = True,
|
||||
tweaks = [] ):
|
||||
tweaks = [],
|
||||
used_chg_addr_resp = None ):
|
||||
|
||||
txdo = (caller or self.test_name)[:4] == 'txdo'
|
||||
|
||||
expect_pat = r'\[q\]uit view, .*?:.'
|
||||
delete_pat = r'Enter account number .*:.'
|
||||
confirm_pat = r'Is this what you want.*:.'
|
||||
|
||||
if used_chg_addr_resp is not None:
|
||||
t.expect('reuse harms your privacy.*:.*',used_chg_addr_resp,regex=True)
|
||||
|
||||
pat = expect_pat
|
||||
for choice in menu + ['q']:
|
||||
t.expect(pat,choice,regex=True)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue