Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SettingsQR: Final changes before official release #394

Merged
merged 14 commits into from
Aug 3, 2023

Conversation

kdmukai
Copy link
Contributor

@kdmukai kdmukai commented Jun 21, 2023

SettingsQR has been quietly supported for a while, but this PR will fully promote SettingsQR to be a user-facing feature.

Two repos have to work hand-in-hand here:


Changes in this PR:

The expected SettingsQR format has been slightly tweaked.

Parsing them has been greatly simplified.

Missing settings (either in an onboard settings.json file or in a scanned SettingsQR) are now set to their default value. The only exception are hidden settings (e.g. qr_brightness); their values are preserved if they are already in the current settings.


How to test

You can use the current public SettingsQR Generator as-is: https://seedsigner.github.io/seedsigner-settings-generator

It is in sync with the changes in this PR.

If you want to build the SettingsQR Generator locally, follow the instructions in the repo. Just note that there is a dependence on the SeedSigner repo and it is currently pointing to this branch in my fork.

Before the SettingsQR Generator is fully released, we must:

  • Transfer ownership to SeedSigner
  • Update the developer instructions and the git submodule to point to the main SeedSigner repo and its dev branch.

@jdlcdl
Copy link

jdlcdl commented Jun 21, 2023

As of commit f7c8213, I've taken a look at this; my thoughts: (tl;dr Nice Work!)

  • It works: when using your SettingsGenerator tool.
  • It works: If old-style settings display_name is used instead of the new abbreviated_name.
  • It works: in defaulting missing settings entries to what they would be by default.
  • It works: in nice display for settings name: underscores become spaces for attrib=name.
  • It works: in ignoring nonsensical settings attributes that don't exist.
  • It works: in failing when a settings-attribute is set to a value that is not valid.
  • After reviewing the code changes, I have no concerns to add at this time.

I did notice a few issues that were unexpected:

  • If a user fiddles with creating their own SettingsQR in some other tool, it's possible that they'll add invalid settings values which correctly fails... but they never reach an error screen. They're brought back to the main menu instead (as with other exceptions, sometimes with remnants of the last camera image on screen, till button presses can redraw screen). Might it be better to catch these and redirect to a DireWarningView "script_type: 'p2pkh' is invalid" ?

  • If we add "qr_brightness=32" (or qr_background_color=x) to an otherwise valid SettingsQR, I was unable to actually get this to work (but maybe it shouldn't, since it's hidden?). It was raising an exception related to missing selection_options" in decode_qr at 886.

Traceback (most recent call last):
  File "/home/pi/seedsigner-dev/src/seedsigner/models/decode_qr.py", line 886, in add
    if v not in [opt[0] for opt in settings_entry.selection_options]:
TypeError: 'NoneType' object is not iterable

I was trying to make a SettingsQR out of this content:

settings::v1
name=jdlcdl_Jean_Do
coords=nun,spa
network=T
scripts=nat,tr
priv_warn=D
qr_brightness=32
  • After a successful load of a SettingsQR, going "BACK" get's us back into the scan screen, but maybe it would be more natural to skip that and be back in MainMenu, as if user had hit "Home".

Very nice work! I'm a big fan of this pr!

@kdmukai
Copy link
Contributor Author

kdmukai commented Jul 6, 2023

Thank you, @jdlcdl, these are excellent notes! In the next few days I'll try to take a look at the unexpected/not ideal behaviors.

@jdlcdl
Copy link

jdlcdl commented Jul 27, 2023

Just food for thought, because it's crossed my mind recently.

SettingsQR makes things so simple to do regularly w/o using persistent settings that I wonder:

Should a load of SettingsQR EVER be allowed to set persistent_settings=True?
Maybe this one settings entry should be ignored, always setting it to False after a successful SettingsQR load?

I hope that this PR makes it into the next release. I'll argue to that end.

@@ -47,42 +47,22 @@ def save(self):
os.fsync(settings_file.fileno())


def update(self, new_settings: dict, disable_missing_entries: bool = True):
def update(self, new_settings: dict, ):
Copy link

@jdlcdl jdlcdl Jul 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this pr was submitted, pr-339 flow-tests framework has been merged.
In that pr, I was using the non-default "disabled_missing_entries=False" feature that is no longer present, so I'll be adjusting my test to setup in a one-by-one manner, otherwise this pr once merged would fail the test suite.

also, I think the trailing "," in the signature isn't intended, but I dont believe it's hurting anything.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing comma fixed!

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's a sneaky trailing comma.

@jdlcdl
Copy link

jdlcdl commented Jul 30, 2023

Since this pr was submitted, pr-339 flow-tests have been merged, and I had written a test that exploited the non-default boolean of "disabled_missing_entries=True" in settings.update(). This pr will fail tests because of this, but the fix is below:

In tests/test_flows_seed.py's test_export_xpub_skip_non_option_flow() method:

