bugfix: simulator crashed, then hung, on Destroy Seed - #730
Open
hitechhayekian wants to merge 2 commits into
Open
bugfix: simulator crashed, then hung, on Destroy Seed#730hitechhayekian wants to merge 2 commits into
hitechhayekian wants to merge 2 commits into
Conversation
wipe_flash_filesystem() drives the internal flash as a block device via pyb.Flash(start=0), but the simulator's pyb stand-in never defined Flash. Destroy Seed died partway through with: File "shared/actions.py", line 609, in clear_seed File "shared/files.py", line 59, in wipe_flash_filesystem AttributeError: 'module' object has no attribute 'Flash' It fails after the confirmations and after trick PINs are cleared, so the wallet is left half-wiped. Add a Flash block-device stub alongside the existing SDCard one, using the same "pretend to work" approach: 512-byte sectors, as files.py asserts, and writes that go nowhere. Also add a test holding the simulator's pyb to the attributes the shared firmware actually uses, which is what would have caught this before it reached a menu action. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ckcc.oneway() stands in for the bootloader callgate that never returns. It printed a NOTE and then looped on utime.sleep(60) forever, so the simulator sat on whatever frame was last drawn. After Destroy Seed that is "Clearing...", which is indistinguishable from a crash - even though the wipe had in fact run to completion. Raise SystemExit instead, and say what the bootloader would have done. All four one-way methods end firmware execution on real hardware (DFU, logout, wipe, brick), so all four stop here rather than spin. machine.py already does exactly this for bootloader()/soft_reset()/reset(), and the simulator is launched with -i, so this lands at the REPL the same way a simulated reset always has. Deliberately not calling machine.py's _flush_data() alongside it: that does settings.save(), and clear_seed() blanks settings on the line before fast_wipe(), so flushing here would write back what was just erased. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
scgbckbone
reviewed
Aug 15, 2026
scgbckbone
left a comment
Collaborator
There was a problem hiding this comment.
Thanks for the contribution. We already cover the Destroy Seed UX in testing/test_ux.py::test_destroy_seed. The destructive behavior itself needs to be verified on real hardware, so I don’t think emulating it in the simulator adds enough testing value to justify the additional code.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Destroy Seed could not complete in the unix simulator. Two separate problems, one behind the other.
1.
pyb.Flashwas missing (crash)wipe_flash_filesystem()drives internal flash as a block device viapyb.Flash(start=0)(shared/files.py:59), butunix/variant/pyb.pynever definedFlash:This fails after both confirmations and after trick PINs are cleared, so the wallet is left half-wiped.
Adds a
Flashblock-device stub alongside the existingSDCardone, using the same "pretend to work" approach: 512-byte sectors, asfiles.py:61asserts, and writes that go nowhere. Also addstesting/test_sim_pyb.py, which holds the simulator'spybto the attributesshared/actually references — that is what would have caught this before it reached a menu action.2. The callgate then hung the simulator
With the crash fixed, Destroy Seed ran to completion and sat on "Clearing..." forever.
ckcc.oneway()printed a NOTE and then looped onutime.sleep(60), so the last drawn frame stayed on screen — a finished wipe and a crash look identical.It now raises
SystemExitand names what the bootloader would have done. All four one-way methods end firmware execution on real hardware (DFU, logout, wipe, brick), so all four stop rather than spin.machine.pyalready does exactly this forbootloader()/soft_reset()/reset(), and the simulator runs with-i, so this lands at the REPL the same way a simulated reset always has.machine.py's_flush_data()is deliberately not called here: it doessettings.save(), andclear_seed()blanks settings on the line beforefast_wipe(), so flushing would write back what was just erased.Testing
testing/test_sim_pyb.py— 7/7 passtesting/referencesoneway,fast_wipe,show_logout, orenter_dfubare_metal.pyinstalls its ownmy_oneway, so bare-metal mode is unaffectedSimulator-only — no changes to
shared/or any on-device code path.