diff options
| author | mtg0001 <106211915+mtg0001@users.noreply.github.com> | 2026-08-03 10:43:42 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-03 10:43:42 -0300 |
| commit | 57441faffb02f4f2eea37d31b29728de25f18bef (patch) | |
| tree | edade03dddf472790e8bc7e3bc52d3e8f8eac87b /src/gui.cpp | |
| parent | 5e37647023463cec4331dc48dc360ba60b22c888 (diff) | |
Add wallet recovery balance audit (#117)
Co-authored-by: Gilcimar Duarte <ti@gpm.infra>
Diffstat (limited to 'src/gui.cpp')
| -rw-r--r-- | src/gui.cpp | 54 |
1 files changed, 52 insertions, 2 deletions
diff --git a/src/gui.cpp b/src/gui.cpp index e3a8499..2335bf9 100644 --- a/src/gui.cpp +++ b/src/gui.cpp | |||
| @@ -65,6 +65,8 @@ static std::string g_sendStatus; | |||
| 65 | static char g_backupPath[512] = {}; | 65 | static char g_backupPath[512] = {}; |
| 66 | static std::string g_backupStatus; | 66 | static std::string g_backupStatus; |
| 67 | static int64 g_lastWalletBackup = 0; | 67 | static int64 g_lastWalletBackup = 0; |
| 68 | static WalletRecoveryAudit g_recoveryAudit; | ||
| 69 | static int64 g_recoveryAuditTime = 0; | ||
| 68 | static bool g_walletSafetyLoaded = false; | 70 | static bool g_walletSafetyLoaded = false; |
| 69 | static char g_participantPool[256] = {}; | 71 | static char g_participantPool[256] = {}; |
| 70 | static char g_poolName[128] = {}; | 72 | static char g_poolName[128] = {}; |
| @@ -184,6 +186,15 @@ static void LoadWalletSafetyState() | |||
| 184 | g_walletSafetyLoaded = true; | 186 | g_walletSafetyLoaded = true; |
| 185 | } | 187 | } |
| 186 | 188 | ||
| 189 | static void RefreshRecoveryAudit(bool fForce=false) | ||
| 190 | { | ||
| 191 | int64 nNow = GetTime(); | ||
| 192 | if (!fForce && g_recoveryAuditTime != 0 && nNow - g_recoveryAuditTime < 5) | ||
| 193 | return; | ||
| 194 | g_recoveryAudit = GetWalletRecoveryAudit(); | ||
| 195 | g_recoveryAuditTime = nNow; | ||
| 196 | } | ||
| 197 | |||
| 187 | static int KeyPoolCount() | 198 | static int KeyPoolCount() |
| 188 | { | 199 | { |
| 189 | int n = 0; | 200 | int n = 0; |
| @@ -267,7 +278,11 @@ static void RefreshWallet() | |||
| 267 | g_lastWalletRefresh = GetTime(); | 278 | g_lastWalletRefresh = GetTime(); |
| 268 | } | 279 | } |
| 269 | 280 | ||
| 270 | void MainFrameRepaint() { g_needRefresh = true; } | 281 | void MainFrameRepaint() |
| 282 | { | ||
| 283 | g_needRefresh = true; | ||
| 284 | g_recoveryAuditTime = 0; | ||
| 285 | } | ||
| 271 | 286 | ||
| 272 | // DateTimeStr moved to util.cpp: main.cpp logs block times with it, so it is | 287 | // DateTimeStr moved to util.cpp: main.cpp logs block times with it, so it is |
| 273 | // needed by builds that have no GUI at all. | 288 | // needed by builds that have no GUI at all. |
| @@ -967,6 +982,7 @@ static void RestoreThread(std::string strPhrase) | |||
| 967 | "Check the words and their order.", nDerived); | 982 | "Check the words and their order.", nDerived); |
| 968 | } | 983 | } |
| 969 | g_restoreRunning.store(false); | 984 | g_restoreRunning.store(false); |
| 985 | g_recoveryAuditTime = 0; | ||
| 970 | g_needRefresh = true; | 986 | g_needRefresh = true; |
| 971 | } | 987 | } |
| 972 | 988 | ||
| @@ -1021,6 +1037,7 @@ static void DrawCreatePhraseDialog() | |||
| 1021 | if (SetHDSeedFromMnemonic(g_pendingMnemonic, strError)) | 1037 | if (SetHDSeedFromMnemonic(g_pendingMnemonic, strError)) |
| 1022 | { | 1038 | { |
| 1023 | TopUpKeyPool(); | 1039 | TopUpKeyPool(); |
| 1040 | g_recoveryAuditTime = 0; | ||
| 1024 | g_phraseStatus = "Recovery phrase created. New addresses come from it."; | 1041 | g_phraseStatus = "Recovery phrase created. New addresses come from it."; |
| 1025 | } | 1042 | } |
| 1026 | else | 1043 | else |
| @@ -1141,8 +1158,9 @@ static void DrawWalletSafetyDialog() | |||
| 1141 | { | 1158 | { |
| 1142 | if (!g_showWalletSafety) return; | 1159 | if (!g_showWalletSafety) return; |
| 1143 | LoadWalletSafetyState(); | 1160 | LoadWalletSafetyState(); |
| 1161 | RefreshRecoveryAudit(); | ||
| 1144 | 1162 | ||
| 1145 | ImGui::SetNextWindowSize(ImVec2(650.0f, 390.0f), ImGuiCond_Always); | 1163 | ImGui::SetNextWindowSize(ImVec2(650.0f, 450.0f), ImGuiCond_Always); |
| 1146 | ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), | 1164 | ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), |
| 1147 | ImGuiCond_Always, ImVec2(0.5f, 0.5f)); | 1165 | ImGuiCond_Always, ImVec2(0.5f, 0.5f)); |
| 1148 | if (ImGui::Begin("Wallet Safety", &g_showWalletSafety, | 1166 | if (ImGui::Begin("Wallet Safety", &g_showWalletSafety, |
| @@ -1229,6 +1247,38 @@ static void DrawWalletSafetyDialog() | |||
| 1229 | ImGui::TextColored(ImVec4(1.0f, 0.75f, 0.25f, 1.0f), | 1247 | ImGui::TextColored(ImVec4(1.0f, 0.75f, 0.25f, 1.0f), |
| 1230 | "No recovery phrase. Only a file backup can rebuild this wallet."); | 1248 | "No recovery phrase. Only a file backup can rebuild this wallet."); |
| 1231 | 1249 | ||
| 1250 | ImGui::Text("Phrase-backed spendable balance: %s BTF", | ||
| 1251 | FmtMoney(g_recoveryAudit.nRecoverableCredit).c_str()); | ||
| 1252 | ImGui::Text("Wallet.dat-only spendable balance: %s BTF", | ||
| 1253 | FmtMoney(g_recoveryAudit.nLegacyCredit).c_str()); | ||
| 1254 | ImGui::Text("Phrase-backed immature mining rewards: %s BTF", | ||
| 1255 | FmtMoney(g_recoveryAudit.nRecoverableImmatureCredit).c_str()); | ||
| 1256 | ImGui::Text("Wallet.dat-only immature mining rewards: %s BTF", | ||
| 1257 | FmtMoney(g_recoveryAudit.nLegacyImmatureCredit).c_str()); | ||
| 1258 | if (!g_recoveryAudit.fDeriveComplete) | ||
| 1259 | { | ||
| 1260 | ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.75f, 0.25f, 1.0f)); | ||
| 1261 | ImGui::TextWrapped("%s", g_recoveryAudit.strDeriveError.c_str()); | ||
| 1262 | ImGui::PopStyleColor(); | ||
| 1263 | } | ||
| 1264 | if (g_recoveryAudit.nLegacyCredit > 0 || | ||
| 1265 | g_recoveryAudit.nLegacyImmatureCredit > 0) | ||
| 1266 | { | ||
| 1267 | ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.75f, 0.25f, 1.0f)); | ||
| 1268 | ImGui::TextWrapped( | ||
| 1269 | "Some coins are on keys the phrase does not reproduce. " | ||
| 1270 | "Keep wallet.dat backups until that balance has been moved to a " | ||
| 1271 | "phrase-backed address."); | ||
| 1272 | ImGui::PopStyleColor(); | ||
| 1273 | } | ||
| 1274 | else if (HaveHDSeed() && | ||
| 1275 | g_recoveryAudit.nRecoverableCredit + | ||
| 1276 | g_recoveryAudit.nRecoverableImmatureCredit > 0) | ||
| 1277 | { | ||
| 1278 | ImGui::TextColored(ImVec4(0.55f, 1.0f, 0.6f, 1.0f), | ||
| 1279 | "All known wallet balance is covered by the phrase."); | ||
| 1280 | } | ||
| 1281 | |||
| 1232 | if (!HaveHDSeed()) | 1282 | if (!HaveHDSeed()) |
| 1233 | { | 1283 | { |
| 1234 | if (ImGui::Button("Create recovery phrase", ImVec2(200.0f, 0.0f))) | 1284 | if (ImGui::Button("Create recovery phrase", ImVec2(200.0f, 0.0f))) |