perf(history): toggle mining address without a full chain re-scan
Marking/unmarking a mining address triggered a long history reload: it called invalidateShieldedHistoryScanProgress() + forced a transaction refresh, which re-scans every z-address over many RPC cycles. But "mined" vs "receive" is a pure function of the LOCAL mining-address set — the daemon knows nothing about it — so a chain re-scan is pointless. Relabel the affected rows in the in-memory history directly and persist just those to the encrypted SQLite history cache. The History tab updates instantly (its display cache rebuilds on the type change), with no daemon round-trip and no reload. Only re-save when something actually changed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -2067,28 +2067,25 @@ bool App::isMiningAddress(const std::string& addr) const
|
||||
|
||||
void App::setMiningAddress(const std::string& addr, bool mining)
|
||||
{
|
||||
if (settings_) {
|
||||
settings_->setMiningAddress(addr, mining);
|
||||
settings_->save();
|
||||
if (!settings_) return;
|
||||
settings_->setMiningAddress(addr, mining);
|
||||
settings_->save();
|
||||
|
||||
// Re-label the in-memory history right away. "mined" vs "receive" is purely a function of
|
||||
// whether the receiving address is flagged for mining, so flip the affected rows now: the
|
||||
// History tab updates immediately, and — importantly — the next refresh's carry-over of
|
||||
// not-yet-rescanned transactions then matches the fresh scan. (Without this, the refresh
|
||||
// re-scans a tx as "receive" but appendMissingPreviousTransactions, which dedupes by
|
||||
// txid+type, still carries the stale "mined" copy over, so the change never showed.)
|
||||
const auto miningAddrs = settings_->getMiningAddresses();
|
||||
for (auto& tx : state_.transactions) {
|
||||
if ((tx.type == "receive" || tx.type == "mined") && !tx.address.empty()) {
|
||||
tx.type = miningAddrs.count(tx.address) ? "mined" : "receive";
|
||||
}
|
||||
// "mined" vs "receive" is a pure function of the LOCAL mining-address set — the daemon knows
|
||||
// nothing about it, so there is NO need to re-scan the chain. Relabel the affected rows in the
|
||||
// in-memory history directly and persist them to the (SQLite) history cache. This is instant,
|
||||
// with no daemon round-trip; the History tab's display cache rebuilds on the type change.
|
||||
const auto miningAddrs = settings_->getMiningAddresses();
|
||||
bool changed = false;
|
||||
for (auto& tx : state_.transactions) {
|
||||
if (tx.address.empty() || (tx.type != "receive" && tx.type != "mined")) continue;
|
||||
std::string newType = miningAddrs.count(tx.address) ? "mined" : "receive";
|
||||
if (tx.type != newType) {
|
||||
tx.type = std::move(newType);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
invalidateShieldedHistoryScanProgress(true);
|
||||
transactions_dirty_ = true;
|
||||
last_tx_block_height_ = -1;
|
||||
network_refresh_.markDue(services::NetworkRefreshService::Timer::Transactions);
|
||||
}
|
||||
if (changed) storeTransactionHistoryCacheIfAvailable();
|
||||
}
|
||||
|
||||
void App::invalidateAddressValidationCache()
|
||||
|
||||
Reference in New Issue
Block a user