fix(settings): scope portfolio groups by wallet identity
Market-tab portfolio groups were tied to a wallet by a hash of its address set. That hash changed whenever an address was added, so a group built for a wallet could silently drop out of view once the wallet gained a new address. - Groups are now scoped by the wallet's stable id, which is persisted and never derived from the address set, so adding an address can no longer orphan a group. - An older build's address-hash scope fails open (the group stays visible) and is migrated once per wallet per session to the stable id. A legacy group is claimed when its old hash matches, when one of its own addresses belongs to this wallet, or when only one wallet is known; anything ambiguous is left legacy and stays visible. - Scope filtering waits until the wallet's addresses are loaded, so a group never flashes an empty 0.0000 balance and Add stays disabled until the wallet is resolved. This works on Lite, which never stamps an address-update time. Behaviour: an older build opened after this change hides groups tagged with a stable "w:" scope (they are not deleted and return on the next upgrade) - worth a release note. Tests: group visibility across global, stable and legacy scopes with the wallet resolved and not; the migration rules (hash match, address overlap, single-wallet claim, ambiguous left alone, idempotent); and a save/load round trip where an address-set change cannot orphan the scope. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -343,6 +343,15 @@ public:
|
||||
// except during a full UI sweep (capture_mode_), where it returns the existing id or "".
|
||||
std::string activeWalletScopeId();
|
||||
|
||||
// Stable scope for the Market-tab portfolio groups: activeWalletScopeId() once this wallet's addresses are
|
||||
// loaded, else "" (so a group never shows a 0.0000 balance from an empty list, and Add stays disabled
|
||||
// until the wallet is known - the same window the old identity-hash gate covered). Never the address hash.
|
||||
// In a full UI sweep (capture_mode_) a fixed demo id so the sweep can still exercise Add.
|
||||
std::string portfolioScopeId();
|
||||
// One-time (per wallet per session) migration of legacy hash-scoped portfolio groups to the stable id.
|
||||
// Called from update(); a no-op until the wallet's addresses are loaded.
|
||||
void reattachLegacyPortfolioScopes();
|
||||
|
||||
data::WalletIndex& walletIndex() { return wallet_index_; }
|
||||
const data::WalletIndex& walletIndex() const { return wallet_index_; }
|
||||
|
||||
@@ -1792,6 +1801,7 @@ private:
|
||||
// Set when a bootstrap completes; consumed once the daemon is connected to auto-run a rescan
|
||||
// that reconciles the preserved wallet.dat against the freshly-imported chain.
|
||||
bool post_bootstrap_rescan_pending_ = false;
|
||||
std::string portfolio_scope_migrated_for_; // scope id the legacy-portfolio-scope migration last ran for
|
||||
bool post_bootstrap_probe_in_flight_ = false; // its detectLowestAvailableBlockHeight() is on worker_
|
||||
int post_bootstrap_probe_attempts_ = 0; // probes that could not tell; gives up after 6
|
||||
std::chrono::steady_clock::time_point post_bootstrap_probe_retry_at_{};
|
||||
|
||||
Reference in New Issue
Block a user