-        self.settings.update({
-            SettingsConstants.SETTING__SIG_TYPES: SettingsConstants.MULTISIG,
-            SettingsConstants.SETTING__SCRIPT_TYPES: SettingsConstants.NESTED_SEGWIT,
-            SettingsConstants.SETTING__COORDINATORS: SettingsConstants.COORDINATOR__SPECTER_DESKTOP,
-        }, disable_missing_entries=False)
+        self.settings.set_value(SettingsConstants.SETTING__SIG_TYPES, [SettingsConstants.MULTISIG])
+        self.settings.set_value(SettingsConstants.SETTING__SCRIPT_TYPES, [SettingsConstants.NESTED_SEGWIT])
+        self.settings.set_value(SettingsConstants.SETTING__COORDINATORS, [SettingsConstants.COORDINATOR__SPECTER_DESKTOP])

@jdlcdl
Copy link

jdlcdl commented Jul 30, 2023

In my summer-solstice comments, I'd mentioned that invalid settings entry values in a SettingsQR cause an exception that doesn't get raised, so users just fall back to MainMenu without understanding what happened... probably to retry the qrcode scan again and again (only geeky users who create invalid SettingsQRs). Sometimes even, the MainMenu doesn't get rendered and they're left with partial image of the scan, until they move around the MainMenu to repaint it.

The last thing I want to do is break something major in a qr decoder, but I've made the following adjustment to models/decode.qr in SettingsQrDecoder.run() with hopes of seeing what the problem is.
I'm not sure if it wouldn't be better not to have everything in try/except so that the exception bubbles up on its own,
or if the View layer should do something special with DecodeQRStatus.INVALID but it would lose granular exception info.

         except Exception as e:
             logger.exception(e)
-            return DecodeQRStatus.INVALID
+            raise e

which was provoked when trying to scan a SettingsQR with content of:

settings::v1
name=jdlcdl_Jean_Do
coords=nun,spa
network=T
scripts=nat,nes,p2pkh
priv_warn=D

sqrinvalid


A similar change might also resolve my issue with trying to set qr_brightness in a SettingsQR, at least I'd know:

settings::v1
name=jdlcdl_Jean_Do
coords=nun,spa
network=T
scripts=nat,tr
priv_warn=D
qr_brightness=32

sqrbrightness

@jdlcdl
Copy link

jdlcdl commented Jul 30, 2023

This pr plays well with pr #416 (maybe you should check it out?).

@jdlcdl
Copy link

jdlcdl commented Jul 30, 2023

Another comment I had made back in late June was:

After a successful scan, if user uses the BACK button, they go into camera scan mode again, whereas I felt it would feel more natural (since it already succeeded and settings are updated) to land in the MainMenu. I've adjusted views/scan_views.py in ScanView.run() so that when self.decoder.is_settings, skip_current_view like so:

           elif self.decoder.is_settings:
                from seedsigner.models.settings import Settings
                settings = self.decoder.get_settings_data()
                Settings.get_instance().update(new_settings=settings)

                print(json.dumps(Settings.get_instance()._data, indent=4))
                
-               return Destination(SettingsUpdatedView, {"config_name": self.decoder.get_settings_config_name()})
+               return Destination(SettingsUpdatedView, {"config_name": self.decoder.get_settings_config_name()}, skip_current_view=True)

For a last nit-picky comment, but I'm not really sure, it could go either way:
Maybe the SettingsUpdatedView is more-at-home in settings_views.py than scan_views.py???

@kdmukai
Copy link
Contributor Author

kdmukai commented Jul 30, 2023

  • Merged the latest from dev into this branch
  • Did some final(?) cleanup
  • Added decoder tests

@kdmukai
Copy link
Contributor Author

kdmukai commented Jul 30, 2023

re: #394 (comment)

Agreed. Now letting exceptions in the SettingsQR decoder bubble up to the UI, where possible.

* Move post-SettingsQR View to settings_views.py
* Improve ingestion cleaning to gracefully handle single-value `Settings.update()` entries for multi-select settings.
* Improve Exception handling and onscreen error reporting during SettingsQR parsing.
* move tests accordingly out of SettingsQR and into Settings.
@kdmukai
Copy link
Contributor Author

kdmukai commented Jul 31, 2023

Users will now see show-stopping Exceptions.

20230731_105302

@jdlcdl
Copy link

jdlcdl commented Jul 31, 2023

as of b14de31 - 9cc5bcd:

tests that I'd done and were working at f7c8213 are still working,

plus what I'd asked for is working too:

  • exceptions while parsing "incorrect" SettingsQRs are no longer hidden,
  • no going back into scan screen because BACK is disabled.
  • plus even more tests.

ACK tested

@newtonick newtonick added this to the 0.7.0 milestone Jul 31, 2023
@newtonick newtonick added the enhancement New feature or request label Aug 1, 2023
@newtonick
Copy link
Collaborator

ACK Tested

newtonick added a commit to newtonick/seedsigner-settings-generator that referenced this pull request Aug 3, 2023
I believe this should complete the last todo "Update the developer instructions and the git submodule to point to the main SeedSigner repo and its dev branch." in SeedSigner/seedsigner#394
@newtonick newtonick merged commit c6df80c into SeedSigner:dev Aug 3, 2023
@kdmukai kdmukai deleted the settings_qr branch September 2, 2024 13:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Development

Successfully merging this pull request may close these issues.

3 participants