upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.cpp3
-rw-r--r--src/main.h2
-rw-r--r--src/selftest.cpp44
-rw-r--r--src/walletcmd.cpp16
4 files changed, 61 insertions, 4 deletions
diff --git a/src/main.cpp b/src/main.cpp
index f83164f..5bd4028 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -4355,6 +4355,9 @@ WalletRecoveryAudit GetWalletRecoveryAudit()
4355 CRITICAL_BLOCK(cs_keyPool) 4355 CRITICAL_BLOCK(cs_keyPool)
4356 { 4356 {
4357 audit.fHaveSeed = HaveHDSeed(); 4357 audit.fHaveSeed = HaveHDSeed();
4358 audit.fSeedEncryptedLocked = !audit.fHaveSeed &&
4359 (!vchCryptedHDMaster.empty() ||
4360 !vchCryptedHDChainCode.empty());
4358 audit.nSchema = nHDKeySchema; 4361 audit.nSchema = nHDKeySchema;
4359 audit.nDerivedKnown = nHDNext; 4362 audit.nDerivedKnown = nHDNext;
4360 audit.nReceiveNext = nHDReceiveNext; 4363 audit.nReceiveNext = nHDReceiveNext;
diff --git a/src/main.h b/src/main.h
index b389f1d..dc5527e 100644
--- a/src/main.h
+++ b/src/main.h
@@ -292,6 +292,7 @@ int64 GetBalance();
292struct WalletRecoveryAudit 292struct WalletRecoveryAudit
293{ 293{
294 bool fHaveSeed; 294 bool fHaveSeed;
295 bool fSeedEncryptedLocked;
295 bool fDeriveComplete; 296 bool fDeriveComplete;
296 int nSchema; 297 int nSchema;
297 unsigned int nDerivedKnown; 298 unsigned int nDerivedKnown;
@@ -311,6 +312,7 @@ struct WalletRecoveryAudit
311 WalletRecoveryAudit() 312 WalletRecoveryAudit()
312 { 313 {
313 fHaveSeed = false; 314 fHaveSeed = false;
315 fSeedEncryptedLocked = false;
314 fDeriveComplete = true; 316 fDeriveComplete = true;
315 nSchema = HD_SCHEMA_NONE; 317 nSchema = HD_SCHEMA_NONE;
316 nDerivedKnown = 0; 318 nDerivedKnown = 0;
diff --git a/src/selftest.cpp b/src/selftest.cpp
index 3c93927..79feddf 100644
--- a/src/selftest.cpp
+++ b/src/selftest.cpp
@@ -941,7 +941,8 @@ static string QuoteCommandArg(const string& str)
941 941
942static int RunBitflashChild(const string& strExe, 942static int RunBitflashChild(const string& strExe,
943 const vector<string>& vArgs, 943 const vector<string>& vArgs,
944 const string* pStdinFile = NULL) 944 const string* pStdinFile = NULL,
945 const string* pOutputFile = NULL)
945{ 946{
946#ifdef _WIN32 947#ifdef _WIN32
947 vector<char*> argv; 948 vector<char*> argv;
@@ -954,8 +955,16 @@ static int RunBitflashChild(const string& strExe,
954 int nOldErr = _dup(2); 955 int nOldErr = _dup(2);
955 int nOldIn = _dup(0); 956 int nOldIn = _dup(0);
956 int nNull = _open("NUL", _O_WRONLY); 957 int nNull = _open("NUL", _O_WRONLY);
958 int nOut = -1;
957 int nIn = -1; 959 int nIn = -1;
958 if (nNull >= 0) 960 if (pOutputFile)
961 nOut = _open(pOutputFile->c_str(), _O_WRONLY|_O_CREAT|_O_TRUNC|_O_BINARY, _S_IREAD|_S_IWRITE);
962 if (nOut >= 0)
963 {
964 _dup2(nOut, 1);
965 _dup2(nOut, 2);
966 }
967 else if (nNull >= 0)
959 { 968 {
960 _dup2(nNull, 1); 969 _dup2(nNull, 1);
961 _dup2(nNull, 2); 970 _dup2(nNull, 2);
@@ -969,6 +978,8 @@ static int RunBitflashChild(const string& strExe,
969 int nRet = _spawnv(_P_WAIT, strExe.c_str(), &argv[0]); 978 int nRet = _spawnv(_P_WAIT, strExe.c_str(), &argv[0]);
970 if (nIn >= 0) 979 if (nIn >= 0)
971 _close(nIn); 980 _close(nIn);
981 if (nOut >= 0)
982 _close(nOut);
972 if (nNull >= 0) 983 if (nNull >= 0)
973 _close(nNull); 984 _close(nNull);
974 if (nOldIn >= 0) 985 if (nOldIn >= 0)
@@ -993,7 +1004,10 @@ static int RunBitflashChild(const string& strExe,
993 strCmd += " " + QuoteCommandArg(vArgs[i]); 1004 strCmd += " " + QuoteCommandArg(vArgs[i]);
994 if (pStdinFile) 1005 if (pStdinFile)
995 strCmd += " < " + QuoteCommandArg(*pStdinFile); 1006 strCmd += " < " + QuoteCommandArg(*pStdinFile);
996 strCmd += " > /dev/null 2>&1"; 1007 if (pOutputFile)
1008 strCmd += " > " + QuoteCommandArg(*pOutputFile) + " 2>&1";
1009 else
1010 strCmd += " > /dev/null 2>&1";
997 return system(strCmd.c_str()); 1011 return system(strCmd.c_str());
998#endif 1012#endif
999} 1013}
@@ -1066,6 +1080,8 @@ static int RunWalletEncryptSelfTest()
1066 string strRightDump = tmp + "/right-pass-dump.txt"; 1080 string strRightDump = tmp + "/right-pass-dump.txt";
1067 string strLiteralDump = tmp + "/literal-pass-dump.txt"; 1081 string strLiteralDump = tmp + "/literal-pass-dump.txt";
1068 string strStdinDump = tmp + "/stdin-pass-dump.txt"; 1082 string strStdinDump = tmp + "/stdin-pass-dump.txt";
1083 string strLockedAudit = tmp + "/locked-recovery-audit.txt";
1084 string strUnlockedAudit = tmp + "/unlocked-recovery-audit.txt";
1069 string strWrongPassFile = tmp + "/wrong-pass.txt"; 1085 string strWrongPassFile = tmp + "/wrong-pass.txt";
1070 string strRightPassFile = tmp + "/right-pass.txt"; 1086 string strRightPassFile = tmp + "/right-pass.txt";
1071 nFail += Check(WriteTextFile(strWrongPassFile, "wrong-passphrase\n") && 1087 nFail += Check(WriteTextFile(strWrongPassFile, "wrong-passphrase\n") &&
@@ -1081,6 +1097,17 @@ static int RunWalletEncryptSelfTest()
1081 nFail += Check(nWrongRet != 0 && !FileExists(strWrongDump.c_str()), 1097 nFail += Check(nWrongRet != 0 && !FileExists(strWrongDump.c_str()),
1082 "a restarted wallet rejects the wrong-passphrase") ? 0 : 1; 1098 "a restarted wallet rejects the wrong-passphrase") ? 0 : 1;
1083 1099
1100 vector<string> vLockedAuditArgs;
1101 vLockedAuditArgs.push_back("-datadir=" + tmp);
1102 vLockedAuditArgs.push_back("-recoveryaudit");
1103 vLockedAuditArgs.push_back("-nogui");
1104 int nLockedAuditRet = RunBitflashChild(strExe, vLockedAuditArgs, NULL, &strLockedAudit);
1105 nFail += Check(nLockedAuditRet == 2 &&
1106 FileContainsText(strLockedAudit, "recovery phrase: encrypted, unlock wallet to audit") &&
1107 FileContainsText(strLockedAudit, "recovery coverage: unavailable while wallet is locked") &&
1108 FileContainsText(strLockedAudit, "Unlock the wallet with /walletpassphrase"),
1109 "a locked encrypted wallet reports that phrase coverage needs unlock") ? 0 : 1;
1110
1084 vector<string> vLiteralArgs; 1111 vector<string> vLiteralArgs;
1085 vLiteralArgs.push_back("-datadir=" + tmp); 1112 vLiteralArgs.push_back("-datadir=" + tmp);
1086 vLiteralArgs.push_back("-walletpassphrase=btf-test-passphrase"); 1113 vLiteralArgs.push_back("-walletpassphrase=btf-test-passphrase");
@@ -1101,6 +1128,17 @@ static int RunWalletEncryptSelfTest()
1101 nFail += Check(FileContainsText(strRightDump, HexStrLocal(vchDefaultPrivBytes)), 1128 nFail += Check(FileContainsText(strRightDump, HexStrLocal(vchDefaultPrivBytes)),
1102 "the restarted wallet can decrypt and dump the original key") ? 0 : 1; 1129 "the restarted wallet can decrypt and dump the original key") ? 0 : 1;
1103 1130
1131 vector<string> vUnlockedAuditArgs;
1132 vUnlockedAuditArgs.push_back("-datadir=" + tmp);
1133 vUnlockedAuditArgs.push_back("-walletpassphrase=@" + strRightPassFile);
1134 vUnlockedAuditArgs.push_back("-recoveryaudit");
1135 vUnlockedAuditArgs.push_back("-nogui");
1136 int nUnlockedAuditRet = RunBitflashChild(strExe, vUnlockedAuditArgs, NULL, &strUnlockedAudit);
1137 nFail += Check(nUnlockedAuditRet == 0 &&
1138 FileContainsText(strUnlockedAudit, "recovery phrase: present") &&
1139 !FileContainsText(strUnlockedAudit, "recovery phrase: not installed"),
1140 "an unlocked encrypted wallet audits the installed recovery phrase") ? 0 : 1;
1141
1104 vector<string> vStdinArgs; 1142 vector<string> vStdinArgs;
1105 vStdinArgs.push_back("-datadir=" + tmp); 1143 vStdinArgs.push_back("-datadir=" + tmp);
1106 vStdinArgs.push_back("-walletpassphrase"); 1144 vStdinArgs.push_back("-walletpassphrase");
diff --git a/src/walletcmd.cpp b/src/walletcmd.cpp
index e8ac4bf..eccb9b3 100644
--- a/src/walletcmd.cpp
+++ b/src/walletcmd.cpp
@@ -400,7 +400,12 @@ int CmdRecoveryAudit()
400 int64 nImmatureTotal = audit.nRecoverableImmatureCredit + audit.nLegacyImmatureCredit; 400 int64 nImmatureTotal = audit.nRecoverableImmatureCredit + audit.nLegacyImmatureCredit;
401 401
402 printf("Wallet recovery audit\n"); 402 printf("Wallet recovery audit\n");
403 printf(" recovery phrase: %s\n", audit.fHaveSeed ? "present" : "not installed"); 403 if (audit.fHaveSeed)
404 printf(" recovery phrase: present\n");
405 else if (audit.fSeedEncryptedLocked)
406 printf(" recovery phrase: encrypted, unlock wallet to audit\n");
407 else
408 printf(" recovery phrase: not installed\n");
404 if (audit.fHaveSeed) 409 if (audit.fHaveSeed)
405 { 410 {
406 printf(" derivation schema: %s\n", HDKeySchemaName(audit.nSchema).c_str()); 411 printf(" derivation schema: %s\n", HDKeySchemaName(audit.nSchema).c_str());
@@ -412,6 +417,15 @@ int CmdRecoveryAudit()
412 if (!audit.fDeriveComplete) 417 if (!audit.fDeriveComplete)
413 printf(" derivation warning: %s\n", audit.strDeriveError.c_str()); 418 printf(" derivation warning: %s\n", audit.strDeriveError.c_str());
414 printf(" total spendable balance: %s BTF\n", FormatMoney(nTotal).c_str()); 419 printf(" total spendable balance: %s BTF\n", FormatMoney(nTotal).c_str());
420 if (audit.fSeedEncryptedLocked)
421 {
422 printf(" recovery coverage: unavailable while wallet is locked\n");
423 printf(" immature mining rewards: %s BTF\n", FormatMoney(nImmatureTotal).c_str());
424 printf("\n");
425 printf("Unlock the wallet with /walletpassphrase or /walletpassphrase=@FILE to audit phrase coverage.\n");
426 fflush(stdout);
427 return 2;
428 }
415 printf(" covered by recovery phrase: %s BTF (%d transaction(s))\n", 429 printf(" covered by recovery phrase: %s BTF (%d transaction(s))\n",
416 FormatMoney(audit.nRecoverableCredit).c_str(), audit.nRecoverableTx); 430 FormatMoney(audit.nRecoverableCredit).c_str(), audit.nRecoverableTx);
417 printf(" wallet.dat-only balance: %s BTF (%d transaction(s))\n", 431 printf(" wallet.dat-only balance: %s BTF (%d transaction(s))\n",