feat: RPC caching, background decrypt import, fast-lane peers, mining fix

RPC client:
- Add call() overload with per-call timeout parameter
- z_exportwallet uses 300s, z_importwallet uses 1200s timeout

Decrypt wallet (app_security.cpp, app.cpp):
- Show per-step and overall elapsed timers during decrypt flow
- Reduce dialog to 5 steps; close before key import begins
- Run z_importwallet on detached background thread
- Add pulsing "Importing keys..." status bar indicator
- Report success/failure via notifications instead of dialog

RPC caching (app_network.cpp, app.h):
- Cache z_viewtransaction results in viewtx_cache_ across refresh cycles
- Skip RPC calls for already-cached txids (biggest perf win)
- Build confirmed_tx_cache_ for deeply-confirmed transactions
- Clear all caches on disconnect
- Remove unused refreshTransactions() dead code

Peers (app_network.cpp, peers_tab.cpp):
- Route refreshPeerInfo() through fast_worker_ to avoid head-of-line blocking
- Replace footer "Refresh Peers" button with ICON_MD_REFRESH in toggle header
- Refresh button triggers both peer list and full blockchain data refresh

Mining (mining_tab.cpp):
- Allow pool mining toggle when blockchain is not synced
- Pool mining only needs xmrig, not local daemon sync
This commit is contained in:
dan_s
2026-03-04 15:12:24 -06:00
parent 7fb1f1de9d
commit 0ca1caf148
8 changed files with 459 additions and 270 deletions

View File

@@ -10,6 +10,8 @@
#include <thread>
#include <atomic>
#include <chrono>
#include <unordered_map>
#include <unordered_set>
#include "data/wallet_state.h"
#include "rpc/connection.h"
#include "ui/sidebar.h"
@@ -443,11 +445,40 @@ private:
// P4: Incremental transaction cache
int last_tx_block_height_ = -1; // block height at last full tx fetch
float tx_age_timer_ = 0.0f; // seconds since last tx fetch
static constexpr float TX_MAX_AGE = 15.0f; // force tx refresh every N seconds even without new blocks
static constexpr int MAX_VIEWTX_PER_CYCLE = 25; // cap z_viewtransaction calls per refresh
// P4b: z_viewtransaction result cache — avoids re-calling the RPC for
// txids we've already enriched. Keyed by txid.
struct ViewTxCacheEntry {
std::string from_address; // first spend address
struct Output {
std::string address;
double value = 0.0;
std::string memo;
};
std::vector<Output> outgoing_outputs;
};
std::unordered_map<std::string, ViewTxCacheEntry> viewtx_cache_;
// P4c: Confirmed transaction cache — deeply-confirmed txns (>= 10 confs)
// are accumulated here and reused across refresh cycles. Only
// recent/unconfirmed txns are re-fetched from the daemon each time.
std::vector<TransactionInfo> confirmed_tx_cache_;
std::unordered_set<std::string> confirmed_tx_ids_; // fast lookup
int confirmed_cache_block_ = -1; // block height when cache was last built
// Dirty flags for demand-driven refresh
bool addresses_dirty_ = true; // true → refreshAddresses() will run
bool transactions_dirty_ = false; // true → force tx refresh regardless of block height
bool encryption_state_prefetched_ = false; // suppress duplicate getwalletinfo on connect
// Pending z_sendmany operation tracking
std::vector<std::string> pending_opids_; // opids to poll for completion
float opid_poll_timer_ = 0.0f;
static constexpr float OPID_POLL_INTERVAL = 2.0f;
// First-run wizard state
WizardPhase wizard_phase_ = WizardPhase::None;
std::unique_ptr<util::Bootstrap> bootstrap_;
@@ -512,6 +543,9 @@ private:
char decrypt_pass_buf_[256] = {};
std::string decrypt_status_;
bool decrypt_in_progress_ = false;
std::chrono::steady_clock::time_point decrypt_step_start_time_{};
std::chrono::steady_clock::time_point decrypt_overall_start_time_{};
std::atomic<bool> decrypt_import_active_{false}; // background z_importwallet running
// Wizard PIN setup state
char wizard_pin_buf_[16] = {};
@@ -544,7 +578,6 @@ private:
void refreshData();
void refreshBalance();
void refreshAddresses();
void refreshTransactions();
void refreshPrice();
void refreshWalletEncryptionState();
void checkAutoLock();