Bitcoin Core  24.1.0
P2P Digital Currency
interfaces.cpp
Go to the documentation of this file.
1 // Copyright (c) 2018-2021 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 <interfaces/wallet.h>
6 
7 #include <consensus/amount.h>
8 #include <interfaces/chain.h>
9 #include <interfaces/handler.h>
10 #include <policy/fees.h>
11 #include <primitives/transaction.h>
12 #include <rpc/server.h>
13 #include <script/standard.h>
15 #include <sync.h>
16 #include <uint256.h>
17 #include <util/check.h>
18 #include <util/system.h>
19 #include <util/translation.h>
20 #include <util/ui_change_type.h>
21 #include <wallet/context.h>
22 #include <wallet/feebumper.h>
23 #include <wallet/fees.h>
24 #include <wallet/ismine.h>
25 #include <wallet/load.h>
26 #include <wallet/receive.h>
27 #include <wallet/rpc/wallet.h>
28 #include <wallet/spend.h>
29 #include <wallet/wallet.h>
30 
31 #include <memory>
32 #include <string>
33 #include <utility>
34 #include <vector>
35 
36 using interfaces::Chain;
40 using interfaces::Wallet;
49 
50 namespace wallet {
51 // All members of the classes in this namespace are intentionally public, as the
52 // classes themselves are private.
53 namespace {
55 WalletTx MakeWalletTx(CWallet& wallet, const CWalletTx& wtx)
56 {
57  LOCK(wallet.cs_wallet);
58  WalletTx result;
59  result.tx = wtx.tx;
60  result.txin_is_mine.reserve(wtx.tx->vin.size());
61  for (const auto& txin : wtx.tx->vin) {
62  result.txin_is_mine.emplace_back(InputIsMine(wallet, txin));
63  }
64  result.txout_is_mine.reserve(wtx.tx->vout.size());
65  result.txout_address.reserve(wtx.tx->vout.size());
66  result.txout_address_is_mine.reserve(wtx.tx->vout.size());
67  for (const auto& txout : wtx.tx->vout) {
68  result.txout_is_mine.emplace_back(wallet.IsMine(txout));
69  result.txout_address.emplace_back();
70  result.txout_address_is_mine.emplace_back(ExtractDestination(txout.scriptPubKey, result.txout_address.back()) ?
71  wallet.IsMine(result.txout_address.back()) :
72  ISMINE_NO);
73  }
74  result.credit = CachedTxGetCredit(wallet, wtx, ISMINE_ALL);
75  result.debit = CachedTxGetDebit(wallet, wtx, ISMINE_ALL);
76  result.change = CachedTxGetChange(wallet, wtx);
77  result.time = wtx.GetTxTime();
78  result.value_map = wtx.mapValue;
79  result.is_coinbase = wtx.IsCoinBase();
80  return result;
81 }
82 
84 WalletTxStatus MakeWalletTxStatus(const CWallet& wallet, const CWalletTx& wtx)
86 {
87  AssertLockHeld(wallet.cs_wallet);
88 
89  WalletTxStatus result;
90  result.block_height =
91  wtx.state<TxStateConfirmed>() ? wtx.state<TxStateConfirmed>()->confirmed_block_height :
92  wtx.state<TxStateConflicted>() ? wtx.state<TxStateConflicted>()->conflicting_block_height :
93  std::numeric_limits<int>::max();
94  result.blocks_to_maturity = wallet.GetTxBlocksToMaturity(wtx);
95  result.depth_in_main_chain = wallet.GetTxDepthInMainChain(wtx);
96  result.time_received = wtx.nTimeReceived;
97  result.lock_time = wtx.tx->nLockTime;
98  result.is_trusted = CachedTxIsTrusted(wallet, wtx);
99  result.is_abandoned = wtx.isAbandoned();
100  result.is_coinbase = wtx.IsCoinBase();
101  result.is_in_main_chain = wallet.IsTxInMainChain(wtx);
102  return result;
103 }
104 
106 WalletTxOut MakeWalletTxOut(const CWallet& wallet,
107  const CWalletTx& wtx,
108  int n,
109  int depth) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
110 {
111  WalletTxOut result;
112  result.txout = wtx.tx->vout[n];
113  result.time = wtx.GetTxTime();
114  result.depth_in_main_chain = depth;
115  result.is_spent = wallet.IsSpent(COutPoint(wtx.GetHash(), n));
116  return result;
117 }
118 
119 WalletTxOut MakeWalletTxOut(const CWallet& wallet,
120  const COutput& output) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
121 {
122  WalletTxOut result;
123  result.txout = output.txout;
124  result.time = output.time;
125  result.depth_in_main_chain = output.depth;
126  result.is_spent = wallet.IsSpent(output.outpoint);
127  return result;
128 }
129 
130 class WalletImpl : public Wallet
131 {
132 public:
133  explicit WalletImpl(WalletContext& context, const std::shared_ptr<CWallet>& wallet) : m_context(context), m_wallet(wallet) {}
134 
135  bool encryptWallet(const SecureString& wallet_passphrase) override
136  {
137  return m_wallet->EncryptWallet(wallet_passphrase);
138  }
139  bool isCrypted() override { return m_wallet->IsCrypted(); }
140  bool lock() override { return m_wallet->Lock(); }
141  bool unlock(const SecureString& wallet_passphrase) override { return m_wallet->Unlock(wallet_passphrase); }
142  bool isLocked() override { return m_wallet->IsLocked(); }
143  bool changeWalletPassphrase(const SecureString& old_wallet_passphrase,
144  const SecureString& new_wallet_passphrase) override
145  {
146  return m_wallet->ChangeWalletPassphrase(old_wallet_passphrase, new_wallet_passphrase);
147  }
148  void abortRescan() override { m_wallet->AbortRescan(); }
149  bool backupWallet(const std::string& filename) override { return m_wallet->BackupWallet(filename); }
150  std::string getWalletName() override { return m_wallet->GetName(); }
151  util::Result<CTxDestination> getNewDestination(const OutputType type, const std::string& label) override
152  {
153  LOCK(m_wallet->cs_wallet);
154  return m_wallet->GetNewDestination(type, label);
155  }
156  bool getPubKey(const CScript& script, const CKeyID& address, CPubKey& pub_key) override
157  {
158  std::unique_ptr<SigningProvider> provider = m_wallet->GetSolvingProvider(script);
159  if (provider) {
160  return provider->GetPubKey(address, pub_key);
161  }
162  return false;
163  }
164  SigningResult signMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) override
165  {
166  return m_wallet->SignMessage(message, pkhash, str_sig);
167  }
168  bool isSpendable(const CTxDestination& dest) override
169  {
170  LOCK(m_wallet->cs_wallet);
171  return m_wallet->IsMine(dest) & ISMINE_SPENDABLE;
172  }
173  bool haveWatchOnly() override
174  {
175  auto spk_man = m_wallet->GetLegacyScriptPubKeyMan();
176  if (spk_man) {
177  return spk_man->HaveWatchOnly();
178  }
179  return false;
180  };
181  bool setAddressBook(const CTxDestination& dest, const std::string& name, const std::string& purpose) override
182  {
183  return m_wallet->SetAddressBook(dest, name, purpose);
184  }
185  bool delAddressBook(const CTxDestination& dest) override
186  {
187  return m_wallet->DelAddressBook(dest);
188  }
189  bool getAddress(const CTxDestination& dest,
190  std::string* name,
191  isminetype* is_mine,
192  std::string* purpose) override
193  {
194  LOCK(m_wallet->cs_wallet);
195  const auto& entry = m_wallet->FindAddressBookEntry(dest, /*allow_change=*/false);
196  if (!entry) return false; // addr not found
197  if (name) {
198  *name = entry->GetLabel();
199  }
200  if (is_mine) {
201  *is_mine = m_wallet->IsMine(dest);
202  }
203  if (purpose) {
204  *purpose = entry->purpose;
205  }
206  return true;
207  }
208  std::vector<WalletAddress> getAddresses() const override
209  {
210  LOCK(m_wallet->cs_wallet);
211  std::vector<WalletAddress> result;
212  m_wallet->ForEachAddrBookEntry([&](const CTxDestination& dest, const std::string& label, const std::string& purpose, bool is_change) EXCLUSIVE_LOCKS_REQUIRED(m_wallet->cs_wallet) {
213  if (is_change) return;
214  result.emplace_back(dest, m_wallet->IsMine(dest), label, purpose);
215  });
216  return result;
217  }
218  std::vector<std::string> getAddressReceiveRequests() override {
219  LOCK(m_wallet->cs_wallet);
220  return m_wallet->GetAddressReceiveRequests();
221  }
222  bool setAddressReceiveRequest(const CTxDestination& dest, const std::string& id, const std::string& value) override {
223  LOCK(m_wallet->cs_wallet);
224  WalletBatch batch{m_wallet->GetDatabase()};
225  return m_wallet->SetAddressReceiveRequest(batch, dest, id, value);
226  }
227  bool displayAddress(const CTxDestination& dest) override
228  {
229  LOCK(m_wallet->cs_wallet);
230  return m_wallet->DisplayAddress(dest);
231  }
232  bool lockCoin(const COutPoint& output, const bool write_to_db) override
233  {
234  LOCK(m_wallet->cs_wallet);
235  std::unique_ptr<WalletBatch> batch = write_to_db ? std::make_unique<WalletBatch>(m_wallet->GetDatabase()) : nullptr;
236  return m_wallet->LockCoin(output, batch.get());
237  }
238  bool unlockCoin(const COutPoint& output) override
239  {
240  LOCK(m_wallet->cs_wallet);
241  std::unique_ptr<WalletBatch> batch = std::make_unique<WalletBatch>(m_wallet->GetDatabase());
242  return m_wallet->UnlockCoin(output, batch.get());
243  }
244  bool isLockedCoin(const COutPoint& output) override
245  {
246  LOCK(m_wallet->cs_wallet);
247  return m_wallet->IsLockedCoin(output);
248  }
249  void listLockedCoins(std::vector<COutPoint>& outputs) override
250  {
251  LOCK(m_wallet->cs_wallet);
252  return m_wallet->ListLockedCoins(outputs);
253  }
254  util::Result<CTransactionRef> createTransaction(const std::vector<CRecipient>& recipients,
255  const CCoinControl& coin_control,
256  bool sign,
257  int& change_pos,
258  CAmount& fee) override
259  {
260  LOCK(m_wallet->cs_wallet);
261  auto res = CreateTransaction(*m_wallet, recipients, change_pos,
262  coin_control, sign);
263  if (!res) return util::Error{util::ErrorString(res)};
264  const auto& txr = *res;
265  fee = txr.fee;
266  change_pos = txr.change_pos;
267 
268  return txr.tx;
269  }
270  void commitTransaction(CTransactionRef tx,
271  WalletValueMap value_map,
272  WalletOrderForm order_form) override
273  {
274  LOCK(m_wallet->cs_wallet);
275  m_wallet->CommitTransaction(std::move(tx), std::move(value_map), std::move(order_form));
276  }
277  bool transactionCanBeAbandoned(const uint256& txid) override { return m_wallet->TransactionCanBeAbandoned(txid); }
278  bool abandonTransaction(const uint256& txid) override
279  {
280  LOCK(m_wallet->cs_wallet);
281  return m_wallet->AbandonTransaction(txid);
282  }
283  bool transactionCanBeBumped(const uint256& txid) override
284  {
285  return feebumper::TransactionCanBeBumped(*m_wallet.get(), txid);
286  }
287  bool createBumpTransaction(const uint256& txid,
288  const CCoinControl& coin_control,
289  std::vector<bilingual_str>& errors,
290  CAmount& old_fee,
291  CAmount& new_fee,
292  CMutableTransaction& mtx) override
293  {
294  return feebumper::CreateRateBumpTransaction(*m_wallet.get(), txid, coin_control, errors, old_fee, new_fee, mtx, /* require_mine= */ true) == feebumper::Result::OK;
295  }
296  bool signBumpTransaction(CMutableTransaction& mtx) override { return feebumper::SignTransaction(*m_wallet.get(), mtx); }
297  bool commitBumpTransaction(const uint256& txid,
298  CMutableTransaction&& mtx,
299  std::vector<bilingual_str>& errors,
300  uint256& bumped_txid) override
301  {
302  return feebumper::CommitTransaction(*m_wallet.get(), txid, std::move(mtx), errors, bumped_txid) ==
304  }
305  CTransactionRef getTx(const uint256& txid) override
306  {
307  LOCK(m_wallet->cs_wallet);
308  auto mi = m_wallet->mapWallet.find(txid);
309  if (mi != m_wallet->mapWallet.end()) {
310  return mi->second.tx;
311  }
312  return {};
313  }
314  WalletTx getWalletTx(const uint256& txid) override
315  {
316  LOCK(m_wallet->cs_wallet);
317  auto mi = m_wallet->mapWallet.find(txid);
318  if (mi != m_wallet->mapWallet.end()) {
319  return MakeWalletTx(*m_wallet, mi->second);
320  }
321  return {};
322  }
323  std::set<WalletTx> getWalletTxs() override
324  {
325  LOCK(m_wallet->cs_wallet);
326  std::set<WalletTx> result;
327  for (const auto& entry : m_wallet->mapWallet) {
328  result.emplace(MakeWalletTx(*m_wallet, entry.second));
329  }
330  return result;
331  }
332  bool tryGetTxStatus(const uint256& txid,
333  interfaces::WalletTxStatus& tx_status,
334  int& num_blocks,
335  int64_t& block_time) override
336  {
337  TRY_LOCK(m_wallet->cs_wallet, locked_wallet);
338  if (!locked_wallet) {
339  return false;
340  }
341  auto mi = m_wallet->mapWallet.find(txid);
342  if (mi == m_wallet->mapWallet.end()) {
343  return false;
344  }
345  num_blocks = m_wallet->GetLastBlockHeight();
346  block_time = -1;
347  CHECK_NONFATAL(m_wallet->chain().findBlock(m_wallet->GetLastBlockHash(), FoundBlock().time(block_time)));
348  tx_status = MakeWalletTxStatus(*m_wallet, mi->second);
349  return true;
350  }
351  WalletTx getWalletTxDetails(const uint256& txid,
352  WalletTxStatus& tx_status,
353  WalletOrderForm& order_form,
354  bool& in_mempool,
355  int& num_blocks) override
356  {
357  LOCK(m_wallet->cs_wallet);
358  auto mi = m_wallet->mapWallet.find(txid);
359  if (mi != m_wallet->mapWallet.end()) {
360  num_blocks = m_wallet->GetLastBlockHeight();
361  in_mempool = mi->second.InMempool();
362  order_form = mi->second.vOrderForm;
363  tx_status = MakeWalletTxStatus(*m_wallet, mi->second);
364  return MakeWalletTx(*m_wallet, mi->second);
365  }
366  return {};
367  }
368  TransactionError fillPSBT(int sighash_type,
369  bool sign,
370  bool bip32derivs,
371  size_t* n_signed,
373  bool& complete) override
374  {
375  return m_wallet->FillPSBT(psbtx, complete, sighash_type, sign, bip32derivs, n_signed);
376  }
377  WalletBalances getBalances() override
378  {
379  const auto bal = GetBalance(*m_wallet);
380  WalletBalances result;
381  result.balance = bal.m_mine_trusted;
382  result.unconfirmed_balance = bal.m_mine_untrusted_pending;
383  result.immature_balance = bal.m_mine_immature;
384  result.have_watch_only = haveWatchOnly();
385  if (result.have_watch_only) {
386  result.watch_only_balance = bal.m_watchonly_trusted;
387  result.unconfirmed_watch_only_balance = bal.m_watchonly_untrusted_pending;
388  result.immature_watch_only_balance = bal.m_watchonly_immature;
389  }
390  return result;
391  }
392  bool tryGetBalances(WalletBalances& balances, uint256& block_hash) override
393  {
394  TRY_LOCK(m_wallet->cs_wallet, locked_wallet);
395  if (!locked_wallet) {
396  return false;
397  }
398  block_hash = m_wallet->GetLastBlockHash();
399  balances = getBalances();
400  return true;
401  }
402  CAmount getBalance() override { return GetBalance(*m_wallet).m_mine_trusted; }
403  CAmount getAvailableBalance(const CCoinControl& coin_control) override
404  {
405  return GetAvailableBalance(*m_wallet, &coin_control);
406  }
407  isminetype txinIsMine(const CTxIn& txin) override
408  {
409  LOCK(m_wallet->cs_wallet);
410  return InputIsMine(*m_wallet, txin);
411  }
412  isminetype txoutIsMine(const CTxOut& txout) override
413  {
414  LOCK(m_wallet->cs_wallet);
415  return m_wallet->IsMine(txout);
416  }
417  CAmount getDebit(const CTxIn& txin, isminefilter filter) override
418  {
419  LOCK(m_wallet->cs_wallet);
420  return m_wallet->GetDebit(txin, filter);
421  }
422  CAmount getCredit(const CTxOut& txout, isminefilter filter) override
423  {
424  LOCK(m_wallet->cs_wallet);
425  return OutputGetCredit(*m_wallet, txout, filter);
426  }
427  CoinsList listCoins() override
428  {
429  LOCK(m_wallet->cs_wallet);
430  CoinsList result;
431  for (const auto& entry : ListCoins(*m_wallet)) {
432  auto& group = result[entry.first];
433  for (const auto& coin : entry.second) {
434  group.emplace_back(coin.outpoint,
435  MakeWalletTxOut(*m_wallet, coin));
436  }
437  }
438  return result;
439  }
440  std::vector<WalletTxOut> getCoins(const std::vector<COutPoint>& outputs) override
441  {
442  LOCK(m_wallet->cs_wallet);
443  std::vector<WalletTxOut> result;
444  result.reserve(outputs.size());
445  for (const auto& output : outputs) {
446  result.emplace_back();
447  auto it = m_wallet->mapWallet.find(output.hash);
448  if (it != m_wallet->mapWallet.end()) {
449  int depth = m_wallet->GetTxDepthInMainChain(it->second);
450  if (depth >= 0) {
451  result.back() = MakeWalletTxOut(*m_wallet, it->second, output.n, depth);
452  }
453  }
454  }
455  return result;
456  }
457  CAmount getRequiredFee(unsigned int tx_bytes) override { return GetRequiredFee(*m_wallet, tx_bytes); }
458  CAmount getMinimumFee(unsigned int tx_bytes,
459  const CCoinControl& coin_control,
460  int* returned_target,
461  FeeReason* reason) override
462  {
463  FeeCalculation fee_calc;
464  CAmount result;
465  result = GetMinimumFee(*m_wallet, tx_bytes, coin_control, &fee_calc);
466  if (returned_target) *returned_target = fee_calc.returnedTarget;
467  if (reason) *reason = fee_calc.reason;
468  return result;
469  }
470  unsigned int getConfirmTarget() override { return m_wallet->m_confirm_target; }
471  bool hdEnabled() override { return m_wallet->IsHDEnabled(); }
472  bool canGetAddresses() override { return m_wallet->CanGetAddresses(); }
473  bool hasExternalSigner() override { return m_wallet->IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER); }
474  bool privateKeysDisabled() override { return m_wallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS); }
475  bool taprootEnabled() override {
476  if (m_wallet->IsLegacy()) return false;
477  auto spk_man = m_wallet->GetScriptPubKeyMan(OutputType::BECH32M, /*internal=*/false);
478  return spk_man != nullptr;
479  }
480  OutputType getDefaultAddressType() override { return m_wallet->m_default_address_type; }
481  CAmount getDefaultMaxTxFee() override { return m_wallet->m_default_max_tx_fee; }
482  void remove() override
483  {
484  RemoveWallet(m_context, m_wallet, false /* load_on_start */);
485  }
486  bool isLegacy() override { return m_wallet->IsLegacy(); }
487  std::unique_ptr<Handler> handleUnload(UnloadFn fn) override
488  {
489  return MakeHandler(m_wallet->NotifyUnload.connect(fn));
490  }
491  std::unique_ptr<Handler> handleShowProgress(ShowProgressFn fn) override
492  {
493  return MakeHandler(m_wallet->ShowProgress.connect(fn));
494  }
495  std::unique_ptr<Handler> handleStatusChanged(StatusChangedFn fn) override
496  {
497  return MakeHandler(m_wallet->NotifyStatusChanged.connect([fn](CWallet*) { fn(); }));
498  }
499  std::unique_ptr<Handler> handleAddressBookChanged(AddressBookChangedFn fn) override
500  {
501  return MakeHandler(m_wallet->NotifyAddressBookChanged.connect(
502  [fn](const CTxDestination& address, const std::string& label, bool is_mine,
503  const std::string& purpose, ChangeType status) { fn(address, label, is_mine, purpose, status); }));
504  }
505  std::unique_ptr<Handler> handleTransactionChanged(TransactionChangedFn fn) override
506  {
507  return MakeHandler(m_wallet->NotifyTransactionChanged.connect(
508  [fn](const uint256& txid, ChangeType status) { fn(txid, status); }));
509  }
510  std::unique_ptr<Handler> handleWatchOnlyChanged(WatchOnlyChangedFn fn) override
511  {
512  return MakeHandler(m_wallet->NotifyWatchonlyChanged.connect(fn));
513  }
514  std::unique_ptr<Handler> handleCanGetAddressesChanged(CanGetAddressesChangedFn fn) override
515  {
516  return MakeHandler(m_wallet->NotifyCanGetAddressesChanged.connect(fn));
517  }
518  CWallet* wallet() override { return m_wallet.get(); }
519 
520  WalletContext& m_context;
521  std::shared_ptr<CWallet> m_wallet;
522 };
523 
524 class WalletLoaderImpl : public WalletLoader
525 {
526 public:
527  WalletLoaderImpl(Chain& chain, ArgsManager& args)
528  {
529  m_context.chain = &chain;
530  m_context.args = &args;
531  }
532  ~WalletLoaderImpl() override { UnloadWallets(m_context); }
533 
535  void registerRpcs() override
536  {
537  for (const CRPCCommand& command : GetWalletRPCCommands()) {
538  m_rpc_commands.emplace_back(command.category, command.name, [this, &command](const JSONRPCRequest& request, UniValue& result, bool last_handler) {
539  JSONRPCRequest wallet_request = request;
540  wallet_request.context = &m_context;
541  return command.actor(wallet_request, result, last_handler);
542  }, command.argNames, command.unique_id);
543  m_rpc_handlers.emplace_back(m_context.chain->handleRpc(m_rpc_commands.back()));
544  }
545  }
546  bool verify() override { return VerifyWallets(m_context); }
547  bool load() override { return LoadWallets(m_context); }
548  void start(CScheduler& scheduler) override { return StartWallets(m_context, scheduler); }
549  void flush() override { return FlushWallets(m_context); }
550  void stop() override { return StopWallets(m_context); }
551  void setMockTime(int64_t time) override { return SetMockTime(time); }
552 
554  util::Result<std::unique_ptr<Wallet>> createWallet(const std::string& name, const SecureString& passphrase, uint64_t wallet_creation_flags, std::vector<bilingual_str>& warnings) override
555  {
556  DatabaseOptions options;
557  DatabaseStatus status;
558  ReadDatabaseArgs(*m_context.args, options);
559  options.require_create = true;
560  options.create_flags = wallet_creation_flags;
561  options.create_passphrase = passphrase;
563  std::unique_ptr<Wallet> wallet{MakeWallet(m_context, CreateWallet(m_context, name, /*load_on_start=*/true, options, status, error, warnings))};
564  if (wallet) {
565  return {std::move(wallet)};
566  } else {
567  return util::Error{error};
568  }
569  }
570  util::Result<std::unique_ptr<Wallet>> loadWallet(const std::string& name, std::vector<bilingual_str>& warnings) override
571  {
572  DatabaseOptions options;
573  DatabaseStatus status;
574  ReadDatabaseArgs(*m_context.args, options);
575  options.require_existing = true;
577  std::unique_ptr<Wallet> wallet{MakeWallet(m_context, LoadWallet(m_context, name, /*load_on_start=*/true, options, status, error, warnings))};
578  if (wallet) {
579  return {std::move(wallet)};
580  } else {
581  return util::Error{error};
582  }
583  }
584  util::Result<std::unique_ptr<Wallet>> restoreWallet(const fs::path& backup_file, const std::string& wallet_name, std::vector<bilingual_str>& warnings) override
585  {
586  DatabaseStatus status;
588  std::unique_ptr<Wallet> wallet{MakeWallet(m_context, RestoreWallet(m_context, backup_file, wallet_name, /*load_on_start=*/true, status, error, warnings))};
589  if (wallet) {
590  return {std::move(wallet)};
591  } else {
592  return util::Error{error};
593  }
594  }
595  std::string getWalletDir() override
596  {
597  return fs::PathToString(GetWalletDir());
598  }
599  std::vector<std::string> listWalletDir() override
600  {
601  std::vector<std::string> paths;
602  for (auto& path : ListDatabases(GetWalletDir())) {
603  paths.push_back(fs::PathToString(path));
604  }
605  return paths;
606  }
607  std::vector<std::unique_ptr<Wallet>> getWallets() override
608  {
609  std::vector<std::unique_ptr<Wallet>> wallets;
610  for (const auto& wallet : GetWallets(m_context)) {
611  wallets.emplace_back(MakeWallet(m_context, wallet));
612  }
613  return wallets;
614  }
615  std::unique_ptr<Handler> handleLoadWallet(LoadWalletFn fn) override
616  {
617  return HandleLoadWallet(m_context, std::move(fn));
618  }
619  WalletContext* context() override { return &m_context; }
620 
621  WalletContext m_context;
622  const std::vector<std::string> m_wallet_filenames;
623  std::vector<std::unique_ptr<Handler>> m_rpc_handlers;
624  std::list<CRPCCommand> m_rpc_commands;
625 };
626 } // namespace
627 } // namespace wallet
628 
629 namespace interfaces {
630 std::unique_ptr<Wallet> MakeWallet(wallet::WalletContext& context, const std::shared_ptr<wallet::CWallet>& wallet) { return wallet ? std::make_unique<wallet::WalletImpl>(context, wallet) : nullptr; }
631 
632 std::unique_ptr<WalletLoader> MakeWalletLoader(Chain& chain, ArgsManager& args)
633 {
634  return std::make_unique<wallet::WalletLoaderImpl>(chain, args);
635 }
636 } // namespace interfaces
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:414
Helper for findBlock to selectively return pieces of block data.
Definition: chain.h:50
void ReadDatabaseArgs(const ArgsManager &args, DatabaseOptions &options)
Definition: db.cpp:142
isminetype InputIsMine(const CWallet &wallet, const CTxIn &txin)
Definition: receive.cpp:12
AssertLockHeld(pool.cs)
std::vector< CTxDestination > txout_address
Definition: wallet.h:390
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
Definition: standard.cpp:237
const std::vector< std::string > m_wallet_filenames
Definition: interfaces.cpp:622
void FlushWallets(WalletContext &context)
Flush all wallets in preparation for shutdown.
Definition: load.cpp:157
int returnedTarget
Definition: fees.h:81
std::function< void(std::unique_ptr< interfaces::Wallet > wallet)> LoadWalletFn
Definition: wallet.h:47
#define TRY_LOCK(cs, name)
Definition: sync.h:265
std::vector< wallet::isminetype > txin_is_mine
Definition: wallet.h:388
unsigned int time_received
Definition: wallet.h:408
Bilingual messages:
Definition: translation.h:18
SigningResult
Definition: message.h:43
std::shared_ptr< CWallet > LoadWallet(WalletContext &context, const std::string &name, std::optional< bool > load_on_start, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error, std::vector< bilingual_str > &warnings)
Definition: wallet.cpp:267
std::shared_ptr< CWallet > m_wallet
Definition: interfaces.cpp:521
#define CHECK_NONFATAL(condition)
Identity function.
Definition: check.h:47
FeeReason reason
Definition: fees.h:79
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
Definition: secure.h:59
std::unique_ptr< Wallet > MakeWallet(wallet::WalletContext &context, const std::shared_ptr< wallet::CWallet > &wallet)
Return implementation of Wallet interface.
Definition: interfaces.cpp:630
CTransactionRef tx
Definition: wallet.h:387
Balance GetBalance(const CWallet &wallet, const int min_depth, bool avoid_reuse)
Definition: receive.cpp:293
A version of CTransaction with the PSBT format.
Definition: psbt.h:946
std::unique_ptr< Handler > MakeHandler(boost::signals2::connection connection)
Return handler wrapping a boost signal connection.
Definition: handler.cpp:35
CAmount CachedTxGetChange(const CWallet &wallet, const CWalletTx &wtx)
Definition: receive.cpp:139
std::map< std::string, std::string > WalletValueMap
Definition: wallet.h:54
fs::path GetWalletDir()
Get the path of the wallet directory.
Definition: walletutil.cpp:11
OutputType
Definition: outputtype.h:17
bool TransactionCanBeBumped(const CWallet &wallet, const uint256 &txid)
Return whether transaction can be bumped.
Definition: feebumper.cpp:146
ArgsManager args
bool LoadWallets(WalletContext &context)
Load wallet databases.
Definition: load.cpp:105
Result CommitTransaction(CWallet &wallet, const uint256 &txid, CMutableTransaction &&mtx, std::vector< bilingual_str > &errors, uint256 &bumped_txid)
Commit the bumpfee transaction.
Definition: feebumper.cpp:299
void StopWallets(WalletContext &context)
Stop all wallets. Wallets will be flushed first.
Definition: load.cpp:164
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
Definition: time.cpp:91
std::vector< wallet::isminetype > txout_is_mine
Definition: wallet.h:389
bool VerifyWallets(WalletContext &context)
Responsible for reading and validating the -wallet arguments and verifying the wallet database...
Definition: load.cpp:25
CAmount GetAvailableBalance(const CWallet &wallet, const CCoinControl *coinControl)
Definition: spend.cpp:312
Indicates that the wallet needs an external signer.
Definition: walletutil.h:69
std::unique_ptr< WalletLoader > MakeWalletLoader(Chain &chain, ArgsManager &args)
Return implementation of ChainClient interface for a wallet loader.
Definition: dummywallet.cpp:62
std::underlying_type< isminetype >::type isminefilter
used for bitflags of isminetype
Definition: wallet.h:41
CAmount CachedTxGetCredit(const CWallet &wallet, const CWalletTx &wtx, const isminefilter &filter)
Definition: receive.cpp:109
static std::string PathToString(const path &path)
Convert path object to a byte string.
Definition: fs.h:150
void StartWallets(WalletContext &context, CScheduler &scheduler)
Complete startup of wallets.
Definition: load.cpp:144
Collection of wallet balances.
Definition: wallet.h:365
An input of a transaction.
Definition: transaction.h:73
#define LOCK(cs)
Definition: sync.h:261
const char * name
Definition: rest.cpp:46
bool CachedTxIsTrusted(const CWallet &wallet, const CWalletTx &wtx, std::set< uint256 > &trusted_parents)
Definition: receive.cpp:256
An encapsulated public key.
Definition: pubkey.h:33
isminetype
IsMine() return codes, which depend on ScriptPubKeyMan implementation.
Definition: ismine.h:41
uint32_t n
Definition: transaction.h:38
Interface for accessing a wallet.
Definition: wallet.h:57
WalletContext context
static bool verify(const CScriptNum10 &bignum, const CScriptNum &scriptnum)
NodeContext * m_context
Definition: interfaces.cpp:390
std::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:149
An output of a transaction.
Definition: transaction.h:156
std::vector< wallet::isminetype > txout_address_is_mine
Definition: wallet.h:391
CAmount immature_watch_only_balance
Definition: wallet.h:373
FeeReason
Definition: fees.h:44
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:34
static RPCHelpMan stop()
Definition: server.cpp:162
Definition: node.h:39
Wallet chain client that in addition to having chain client methods for starting up, shutting down, and registering RPCs, also has additional methods (called by the GUI) to load and create wallets.
Definition: wallet.h:319
bool SignTransaction(CWallet &wallet, CMutableTransaction &mtx)
Sign the new transaction,.
Definition: feebumper.cpp:294
bool RemoveWallet(WalletContext &context, const std::shared_ptr< CWallet > &wallet, std::optional< bool > load_on_start, std::vector< bilingual_str > &warnings)
Definition: wallet.cpp:122
Generic interface for managing an event handler or callback function registered with another interfac...
Definition: handler.h:22
DatabaseStatus
Definition: db.h:219
256-bit opaque blob.
Definition: uint256.h:119
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:49
std::vector< std::shared_ptr< CWallet > > GetWallets(WalletContext &context)
Definition: wallet.cpp:148
const auto command
CAmount unconfirmed_watch_only_balance
Definition: wallet.h:372
Interface giving clients (wallet processes, maybe other analysis tools in the future) ability to acce...
Definition: chain.h:117
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:410
std::vector< std::unique_ptr< Handler > > m_rpc_handlers
Definition: interfaces.cpp:623
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:23
std::unique_ptr< interfaces::Handler > HandleLoadWallet(WalletContext &context, LoadWalletFn load_wallet)
Definition: wallet.cpp:170
WalletContext struct containing references to state shared between CWallet instances, like the reference to the chain interface, and the list of opened wallets.
Definition: context.h:35
TransactionError
Definition: error.h:22
CAmount m_mine_trusted
Trusted, at depth=GetBalance.min_depth or more.
Definition: receive.h:52
util::Result< CreatedTransactionResult > CreateTransaction(CWallet &wallet, const std::vector< CRecipient > &vecSend, int change_pos, const CCoinControl &coin_control, bool sign)
Create a new transaction paying the recipients with a set of coins selected by SelectCoins(); Also cr...
Definition: spend.cpp:1050
std::vector< std::pair< std::string, std::string > > WalletOrderForm
Definition: wallet.h:53
bilingual_str ErrorString(const Result< T > &result)
Definition: result.h:78
Information about one wallet address.
Definition: wallet.h:351
A mutable version of CTransaction.
Definition: transaction.h:372
std::vector< fs::path > ListDatabases(const fs::path &wallet_dir)
Recursively list database paths in directory.
Definition: db.cpp:19
void UnloadWallets(WalletContext &context)
Close all wallets.
Definition: load.cpp:171
std::map< std::string, std::string > value_map
Definition: wallet.h:396
CAmount GetRequiredFee(const CWallet &wallet, unsigned int nTxBytes)
Return the minimum required absolute fee for this size based on the required fee rate.
Definition: fees.cpp:13
Span< const CRPCCommand > GetWalletRPCCommands()
Definition: wallet.cpp:844
std::shared_ptr< CWallet > wallet
Simple class for background tasks that should be run periodically or once "after a while"...
Definition: scheduler.h:38
std::shared_ptr< CWallet > CreateWallet(WalletContext &context, const std::string &name, std::optional< bool > load_on_start, DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error, std::vector< bilingual_str > &warnings)
Definition: wallet.cpp:280
Result CreateRateBumpTransaction(CWallet &wallet, const uint256 &txid, const CCoinControl &coin_control, std::vector< bilingual_str > &errors, CAmount &old_fee, CAmount &new_fee, CMutableTransaction &mtx, bool require_mine)
Create bumpfee transaction based on feerate estimates.
Definition: feebumper.cpp:157
ChangeType
General change type (added, updated, removed).
Definition: ui_change_type.h:9
CAmount GetMinimumFee(const CWallet &wallet, unsigned int nTxBytes, const CCoinControl &coin_control, FeeCalculation *feeCalc)
Estimate the minimum fee considering user set parameters and the required fee.
Definition: fees.cpp:19
std::shared_ptr< CWallet > RestoreWallet(WalletContext &context, const fs::path &backup_file, const std::string &wallet_name, std::optional< bool > load_on_start, DatabaseStatus &status, bilingual_str &error, std::vector< bilingual_str > &warnings)
Definition: wallet.cpp:385
std::list< CRPCCommand > m_rpc_commands
Definition: interfaces.cpp:624
Wallet transaction output.
Definition: wallet.h:417
CAmount OutputGetCredit(const CWallet &wallet, const CTxOut &txout, const isminefilter &filter)
Definition: receive.cpp:31
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:30
bool error(const char *fmt, const Args &... args)
Definition: system.h:48
Updated transaction status.
Definition: wallet.h:403
FoundBlock & time(int64_t &time)
Definition: chain.h:55
std::map< CTxDestination, std::vector< COutput > > ListCoins(const CWallet &wallet)
Return list of available coins and locked coins grouped by non-change output address.
Definition: spend.cpp:348
CAmount CachedTxGetDebit(const CWallet &wallet, const CWalletTx &wtx, const isminefilter &filter)
filter decides which addresses will count towards the debit
Definition: receive.cpp:126
uint256 hash
Definition: transaction.h:37