diff options
Diffstat (limited to 'src/db.cpp')
| -rw-r--r-- | src/db.cpp | 91 |
1 files changed, 91 insertions, 0 deletions
| @@ -124,6 +124,13 @@ void WalletSQLiteRuntimeClose() | |||
| 124 | { | 124 | { |
| 125 | if (pWalletSQLiteRuntime) | 125 | if (pWalletSQLiteRuntime) |
| 126 | { | 126 | { |
| 127 | // Fold the write-ahead log into the main file on the way out. WAL + | ||
| 128 | // synchronous=FULL already makes every committed write durable across a | ||
| 129 | // kill, so this is housekeeping, not the thing that protects the data: | ||
| 130 | // if it fails, or the node is killed before it runs, the wallet is | ||
| 131 | // still whole. Best effort, never throws. | ||
| 132 | string strCheckpointError; | ||
| 133 | pWalletSQLiteRuntime->Checkpoint(strCheckpointError); | ||
| 127 | delete pWalletSQLiteRuntime; | 134 | delete pWalletSQLiteRuntime; |
| 128 | pWalletSQLiteRuntime = NULL; | 135 | pWalletSQLiteRuntime = NULL; |
| 129 | } | 136 | } |
| @@ -1426,6 +1433,90 @@ bool LoadWalletFromSQLite(const string& strPath) | |||
| 1426 | return FinishLoadedWallet(visitor.vchDefaultKey, false); | 1433 | return FinishLoadedWallet(visitor.vchDefaultKey, false); |
| 1427 | } | 1434 | } |
| 1428 | 1435 | ||
| 1436 | // Open a SQLite wallet read-write and keep it open as the active runtime | ||
| 1437 | // backend, then load its records into memory the same way LoadWalletFromSQLite | ||
| 1438 | // does. Unlike the read-only staging path, this leaves pWalletSQLiteRuntime set | ||
| 1439 | // so every later CWalletDB read/write/erase routes to this file for the life of | ||
| 1440 | // the process. The Berkeley DB wallet.dat is never opened. | ||
| 1441 | bool LoadWalletFromSQLiteRuntime(const string& strPath) | ||
| 1442 | { | ||
| 1443 | strWalletLoadError.clear(); | ||
| 1444 | |||
| 1445 | if (!FileExists(strPath.c_str())) | ||
| 1446 | { | ||
| 1447 | strWalletLoadError = strprintf("SQLite wallet does not exist: %s", | ||
| 1448 | strPath.c_str()); | ||
| 1449 | printf("LoadWallet: %s\n", strWalletLoadError.c_str()); | ||
| 1450 | return false; | ||
| 1451 | } | ||
| 1452 | |||
| 1453 | string strError; | ||
| 1454 | if (!WalletSQLiteRuntimeOpen(strPath, strError)) | ||
| 1455 | { | ||
| 1456 | strWalletLoadError = strError; | ||
| 1457 | printf("LoadWallet: cannot open SQLite wallet backend: %s\n", | ||
| 1458 | strError.c_str()); | ||
| 1459 | return false; | ||
| 1460 | } | ||
| 1461 | |||
| 1462 | CSQLiteWalletRuntimeLoadVisitor visitor; | ||
| 1463 | try | ||
| 1464 | { | ||
| 1465 | CRITICAL_BLOCK(cs_mapKeys) | ||
| 1466 | CRITICAL_BLOCK(cs_mapWallet) | ||
| 1467 | { | ||
| 1468 | if (!pWalletSQLiteRuntime->ScanRecords(visitor, strError)) | ||
| 1469 | { | ||
| 1470 | WalletSQLiteRuntimeClose(); | ||
| 1471 | if (strWalletLoadError.empty()) | ||
| 1472 | strWalletLoadError = strError; | ||
| 1473 | printf("LoadWallet: SQLite wallet backend could not be read. " | ||
| 1474 | "Failed while handling a '%s' record: %s\n", | ||
| 1475 | visitor.strLastType.c_str(), strError.c_str()); | ||
| 1476 | return false; | ||
| 1477 | } | ||
| 1478 | } | ||
| 1479 | } | ||
| 1480 | catch (const std::exception& e) | ||
| 1481 | { | ||
| 1482 | WalletSQLiteRuntimeClose(); | ||
| 1483 | strWalletLoadError = strprintf( | ||
| 1484 | "SQLite wallet backend could not be read while handling a '%s' record: %s", | ||
| 1485 | visitor.strLastType.c_str(), e.what()); | ||
| 1486 | printf("LoadWallet: %s\n", strWalletLoadError.c_str()); | ||
| 1487 | return false; | ||
| 1488 | } | ||
| 1489 | catch (...) | ||
| 1490 | { | ||
| 1491 | WalletSQLiteRuntimeClose(); | ||
| 1492 | strWalletLoadError = strprintf( | ||
| 1493 | "SQLite wallet backend could not be read while handling a '%s' record", | ||
| 1494 | visitor.strLastType.c_str()); | ||
| 1495 | printf("LoadWallet: %s\n", strWalletLoadError.c_str()); | ||
| 1496 | return false; | ||
| 1497 | } | ||
| 1498 | |||
| 1499 | if (!ReconcileLoadedWalletMetadata(visitor.fHaveStoredMineMode, | ||
| 1500 | visitor.fHaveStoredHDCoinType)) | ||
| 1501 | { | ||
| 1502 | WalletSQLiteRuntimeClose(); | ||
| 1503 | if (strWalletLoadError.empty()) | ||
| 1504 | strWalletLoadError = "SQLite wallet metadata is not supported by this build"; | ||
| 1505 | return false; | ||
| 1506 | } | ||
| 1507 | |||
| 1508 | // Never fabricate a default key: an export always carries one, and a file | ||
| 1509 | // that does not is refused with the wallet left open to no writes rather | ||
| 1510 | // than quietly minted into a new identity. | ||
| 1511 | if (!FinishLoadedWallet(visitor.vchDefaultKey, false)) | ||
| 1512 | { | ||
| 1513 | WalletSQLiteRuntimeClose(); | ||
| 1514 | return false; | ||
| 1515 | } | ||
| 1516 | |||
| 1517 | return true; | ||
| 1518 | } | ||
| 1519 | |||
| 1429 | 1520 | ||
| 1430 | // Write a copy of wallet.dat that can be opened anywhere. | 1521 | // Write a copy of wallet.dat that can be opened anywhere. |
| 1431 | // | 1522 | // |