Reduce redundant RPC calls in periodic refresh cycle

- Remove getinfo from refreshMiningInfo slow path; daemon_version,
  protocol_version, and p2p_port are static per connection (set in
  onConnected). Move longestchain/notarized into refreshBalance's
  existing getblockchaininfo callback.

- Remove refreshMiningInfo from refreshData(); it already runs on
  the 1-second fast_refresh_timer_ independently.

- Make refreshAddresses demand-driven via addresses_dirty_ flag;
  only re-fetch when a new address is created or a send completes,
  not unconditionally every 5 seconds.

- Gate refreshPeerInfo to only run when the Peers tab is active.

- Skip duplicate getwalletinfo on connect; onConnected() already
  prefetches it for immediate lock-screen display, so suppress the
  redundant call in the first refreshData() cycle.

Steady-state savings: ~8 fewer RPC calls per 5-second cycle
(from ~12+ down to ~4-5 in the common case).
This commit is contained in:
dan_s
2026-02-27 02:28:29 -06:00
parent b1d87a65f8
commit b4e09cdf75
3 changed files with 151 additions and 44 deletions

View File

@@ -46,6 +46,12 @@ static bool s_pool_settings_dirty = false;
static bool s_pool_state_loaded = false;
static bool s_show_pool_log = false; // Toggle: false=chart, true=log
// Chart smooth-scroll state
static size_t s_chart_last_n = 0;
static double s_chart_last_newest = -1.0;
static double s_chart_update_time = 0.0;
static float s_chart_interval = 1.0f; // measured seconds between data updates
// Get max threads based on hardware
static int GetMaxMiningThreads()
{
@@ -983,17 +989,69 @@ void RenderMiningTab(App* app)
float plotW = plotRight - plotLeft;
float plotH = std::max(1.0f, plotBottom - plotTop);
// --- Smooth scroll: detect new data and measure interval ---
size_t n = chartHistory.size();
std::vector<ImVec2> points(n);
double newestVal = chartHistory.back();
double nowTime = ImGui::GetTime();
bool dataChanged = (n != s_chart_last_n) || (newestVal != s_chart_last_newest);
if (dataChanged) {
float dt = (float)(nowTime - s_chart_update_time);
if (dt > 0.3f && dt < 10.0f)
s_chart_interval = s_chart_interval * 0.6f + dt * 0.4f; // smoothed
s_chart_last_n = n;
s_chart_last_newest = newestVal;
s_chart_update_time = nowTime;
}
float elapsed = (float)(nowTime - s_chart_update_time);
float scrollFrac = std::clamp(elapsed / s_chart_interval, 0.0f, 1.0f);
// Build raw data points with smooth scroll offset.
// Newest point is anchored at plotRight; as scrollFrac grows
// the spacing compresses by one virtual slot so the next
// incoming point will appear seamlessly at plotRight.
float virtualSlots = (float)(n - 1) + scrollFrac;
if (virtualSlots < 1.0f) virtualSlots = 1.0f;
float stepW = plotW / virtualSlots;
std::vector<ImVec2> rawPts(n);
for (size_t i = 0; i < n; i++) {
float t2 = (n > 1) ? (float)i / (float)(n - 1) : 0.0f;
float x = plotLeft + t2 * plotW;
float x = plotRight - (float)(n - 1 - i) * stepW;
float y = plotBottom - (float)((chartHistory[i] - yMin) / (yMax - yMin)) * plotH;
points[i] = ImVec2(x, y);
rawPts[i] = ImVec2(x, y);
}
// Catmull-Rom spline interpolation for smooth curve
std::vector<ImVec2> points;
if (n <= 2) {
points = rawPts;
} else {
const int subdivs = 8; // segments between each pair of data points
points.reserve((n - 1) * subdivs + 1);
for (size_t i = 0; i + 1 < n; i++) {
// Four control points: p0, p1, p2, p3
ImVec2 p0 = rawPts[i > 0 ? i - 1 : 0];
ImVec2 p1 = rawPts[i];
ImVec2 p2 = rawPts[i + 1];
ImVec2 p3 = rawPts[i + 2 < n ? i + 2 : n - 1];
for (int s = 0; s < subdivs; s++) {
float t = (float)s / (float)subdivs;
float t2 = t * t;
float t3 = t2 * t;
// Catmull-Rom basis
float q0 = -t3 + 2.0f * t2 - t;
float q1 = 3.0f * t3 - 5.0f * t2 + 2.0f;
float q2 = -3.0f * t3 + 4.0f * t2 + t;
float q3 = t3 - t2;
float sx = 0.5f * (p0.x * q0 + p1.x * q1 + p2.x * q2 + p3.x * q3);
float sy = 0.5f * (p0.y * q0 + p1.y * q1 + p2.y * q2 + p3.y * q3);
points.push_back(ImVec2(sx, sy));
}
}
points.push_back(rawPts[n - 1]); // final point
}
// Fill under curve
for (size_t i = 0; i + 1 < n; i++) {
for (size_t i = 0; i + 1 < points.size(); i++) {
ImVec2 quad[4] = {
points[i], points[i + 1],
ImVec2(points[i + 1].x, plotBottom),
@@ -1033,14 +1091,27 @@ void RenderMiningTab(App* app)
}
// ================================================================
// EARNINGS — Horizontal row card (Today | All Time | Est. Daily)
// EARNINGS — Horizontal row card (Today | Yesterday | All Time | Est. Daily)
// ================================================================
{
// Gather mining transactions from state
double minedToday = 0.0, minedAllTime = 0.0;
int minedTodayCount = 0, minedAllTimeCount = 0;
double minedToday = 0.0, minedYesterday = 0.0, minedAllTime = 0.0;
int minedTodayCount = 0, minedYesterdayCount = 0, minedAllTimeCount = 0;
int64_t now = (int64_t)std::time(nullptr);
int64_t dayStart = now - 86400;
// Calendar-day boundaries (local time)
time_t nowT = (time_t)now;
struct tm local;
#ifdef _WIN32
localtime_s(&local, &nowT);
#else
localtime_r(&nowT, &local);
#endif
local.tm_hour = 0;
local.tm_min = 0;
local.tm_sec = 0;
int64_t todayStart = (int64_t)mktime(&local);
int64_t yesterdayStart = todayStart - 86400;
struct MinedTx {
int64_t timestamp;
@@ -1055,9 +1126,12 @@ void RenderMiningTab(App* app)
double amt = std::abs(tx.amount);
minedAllTime += amt;
minedAllTimeCount++;
if (tx.timestamp >= dayStart) {
if (tx.timestamp >= todayStart) {
minedToday += amt;
minedTodayCount++;
} else if (tx.timestamp >= yesterdayStart) {
minedYesterday += amt;
minedYesterdayCount++;
}
if (recentMined.size() < 4) {
recentMined.push_back({tx.timestamp, amt, tx.confirmations, tx.confirmations >= 100});
@@ -1089,7 +1163,8 @@ void RenderMiningTab(App* app)
// === Earnings section (top of combined card) ===
{
float colW = (availWidth - pad * 2) / 3.0f;
const int numCols = 4;
float colW = (availWidth - pad * 2) / (float)numCols;
float ey = cardMin.y + pad * 0.5f;
char valBuf[64], subBuf2[64];
@@ -1106,6 +1181,10 @@ void RenderMiningTab(App* app)
strncpy(todayVal, valBuf, sizeof(todayVal));
strncpy(todaySub, subBuf2, sizeof(todaySub));
char yesterdayVal[64], yesterdaySub[64];
snprintf(yesterdayVal, sizeof(yesterdayVal), "+%.4f", minedYesterday);
snprintf(yesterdaySub, sizeof(yesterdaySub), "(%d blk)", minedYesterdayCount);
char allVal[64], allSub[64];
snprintf(allVal, sizeof(allVal), "+%.4f", minedAllTime);
snprintf(allSub, sizeof(allSub), "(%d blk)", minedAllTimeCount);
@@ -1117,12 +1196,13 @@ void RenderMiningTab(App* app)
snprintf(estVal, sizeof(estVal), "N/A");
EarningsEntry entries[] = {
{ "TODAY", todayVal, todaySub, greenCol2 },
{ "ALL TIME", allVal, allSub, OnSurface() },
{ "EST. DAILY", estVal, nullptr, estActive ? greenCol2 : OnSurfaceDisabled() },
{ "TODAY", todayVal, todaySub, greenCol2 },
{ "YESTERDAY", yesterdayVal, yesterdaySub, OnSurface() },
{ "ALL TIME", allVal, allSub, OnSurface() },
{ "EST. DAILY", estVal, nullptr, estActive ? greenCol2 : OnSurfaceDisabled() },
};
for (int ei = 0; ei < 3; ei++) {
for (int ei = 0; ei < numCols; ei++) {
float sx = cardMin.x + pad + ei * colW;
float centerX = sx + colW * 0.5f;