upleb.uk

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

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNsable-sh <nsable-sh@noreply.git.bitflash.network>2026-08-13 17:19:37 -0300
committerNsable-sh <nsable-sh@noreply.git.bitflash.network>2026-08-13 17:59:24 -0300
commit6f9e07186d06f772c93832f0dcbd4f9432b44579 (patch)
tree1ee2e5a351e704dd7ac0d3789a85d5a77f2981fb
parentf57d58155cdf65ec2ddb1a01c9d9466bf60df9ab (diff)
tests: cover portable wallet copies
-rw-r--r--src/main_gui.cpp3
-rw-r--r--src/selftest.cpp164
2 files changed, 165 insertions, 2 deletions
diff --git a/src/main_gui.cpp b/src/main_gui.cpp
index 3f52e91..50c4f34 100644
--- a/src/main_gui.cpp
+++ b/src/main_gui.cpp
@@ -114,7 +114,8 @@ static void PrintUsage()
114 printf(" /gen\n"); 114 printf(" /gen\n");
115 printf(" /nogui or /daemon\n"); 115 printf(" /nogui or /daemon\n");
116 printf(" /selftest=wallet-keypool, wallet-hd, wallet-format, wallet-crypto, wallet-encrypt,\n"); 116 printf(" /selftest=wallet-keypool, wallet-hd, wallet-format, wallet-crypto, wallet-encrypt,\n");
117 printf(" net-message, consensus-limits, pool-stratum, parse-money, socks5-proxy, or managed-tor\n"); 117 printf(" wallet-portability, net-message, consensus-limits, pool-stratum,\n");
118 printf(" parse-money, socks5-proxy, or managed-tor\n");
118 printf("\n"); 119 printf("\n");
119 printf("Mining mode:\n"); 120 printf("Mining mode:\n");
120 printf(" /operator\n"); 121 printf(" /operator\n");
diff --git a/src/selftest.cpp b/src/selftest.cpp
index 79feddf..3f3cb16 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,46 @@ 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
928static string QuoteCommandArg(const string& str) 969static string QuoteCommandArg(const string& str)
929{ 970{
930 string out = "\""; 971 string out = "\"";
@@ -1169,6 +1210,125 @@ static int RunWalletEncryptSelfTest()
1169 return nFail == 0 ? 0 : 1; 1210 return nFail == 0 ? 0 : 1;
1170} 1211}
1171 1212
1213static int RunWalletPortabilitySelfTest()
1214{
1215 fflush(stdout);
1216 printf("wallet-portability self-test\n");
1217
1218 std::string tmp;
1219 std::string cwd;
1220 if (!MakeTempDir(tmp))
1221 {
1222 printf(" FAIL could not create a temporary data directory\n");
1223 return 1;
1224 }
1225 if (!GetCurrentDir(cwd))
1226 {
1227 printf(" FAIL could not read current directory\n");
1228 RemoveTree(tmp);
1229 return 1;
1230 }
1231
1232 int nFail = 0;
1233 printf(" temp root: %s\n", tmp.c_str());
1234
1235 try
1236 {
1237#ifdef _WIN32
1238 string strExe = cwd + "\\bitflash.exe";
1239#else
1240 string strExe = cwd + "/bitflash-node";
1241#endif
1242 string strOriginal = tmp + "/original";
1243 string strRawCopy = tmp + "/raw-copy";
1244 string strBackupCopy = tmp + "/backup-copy";
1245 nFail += Check(MakeDirLocal(strOriginal) &&
1246 MakeDirLocal(strRawCopy) &&
1247 MakeDirLocal(strBackupCopy),
1248 "temporary wallet directories can be created") ? 0 : 1;
1249
1250 string strCreateOut = tmp + "/create.txt";
1251 vector<string> vCreateArgs;
1252 vCreateArgs.push_back("-datadir=" + strOriginal);
1253 vCreateArgs.push_back("-nomanagedtor");
1254 vCreateArgs.push_back("-nogui");
1255 vCreateArgs.push_back("-newphrase");
1256 int nCreateRet = RunBitflashChild(strExe, vCreateArgs, NULL, &strCreateOut);
1257 nFail += Check(nCreateRet == 0 &&
1258 FileContainsText(strCreateOut, "Write these twelve words down"),
1259 "a phrase wallet can be created in a fresh datadir") ? 0 : 1;
1260
1261 string strOriginalAudit = tmp + "/original-audit.txt";
1262 vector<string> vOriginalAuditArgs;
1263 vOriginalAuditArgs.push_back("-datadir=" + strOriginal);
1264 vOriginalAuditArgs.push_back("-nomanagedtor");
1265 vOriginalAuditArgs.push_back("-nogui");
1266 vOriginalAuditArgs.push_back("-recoveryaudit");
1267 int nOriginalAuditRet = RunBitflashChild(strExe, vOriginalAuditArgs, NULL, &strOriginalAudit);
1268 nFail += Check(nOriginalAuditRet == 0 &&
1269 FileContainsText(strOriginalAudit, "recovery phrase: present") &&
1270 FileContainsText(strOriginalAudit, "SLIP-0044 BITFLASH"),
1271 "the original wallet reports its recovery phrase") ? 0 : 1;
1272
1273 string strPortableWallet = tmp + "/portable-wallet.dat";
1274 string strBackupOut = tmp + "/backupwallet.txt";
1275 vector<string> vBackupArgs;
1276 vBackupArgs.push_back("-datadir=" + strOriginal);
1277 vBackupArgs.push_back("-nomanagedtor");
1278 vBackupArgs.push_back("-nogui");
1279 vBackupArgs.push_back("-backupwallet=" + strPortableWallet);
1280 int nBackupRet = RunBitflashChild(strExe, vBackupArgs, NULL, &strBackupOut);
1281 nFail += Check(nBackupRet == 0 && FileExists(strPortableWallet.c_str()),
1282 "/backupwallet writes a portable wallet.dat") ? 0 : 1;
1283
1284 nFail += Check(CopyFileLocal(strOriginal + "/wallet.dat",
1285 strRawCopy + "/wallet.dat"),
1286 "a raw wallet.dat can be copied without database logs") ? 0 : 1;
1287 string strRawAudit = tmp + "/raw-copy-audit.txt";
1288 vector<string> vRawAuditArgs;
1289 vRawAuditArgs.push_back("-datadir=" + strRawCopy);
1290 vRawAuditArgs.push_back("-nomanagedtor");
1291 vRawAuditArgs.push_back("-nogui");
1292 vRawAuditArgs.push_back("-recoveryaudit");
1293 int nRawAuditRet = RunBitflashChild(strExe, vRawAuditArgs, NULL, &strRawAudit);
1294 nFail += Check(nRawAuditRet == 0 &&
1295 FileContainsText(strRawAudit, "recovery phrase: present") &&
1296 !FileContainsText(strRawAudit, "Cannot open wallet.dat"),
1297 "a raw wallet.dat copy opens in a new datadir") ? 0 : 1;
1298
1299 nFail += Check(CopyFileLocal(strPortableWallet,
1300 strBackupCopy + "/wallet.dat"),
1301 "the portable backup can be installed as wallet.dat") ? 0 : 1;
1302 string strBackupAudit = tmp + "/backup-copy-audit.txt";
1303 vector<string> vBackupAuditArgs;
1304 vBackupAuditArgs.push_back("-datadir=" + strBackupCopy);
1305 vBackupAuditArgs.push_back("-nomanagedtor");
1306 vBackupAuditArgs.push_back("-nogui");
1307 vBackupAuditArgs.push_back("-recoveryaudit");
1308 int nBackupAuditRet = RunBitflashChild(strExe, vBackupAuditArgs, NULL, &strBackupAudit);
1309 nFail += Check(nBackupAuditRet == 0 &&
1310 FileContainsText(strBackupAudit, "recovery phrase: present") &&
1311 FileContainsText(strBackupAudit, "SLIP-0044 BITFLASH"),
1312 "a /backupwallet copy opens in a new datadir") ? 0 : 1;
1313 }
1314 catch (const std::exception& e)
1315 {
1316 printf(" FAIL exception: %s\n", e.what());
1317 nFail++;
1318 }
1319 catch (...)
1320 {
1321 printf(" FAIL unknown exception\n");
1322 nFail++;
1323 }
1324
1325 RemoveTree(tmp);
1326 printf("%s (%d failure%s)\n", nFail == 0 ? "ALL TESTS PASSED" : "TESTS FAILED",
1327 nFail, nFail == 1 ? "" : "s");
1328 fflush(stdout);
1329 return nFail == 0 ? 0 : 1;
1330}
1331
1172static int RunNetMessageSelfTest() 1332static int RunNetMessageSelfTest()
1173{ 1333{
1174 fflush(stdout); 1334 fflush(stdout);
@@ -1653,6 +1813,8 @@ int RunSelfTest(const std::string& name)
1653 return RunWalletCryptoSelfTest(); 1813 return RunWalletCryptoSelfTest();
1654 if (name == "wallet-encrypt") 1814 if (name == "wallet-encrypt")
1655 return RunWalletEncryptSelfTest(); 1815 return RunWalletEncryptSelfTest();
1816 if (name == "wallet-portability")
1817 return RunWalletPortabilitySelfTest();
1656 if (name == "net-message") 1818 if (name == "net-message")
1657 return RunNetMessageSelfTest(); 1819 return RunNetMessageSelfTest();
1658 if (name == "consensus-limits") 1820 if (name == "consensus-limits")
@@ -1667,6 +1829,6 @@ int RunSelfTest(const std::string& name)
1667 return RunManagedTorSelfTest(); 1829 return RunManagedTorSelfTest();
1668 1830
1669 printf("Unknown self-test '%s'\n", name.c_str()); 1831 printf("Unknown self-test '%s'\n", name.c_str());
1670 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"); 1832 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");
1671 return 1; 1833 return 1;
1672} 1834}