Bitcoin ABC  0.24.10
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 <fs.h>
7 #include <util/system.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 
15 namespace 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.
20 static void WalletToolReleaseWallet(CWallet *wallet) {
21  wallet->WalletLogPrintf("Releasing wallet\n");
22  wallet->Close();
23  delete wallet;
24 }
25 
26 static 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 
40 static 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  bool first_run;
64  load_wallet_ret = wallet_instance->LoadWallet(first_run);
65  } catch (const std::runtime_error &) {
67  std::cerr,
68  "Error loading %s. Is wallet being used by another process?\n",
69  name);
70  return nullptr;
71  }
72 
73  if (load_wallet_ret != DBErrors::LOAD_OK) {
74  wallet_instance = nullptr;
75  if (load_wallet_ret == DBErrors::CORRUPT) {
76  tfm::format(std::cerr, "Error loading %s: Wallet corrupted", name);
77  return nullptr;
78  } else if (load_wallet_ret == DBErrors::NONCRITICAL_ERROR) {
80  std::cerr,
81  "Error reading %s! All keys read correctly, but transaction "
82  "data or address book entries might be missing or incorrect.",
83  name);
84  } else if (load_wallet_ret == DBErrors::TOO_NEW) {
85  tfm::format(std::cerr,
86  "Error loading %s: Wallet requires newer version of %s",
87  name, PACKAGE_NAME);
88  return nullptr;
89  } else if (load_wallet_ret == DBErrors::NEED_REWRITE) {
90  tfm::format(std::cerr,
91  "Wallet needed to be rewritten: restart %s to complete",
92  PACKAGE_NAME);
93  return nullptr;
94  } else {
95  tfm::format(std::cerr, "Error loading %s", name);
96  return nullptr;
97  }
98  }
99 
100  if (create) {
101  WalletCreate(wallet_instance.get());
102  }
103 
104  return wallet_instance;
105 }
106 
107 static void WalletShowInfo(CWallet *wallet_instance) {
108  LOCK(wallet_instance->cs_wallet);
109 
110  tfm::format(std::cout, "Wallet info\n===========\n");
111  tfm::format(std::cout, "Encrypted: %s\n",
112  wallet_instance->IsCrypted() ? "yes" : "no");
113  tfm::format(std::cout, "HD (hd seed available): %s\n",
114  wallet_instance->IsHDEnabled() ? "yes" : "no");
115  tfm::format(std::cout, "Keypool Size: %u\n",
116  wallet_instance->GetKeyPoolSize());
117  tfm::format(std::cout, "Transactions: %zu\n",
118  wallet_instance->mapWallet.size());
119  tfm::format(std::cout, "Address Book: %zu\n",
120  wallet_instance->m_address_book.size());
121 }
122 
123 bool ExecuteWalletToolFunc(const std::string &command,
124  const std::string &name) {
125  fs::path path = fs::absolute(fs::PathFromString(name), GetWalletDir());
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
WalletTool::WalletShowInfo
static void WalletShowInfo(CWallet *wallet_instance)
Definition: wallettool.cpp:107
CWallet::GetKeyPoolSize
unsigned int GetKeyPoolSize() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:3718
DatabaseOptions::require_existing
bool require_existing
Definition: db.h:222
DatabaseOptions
Definition: db.h:221
CWallet::WalletLogPrintf
void WalletLogPrintf(std::string fmt, Params... parameters) const
Prepends the wallet name in logging output to ease debugging in multi-wallet use cases.
Definition: wallet.h:1464
FEATURE_HD_SPLIT
@ FEATURE_HD_SPLIT
Definition: walletutil.h:28
tinyformat::format
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:1111
wallet.h
CWallet::SetMinVersion
void SetMinVersion(enum WalletFeature, WalletBatch *batch_in=nullptr, bool fExplicit=false) override
signify that a particular wallet feature is now used.
Definition: wallet.cpp:532
fs.h
DBErrors::NEED_REWRITE
@ NEED_REWRITE
bilingual_str
Bilingual messages:
Definition: translation.h:17
CWallet::IsCrypted
bool IsCrypted() const
Definition: wallet.cpp:4750
DatabaseOptions::require_create
bool require_create
Definition: db.h:223
WalletTool::WalletToolReleaseWallet
static void WalletToolReleaseWallet(CWallet *wallet)
Definition: wallettool.cpp:20
DBErrors::NONCRITICAL_ERROR
@ NONCRITICAL_ERROR
WalletTool
Definition: wallettool.cpp:15
chainparams.h
WalletTool::MakeWallet
static std::shared_ptr< CWallet > MakeWallet(const std::string &name, const fs::path &path, bool create)
Definition: wallettool.cpp:40
WalletTool::WalletCreate
static void WalletCreate(CWallet *wallet_instance)
Definition: wallettool.cpp:26
salvage.h
walletutil.h
RecoverDatabaseFile
bool RecoverDatabaseFile(const fs::path &file_path, bilingual_str &error, std::vector< bilingual_str > &warnings)
Definition: salvage.cpp:24
fs::path
Path class wrapper to prepare application code for transition from boost::filesystem library to std::...
Definition: fs.h:33
CWallet::IsHDEnabled
bool IsHDEnabled() const
Definition: wallet.cpp:1580
fs::PathFromString
static path PathFromString(const std::string &string)
Convert byte string to path object.
Definition: fs.h:147
DBErrors::LOAD_OK
@ LOAD_OK
name
const char * name
Definition: rest.cpp:43
system.h
DBErrors
DBErrors
Error statuses for the wallet database.
Definition: walletdb.h:46
CPubKey
An encapsulated public key.
Definition: pubkey.h:31
CWallet::TopUpKeyPool
bool TopUpKeyPool(unsigned int kpSize=0)
Definition: wallet.cpp:3728
translation.h
LOCK
#define LOCK(cs)
Definition: sync.h:241
CWallet
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
Definition: wallet.h:678
MakeDatabase
std::unique_ptr< WalletDatabase > MakeDatabase(const fs::path &path, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error)
Definition: walletdb.cpp:1114
DBErrors::CORRUPT
@ CORRUPT
DatabaseStatus
DatabaseStatus
Definition: db.h:229
CWallet::cs_wallet
RecursiveMutex cs_wallet
Definition: wallet.h:819
error
bool error(const char *fmt, const Args &... args)
Definition: system.h:48
GetWalletDir
fs::path GetWalletDir()
Get the path of the wallet directory.
Definition: walletutil.cpp:10
CWallet::Close
void Close()
Close wallet database.
Definition: wallet.cpp:612
WalletTool::ExecuteWalletToolFunc
bool ExecuteWalletToolFunc(const std::string &command, const std::string &name)
Definition: wallettool.cpp:123
CWallet::GetOrCreateLegacyScriptPubKeyMan
LegacyScriptPubKeyMan * GetOrCreateLegacyScriptPubKeyMan()
Definition: wallet.cpp:4887
DBErrors::TOO_NEW
@ TOO_NEW