Bitcoin ABC 0.30.13
P2P Digital Currency
wallettool.cpp
Go to the documentation of this file.
1// Copyright (c) 2016-2018 The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5#include <chainparams.h>
6#include <common/system.h>
7#include <util/fs.h>
8#include <util/translation.h>
9#include <wallet/salvage.h>
10#include <wallet/wallet.h>
11#include <wallet/walletutil.h>
12
13#include <stdexcept>
14
15namespace WalletTool {
16
17// The standard wallet deleter function blocks on the validation interface
18// queue, which doesn't exist for the bitcoin-wallet. Define our own
19// deleter here.
21 wallet->WalletLogPrintf("Releasing wallet\n");
22 wallet->Close();
23 delete wallet;
24}
25
26static void WalletCreate(CWallet *wallet_instance) {
27 LOCK(wallet_instance->cs_wallet);
28
29 wallet_instance->SetMinVersion(FEATURE_HD_SPLIT);
30
31 // generate a new HD seed
32 auto spk_man = wallet_instance->GetOrCreateLegacyScriptPubKeyMan();
33 CPubKey seed = spk_man->GenerateNewSeed();
34 spk_man->SetHDSeed(seed);
35
36 tfm::format(std::cout, "Topping up keypool...\n");
37 wallet_instance->TopUpKeyPool();
38}
39
40static std::shared_ptr<CWallet> MakeWallet(const std::string &name,
41 const fs::path &path, bool create) {
42 DatabaseOptions options;
43 DatabaseStatus status;
44 if (create) {
45 options.require_create = true;
46 } else {
47 options.require_existing = true;
48 }
50 std::unique_ptr<WalletDatabase> database =
51 MakeDatabase(path, options, status, error);
52 if (!database) {
53 tfm::format(std::cerr, "%s\n", error.original);
54 return nullptr;
55 }
56
57 // dummy chain interface
58 std::shared_ptr<CWallet> wallet_instance{
59 new CWallet(nullptr /* chain */, name, std::move(database)),
61 DBErrors load_wallet_ret;
62 try {
63 load_wallet_ret = wallet_instance->LoadWallet();
64 } catch (const std::runtime_error &) {
66 std::cerr,
67 "Error loading %s. Is wallet being used by another process?\n",
68 name);
69 return nullptr;
70 }
71
72 if (load_wallet_ret != DBErrors::LOAD_OK) {
73 wallet_instance = nullptr;
74 if (load_wallet_ret == DBErrors::CORRUPT) {
75 tfm::format(std::cerr, "Error loading %s: Wallet corrupted", name);
76 return nullptr;
77 } else if (load_wallet_ret == DBErrors::NONCRITICAL_ERROR) {
79 std::cerr,
80 "Error reading %s! All keys read correctly, but transaction "
81 "data or address book entries might be missing or incorrect.",
82 name);
83 } else if (load_wallet_ret == DBErrors::TOO_NEW) {
84 tfm::format(std::cerr,
85 "Error loading %s: Wallet requires newer version of %s",
86 name, PACKAGE_NAME);
87 return nullptr;
88 } else if (load_wallet_ret == DBErrors::NEED_REWRITE) {
89 tfm::format(std::cerr,
90 "Wallet needed to be rewritten: restart %s to complete",
91 PACKAGE_NAME);
92 return nullptr;
93 } else {
94 tfm::format(std::cerr, "Error loading %s", name);
95 return nullptr;
96 }
97 }
98
99 if (create) {
100 WalletCreate(wallet_instance.get());
101 }
102
103 return wallet_instance;
104}
105
106static void WalletShowInfo(CWallet *wallet_instance) {
107 LOCK(wallet_instance->cs_wallet);
108
109 tfm::format(std::cout, "Wallet info\n===========\n");
110 tfm::format(std::cout, "Encrypted: %s\n",
111 wallet_instance->IsCrypted() ? "yes" : "no");
112 tfm::format(std::cout, "HD (hd seed available): %s\n",
113 wallet_instance->IsHDEnabled() ? "yes" : "no");
114 tfm::format(std::cout, "Keypool Size: %u\n",
115 wallet_instance->GetKeyPoolSize());
116 tfm::format(std::cout, "Transactions: %zu\n",
117 wallet_instance->mapWallet.size());
118 tfm::format(std::cout, "Address Book: %zu\n",
119 wallet_instance->m_address_book.size());
120}
121
122bool ExecuteWalletToolFunc(const std::string &command,
123 const std::string &name) {
124 const fs::path path =
126
127 if (command == "create") {
128 std::shared_ptr<CWallet> wallet_instance =
129 MakeWallet(name, path, /* create= */ true);
130 if (wallet_instance) {
131 WalletShowInfo(wallet_instance.get());
132 wallet_instance->Close();
133 }
134 } else if (command == "info" || command == "salvage") {
135 if (command == "info") {
136 std::shared_ptr<CWallet> wallet_instance =
137 MakeWallet(name, path, /* create= */ false);
138 if (!wallet_instance) {
139 return false;
140 }
141 WalletShowInfo(wallet_instance.get());
142 wallet_instance->Close();
143 } else if (command == "salvage") {
145 std::vector<bilingual_str> warnings;
146 bool ret = RecoverDatabaseFile(path, error, warnings);
147 if (!ret) {
148 for (const auto &warning : warnings) {
149 tfm::format(std::cerr, "%s\n", warning.original);
150 }
151 if (!error.empty()) {
152 tfm::format(std::cerr, "%s\n", error.original);
153 }
154 }
155 return ret;
156 }
157 } else {
158 tfm::format(std::cerr, "Invalid command: %s\n", command);
159 return false;
160 }
161
162 return true;
163}
164} // namespace WalletTool
An encapsulated public key.
Definition: pubkey.h:31
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
Definition: wallet.h:254
RecursiveMutex cs_wallet
Definition: wallet.h:399
LegacyScriptPubKeyMan * GetOrCreateLegacyScriptPubKeyMan()
Definition: wallet.cpp:3335
bool IsCrypted() const
Definition: wallet.cpp:3193
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:30
unsigned int GetKeyPoolSize() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:2313
bool TopUpKeyPool(unsigned int kpSize=0)
Definition: wallet.cpp:2323
bool IsHDEnabled() const
Definition: wallet.cpp:1474
void SetMinVersion(enum WalletFeature, WalletBatch *batch_in=nullptr, bool fExplicit=false) override
signify that a particular wallet feature is now used.
Definition: wallet.cpp:535
bool error(const char *fmt, const Args &...args)
Definition: logging.h:263
static void WalletCreate(CWallet *wallet_instance)
Definition: wallettool.cpp:26
static void WalletToolReleaseWallet(CWallet *wallet)
Definition: wallettool.cpp:20
bool ExecuteWalletToolFunc(const std::string &command, const std::string &name)
Definition: wallettool.cpp:122
static std::shared_ptr< CWallet > MakeWallet(const std::string &name, const fs::path &path, bool create)
Definition: wallettool.cpp:40
static void WalletShowInfo(CWallet *wallet_instance)
Definition: wallettool.cpp:106
static path PathFromString(const std::string &string)
Convert byte string to path object.
Definition: fs.h:165
fs::path AbsPathJoin(const fs::path &base, const fs::path &path)
Helper function for joining two paths.
Definition: fs.cpp:39
void format(std::ostream &out, const char *fmt, const Args &...args)
Format list of arguments to the stream according to given format string.
Definition: tinyformat.h:1112
const char * name
Definition: rest.cpp:47
bool RecoverDatabaseFile(const fs::path &file_path, bilingual_str &error, std::vector< bilingual_str > &warnings)
Definition: salvage.cpp:24
bool require_create
Definition: db.h:223
bool require_existing
Definition: db.h:222
Bilingual messages:
Definition: translation.h:17
#define LOCK(cs)
Definition: sync.h:306
std::unique_ptr< WalletDatabase > MakeDatabase(const fs::path &path, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error)
Definition: walletdb.cpp:1120
DatabaseStatus
Definition: db.h:229
DBErrors
Error statuses for the wallet database.
Definition: walletdb.h:45
@ NONCRITICAL_ERROR
fs::path GetWalletDir()
Get the path of the wallet directory.
Definition: walletutil.cpp:13
@ FEATURE_HD_SPLIT
Definition: walletutil.h:28