SeedSigner / seedsigner

Use an air-gapped Raspberry Pi Zero to sign for Bitcoin transactions! (and do other cool stuff)
MIT License
699 stars 161 forks source link

TextDoesNotFitException when trying to sign very long messages. #550

Open Lagrang3 opened 5 months ago

Lagrang3 commented 5 months ago

OCEAN mining pool have just announced lightning payouts (https://ocean.xyz/docs/lightning). The instructions require to sign a message containing a BOLT12 lightning invoice which is usually a very long string of characters with no white spaces. When trying to sign he message with Seedsigner version 0.7.0 i get on screen an error:

TextDoesNotFitException
components.py 1398, ...

It seems that the exception is raised not because the device is not able to sign the message, but instead because it is unable to display it on screen.

newtonick commented 5 months ago

Can you provide some additional information to help us recreate this error? Which coordinator are you using or how are you getting the message to SeedSigner? Can you give an example message with all private information replaced with some character (like x)?

Lagrang3 commented 5 months ago

Hi. I used Sparrow Wallet's sign message dialog, the message is passed through a QR code. The message to sign is something like this:

{"height":841407,"lightning_bolt12":"lno1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}

x's obscuring the actual BOLT12 invoice characters. But already this message veryloooooooooooooooooonnnnnngtext is enough to trigger the error.

newtonick commented 5 months ago

Hi. I used Sparrow Wallet's sign message dialog, the message is passed through a QR code. The message to sign is something like this:

{"height":841407,"lightning_bolt12":"lno1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}

x's obscuring the actual BOLT12 invoice characters. But already this message veryloooooooooooooooooonnnnnngtext is enough to trigger the error.

Thank you. I was able to recreate the issue.

Python backend full error output:

Executing SeedSignMessageConfirmMessageView()
Traceback (most recent call last):
  File "/home/pi/seedsigner/src/seedsigner/controller.py", line 313, in start
    next_destination = next_destination.run()
  File "/home/pi/seedsigner/src/seedsigner/views/view.py", line 161, in run
    return self._run_view()
  File "/home/pi/seedsigner/src/seedsigner/views/view.py", line 156, in _run_view
    return self.view.run()
  File "/home/pi/seedsigner/src/seedsigner/views/seed_views.py", line 1976, in run
    selected_menu_num = self.run_screen(
  File "/home/pi/seedsigner/src/seedsigner/views/view.py", line 109, in run_screen
    self.screen = Screen_cls(**kwargs)
  File "<string>", line 21, in __init__
  File "/home/pi/seedsigner/src/seedsigner/gui/screens/seed_screens.py", line 1516, in __post_init__
    paged = reflow_text_into_pages(
  File "/home/pi/seedsigner/src/seedsigner/gui/components.py", line 1431, in reflow_text_into_pages
    reflowed_lines_dicts = reflow_text_for_width(text=text,
  File "/home/pi/seedsigner/src/seedsigner/gui/components.py", line 1399, in reflow_text_for_width
    raise TextDoesNotFitException("Text cannot fit in target rect with this font+size")
seedsigner.gui.components.TextDoesNotFitException: Text cannot fit in target rect with this font+size
Text cannot fit in target rect with this font+size
Traceback (most recent call last):
  File "/home/pi/seedsigner/src/seedsigner/controller.py", line 313, in start
    next_destination = next_destination.run()
  File "/home/pi/seedsigner/src/seedsigner/views/view.py", line 161, in run
    return self._run_view()
  File "/home/pi/seedsigner/src/seedsigner/views/view.py", line 156, in _run_view
    return self.view.run()
  File "/home/pi/seedsigner/src/seedsigner/views/seed_views.py", line 1976, in run
    selected_menu_num = self.run_screen(
  File "/home/pi/seedsigner/src/seedsigner/views/view.py", line 109, in run_screen
    self.screen = Screen_cls(**kwargs)
  File "<string>", line 21, in __init__
  File "/home/pi/seedsigner/src/seedsigner/gui/screens/seed_screens.py", line 1516, in __post_init__
    paged = reflow_text_into_pages(
  File "/home/pi/seedsigner/src/seedsigner/gui/components.py", line 1431, in reflow_text_into_pages
    reflowed_lines_dicts = reflow_text_for_width(text=text,
  File "/home/pi/seedsigner/src/seedsigner/gui/components.py", line 1399, in reflow_text_for_width
    raise TextDoesNotFitException("Text cannot fit in target rect with this font+size")
seedsigner.gui.components.TextDoesNotFitException: Text cannot fit in target rect with this font+size
Appending next destination: UnhandledExceptionView({'error': ['TextDoesNotFitException', 'components.py, 1399, in reflow_text_for_width', ' Text cannot fit in target rect with this font+size']}) | clear_history: True
------------------------------
back_stack: [
     0: UnhandledExceptionView({'error': ['TextDoesNotFitException', 'components.py, 1399, in reflow_text_for_width', ' Text cannot fit in target rect with this font+size']}) | clear_history: True
]
Executing UnhandledExceptionView({'error': ['TextDoesNotFitException', 'components.py, 1399, in reflow_text_for_width', ' Text cannot fit in target rect with this font+size']}) | clear_history: True

Looks like this error might be raised intentionally. I've not used message signing much and I would have not expected a use case with no whitespace at all. https://github.com/SeedSigner/seedsigner/blob/adbf5bc1967c8e91a3fa4cf2c7c6e9a4cb7342a4/src/seedsigner/gui/components.py#L1397

newtonick commented 5 months ago

This one line change in the code would allow signing to continue, but the entire content of the message would not be visible.

diff --git a/src/seedsigner/gui/screens/seed_screens.py b/src/seedsigner/gui/screens/seed_screens.py
index 9fe35c1..b2bc48d 100644
--- a/src/seedsigner/gui/screens/seed_screens.py
+++ b/src/seedsigner/gui/screens/seed_screens.py
@@ -1517,6 +1517,7 @@ class SeedSignMessageConfirmMessageScreen(ButtonListScreen):
                 text=self.sign_message_data["message"],
                 width=renderer.canvas_width - 2*GUIConstants.EDGE_PADDING,
                 height=message_height,
+                allow_text_overflow=True,
             )
             self.sign_message_data["paged_message"] = paged
jdlcdl commented 2 months ago

While text flows off the screen, this is working for me.