diff options
Diffstat (limited to 'src/walletcmd.cpp')
| -rw-r--r-- | src/walletcmd.cpp | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/src/walletcmd.cpp b/src/walletcmd.cpp index eccb9b3..896d593 100644 --- a/src/walletcmd.cpp +++ b/src/walletcmd.cpp | |||
| @@ -470,6 +470,184 @@ int CmdRecoveryAudit() | |||
| 470 | return 0; | 470 | return 0; |
| 471 | } | 471 | } |
| 472 | 472 | ||
| 473 | struct WalletStorageAuditCounts | ||
| 474 | { | ||
| 475 | unsigned int nTotal; | ||
| 476 | unsigned int nMalformed; | ||
| 477 | unsigned int nUnknown; | ||
| 478 | unsigned int nVersion; | ||
| 479 | unsigned int nNames; | ||
| 480 | unsigned int nTransactions; | ||
| 481 | unsigned int nPlainKeys; | ||
| 482 | unsigned int nEncryptedKeys; | ||
| 483 | unsigned int nMasterKeys; | ||
| 484 | unsigned int nDefaultKey; | ||
| 485 | unsigned int nPlainHDMaster; | ||
| 486 | unsigned int nPlainHDChainCode; | ||
| 487 | unsigned int nCryptedHDMaster; | ||
| 488 | unsigned int nCryptedHDChainCode; | ||
| 489 | unsigned int nWalletMinVersion; | ||
| 490 | unsigned int nPool; | ||
| 491 | unsigned int nSettings; | ||
| 492 | unsigned int nHDNext; | ||
| 493 | unsigned int nHDSchema; | ||
| 494 | unsigned int nHDCoinType; | ||
| 495 | unsigned int nHDReceiveNext; | ||
| 496 | unsigned int nHDChangeNext; | ||
| 497 | |||
| 498 | WalletStorageAuditCounts() | ||
| 499 | { | ||
| 500 | memset(this, 0, sizeof(*this)); | ||
| 501 | } | ||
| 502 | }; | ||
| 503 | |||
| 504 | static std::string HDSeedStorageState(unsigned int nMaster, unsigned int nChain) | ||
| 505 | { | ||
| 506 | if (nMaster == 0 && nChain == 0) | ||
| 507 | return "none"; | ||
| 508 | if (nMaster > 0 && nChain > 0) | ||
| 509 | return "complete"; | ||
| 510 | return "incomplete"; | ||
| 511 | } | ||
| 512 | |||
| 513 | static void CountWalletStorageType(const std::string& strType, | ||
| 514 | WalletStorageAuditCounts& c) | ||
| 515 | { | ||
| 516 | if (strType == "version") | ||
| 517 | c.nVersion++; | ||
| 518 | else if (strType == "name") | ||
| 519 | c.nNames++; | ||
| 520 | else if (strType == "tx") | ||
| 521 | c.nTransactions++; | ||
| 522 | else if (strType == "key") | ||
| 523 | c.nPlainKeys++; | ||
| 524 | else if (strType == "ckey") | ||
| 525 | c.nEncryptedKeys++; | ||
| 526 | else if (strType == "mkey") | ||
| 527 | c.nMasterKeys++; | ||
| 528 | else if (strType == "defaultkey") | ||
| 529 | c.nDefaultKey++; | ||
| 530 | else if (strType == "hdmaster") | ||
| 531 | c.nPlainHDMaster++; | ||
| 532 | else if (strType == "hdchaincode") | ||
| 533 | c.nPlainHDChainCode++; | ||
| 534 | else if (strType == "cryptedhdmaster") | ||
| 535 | c.nCryptedHDMaster++; | ||
| 536 | else if (strType == "cryptedhdchaincode") | ||
| 537 | c.nCryptedHDChainCode++; | ||
| 538 | else if (strType == "walletminversion") | ||
| 539 | c.nWalletMinVersion++; | ||
| 540 | else if (strType == "pool") | ||
| 541 | c.nPool++; | ||
| 542 | else if (strType == "setting") | ||
| 543 | c.nSettings++; | ||
| 544 | else if (strType == "hdnext") | ||
| 545 | c.nHDNext++; | ||
| 546 | else if (strType == "hdschema") | ||
| 547 | c.nHDSchema++; | ||
| 548 | else if (strType == "hdcointype") | ||
| 549 | c.nHDCoinType++; | ||
| 550 | else if (strType == "hdreceivenext") | ||
| 551 | c.nHDReceiveNext++; | ||
| 552 | else if (strType == "hdchangenext") | ||
| 553 | c.nHDChangeNext++; | ||
| 554 | else | ||
| 555 | c.nUnknown++; | ||
| 556 | } | ||
| 557 | |||
| 558 | static bool ReadWalletStorageCounts(WalletStorageAuditCounts& counts, | ||
| 559 | std::string& strError) | ||
| 560 | { | ||
| 561 | class CWalletAuditDB : public CWalletDB | ||
| 562 | { | ||
| 563 | public: | ||
| 564 | CWalletAuditDB() : CWalletDB("r") { } | ||
| 565 | using CDB::GetCursor; | ||
| 566 | using CDB::ReadAtCursor; | ||
| 567 | }; | ||
| 568 | |||
| 569 | CWalletAuditDB walletdb; | ||
| 570 | Dbc* pcursor = walletdb.GetCursor(); | ||
| 571 | if (!pcursor) | ||
| 572 | { | ||
| 573 | strError = "cannot open wallet.dat cursor"; | ||
| 574 | return false; | ||
| 575 | } | ||
| 576 | |||
| 577 | for (;;) | ||
| 578 | { | ||
| 579 | CDataStream ssKey(SER_DISK); | ||
| 580 | CDataStream ssValue(SER_DISK); | ||
| 581 | int ret = walletdb.ReadAtCursor(pcursor, ssKey, ssValue); | ||
| 582 | if (ret == DB_NOTFOUND) | ||
| 583 | break; | ||
| 584 | if (ret != 0) | ||
| 585 | { | ||
| 586 | pcursor->close(); | ||
| 587 | strError = strprintf("Berkeley DB cursor read failed (%d)", ret); | ||
| 588 | return false; | ||
| 589 | } | ||
| 590 | |||
| 591 | counts.nTotal++; | ||
| 592 | try | ||
| 593 | { | ||
| 594 | std::string strType; | ||
| 595 | ssKey >> strType; | ||
| 596 | CountWalletStorageType(strType, counts); | ||
| 597 | } | ||
| 598 | catch (...) | ||
| 599 | { | ||
| 600 | counts.nMalformed++; | ||
| 601 | } | ||
| 602 | } | ||
| 603 | |||
| 604 | pcursor->close(); | ||
| 605 | return true; | ||
| 606 | } | ||
| 607 | |||
| 608 | int CmdWalletStorageAudit() | ||
| 609 | { | ||
| 610 | AttachTerminal(); | ||
| 611 | |||
| 612 | WalletStorageAuditCounts counts; | ||
| 613 | std::string strError; | ||
| 614 | if (!ReadWalletStorageCounts(counts, strError)) | ||
| 615 | { | ||
| 616 | fprintf(stderr, "Cannot audit wallet storage: %s\n", strError.c_str()); | ||
| 617 | return 1; | ||
| 618 | } | ||
| 619 | |||
| 620 | printf("Wallet storage audit\n"); | ||
| 621 | printf(" records total: %u\n", counts.nTotal); | ||
| 622 | printf(" malformed records: %u\n", counts.nMalformed); | ||
| 623 | printf(" unknown records: %u\n", counts.nUnknown); | ||
| 624 | printf(" plain private keys: %u\n", counts.nPlainKeys); | ||
| 625 | printf(" encrypted private keys: %u\n", counts.nEncryptedKeys); | ||
| 626 | printf(" encryption master keys: %u\n", counts.nMasterKeys); | ||
| 627 | printf(" default public key: %s\n", counts.nDefaultKey ? "present" : "none"); | ||
| 628 | printf(" plain HD seed: %s\n", | ||
| 629 | HDSeedStorageState(counts.nPlainHDMaster, | ||
| 630 | counts.nPlainHDChainCode).c_str()); | ||
| 631 | printf(" encrypted HD seed: %s\n", | ||
| 632 | HDSeedStorageState(counts.nCryptedHDMaster, | ||
| 633 | counts.nCryptedHDChainCode).c_str()); | ||
| 634 | printf(" wallet minimum version: %s\n", | ||
| 635 | counts.nWalletMinVersion ? "present" : "none"); | ||
| 636 | printf(" keypool entries: %u\n", counts.nPool); | ||
| 637 | printf(" wallet transactions: %u\n", counts.nTransactions); | ||
| 638 | printf(" address book labels: %u\n", counts.nNames); | ||
| 639 | printf(" settings: %u\n", counts.nSettings); | ||
| 640 | printf(" HD metadata records: %u\n", | ||
| 641 | counts.nHDNext + counts.nHDSchema + counts.nHDCoinType + | ||
| 642 | counts.nHDReceiveNext + counts.nHDChangeNext); | ||
| 643 | printf(" database version records: %u\n", counts.nVersion); | ||
| 644 | fflush(stdout); | ||
| 645 | |||
| 646 | if (counts.nMalformed > 0) | ||
| 647 | return 2; | ||
| 648 | return 0; | ||
| 649 | } | ||
| 650 | |||
| 473 | int CmdEncryptWallet(const std::string& strPassphrase) | 651 | int CmdEncryptWallet(const std::string& strPassphrase) |
| 474 | { | 652 | { |
| 475 | AttachTerminal(); | 653 | AttachTerminal(); |