Skip to content

Feat/rescan height - #1382

Draft
sneurlax wants to merge 49 commits into
stagingfrom
feat/rescan-height
Draft

sneurlax wants to merge 49 commits into
stagingfrom
feat/rescan-height

Conversation

@sneurlax

Copy link
Copy Markdown
Member

No description provided.

sneurlax and others added 10 commits February 21, 2026 11:02
Co-Authored-By: detherminal <76167420+detherminal@users.noreply.github.com>
these shouldn't exist/happen, but do/can
previously if it had a newline at the beginning it would choke
monero_wallet worked. now monero-wallet works, too

there's a frustrating variety of xmr wallet uri schemes: some with underscores, some with dashes
@codecov

codecov Bot commented May 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 8.87097% with 113 lines in your changes missing coverage. Please review.
✅ Project coverage is 13.11%. Comparing base (8208fe7) to head (230b247).
⚠️ Report is 11 commits behind head on staging.

Files with missing lines Patch % Lines
lib/utilities/address_utils.dart 15.06% 62 Missing ⚠️
...wallets/wallet/intermediate/lib_monero_wallet.dart 0.00% 44 Missing ⚠️
lib/wallets/wallet/wallet.dart 0.00% 4 Missing ⚠️
lib/wallets/wallet/impl/monero_wallet.dart 0.00% 3 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           staging    #1382      +/-   ##
===========================================
+ Coverage     4.84%   13.11%   +8.27%     
===========================================
  Files         1092      424     -668     
  Lines       109141    35637   -73504     
===========================================
- Hits          5283     4675     -608     
+ Misses      103858    30962   -72896     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

The date/block-height control was duplicated three times in the restore
options view, once per restore mode, over a single set of controllers.
StartHeightPicker replaces all three with one widget and gives each mode
its own StartHeightPickerController, so a height chosen in one mode can no
longer follow the user into a mode that shows no control.

The controller reports a nullable height: null means nothing was chosen,
which is distinct from a deliberate height of 0. Salvium now converts the
date the user picked rather than one week ago, and Mimblewimblecoin gets
the same date to height estimate Epic Cash already had.

restore_from_date_picker.dart moves to lib/widgets so the shared widget
does not have to import from lib/pages.
The rescan confirmation dialog now offers the start height picker to the
coins whose rescan can act on it, and hands the choice to the caller, which
persists it before starting the rescan: the wallet info restore height for
every coin, plus the native refresh height for Cryptonote wallets and the
per-coin restore height that Epic Cash and Mimblewimblecoin reset their
last scanned block to.

Mimblewimblecoin gains the updateRestoreHeight that Epic Cash already had,
without which its rescan would have ignored the height. Coins that cannot
apply a start height are not shown the control, and choosing nothing leaves
the stored restore height untouched.

setRefreshFromBlockHeight becomes a Future so the native height is set
before the rescan begins rather than racing it.
A URI's `height=` now fills the visible picker in and stops there: the
restore uses whatever the picker reports, so a correction the user makes
after pasting is the value that takes effect.

A URI whose scheme names a different coin than the page is refused with a
message naming that coin, instead of being restored under the page's coin
from another chain's recovery material.
Uri.parse throws a FormatException whose source is the string it was
given, and FormatException.toString() quotes a window of that source. The
redacted branch of the URI parser interpolated the exception and passed it
to the logger as well, so a paste the parser choked on -- a label in front
of the URI, a stray bracket, a leading space -- wrote the pasted seed or
private keys to the console and, at debug log level, to the exportable log
file. Log the exception's message alone instead.
@sneurlax
sneurlax force-pushed the feat/rescan-height branch from 230b247 to 839132d Compare August 25, 2026 17:41
sneurlax and others added 8 commits October 6, 2026 21:29
Serializes open, node updates, native replacement and shutdown on a single
mutex, and rejects queued work once shutdown has begun. The Tor transition
gate parks a node update while Tor is bootstrapping and abandons it as soon
as the operation is superseded.
Every LibMonero/Wownero/Salvium instance subscribed to the Tor status and
preference events from its constructor, so toggling Tor ran updateNode() on
the dozens of wallets Wallets.load() constructs but never opens. With a
Tor-only or clearnet-only node the TOR/clearnet mismatch escaped the async
listener as an unhandled exception.

