diff options
| author | Bitflash <admin@bitflash.network> | 2026-08-17 12:08:12 -0300 |
|---|---|---|
| committer | Bitflash <admin@bitflash.network> | 2026-08-17 12:08:12 -0300 |
| commit | a6eb8dab830be3135c054ae3ae442886f1867b4e (patch) | |
| tree | 5372e845b7c6cf75fb9aaab2caaaf15eaadd0dd3 | |
| parent | 0175bb9205d7e3dc474aede8000a05f1d70ed0e6 (diff) | |
| parent | d082210c5d080c0a91412b94a109d8e73422eb31 (diff) | |
Merge pull request 'wallet: route CWalletDB through SQLite runtime' (#58) from wallet-sqlite-runtime-write into main
| -rw-r--r-- | src/db.cpp | 67 | ||||
| -rw-r--r-- | src/db.h | 145 | ||||
| -rw-r--r-- | src/selftest.cpp | 76 |
3 files changed, 259 insertions, 29 deletions
| @@ -56,6 +56,7 @@ string strWalletLoadError; | |||
| 56 | static DbEnv* pdbenv = NULL; | 56 | static DbEnv* pdbenv = NULL; |
| 57 | static FILE* pdbErrFile = NULL; | 57 | static FILE* pdbErrFile = NULL; |
| 58 | static map<string, int> mapFileUseCount; | 58 | static map<string, int> mapFileUseCount; |
| 59 | static CWalletDBSQLite* pWalletSQLiteRuntime = NULL; | ||
| 59 | 60 | ||
| 60 | DbEnv& GetDbEnv() | 61 | DbEnv& GetDbEnv() |
| 61 | { | 62 | { |
| @@ -95,6 +96,67 @@ public: | |||
| 95 | } | 96 | } |
| 96 | instance_of_cdbinit; | 97 | instance_of_cdbinit; |
| 97 | 98 | ||
| 99 | bool WalletSQLiteRuntimeActive() | ||
| 100 | { | ||
| 101 | return pWalletSQLiteRuntime != NULL; | ||
| 102 | } | ||
| 103 | |||
| 104 | bool WalletSQLiteRuntimeOpen(const string& strPath, string& strErrorRet) | ||
| 105 | { | ||
| 106 | strErrorRet.clear(); | ||
| 107 | if (!FileExists(strPath.c_str())) | ||
| 108 | { | ||
| 109 | strErrorRet = strprintf("SQLite wallet does not exist: %s", | ||
| 110 | strPath.c_str()); | ||
| 111 | return false; | ||
| 112 | } | ||
| 113 | |||
| 114 | WalletSQLiteRuntimeClose(); | ||
| 115 | std::auto_ptr<CWalletDBSQLite> db(new CWalletDBSQLite()); | ||
| 116 | if (!db->Open(strPath, strErrorRet)) | ||
| 117 | return false; | ||
| 118 | |||
| 119 | pWalletSQLiteRuntime = db.release(); | ||
| 120 | return true; | ||
| 121 | } | ||
| 122 | |||
| 123 | void WalletSQLiteRuntimeClose() | ||
| 124 | { | ||
| 125 | if (pWalletSQLiteRuntime) | ||
| 126 | { | ||
| 127 | delete pWalletSQLiteRuntime; | ||
| 128 | pWalletSQLiteRuntime = NULL; | ||
| 129 | } | ||
| 130 | } | ||
| 131 | |||
| 132 | bool WalletSQLiteRuntimeReadRecord(const vector<unsigned char>& vchKey, | ||
| 133 | vector<unsigned char>& vchValueRet) | ||
| 134 | { | ||
| 135 | if (!pWalletSQLiteRuntime) | ||
| 136 | return false; | ||
| 137 | string strError; | ||
| 138 | return pWalletSQLiteRuntime->ReadRecord(vchKey, vchValueRet, strError); | ||
| 139 | } | ||
| 140 | |||
| 141 | bool WalletSQLiteRuntimeWriteRecord(const vector<unsigned char>& vchKey, | ||
| 142 | const vector<unsigned char>& vchValue, | ||
| 143 | bool fOverwrite) | ||
| 144 | { | ||
| 145 | if (!pWalletSQLiteRuntime) | ||
| 146 | return false; | ||
| 147 | string strError; | ||
| 148 | return pWalletSQLiteRuntime->WriteRecord(vchKey, vchValue, strError, | ||
| 149 | fOverwrite); | ||
| 150 | } | ||
| 151 | |||
| 152 | bool WalletSQLiteRuntimeEraseRecord(const vector<unsigned char>& vchKey) | ||
| 153 | { | ||
| 154 | if (!pWalletSQLiteRuntime) | ||
| 155 | return false; | ||
| 156 | string strError; | ||
| 157 | return pWalletSQLiteRuntime->EraseRecord(vchKey, strError); | ||
| 158 | } | ||
| 159 | |||
| 98 | 160 | ||
| 99 | CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL) | 161 | CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL) |
| 100 | { | 162 | { |
| @@ -651,6 +713,11 @@ bool CReviewDB::WriteReviews(uint256 hash, const vector<CReview>& vReviews) | |||
| 651 | // CWalletDB | 713 | // CWalletDB |
| 652 | // | 714 | // |
| 653 | 715 | ||
| 716 | CWalletDB::CWalletDB(const char* pszMode, bool fTxn) : | ||
| 717 | CDB(WalletSQLiteRuntimeActive() ? NULL : "wallet.dat", pszMode, fTxn) | ||
| 718 | { | ||
| 719 | } | ||
| 720 | |||
| 654 | class CSQLiteWalletRuntimeLoadVisitor : public CWalletRecordVisitor | 721 | class CSQLiteWalletRuntimeLoadVisitor : public CWalletRecordVisitor |
| 655 | { | 722 | { |
| 656 | public: | 723 | public: |
| @@ -356,6 +356,16 @@ private: | |||
| 356 | // Legacy IP-based peer address database (CAddrDB / addr.dat) removed -- | 356 | // Legacy IP-based peer address database (CAddrDB / addr.dat) removed -- |
| 357 | // peer discovery is entirely Nostr/.btf-based now. | 357 | // peer discovery is entirely Nostr/.btf-based now. |
| 358 | 358 | ||
| 359 | bool WalletSQLiteRuntimeActive(); | ||
| 360 | bool WalletSQLiteRuntimeOpen(const string& strPath, string& strErrorRet); | ||
| 361 | void WalletSQLiteRuntimeClose(); | ||
| 362 | bool WalletSQLiteRuntimeReadRecord(const vector<unsigned char>& vchKey, | ||
| 363 | vector<unsigned char>& vchValueRet); | ||
| 364 | bool WalletSQLiteRuntimeWriteRecord(const vector<unsigned char>& vchKey, | ||
| 365 | const vector<unsigned char>& vchValue, | ||
| 366 | bool fOverwrite); | ||
| 367 | bool WalletSQLiteRuntimeEraseRecord(const vector<unsigned char>& vchKey); | ||
| 368 | |||
| 359 | 369 | ||
| 360 | 370 | ||
| 361 | 371 | ||
| @@ -363,64 +373,141 @@ private: | |||
| 363 | class CWalletDB : public CDB | 373 | class CWalletDB : public CDB |
| 364 | { | 374 | { |
| 365 | public: | 375 | public: |
| 366 | CWalletDB(const char* pszMode="r+", bool fTxn=false) : CDB("wallet.dat", pszMode, fTxn) { } | 376 | CWalletDB(const char* pszMode="r+", bool fTxn=false); |
| 367 | private: | 377 | private: |
| 368 | CWalletDB(const CWalletDB&); | 378 | CWalletDB(const CWalletDB&); |
| 369 | void operator=(const CWalletDB&); | 379 | void operator=(const CWalletDB&); |
| 380 | |||
| 381 | template<typename K, typename T> | ||
| 382 | bool ReadWalletRecord(const K& key, T& value) | ||
| 383 | { | ||
| 384 | if (!WalletSQLiteRuntimeActive()) | ||
| 385 | return Read(key, value); | ||
| 386 | |||
| 387 | CDataStream ssKey(SER_DISK); | ||
| 388 | ssKey.reserve(1000); | ||
| 389 | ssKey << key; | ||
| 390 | vector<unsigned char> vchKey(ssKey.begin(), ssKey.end()); | ||
| 391 | vector<unsigned char> vchValue; | ||
| 392 | |||
| 393 | bool fOk = WalletSQLiteRuntimeReadRecord(vchKey, vchValue); | ||
| 394 | if (!vchKey.empty()) | ||
| 395 | memset(&vchKey[0], 0, vchKey.size()); | ||
| 396 | if (!ssKey.empty()) | ||
| 397 | memset(&ssKey[0], 0, ssKey.size()); | ||
| 398 | if (!fOk) | ||
| 399 | return false; | ||
| 400 | |||
| 401 | CDataStream ssValue(vchValue, SER_DISK); | ||
| 402 | ssValue >> value; | ||
| 403 | bool fReadOk = !ssValue.fail(); | ||
| 404 | if (!vchValue.empty()) | ||
| 405 | memset(&vchValue[0], 0, vchValue.size()); | ||
| 406 | if (!ssValue.empty()) | ||
| 407 | memset(&ssValue[0], 0, ssValue.size()); | ||
| 408 | return fReadOk; | ||
| 409 | } | ||
| 410 | |||
| 411 | template<typename K, typename T> | ||
| 412 | bool WriteWalletRecord(const K& key, const T& value, bool fOverwrite=true) | ||
| 413 | { | ||
| 414 | if (!WalletSQLiteRuntimeActive()) | ||
| 415 | return Write(key, value, fOverwrite); | ||
| 416 | |||
| 417 | CDataStream ssKey(SER_DISK); | ||
| 418 | ssKey.reserve(1000); | ||
| 419 | ssKey << key; | ||
| 420 | CDataStream ssValue(SER_DISK); | ||
| 421 | ssValue.reserve(10000); | ||
| 422 | ssValue << value; | ||
| 423 | |||
| 424 | vector<unsigned char> vchKey(ssKey.begin(), ssKey.end()); | ||
| 425 | vector<unsigned char> vchValue(ssValue.begin(), ssValue.end()); | ||
| 426 | bool fOk = WalletSQLiteRuntimeWriteRecord(vchKey, vchValue, fOverwrite); | ||
| 427 | |||
| 428 | if (!vchKey.empty()) | ||
| 429 | memset(&vchKey[0], 0, vchKey.size()); | ||
| 430 | if (!vchValue.empty()) | ||
| 431 | memset(&vchValue[0], 0, vchValue.size()); | ||
| 432 | if (!ssKey.empty()) | ||
| 433 | memset(&ssKey[0], 0, ssKey.size()); | ||
| 434 | if (!ssValue.empty()) | ||
| 435 | memset(&ssValue[0], 0, ssValue.size()); | ||
| 436 | return fOk; | ||
| 437 | } | ||
| 438 | |||
| 439 | template<typename K> | ||
| 440 | bool EraseWalletRecord(const K& key) | ||
| 441 | { | ||
| 442 | if (!WalletSQLiteRuntimeActive()) | ||
| 443 | return Erase(key); | ||
| 444 | |||
| 445 | CDataStream ssKey(SER_DISK); | ||
| 446 | ssKey.reserve(1000); | ||
| 447 | ssKey << key; | ||
| 448 | vector<unsigned char> vchKey(ssKey.begin(), ssKey.end()); | ||
| 449 | bool fOk = WalletSQLiteRuntimeEraseRecord(vchKey); | ||
| 450 | |||
| 451 | if (!vchKey.empty()) | ||
| 452 | memset(&vchKey[0], 0, vchKey.size()); | ||
| 453 | if (!ssKey.empty()) | ||
| 454 | memset(&ssKey[0], 0, ssKey.size()); | ||
| 455 | return fOk; | ||
| 456 | } | ||
| 370 | public: | 457 | public: |
| 371 | bool ReadName(const string& strAddress, string& strName) | 458 | bool ReadName(const string& strAddress, string& strName) |
| 372 | { | 459 | { |
| 373 | strName = ""; | 460 | strName = ""; |
| 374 | return Read(make_pair(string("name"), strAddress), strName); | 461 | return ReadWalletRecord(make_pair(string("name"), strAddress), strName); |
| 375 | } | 462 | } |
| 376 | 463 | ||
| 377 | bool WriteName(const string& strAddress, const string& strName) | 464 | bool WriteName(const string& strAddress, const string& strName) |
| 378 | { | 465 | { |
| 379 | mapAddressBook[strAddress] = strName; | 466 | mapAddressBook[strAddress] = strName; |
| 380 | return Write(make_pair(string("name"), strAddress), strName); | 467 | return WriteWalletRecord(make_pair(string("name"), strAddress), strName); |
| 381 | } | 468 | } |
| 382 | 469 | ||
| 383 | bool EraseName(const string& strAddress) | 470 | bool EraseName(const string& strAddress) |
| 384 | { | 471 | { |
| 385 | mapAddressBook.erase(strAddress); | 472 | mapAddressBook.erase(strAddress); |
| 386 | return Erase(make_pair(string("name"), strAddress)); | 473 | return EraseWalletRecord(make_pair(string("name"), strAddress)); |
| 387 | } | 474 | } |
| 388 | 475 | ||
| 389 | bool ReadTx(uint256 hash, CWalletTx& wtx) | 476 | bool ReadTx(uint256 hash, CWalletTx& wtx) |
| 390 | { | 477 | { |
| 391 | return Read(make_pair(string("tx"), hash), wtx); | 478 | return ReadWalletRecord(make_pair(string("tx"), hash), wtx); |
| 392 | } | 479 | } |
| 393 | 480 | ||
| 394 | bool WriteTx(uint256 hash, const CWalletTx& wtx) | 481 | bool WriteTx(uint256 hash, const CWalletTx& wtx) |
| 395 | { | 482 | { |
| 396 | return Write(make_pair(string("tx"), hash), wtx); | 483 | return WriteWalletRecord(make_pair(string("tx"), hash), wtx); |
| 397 | } | 484 | } |
| 398 | 485 | ||
| 399 | bool EraseTx(uint256 hash) | 486 | bool EraseTx(uint256 hash) |
| 400 | { | 487 | { |
| 401 | return Erase(make_pair(string("tx"), hash)); | 488 | return EraseWalletRecord(make_pair(string("tx"), hash)); |
| 402 | } | 489 | } |
| 403 | 490 | ||
| 404 | bool ReadKey(const vector<unsigned char>& vchPubKey, CPrivKey& vchPrivKey) | 491 | bool ReadKey(const vector<unsigned char>& vchPubKey, CPrivKey& vchPrivKey) |
| 405 | { | 492 | { |
| 406 | vchPrivKey.clear(); | 493 | vchPrivKey.clear(); |
| 407 | return Read(make_pair(string("key"), vchPubKey), vchPrivKey); | 494 | return ReadWalletRecord(make_pair(string("key"), vchPubKey), vchPrivKey); |
| 408 | } | 495 | } |
| 409 | 496 | ||
| 410 | bool WriteKey(const vector<unsigned char>& vchPubKey, const CPrivKey& vchPrivKey) | 497 | bool WriteKey(const vector<unsigned char>& vchPubKey, const CPrivKey& vchPrivKey) |
| 411 | { | 498 | { |
| 412 | return Write(make_pair(string("key"), vchPubKey), vchPrivKey, false); | 499 | return WriteWalletRecord(make_pair(string("key"), vchPubKey), vchPrivKey, false); |
| 413 | } | 500 | } |
| 414 | 501 | ||
| 415 | bool ReadDefaultKey(vector<unsigned char>& vchPubKey) | 502 | bool ReadDefaultKey(vector<unsigned char>& vchPubKey) |
| 416 | { | 503 | { |
| 417 | vchPubKey.clear(); | 504 | vchPubKey.clear(); |
| 418 | return Read(string("defaultkey"), vchPubKey); | 505 | return ReadWalletRecord(string("defaultkey"), vchPubKey); |
| 419 | } | 506 | } |
| 420 | 507 | ||
| 421 | bool WriteDefaultKey(const vector<unsigned char>& vchPubKey) | 508 | bool WriteDefaultKey(const vector<unsigned char>& vchPubKey) |
| 422 | { | 509 | { |
| 423 | return Write(string("defaultkey"), vchPubKey); | 510 | return WriteWalletRecord(string("defaultkey"), vchPubKey); |
| 424 | } | 511 | } |
| 425 | 512 | ||
| 426 | // --- Deterministic (BIP32) seed --------------------------------------- | 513 | // --- Deterministic (BIP32) seed --------------------------------------- |
| @@ -438,62 +525,62 @@ public: | |||
| 438 | { | 525 | { |
| 439 | vchMasterRet.clear(); | 526 | vchMasterRet.clear(); |
| 440 | vchChainCodeRet.clear(); | 527 | vchChainCodeRet.clear(); |
| 441 | return Read(string("hdmaster"), vchMasterRet) | 528 | return ReadWalletRecord(string("hdmaster"), vchMasterRet) |
| 442 | && Read(string("hdchaincode"), vchChainCodeRet); | 529 | && ReadWalletRecord(string("hdchaincode"), vchChainCodeRet); |
| 443 | } | 530 | } |
| 444 | 531 | ||
| 445 | bool WriteHDMaster(const vector<unsigned char>& vchMaster, const vector<unsigned char>& vchChainCode) | 532 | bool WriteHDMaster(const vector<unsigned char>& vchMaster, const vector<unsigned char>& vchChainCode) |
| 446 | { | 533 | { |
| 447 | return Write(string("hdmaster"), vchMaster) | 534 | return WriteWalletRecord(string("hdmaster"), vchMaster) |
| 448 | && Write(string("hdchaincode"), vchChainCode); | 535 | && WriteWalletRecord(string("hdchaincode"), vchChainCode); |
| 449 | } | 536 | } |
| 450 | 537 | ||
| 451 | bool WriteWalletMinVersion(int nVersion) | 538 | bool WriteWalletMinVersion(int nVersion) |
| 452 | { | 539 | { |
| 453 | return Write(string("walletminversion"), nVersion); | 540 | return WriteWalletRecord(string("walletminversion"), nVersion); |
| 454 | } | 541 | } |
| 455 | 542 | ||
| 456 | bool WriteMasterKey(unsigned int nID, const CWalletMasterKey& kMasterKey) | 543 | bool WriteMasterKey(unsigned int nID, const CWalletMasterKey& kMasterKey) |
| 457 | { | 544 | { |
| 458 | return Write(make_pair(string("mkey"), nID), kMasterKey, true); | 545 | return WriteWalletRecord(make_pair(string("mkey"), nID), kMasterKey, true); |
| 459 | } | 546 | } |
| 460 | 547 | ||
| 461 | bool WriteCryptedKey(const vector<unsigned char>& vchPubKey, | 548 | bool WriteCryptedKey(const vector<unsigned char>& vchPubKey, |
| 462 | const vector<unsigned char>& vchCryptedSecret) | 549 | const vector<unsigned char>& vchCryptedSecret) |
| 463 | { | 550 | { |
| 464 | return Write(make_pair(string("ckey"), vchPubKey), vchCryptedSecret, false); | 551 | return WriteWalletRecord(make_pair(string("ckey"), vchPubKey), vchCryptedSecret, false); |
| 465 | } | 552 | } |
| 466 | 553 | ||
| 467 | bool WriteCryptedHDMaster(const vector<unsigned char>& vchCryptedMaster, | 554 | bool WriteCryptedHDMaster(const vector<unsigned char>& vchCryptedMaster, |
| 468 | const vector<unsigned char>& vchCryptedChainCode) | 555 | const vector<unsigned char>& vchCryptedChainCode) |
| 469 | { | 556 | { |
| 470 | return Write(string("cryptedhdmaster"), vchCryptedMaster) | 557 | return WriteWalletRecord(string("cryptedhdmaster"), vchCryptedMaster) |
| 471 | && Write(string("cryptedhdchaincode"), vchCryptedChainCode); | 558 | && WriteWalletRecord(string("cryptedhdchaincode"), vchCryptedChainCode); |
| 472 | } | 559 | } |
| 473 | 560 | ||
| 474 | bool WriteHDNext(unsigned int nNext) | 561 | bool WriteHDNext(unsigned int nNext) |
| 475 | { | 562 | { |
| 476 | return Write(string("hdnext"), nNext); | 563 | return WriteWalletRecord(string("hdnext"), nNext); |
| 477 | } | 564 | } |
| 478 | 565 | ||
| 479 | bool WriteHDSchema(int nSchema) | 566 | bool WriteHDSchema(int nSchema) |
| 480 | { | 567 | { |
| 481 | return Write(string("hdschema"), nSchema); | 568 | return WriteWalletRecord(string("hdschema"), nSchema); |
| 482 | } | 569 | } |
| 483 | 570 | ||
| 484 | bool WriteHDCoinType(unsigned int nCoinType) | 571 | bool WriteHDCoinType(unsigned int nCoinType) |
| 485 | { | 572 | { |
| 486 | return Write(string("hdcointype"), nCoinType); | 573 | return WriteWalletRecord(string("hdcointype"), nCoinType); |
| 487 | } | 574 | } |
| 488 | 575 | ||
| 489 | bool WriteHDReceiveNext(unsigned int nNext) | 576 | bool WriteHDReceiveNext(unsigned int nNext) |
| 490 | { | 577 | { |
| 491 | return Write(string("hdreceivenext"), nNext); | 578 | return WriteWalletRecord(string("hdreceivenext"), nNext); |
| 492 | } | 579 | } |
| 493 | 580 | ||
| 494 | bool WriteHDChangeNext(unsigned int nNext) | 581 | bool WriteHDChangeNext(unsigned int nNext) |
| 495 | { | 582 | { |
| 496 | return Write(string("hdchangenext"), nNext); | 583 | return WriteWalletRecord(string("hdchangenext"), nNext); |
| 497 | } | 584 | } |
| 498 | 585 | ||
| 499 | // Keys generated ahead of time and not yet handed out. The private key of | 586 | // Keys generated ahead of time and not yet handed out. The private key of |
| @@ -501,24 +588,24 @@ public: | |||
| 501 | // record only says that this one is still unspoken for. | 588 | // record only says that this one is still unspoken for. |
| 502 | bool WritePool(int64 nIndex, const vector<unsigned char>& vchPubKey) | 589 | bool WritePool(int64 nIndex, const vector<unsigned char>& vchPubKey) |
| 503 | { | 590 | { |
| 504 | return Write(make_pair(string("pool"), nIndex), vchPubKey); | 591 | return WriteWalletRecord(make_pair(string("pool"), nIndex), vchPubKey); |
| 505 | } | 592 | } |
| 506 | 593 | ||
| 507 | bool ErasePool(int64 nIndex) | 594 | bool ErasePool(int64 nIndex) |
| 508 | { | 595 | { |
| 509 | return Erase(make_pair(string("pool"), nIndex)); | 596 | return EraseWalletRecord(make_pair(string("pool"), nIndex)); |
| 510 | } | 597 | } |
| 511 | 598 | ||
| 512 | template<typename T> | 599 | template<typename T> |
| 513 | bool ReadSetting(const string& strKey, T& value) | 600 | bool ReadSetting(const string& strKey, T& value) |
| 514 | { | 601 | { |
| 515 | return Read(make_pair(string("setting"), strKey), value); | 602 | return ReadWalletRecord(make_pair(string("setting"), strKey), value); |
| 516 | } | 603 | } |
| 517 | 604 | ||
| 518 | template<typename T> | 605 | template<typename T> |
| 519 | bool WriteSetting(const string& strKey, const T& value) | 606 | bool WriteSetting(const string& strKey, const T& value) |
| 520 | { | 607 | { |
| 521 | return Write(make_pair(string("setting"), strKey), value); | 608 | return WriteWalletRecord(make_pair(string("setting"), strKey), value); |
| 522 | } | 609 | } |
| 523 | 610 | ||
| 524 | bool LoadWallet(vector<unsigned char>& vchDefaultKeyRet); | 611 | bool LoadWallet(vector<unsigned char>& vchDefaultKeyRet); |
diff --git a/src/selftest.cpp b/src/selftest.cpp index a1efaa0..9fa0938 100644 --- a/src/selftest.cpp +++ b/src/selftest.cpp | |||
| @@ -1051,6 +1051,8 @@ static int RunWalletSQLiteSelfTest() | |||
| 1051 | int nFail = 0; | 1051 | int nFail = 0; |
| 1052 | string strPath = tmp + "/wallet.sqlite"; | 1052 | string strPath = tmp + "/wallet.sqlite"; |
| 1053 | string strError; | 1053 | string strError; |
| 1054 | string strOldRuntimeDataDir; | ||
| 1055 | bool fRestoreRuntimeDataDir = false; | ||
| 1054 | 1056 | ||
| 1055 | try | 1057 | try |
| 1056 | { | 1058 | { |
| @@ -1166,14 +1168,88 @@ static int RunWalletSQLiteSelfTest() | |||
| 1166 | vchTypedPubKey == vchPubKey, | 1168 | vchTypedPubKey == vchPubKey, |
| 1167 | "SQLite wallet reads a typed defaultkey record") ? 0 : 1; | 1169 | "SQLite wallet reads a typed defaultkey record") ? 0 : 1; |
| 1168 | } | 1170 | } |
| 1171 | |||
| 1172 | { | ||
| 1173 | string strRuntimePath = tmp + "/runtime-wallet.sqlite"; | ||
| 1174 | string strRuntimeDir = tmp + "/runtime-datadir"; | ||
| 1175 | nFail += Check(MakeDirLocal(strRuntimeDir), | ||
| 1176 | "SQLite runtime datadir can be created") ? 0 : 1; | ||
| 1177 | |||
| 1178 | { | ||
| 1179 | CWalletDBSQLite db; | ||
| 1180 | nFail += Check(db.Open(strRuntimePath, strError), | ||
| 1181 | "SQLite runtime wallet file can be created") ? 0 : 1; | ||
| 1182 | } | ||
| 1183 | |||
| 1184 | string strOldDataDir = strSetDataDir; | ||
| 1185 | strSetDataDir = strRuntimeDir; | ||
| 1186 | strOldRuntimeDataDir = strOldDataDir; | ||
| 1187 | fRestoreRuntimeDataDir = true; | ||
| 1188 | bool fRuntimeOpened = WalletSQLiteRuntimeOpen(strRuntimePath, strError); | ||
| 1189 | nFail += Check(fRuntimeOpened, | ||
| 1190 | "SQLite runtime wallet can be activated") ? 0 : 1; | ||
| 1191 | |||
| 1192 | if (fRuntimeOpened) | ||
| 1193 | { | ||
| 1194 | CKey key; | ||
| 1195 | key.MakeNewKey(); | ||
| 1196 | vector<unsigned char> vchRuntimePubKey = key.GetPubKey(); | ||
| 1197 | CPrivKey vchRuntimePrivKey = key.GetPrivKey(); | ||
| 1198 | string strRuntimeAddress = PubKeyToAddress(vchRuntimePubKey); | ||
| 1199 | |||
| 1200 | nFail += Check(CWalletDB().WriteSetting("runtime-sqlite-setting", | ||
| 1201 | (int64)909090) && | ||
| 1202 | CWalletDB().WriteDefaultKey(vchRuntimePubKey) && | ||
| 1203 | CWalletDB().WriteKey(vchRuntimePubKey, | ||
| 1204 | vchRuntimePrivKey) && | ||
| 1205 | CWalletDB().WriteName(strRuntimeAddress, | ||
| 1206 | "SQLite Runtime Address"), | ||
| 1207 | "CWalletDB writes route to active SQLite runtime") ? 0 : 1; | ||
| 1208 | |||
| 1209 | int64 nRuntimeSetting = 0; | ||
| 1210 | vector<unsigned char> vchRuntimeDefaultKey; | ||
| 1211 | CPrivKey vchRuntimeReadPrivKey; | ||
| 1212 | string strRuntimeName; | ||
| 1213 | nFail += Check(CWalletDB("r").ReadSetting("runtime-sqlite-setting", | ||
| 1214 | nRuntimeSetting) && | ||
| 1215 | nRuntimeSetting == 909090 && | ||
| 1216 | CWalletDB("r").ReadDefaultKey(vchRuntimeDefaultKey) && | ||
| 1217 | vchRuntimeDefaultKey == vchRuntimePubKey && | ||
| 1218 | CWalletDB("r").ReadKey(vchRuntimePubKey, | ||
| 1219 | vchRuntimeReadPrivKey) && | ||
| 1220 | vchRuntimeReadPrivKey == vchRuntimePrivKey && | ||
| 1221 | CWalletDB("r").ReadName(strRuntimeAddress, | ||
| 1222 | strRuntimeName) && | ||
| 1223 | strRuntimeName == "SQLite Runtime Address", | ||
| 1224 | "CWalletDB reads route to active SQLite runtime") ? 0 : 1; | ||
| 1225 | |||
| 1226 | nFail += Check(CWalletDB().EraseName(strRuntimeAddress) && | ||
| 1227 | !CWalletDB("r").ReadName(strRuntimeAddress, | ||
| 1228 | strRuntimeName), | ||
| 1229 | "CWalletDB erases route to active SQLite runtime") ? 0 : 1; | ||
| 1230 | |||
| 1231 | nFail += Check(!FileExists((strRuntimeDir + "/wallet.dat").c_str()), | ||
| 1232 | "active SQLite runtime does not create wallet.dat") ? 0 : 1; | ||
| 1233 | } | ||
| 1234 | |||
| 1235 | WalletSQLiteRuntimeClose(); | ||
| 1236 | strSetDataDir = strOldDataDir; | ||
| 1237 | fRestoreRuntimeDataDir = false; | ||
| 1238 | } | ||
| 1169 | } | 1239 | } |
| 1170 | catch (const std::exception& e) | 1240 | catch (const std::exception& e) |
| 1171 | { | 1241 | { |
| 1242 | WalletSQLiteRuntimeClose(); | ||
| 1243 | if (fRestoreRuntimeDataDir) | ||
| 1244 | strSetDataDir = strOldRuntimeDataDir; | ||
| 1172 | printf(" FAIL exception: %s\n", e.what()); | 1245 | printf(" FAIL exception: %s\n", e.what()); |
| 1173 | nFail++; | 1246 | nFail++; |
| 1174 | } | 1247 | } |
| 1175 | catch (...) | 1248 | catch (...) |
| 1176 | { | 1249 | { |
| 1250 | WalletSQLiteRuntimeClose(); | ||
| 1251 | if (fRestoreRuntimeDataDir) | ||
| 1252 | strSetDataDir = strOldRuntimeDataDir; | ||
| 1177 | printf(" FAIL unknown exception\n"); | 1253 | printf(" FAIL unknown exception\n"); |
| 1178 | nFail++; | 1254 | nFail++; |
| 1179 | } | 1255 | } |