verify addr in QR better, fix some related issues
(cherry picked from commit dd66cd8811)
This commit is contained in:
parent
58c809fc3f
commit
1bc2a95a1b
@ -1538,7 +1538,7 @@ class ShowAddressBase(UserAuthorizedAction):
|
||||
hint_icons=KEY_QR+(KEY_NFC if NFC else ''))
|
||||
|
||||
if ch in '4'+KEY_QR:
|
||||
await show_qr_code(self.address, (self.addr_fmt & AFC_BECH32))
|
||||
await show_qr_code(self.address, (self.addr_fmt & AFC_BECH32), is_addrs=True)
|
||||
continue
|
||||
|
||||
if NFC and (ch in '3'+KEY_NFC):
|
||||
|
||||
@ -667,9 +667,13 @@ class Display:
|
||||
# With fancy display, no address, even classic can fit in single line,
|
||||
# so always split nicely in middle and at mod4
|
||||
hh = len(msg) // 2
|
||||
hh = (hh + 3) & ~0x3
|
||||
parts = [msg[0:hh], msg[hh:]]
|
||||
num_lines = 2
|
||||
if hh <= 20:
|
||||
hh = (hh + 3) & ~0x3
|
||||
parts = [msg[0:hh], msg[hh:]]
|
||||
num_lines = 2
|
||||
else:
|
||||
# p2wsh address would need 3 lines to show, so we won't
|
||||
num_lines = 0
|
||||
elif msg:
|
||||
if len(msg) <= CHARS_W:
|
||||
parts = [msg]
|
||||
|
||||
@ -349,7 +349,7 @@ class OwnershipCache:
|
||||
await show_qr_code(
|
||||
addr,
|
||||
is_alnum=(wallet.addr_fmt & (AFC_BECH32 | AFC_BECH32M)),
|
||||
msg=addr
|
||||
msg=addr, is_addrs=True
|
||||
)
|
||||
elif not is_complex and (ch == "0"): # only singlesig
|
||||
from auth import sign_with_own_address
|
||||
|
||||
@ -595,6 +595,42 @@ def cap_screen_qr(cap_image):
|
||||
|
||||
return doit
|
||||
|
||||
@pytest.fixture
|
||||
def verify_qr_address(cap_screen_qr, cap_screen, is_q1):
|
||||
# check we can read QR and that it has exact value expected
|
||||
# plus text version of address, if any, is right.
|
||||
from ckcc_protocol.constants import AFC_BECH32
|
||||
|
||||
def doit(addr_fmt, expect_addr=None):
|
||||
qr = cap_screen_qr().decode('ascii')
|
||||
|
||||
if addr_fmt & AFC_BECH32:
|
||||
qr = qr.lower()
|
||||
|
||||
# check text --if any-- matches QR contents
|
||||
# - remove spaces and newlines
|
||||
# - ok if no text, which happens when QR is productively using screen space
|
||||
# - skips first line, which on Q shows the index number sometimes
|
||||
# - insists on some spaces
|
||||
full = cap_screen()
|
||||
if is_q1:
|
||||
txt = ''.join(full.split()[1:]).replace('~', '')
|
||||
else:
|
||||
txt = ''.join(full.split())
|
||||
|
||||
if txt:
|
||||
assert txt == qr
|
||||
if is_q1:
|
||||
# addr is not spaced out on Mk4, but check it was on Q
|
||||
assert (qr[0:4] + ' ' + qr[4:8]) in full, 'was not spaced out'
|
||||
|
||||
if expect_addr is not None:
|
||||
assert qr == expect_addr
|
||||
|
||||
return qr
|
||||
|
||||
return doit
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def get_pp_sofar(sim_exec):
|
||||
# get entry value for bip39 passphrase
|
||||
|
||||
@ -30,7 +30,7 @@ def test_show_addr_usb(dev, press_select, addr_vs_path, path, addr_fmt, is_simul
|
||||
@pytest.mark.parametrize('path', [ 'm', "m/1/2", "m/1'/100'", "m/0h/500h"])
|
||||
@pytest.mark.parametrize('addr_fmt', [ AF_CLASSIC, AF_P2WPKH, AF_P2WPKH_P2SH, AF_P2TR ])
|
||||
def test_show_addr_displayed(dev, need_keypress, addr_vs_path, path, addr_fmt,
|
||||
cap_story, cap_screen_qr, qr_quality_check,
|
||||
cap_story, verify_qr_address, qr_quality_check,
|
||||
press_cancel, is_q1):
|
||||
time.sleep(0.1)
|
||||
|
||||
@ -55,9 +55,8 @@ def test_show_addr_displayed(dev, need_keypress, addr_vs_path, path, addr_fmt,
|
||||
|
||||
need_keypress(KEY_QR if is_q1 else '4')
|
||||
time.sleep(0.1)
|
||||
qr = cap_screen_qr().decode('ascii')
|
||||
|
||||
assert qr == addr or qr == addr.upper()
|
||||
verify_qr_address(addr_fmt, addr)
|
||||
|
||||
@pytest.mark.bitcoind
|
||||
@pytest.mark.parametrize("addr_fmt", [
|
||||
|
||||
@ -374,7 +374,7 @@ def test_account_menu(way, account_num, sim_execfile, pick_menu_item,
|
||||
@pytest.mark.parametrize('which_fmt', [ AF_CLASSIC, AF_P2WPKH, AF_P2WPKH_P2SH, AF_P2TR])
|
||||
def test_custom_path(path_sidx, which_fmt, addr_vs_path, pick_menu_item, goto_address_explorer,
|
||||
need_keypress, cap_menu, parse_display_screen, validate_address,
|
||||
cap_screen_qr, qr_quality_check, nfc_read_text, get_setting,
|
||||
verify_qr_address, qr_quality_check, nfc_read_text, get_setting,
|
||||
press_select, press_cancel, is_q1, press_nfc, cap_story,
|
||||
generate_addresses_file, settings_set, set_addr_exp_start_idx,
|
||||
sign_msg_from_address):
|
||||
@ -474,11 +474,7 @@ def test_custom_path(path_sidx, which_fmt, addr_vs_path, pick_menu_item, goto_ad
|
||||
addr_vs_path(addr, path, addr_fmt=which_fmt)
|
||||
|
||||
need_keypress(KEY_QR if is_q1 else '4')
|
||||
qr = cap_screen_qr().decode('ascii')
|
||||
if which_fmt in (AF_P2WPKH, AF_P2TR):
|
||||
assert qr == addr.upper()
|
||||
else:
|
||||
assert qr == addr
|
||||
qr = verify_qr_address(which_fmt, addr)
|
||||
|
||||
if get_setting('nfc', 0):
|
||||
# this is actually testing NFC export in qr code menu
|
||||
@ -534,9 +530,7 @@ def test_custom_path(path_sidx, which_fmt, addr_vs_path, pick_menu_item, goto_ad
|
||||
qr_addr_list = []
|
||||
need_keypress(KEY_QR if is_q1 else '4')
|
||||
for i in range(n):
|
||||
qr = cap_screen_qr().decode('ascii')
|
||||
if which_fmt in (AF_P2WPKH, AF_P2TR):
|
||||
qr = qr.lower()
|
||||
qr = verify_qr_address(which_fmt)
|
||||
qr_addr_list.append(qr)
|
||||
need_keypress(KEY_RIGHT if is_q1 else "9")
|
||||
time.sleep(.5)
|
||||
|
||||
@ -9,6 +9,7 @@ from helpers import hash160, taptweak, addr_from_display_format
|
||||
from bip32 import BIP32Node
|
||||
from constants import AF_P2WSH, AF_P2SH, AF_P2WSH_P2SH, AF_CLASSIC, AF_P2WPKH, AF_P2WPKH_P2SH, AF_P2TR
|
||||
from constants import simulator_fixed_xprv, simulator_fixed_tprv, addr_fmt_names
|
||||
from charcodes import KEY_QR
|
||||
|
||||
@pytest.fixture
|
||||
def wipe_cache(sim_exec):
|
||||
@ -173,7 +174,7 @@ def test_ux(valid, testnet, method,
|
||||
sim_exec, wipe_cache, make_myself_wallet, use_testnet, goto_home, pick_menu_item,
|
||||
press_cancel, press_select, settings_set, is_q1, nfc_write, need_keypress,
|
||||
cap_screen, cap_story, load_shared_mod, scan_a_qr, skip_if_useless_way,
|
||||
sign_msg_from_address, multisig, import_ms_wallet, clear_ms,
|
||||
sign_msg_from_address, multisig, import_ms_wallet, clear_ms, verify_qr_address
|
||||
):
|
||||
skip_if_useless_way(method)
|
||||
addr_fmt = AF_CLASSIC
|
||||
@ -192,6 +193,7 @@ def test_ux(valid, testnet, method,
|
||||
M, keys, is_change=0, idx=50, addr_fmt=AF_P2WSH,
|
||||
testnet=int(testnet), path_mapper=lambda cosigner: [HARD(45), 0, 50]
|
||||
)
|
||||
addr_fmt = AF_P2WSH
|
||||
else:
|
||||
mk = BIP32Node.from_wallet_key(simulator_fixed_tprv if testnet else simulator_fixed_xprv)
|
||||
path = "m/44h/{ct}h/{acc}h/0/3".format(acc=0, ct=(1 if testnet else 0))
|
||||
@ -242,6 +244,12 @@ def test_ux(valid, testnet, method,
|
||||
assert 'Found in wallet' in story
|
||||
assert 'Derivation path' in story
|
||||
|
||||
if is_q1:
|
||||
# check it can display as QR from here
|
||||
need_keypress(KEY_QR)
|
||||
verify_qr_address(addr_fmt, addr)
|
||||
press_cancel()
|
||||
|
||||
if multisig:
|
||||
assert expect_name in story
|
||||
assert "Press (0) to sign message with this key" not in story
|
||||
|
||||
Loading…
Reference in New Issue
Block a user