Listeners are now attached in open() and detached on exit() or a failed open,
and the native lifecycle runs through CryptonoteWalletLifecycle so concurrent
open/exit calls cannot load or tear down the native wallet twice. Because an
exited wallet no longer follows node or Tor changes, open() re-runs the node
update whenever the native daemon session was torn down; otherwise a reopened
wallet resumes syncing over its stale clearnet session. Also corrects the
inverted null guard in recoverViewOnly().
Co-Authored-By: detherminal <76167420+detherminal@users.noreply.github.com>
these shouldn't exist/happen, but do/can
previously if it had a newline at the beginning it would choke
monero_wallet worked. now monero-wallet works, too

there's a frustrating variety of xmr wallet uri schemes: some with underscores, some with dashes
The date/block-height control was duplicated three times in the restore
options view, once per restore mode, over a single set of controllers.
StartHeightPicker replaces all three with one widget and gives each mode
its own StartHeightPickerController, so a height chosen in one mode can no
longer follow the user into a mode that shows no control.

The controller reports a nullable height: null means nothing was chosen,
which is distinct from a deliberate height of 0. Salvium now converts the
date the user picked rather than one week ago, and Mimblewimblecoin gets
the same date to height estimate Epic Cash already had.

restore_from_date_picker.dart moves to lib/widgets so the shared widget
does not have to import from lib/pages.
The rescan confirmation dialog now offers the start height picker to the
coins whose rescan can act on it, and hands the choice to the caller, which
persists it before starting the rescan: the wallet info restore height for
every coin, plus the native refresh height for Cryptonote wallets and the
per-coin restore height that Epic Cash and Mimblewimblecoin reset their
last scanned block to.

Mimblewimblecoin gains the updateRestoreHeight that Epic Cash already had,
without which its rescan would have ignored the height. Coins that cannot
apply a start height are not shown the control, and choosing nothing leaves
the stored restore height untouched.

setRefreshFromBlockHeight becomes a Future so the native height is set
before the rescan begins rather than racing it.
A URI's `height=` now fills the visible picker in and stops there: the
restore uses whatever the picker reports, so a correction the user makes
after pasting is the value that takes effect.

A URI whose scheme names a different coin than the page is refused with a
message naming that coin, instead of being restored under the page's coin
from another chain's recovery material.
Uri.parse throws a FormatException whose source is the string it was
given, and FormatException.toString() quotes a window of that source. The
URI parser now rethrows FormatException to its caller, so a wallet URI the
parser chokes on -- a label in front of the URI, a stray bracket, a leading
space -- would hand the pasted seed or private keys to whoever logs the
error. Rethrow the message alone from the wallet URI parser, and have the
redacted log branch record only the exception type.
StartHeightPicker assumed Epic Cash and Mimblewimblecoin share a genesis
timestamp, but MWC's first block is 1573462800, so its date estimates
started too high. Use each coin's own genesis time.
…20261110/pr-1382

# Conflicts:
#	lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/wallet_keys_desktop_popup.dart
#	lib/services/wallets.dart
#	lib/utilities/address_utils.dart
#	test/address_utils_test.dart
…20261110/pr-1382

# Conflicts:
#	lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart
#	lib/pages/settings_views/wallet_settings_view/wallet_backup_views/wallet_backup_view.dart
#	lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/sub_widgets/confirm_full_rescan.dart
#	lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_recovery_phrase_view.dart
#	lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_warning_view.dart
#	lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/delete_wallet_keys_popup.dart
#	lib/utilities/address_utils.dart
#	lib/wallets/wallet/impl/monero_wallet.dart
#	lib/wallets/wallet/intermediate/lib_monero_wallet.dart
#	lib/widgets/date_picker/restore_from_date_picker.dart
#	lib/widgets/start_height_picker.dart
#	lib/wl_gen/interfaces/cs_monero_interface.dart
#	test/address_utils_test.dart
#	test/pages/restore_options_uri_test.dart
#	test/utilities/wallet_uri_secrets_test.dart
#	test/widgets/start_height_picker_test.dart
@sneurlax

Copy link
Copy Markdown
Member Author

Merged staging at d29d84c660492fd6dcc7ee67dbce4a76e85c026a and incorporated the divergent cypherstack branch's selected-network, native lifecycle, height-picker state, and per-coin genesis fixes. Staging's multi-recipient payment URI behavior is retained. Wallet-URI parse and restore errors avoid exposing recovery secrets.

Validation: 98 focused start-height, rescan, restore UI, URI, backup and secure-storage tests passed. Targeted Dart analysis reported no errors or warnings, with informational lints. Real chain rescans and native key restores were not exercised end to end.

@sneurlax

Copy link
Copy Markdown
Member Author

Follow-up f2e074185: MWC recovery now keeps the height chosen in restore options instead of replacing it with an estimate for the current day. The focused height-picker, rescan, restore UI and wallet-URI suites passed (52 tests). Native MWC restoration remains untested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant