upleb.uk

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

summaryrefslogtreecommitdiff
path: root/src/selftest.cpp
diff options
context:
space:
mode:
authorBitflash <admin@bitflash.network>2026-08-14 08:56:40 -0300
committerBitflash <admin@bitflash.network>2026-08-14 08:56:40 -0300
commit5306542f6121e0c0b4ed1210e24d55fa4fbb7127 (patch)
tree5faf35daa569d987b87dbb161bb18ec170f944b0 /src/selftest.cpp
parent9e39a50d1f110020b0841d31e4b931aa877cc448 (diff)
parent805c5757b801d80ea575c6a8b58e2855254f9046 (diff)
Merge pull request 'wallet: audit Berkeley DB wallet storage' (#38) from wallet-storage-audit-bdb into main
Diffstat (limited to 'src/selftest.cpp')
-rw-r--r--src/selftest.cpp336
1 files changed, 332 insertions, 4 deletions
diff --git a/src/selftest.cpp b/src/selftest.cpp
index 3c93927..73c2935 100644
--- a/src/selftest.cpp
+++ b/src/selftest.cpp
@@ -34,6 +34,7 @@ extern int RunPoolStratumSelfTest();
34#undef printf 34#undef printf
35 35
36#include <mutex> 36#include <mutex>
37#include <cerrno>
37#include <stdexcept> 38#include <stdexcept>
38#include <thread> 39#include <thread>
39 40
@@ -925,6 +926,90 @@ static bool WriteTextFile(const string& strPath, const string& strText)
925 return fOk; 926 return fOk;
926} 927}
927 928
929static bool MakeDirLocal(const string& strPath)
930{
931#ifdef _WIN32
932 return CreateDirectoryA(strPath.c_str(), NULL) || GetLastError() == ERROR_ALREADY_EXISTS;
933#else
934 return mkdir(strPath.c_str(), 0700) == 0 || errno == EEXIST;
935#endif
936}
937
938static bool CopyFileLocal(const string& strSrc, const string& strDst)
939{
940 FILE* in = fopen(strSrc.c_str(), "rb");
941 if (!in)
942 return false;
943 FILE* out = fopen(strDst.c_str(), "wb");
944 if (!out)
945 {
946 fclose(in);
947 return false;
948 }
949
950 bool fOk = true;
951 char buf[65536];
952 size_t n = 0;
953 while ((n = fread(buf, 1, sizeof(buf), in)) > 0)
954 {
955 if (fwrite(buf, 1, n, out) != n)
956 {
957 fOk = false;
958 break;
959 }
960 }
961 if (ferror(in))
962 fOk = false;
963 if (fclose(out) != 0)
964 fOk = false;
965 fclose(in);
966 return fOk;
967}
968
969static bool DirectoryHasFileWithPrefix(const string& strDir, const string& strPrefix)
970{
971#ifdef _WIN32
972 WIN32_FIND_DATAA findData;
973 string pattern = strDir + "\\*";
974 HANDLE hFind = FindFirstFileA(pattern.c_str(), &findData);
975 if (hFind == INVALID_HANDLE_VALUE)
976 return false;
977 bool fFound = false;
978 do
979 {
980 if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
981 {
982 string name = findData.cFileName;
983 if (name.compare(0, strPrefix.size(), strPrefix) == 0)
984 {
985 fFound = true;
986 break;
987 }
988 }
989 }
990 while (FindNextFileA(hFind, &findData));
991 FindClose(hFind);
992 return fFound;
993#else
994 DIR* dir = opendir(strDir.c_str());
995 if (!dir)
996 return false;
997 bool fFound = false;
998 struct dirent* ent;
999 while ((ent = readdir(dir)) != NULL)
1000 {
1001 string name = ent->d_name;
1002 if (name.compare(0, strPrefix.size(), strPrefix) == 0)
1003 {
1004 fFound = true;
1005 break;
1006 }
1007 }
1008 closedir(dir);
1009 return fFound;
1010#endif
1011}
1012
928static string QuoteCommandArg(const string& str) 1013static string QuoteCommandArg(const string& str)
929{ 1014{
930 string out = "\""; 1015 string out = "\"";
@@ -941,7 +1026,8 @@ static string QuoteCommandArg(const string& str)
941 1026
942static int RunBitflashChild(const string& strExe, 1027static int RunBitflashChild(const string& strExe,
943 const vector<string>& vArgs, 1028 const vector<string>& vArgs,
944 const string* pStdinFile = NULL) 1029 const string* pStdinFile = NULL,
1030 const string* pOutputFile = NULL)
945{ 1031{
946#ifdef _WIN32 1032#ifdef _WIN32
947 vector<char*> argv; 1033 vector<char*> argv;
@@ -954,8 +1040,16 @@ static int RunBitflashChild(const string& strExe,
954 int nOldErr = _dup(2); 1040 int nOldErr = _dup(2);
955 int nOldIn = _dup(0); 1041 int nOldIn = _dup(0);
956 int nNull = _open("NUL", _O_WRONLY); 1042 int nNull = _open("NUL", _O_WRONLY);
1043 int nOut = -1;
957 int nIn = -1; 1044 int nIn = -1;
958 if (nNull >= 0) 1045 if (pOutputFile)
1046 nOut = _open(pOutputFile->c_str(), _O_WRONLY|_O_CREAT|_O_TRUNC|_O_BINARY, _S_IREAD|_S_IWRITE);
1047 if (nOut >= 0)
1048 {
1049 _dup2(nOut, 1);
1050 _dup2(nOut, 2);
1051 }
1052 else if (nNull >= 0)
959 { 1053 {
960 _dup2(nNull, 1); 1054 _dup2(nNull, 1);
961 _dup2(nNull, 2); 1055 _dup2(nNull, 2);
@@ -969,6 +1063,8 @@ static int RunBitflashChild(const string& strExe,
969 int nRet = _spawnv(_P_WAIT, strExe.c_str(), &argv[0]); 1063 int nRet = _spawnv(_P_WAIT, strExe.c_str(), &argv[0]);
970 if (nIn >= 0) 1064 if (nIn >= 0)
971 _close(nIn); 1065 _close(nIn);
1066 if (nOut >= 0)
1067 _close(nOut);
972 if (nNull >= 0) 1068 if (nNull >= 0)
973 _close(nNull); 1069 _close(nNull);
974 if (nOldIn >= 0) 1070 if (nOldIn >= 0)
@@ -993,7 +1089,10 @@ static int RunBitflashChild(const string& strExe,
993 strCmd += " " + QuoteCommandArg(vArgs[i]); 1089 strCmd += " " + QuoteCommandArg(vArgs[i]);
994 if (pStdinFile) 1090 if (pStdinFile)
995 strCmd += " < " + QuoteCommandArg(*pStdinFile); 1091 strCmd += " < " + QuoteCommandArg(*pStdinFile);
996 strCmd += " > /dev/null 2>&1"; 1092 if (pOutputFile)
1093 strCmd += " > " + QuoteCommandArg(*pOutputFile) + " 2>&1";
1094 else
1095 strCmd += " > /dev/null 2>&1";
997 return system(strCmd.c_str()); 1096 return system(strCmd.c_str());
998#endif 1097#endif
999} 1098}
@@ -1066,6 +1165,8 @@ static int RunWalletEncryptSelfTest()
1066 string strRightDump = tmp + "/right-pass-dump.txt"; 1165 string strRightDump = tmp + "/right-pass-dump.txt";
1067 string strLiteralDump = tmp + "/literal-pass-dump.txt"; 1166 string strLiteralDump = tmp + "/literal-pass-dump.txt";
1068 string strStdinDump = tmp + "/stdin-pass-dump.txt"; 1167 string strStdinDump = tmp + "/stdin-pass-dump.txt";
1168 string strLockedAudit = tmp + "/locked-recovery-audit.txt";
1169 string strUnlockedAudit = tmp + "/unlocked-recovery-audit.txt";
1069 string strWrongPassFile = tmp + "/wrong-pass.txt"; 1170 string strWrongPassFile = tmp + "/wrong-pass.txt";
1070 string strRightPassFile = tmp + "/right-pass.txt"; 1171 string strRightPassFile = tmp + "/right-pass.txt";
1071 nFail += Check(WriteTextFile(strWrongPassFile, "wrong-passphrase\n") && 1172 nFail += Check(WriteTextFile(strWrongPassFile, "wrong-passphrase\n") &&
@@ -1081,6 +1182,17 @@ static int RunWalletEncryptSelfTest()
1081 nFail += Check(nWrongRet != 0 && !FileExists(strWrongDump.c_str()), 1182 nFail += Check(nWrongRet != 0 && !FileExists(strWrongDump.c_str()),
1082 "a restarted wallet rejects the wrong-passphrase") ? 0 : 1; 1183 "a restarted wallet rejects the wrong-passphrase") ? 0 : 1;
1083 1184
1185 vector<string> vLockedAuditArgs;
1186 vLockedAuditArgs.push_back("-datadir=" + tmp);
1187 vLockedAuditArgs.push_back("-recoveryaudit");
1188 vLockedAuditArgs.push_back("-nogui");
1189 int nLockedAuditRet = RunBitflashChild(strExe, vLockedAuditArgs, NULL, &strLockedAudit);
1190 nFail += Check(nLockedAuditRet == 2 &&
1191 FileContainsText(strLockedAudit, "recovery phrase: encrypted, unlock wallet to audit") &&
1192 FileContainsText(strLockedAudit, "recovery coverage: unavailable while wallet is locked") &&
1193 FileContainsText(strLockedAudit, "Unlock the wallet with /walletpassphrase"),
1194 "a locked encrypted wallet reports that phrase coverage needs unlock") ? 0 : 1;
1195
1084 vector<string> vLiteralArgs; 1196 vector<string> vLiteralArgs;
1085 vLiteralArgs.push_back("-datadir=" + tmp); 1197 vLiteralArgs.push_back("-datadir=" + tmp);
1086 vLiteralArgs.push_back("-walletpassphrase=btf-test-passphrase"); 1198 vLiteralArgs.push_back("-walletpassphrase=btf-test-passphrase");
@@ -1101,6 +1213,17 @@ static int RunWalletEncryptSelfTest()
1101 nFail += Check(FileContainsText(strRightDump, HexStrLocal(vchDefaultPrivBytes)), 1213 nFail += Check(FileContainsText(strRightDump, HexStrLocal(vchDefaultPrivBytes)),
1102 "the restarted wallet can decrypt and dump the original key") ? 0 : 1; 1214 "the restarted wallet can decrypt and dump the original key") ? 0 : 1;
1103 1215
1216 vector<string> vUnlockedAuditArgs;
1217 vUnlockedAuditArgs.push_back("-datadir=" + tmp);
1218 vUnlockedAuditArgs.push_back("-walletpassphrase=@" + strRightPassFile);
1219 vUnlockedAuditArgs.push_back("-recoveryaudit");
1220 vUnlockedAuditArgs.push_back("-nogui");
1221 int nUnlockedAuditRet = RunBitflashChild(strExe, vUnlockedAuditArgs, NULL, &strUnlockedAudit);
1222 nFail += Check(nUnlockedAuditRet == 0 &&
1223 FileContainsText(strUnlockedAudit, "recovery phrase: present") &&
1224 !FileContainsText(strUnlockedAudit, "recovery phrase: not installed"),
1225 "an unlocked encrypted wallet audits the installed recovery phrase") ? 0 : 1;
1226
1104 vector<string> vStdinArgs; 1227 vector<string> vStdinArgs;
1105 vStdinArgs.push_back("-datadir=" + tmp); 1228 vStdinArgs.push_back("-datadir=" + tmp);
1106 vStdinArgs.push_back("-walletpassphrase"); 1229 vStdinArgs.push_back("-walletpassphrase");
@@ -1131,6 +1254,209 @@ static int RunWalletEncryptSelfTest()
1131 return nFail == 0 ? 0 : 1; 1254 return nFail == 0 ? 0 : 1;
1132} 1255}
1133 1256
1257static int RunWalletPortabilitySelfTest()
1258{
1259 fflush(stdout);
1260 printf("wallet-portability self-test\n");
1261
1262 std::string tmp;
1263 std::string cwd;
1264 if (!MakeTempDir(tmp))
1265 {
1266 printf(" FAIL could not create a temporary data directory\n");
1267 return 1;
1268 }
1269 if (!GetCurrentDir(cwd))
1270 {
1271 printf(" FAIL could not read current directory\n");
1272 RemoveTree(tmp);
1273 return 1;
1274 }
1275
1276 int nFail = 0;
1277 printf(" temp root: %s\n", tmp.c_str());
1278
1279 try
1280 {
1281#ifdef _WIN32
1282 string strExe = cwd + "\\bitflash.exe";
1283#else
1284 string strExe = cwd + "/bitflash-node";
1285#endif
1286 string strOriginal = tmp + "/original";
1287 string strRawCopy = tmp + "/raw-copy";
1288 string strBackupCopy = tmp + "/backup-copy";
1289 nFail += Check(MakeDirLocal(strOriginal) &&
1290 MakeDirLocal(strRawCopy) &&
1291 MakeDirLocal(strBackupCopy),
1292 "temporary wallet directories can be created") ? 0 : 1;
1293
1294 string strCreateOut = tmp + "/create.txt";
1295 vector<string> vCreateArgs;
1296 vCreateArgs.push_back("-datadir=" + strOriginal);
1297 vCreateArgs.push_back("-nomanagedtor");
1298 vCreateArgs.push_back("-nogui");
1299 vCreateArgs.push_back("-newphrase");
1300 int nCreateRet = RunBitflashChild(strExe, vCreateArgs, NULL, &strCreateOut);
1301 nFail += Check(nCreateRet == 0 &&
1302 FileContainsText(strCreateOut, "Write these twelve words down"),
1303 "a phrase wallet can be created in a fresh datadir") ? 0 : 1;
1304
1305 string strOriginalAudit = tmp + "/original-audit.txt";
1306 vector<string> vOriginalAuditArgs;
1307 vOriginalAuditArgs.push_back("-datadir=" + strOriginal);
1308 vOriginalAuditArgs.push_back("-nomanagedtor");
1309 vOriginalAuditArgs.push_back("-nogui");
1310 vOriginalAuditArgs.push_back("-recoveryaudit");
1311 int nOriginalAuditRet = RunBitflashChild(strExe, vOriginalAuditArgs, NULL, &strOriginalAudit);
1312 nFail += Check(nOriginalAuditRet == 0 &&
1313 FileContainsText(strOriginalAudit, "recovery phrase: present") &&
1314 FileContainsText(strOriginalAudit, "SLIP-0044 BITFLASH"),
1315 "the original wallet reports its recovery phrase") ? 0 : 1;
1316
1317 string strOriginalStorageAudit = tmp + "/original-storage-audit.txt";
1318 vector<string> vOriginalStorageAuditArgs;
1319 vOriginalStorageAuditArgs.push_back("-datadir=" + strOriginal);
1320 vOriginalStorageAuditArgs.push_back("-nomanagedtor");
1321 vOriginalStorageAuditArgs.push_back("-nogui");
1322 vOriginalStorageAuditArgs.push_back("-walletstorageaudit");
1323 int nOriginalStorageAuditRet =
1324 RunBitflashChild(strExe, vOriginalStorageAuditArgs, NULL, &strOriginalStorageAudit);
1325 nFail += Check(nOriginalStorageAuditRet == 0 &&
1326 FileContainsText(strOriginalStorageAudit, "Wallet storage audit") &&
1327 FileContainsText(strOriginalStorageAudit, "plain HD seed: complete") &&
1328 FileContainsText(strOriginalStorageAudit, "encrypted HD seed: none") &&
1329 FileContainsText(strOriginalStorageAudit, "malformed records: 0"),
1330 "the storage audit recognizes a plaintext phrase wallet") ? 0 : 1;
1331
1332 string strOriginalStorageAuditJson = tmp + "/original-storage-audit.json";
1333 vector<string> vOriginalStorageAuditJsonArgs;
1334 vOriginalStorageAuditJsonArgs.push_back("-datadir=" + strOriginal);
1335 vOriginalStorageAuditJsonArgs.push_back("-nomanagedtor");
1336 vOriginalStorageAuditJsonArgs.push_back("-nogui");
1337 vOriginalStorageAuditJsonArgs.push_back("-walletstorageauditjson=" +
1338 strOriginalStorageAuditJson);
1339 int nOriginalStorageAuditJsonRet =
1340 RunBitflashChild(strExe, vOriginalStorageAuditJsonArgs);
1341 nFail += Check(nOriginalStorageAuditJsonRet == 0 &&
1342 FileContainsText(strOriginalStorageAuditJson,
1343 "\"format\": \"bitflash-wallet-storage-audit-v1\"") &&
1344 FileContainsText(strOriginalStorageAuditJson,
1345 "\"plain_hd_seed\": \"complete\"") &&
1346 FileContainsText(strOriginalStorageAuditJson,
1347 "\"encrypted_hd_seed\": \"none\""),
1348 "the storage audit can write plaintext-wallet JSON") ? 0 : 1;
1349
1350 string strPortableWallet = tmp + "/portable-wallet.dat";
1351 string strBackupOut = tmp + "/backupwallet.txt";
1352 vector<string> vBackupArgs;
1353 vBackupArgs.push_back("-datadir=" + strOriginal);
1354 vBackupArgs.push_back("-nomanagedtor");
1355 vBackupArgs.push_back("-nogui");
1356 vBackupArgs.push_back("-backupwallet=" + strPortableWallet);
1357 int nBackupRet = RunBitflashChild(strExe, vBackupArgs, NULL, &strBackupOut);
1358 nFail += Check(nBackupRet == 0 && FileExists(strPortableWallet.c_str()),
1359 "/backupwallet writes a portable wallet.dat") ? 0 : 1;
1360
1361 nFail += Check(CopyFileLocal(strOriginal + "/wallet.dat",
1362 strRawCopy + "/wallet.dat"),
1363 "a raw wallet.dat can be copied without database logs") ? 0 : 1;
1364 string strRawAudit = tmp + "/raw-copy-audit.txt";
1365 vector<string> vRawAuditArgs;
1366 vRawAuditArgs.push_back("-datadir=" + strRawCopy);
1367 vRawAuditArgs.push_back("-nomanagedtor");
1368 vRawAuditArgs.push_back("-nogui");
1369 vRawAuditArgs.push_back("-recoveryaudit");
1370 int nRawAuditRet = RunBitflashChild(strExe, vRawAuditArgs, NULL, &strRawAudit);
1371 nFail += Check(nRawAuditRet == 0 &&
1372 FileContainsText(strRawAudit, "recovery phrase: present") &&
1373 !FileContainsText(strRawAudit, "Cannot open wallet.dat"),
1374 "a raw wallet.dat copy opens in a new datadir") ? 0 : 1;
1375
1376 nFail += Check(CopyFileLocal(strPortableWallet,
1377 strBackupCopy + "/wallet.dat"),
1378 "the portable backup can be installed as wallet.dat") ? 0 : 1;
1379 string strBackupAudit = tmp + "/backup-copy-audit.txt";
1380 vector<string> vBackupAuditArgs;
1381 vBackupAuditArgs.push_back("-datadir=" + strBackupCopy);
1382 vBackupAuditArgs.push_back("-nomanagedtor");
1383 vBackupAuditArgs.push_back("-nogui");
1384 vBackupAuditArgs.push_back("-recoveryaudit");
1385 int nBackupAuditRet = RunBitflashChild(strExe, vBackupAuditArgs, NULL, &strBackupAudit);
1386 nFail += Check(nBackupAuditRet == 0 &&
1387 FileContainsText(strBackupAudit, "recovery phrase: present") &&
1388 FileContainsText(strBackupAudit, "SLIP-0044 BITFLASH"),
1389 "a /backupwallet copy opens in a new datadir") ? 0 : 1;
1390
1391 string strPassFile = tmp + "/encrypt-pass.txt";
1392 string strEncryptOut = tmp + "/encryptwallet.txt";
1393 nFail += Check(WriteTextFile(strPassFile, "portable-test-passphrase\n"),
1394 "an encryption passphrase file can be written") ? 0 : 1;
1395 vector<string> vEncryptArgs;
1396 vEncryptArgs.push_back("-datadir=" + strOriginal);
1397 vEncryptArgs.push_back("-nomanagedtor");
1398 vEncryptArgs.push_back("-nogui");
1399 vEncryptArgs.push_back("-encryptwallet=@" + strPassFile);
1400 int nEncryptRet = RunBitflashChild(strExe, vEncryptArgs, NULL, &strEncryptOut);
1401 nFail += Check(nEncryptRet == 0 &&
1402 !DirectoryHasFileWithPrefix(strOriginal + "/database", "log."),
1403 "the encryptwallet command purges Berkeley DB environment logs") ? 0 : 1;
1404
1405 string strEncryptedStorageAudit = tmp + "/encrypted-storage-audit.txt";
1406 vector<string> vEncryptedStorageAuditArgs;
1407 vEncryptedStorageAuditArgs.push_back("-datadir=" + strOriginal);
1408 vEncryptedStorageAuditArgs.push_back("-nomanagedtor");
1409 vEncryptedStorageAuditArgs.push_back("-nogui");
1410 vEncryptedStorageAuditArgs.push_back("-walletstorageaudit");
1411 int nEncryptedStorageAuditRet =
1412 RunBitflashChild(strExe, vEncryptedStorageAuditArgs, NULL, &strEncryptedStorageAudit);
1413 nFail += Check(nEncryptedStorageAuditRet == 0 &&
1414 FileContainsText(strEncryptedStorageAudit, "plain private keys: 0") &&
1415 FileContainsText(strEncryptedStorageAudit, "encrypted private keys:") &&
1416 FileContainsText(strEncryptedStorageAudit, "plain HD seed: none") &&
1417 FileContainsText(strEncryptedStorageAudit, "encrypted HD seed: complete") &&
1418 FileContainsText(strEncryptedStorageAudit, "wallet minimum version: present") &&
1419 FileContainsText(strEncryptedStorageAudit, "malformed records: 0"),
1420 "the storage audit recognizes an encrypted wallet") ? 0 : 1;
1421
1422 string strEncryptedStorageAuditJson = tmp + "/encrypted-storage-audit.json";
1423 vector<string> vEncryptedStorageAuditJsonArgs;
1424 vEncryptedStorageAuditJsonArgs.push_back("-datadir=" + strOriginal);
1425 vEncryptedStorageAuditJsonArgs.push_back("-nomanagedtor");
1426 vEncryptedStorageAuditJsonArgs.push_back("-nogui");
1427 vEncryptedStorageAuditJsonArgs.push_back("-walletstorageauditjson=" +
1428 strEncryptedStorageAuditJson);
1429 int nEncryptedStorageAuditJsonRet =
1430 RunBitflashChild(strExe, vEncryptedStorageAuditJsonArgs);
1431 nFail += Check(nEncryptedStorageAuditJsonRet == 0 &&
1432 FileContainsText(strEncryptedStorageAuditJson,
1433 "\"plain_private_keys\": 0") &&
1434 FileContainsText(strEncryptedStorageAuditJson,
1435 "\"plain_hd_seed\": \"none\"") &&
1436 FileContainsText(strEncryptedStorageAuditJson,
1437 "\"encrypted_hd_seed\": \"complete\"") &&
1438 FileContainsText(strEncryptedStorageAuditJson,
1439 "\"wallet_minimum_version\": \"present\""),
1440 "the storage audit can write encrypted-wallet JSON") ? 0 : 1;
1441 }
1442 catch (const std::exception& e)
1443 {
1444 printf(" FAIL exception: %s\n", e.what());
1445 nFail++;
1446 }
1447 catch (...)
1448 {
1449 printf(" FAIL unknown exception\n");
1450 nFail++;
1451 }
1452
1453 RemoveTree(tmp);
1454 printf("%s (%d failure%s)\n", nFail == 0 ? "ALL TESTS PASSED" : "TESTS FAILED",
1455 nFail, nFail == 1 ? "" : "s");
1456 fflush(stdout);
1457 return nFail == 0 ? 0 : 1;
1458}
1459
1134static int RunNetMessageSelfTest() 1460static int RunNetMessageSelfTest()
1135{ 1461{
1136 fflush(stdout); 1462 fflush(stdout);
@@ -1615,6 +1941,8 @@ int RunSelfTest(const std::string& name)
1615 return RunWalletCryptoSelfTest(); 1941 return RunWalletCryptoSelfTest();
1616 if (name == "wallet-encrypt") 1942 if (name == "wallet-encrypt")
1617 return RunWalletEncryptSelfTest(); 1943 return RunWalletEncryptSelfTest();
1944 if (name == "wallet-portability")
1945 return RunWalletPortabilitySelfTest();
1618 if (name == "net-message") 1946 if (name == "net-message")
1619 return RunNetMessageSelfTest(); 1947 return RunNetMessageSelfTest();
1620 if (name == "consensus-limits") 1948 if (name == "consensus-limits")
@@ -1629,6 +1957,6 @@ int RunSelfTest(const std::string& name)
1629 return RunManagedTorSelfTest(); 1957 return RunManagedTorSelfTest();
1630 1958
1631 printf("Unknown self-test '%s'\n", name.c_str()); 1959 printf("Unknown self-test '%s'\n", name.c_str());
1632 printf("Known self-tests: wallet-keypool, wallet-hd, wallet-format, wallet-crypto, wallet-encrypt, net-message, consensus-limits, pool-stratum, parse-money, socks5-proxy, managed-tor\n"); 1960 printf("Known self-tests: wallet-keypool, wallet-hd, wallet-format, wallet-crypto, wallet-encrypt, wallet-portability, net-message, consensus-limits, pool-stratum, parse-money, socks5-proxy, managed-tor\n");
1633 return 1; 1961 return 1;
1634} 1962}