Add an encrypted SQLite transaction history cache with cached tip metadata and per-address shielded scan progress so startup and full refreshes avoid re-scanning every z-address while still invalidating on wallet/address/rescan changes. Improve wallet history loading by paging transparent transactions, preserving cached shielded and sent rows, keeping recent/unconfirmed activity visible, and classifying mining-address receives. Show z_sendmany opid sends immediately in History and Overview, pin pending rows through refreshes, and apply optimistic address/balance debits until opids resolve. Add timestamped RPC console tracing by source/method without logging params or results, reduce redundant refresh/RPC calls, and cache Explorer recent block summaries in SQLite. Expand focused tests for transaction cache encryption, scan-progress persistence/invalidation, history preservation, operation-status parsing, pending send visibility, and Explorer/RPC refresh behavior.
157 lines
4.4 KiB
C++
157 lines
4.4 KiB
C++
#include "refresh_scheduler.h"
|
|
|
|
#include <algorithm>
|
|
|
|
namespace dragonx {
|
|
namespace services {
|
|
|
|
RefreshScheduler::Intervals RefreshScheduler::intervalsForPage(ui::NavPage page)
|
|
{
|
|
using NP = ui::NavPage;
|
|
switch (page) {
|
|
case NP::Overview: return {2.0f, 10.0f, 15.0f, 0.0f};
|
|
case NP::Send: return {3.0f, 10.0f, 5.0f, 0.0f};
|
|
case NP::Receive: return {5.0f, 15.0f, 5.0f, 0.0f};
|
|
case NP::History: return {5.0f, 3.0f, 15.0f, 0.0f};
|
|
case NP::Mining: return {5.0f, 15.0f, 15.0f, 0.0f};
|
|
case NP::Peers: return {5.0f, 15.0f, 15.0f, 5.0f};
|
|
case NP::Market: return {5.0f, 15.0f, 15.0f, 0.0f};
|
|
case NP::Console: return {10.0f, 30.0f, 30.0f, 0.0f};
|
|
default: return {5.0f, 15.0f, 15.0f, 0.0f};
|
|
}
|
|
}
|
|
|
|
void RefreshScheduler::applyPage(ui::NavPage page)
|
|
{
|
|
setIntervals(intervalsForPage(page));
|
|
}
|
|
|
|
void RefreshScheduler::setIntervals(Intervals intervals)
|
|
{
|
|
intervals_ = intervals;
|
|
}
|
|
|
|
void RefreshScheduler::tick(float deltaSeconds)
|
|
{
|
|
float delta = std::max(0.0f, deltaSeconds);
|
|
timers_.core += delta;
|
|
timers_.transactions += delta;
|
|
timers_.addresses += delta;
|
|
timers_.peers += delta;
|
|
timers_.price += delta;
|
|
timers_.fast += delta;
|
|
timers_.txAge += delta;
|
|
timers_.opid += delta;
|
|
}
|
|
|
|
bool RefreshScheduler::isDue(Timer timer) const
|
|
{
|
|
float timerInterval = interval(timer);
|
|
return timerInterval > 0.0f && timerRef(timer) >= timerInterval;
|
|
}
|
|
|
|
bool RefreshScheduler::consumeDue(Timer timer)
|
|
{
|
|
if (!isDue(timer)) return false;
|
|
reset(timer);
|
|
return true;
|
|
}
|
|
|
|
void RefreshScheduler::reset(Timer timer)
|
|
{
|
|
timerRef(timer) = 0.0f;
|
|
}
|
|
|
|
void RefreshScheduler::markDue(Timer timer)
|
|
{
|
|
float timerInterval = interval(timer);
|
|
timerRef(timer) = timerInterval > 0.0f ? timerInterval : 0.0f;
|
|
}
|
|
|
|
void RefreshScheduler::setTimer(Timer timer, float seconds)
|
|
{
|
|
timerRef(timer) = std::max(0.0f, seconds);
|
|
}
|
|
|
|
float RefreshScheduler::timer(Timer timer) const
|
|
{
|
|
return timerRef(timer);
|
|
}
|
|
|
|
float RefreshScheduler::interval(Timer timer) const
|
|
{
|
|
switch (timer) {
|
|
case Timer::Core: return intervals_.core;
|
|
case Timer::Transactions: return intervals_.transactions;
|
|
case Timer::Addresses: return intervals_.addresses;
|
|
case Timer::Peers: return intervals_.peers;
|
|
case Timer::Price: return kPrice;
|
|
case Timer::Fast: return kFast;
|
|
case Timer::TxAge: return kTxMaxAge;
|
|
case Timer::Opid: return kOpidPoll;
|
|
}
|
|
return 0.0f;
|
|
}
|
|
|
|
void RefreshScheduler::markImmediateRefresh()
|
|
{
|
|
markDue(Timer::Core);
|
|
markDue(Timer::Transactions);
|
|
markDue(Timer::Addresses);
|
|
markDue(Timer::Peers);
|
|
}
|
|
|
|
void RefreshScheduler::markWalletMutationRefresh()
|
|
{
|
|
markDue(Timer::Core);
|
|
markDue(Timer::Transactions);
|
|
markDue(Timer::Addresses);
|
|
}
|
|
|
|
void RefreshScheduler::resetTxAge()
|
|
{
|
|
reset(Timer::TxAge);
|
|
}
|
|
|
|
bool RefreshScheduler::shouldRefreshTransactions(int lastTxBlockHeight,
|
|
int currentBlockHeight,
|
|
bool transactionsDirty) const
|
|
{
|
|
return lastTxBlockHeight < 0
|
|
|| currentBlockHeight != lastTxBlockHeight
|
|
|| transactionsDirty;
|
|
}
|
|
|
|
float& RefreshScheduler::timerRef(Timer timer)
|
|
{
|
|
switch (timer) {
|
|
case Timer::Core: return timers_.core;
|
|
case Timer::Transactions: return timers_.transactions;
|
|
case Timer::Addresses: return timers_.addresses;
|
|
case Timer::Peers: return timers_.peers;
|
|
case Timer::Price: return timers_.price;
|
|
case Timer::Fast: return timers_.fast;
|
|
case Timer::TxAge: return timers_.txAge;
|
|
case Timer::Opid: return timers_.opid;
|
|
}
|
|
return timers_.core;
|
|
}
|
|
|
|
const float& RefreshScheduler::timerRef(Timer timer) const
|
|
{
|
|
switch (timer) {
|
|
case Timer::Core: return timers_.core;
|
|
case Timer::Transactions: return timers_.transactions;
|
|
case Timer::Addresses: return timers_.addresses;
|
|
case Timer::Peers: return timers_.peers;
|
|
case Timer::Price: return timers_.price;
|
|
case Timer::Fast: return timers_.fast;
|
|
case Timer::TxAge: return timers_.txAge;
|
|
case Timer::Opid: return timers_.opid;
|
|
}
|
|
return timers_.core;
|
|
}
|
|
|
|
} // namespace services
|
|
} // namespace dragonx
|