LCOV - code coverage report
Current view: top level - src/wallet - interfaces.cpp (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 235 434 54.1 %
Date: 2022-04-21 14:51:19 Functions: 59 97 60.8 %
Legend: Modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed

Not modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed
Branches: 38 76 50.0 %

           Branch data     Line data    Source code
#       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>
#      14                 :            : #include <support/allocators/secure.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;
#      37                 :            : using interfaces::FoundBlock;
#      38                 :            : using interfaces::Handler;
#      39                 :            : using interfaces::MakeHandler;
#      40                 :            : using interfaces::Wallet;
#      41                 :            : using interfaces::WalletAddress;
#      42                 :            : using interfaces::WalletBalances;
#      43                 :            : using interfaces::WalletLoader;
#      44                 :            : using interfaces::WalletOrderForm;
#      45                 :            : using interfaces::WalletTx;
#      46                 :            : using interfaces::WalletTxOut;
#      47                 :            : using interfaces::WalletTxStatus;
#      48                 :            : using interfaces::WalletValueMap;
#      49                 :            : 
#      50                 :            : namespace wallet {
#      51                 :            : namespace {
#      52                 :            : //! Construct wallet tx struct.
#      53                 :            : WalletTx MakeWalletTx(CWallet& wallet, const CWalletTx& wtx)
#      54                 :        108 : {
#      55                 :        108 :     LOCK(wallet.cs_wallet);
#      56                 :        108 :     WalletTx result;
#      57                 :        108 :     result.tx = wtx.tx;
#      58                 :        108 :     result.txin_is_mine.reserve(wtx.tx->vin.size());
#      59         [ +  + ]:        108 :     for (const auto& txin : wtx.tx->vin) {
#      60                 :        108 :         result.txin_is_mine.emplace_back(InputIsMine(wallet, txin));
#      61                 :        108 :     }
#      62                 :        108 :     result.txout_is_mine.reserve(wtx.tx->vout.size());
#      63                 :        108 :     result.txout_address.reserve(wtx.tx->vout.size());
#      64                 :        108 :     result.txout_address_is_mine.reserve(wtx.tx->vout.size());
#      65         [ +  + ]:        216 :     for (const auto& txout : wtx.tx->vout) {
#      66                 :        216 :         result.txout_is_mine.emplace_back(wallet.IsMine(txout));
#      67                 :        216 :         result.txout_address.emplace_back();
#      68         [ +  + ]:        216 :         result.txout_address_is_mine.emplace_back(ExtractDestination(txout.scriptPubKey, result.txout_address.back()) ?
#      69                 :        111 :                                                       wallet.IsMine(result.txout_address.back()) :
#      70                 :        216 :                                                       ISMINE_NO);
#      71                 :        216 :     }
#      72                 :        108 :     result.credit = CachedTxGetCredit(wallet, wtx, ISMINE_ALL);
#      73                 :        108 :     result.debit = CachedTxGetDebit(wallet, wtx, ISMINE_ALL);
#      74                 :        108 :     result.change = CachedTxGetChange(wallet, wtx);
#      75                 :        108 :     result.time = wtx.GetTxTime();
#      76                 :        108 :     result.value_map = wtx.mapValue;
#      77                 :        108 :     result.is_coinbase = wtx.IsCoinBase();
#      78                 :        108 :     return result;
#      79                 :        108 : }
#      80                 :            : 
#      81                 :            : //! Construct wallet tx status struct.
#      82                 :            : WalletTxStatus MakeWalletTxStatus(const CWallet& wallet, const CWalletTx& wtx)
#      83                 :        112 : {
#      84                 :        112 :     WalletTxStatus result;
#      85                 :        112 :     result.block_height =
#      86         [ +  + ]:        112 :         wtx.state<TxStateConfirmed>() ? wtx.state<TxStateConfirmed>()->confirmed_block_height :
#      87         [ -  + ]:        112 :         wtx.state<TxStateConflicted>() ? wtx.state<TxStateConflicted>()->conflicting_block_height :
#      88                 :          5 :         std::numeric_limits<int>::max();
#      89                 :        112 :     result.blocks_to_maturity = wallet.GetTxBlocksToMaturity(wtx);
#      90                 :        112 :     result.depth_in_main_chain = wallet.GetTxDepthInMainChain(wtx);
#      91                 :        112 :     result.time_received = wtx.nTimeReceived;
#      92                 :        112 :     result.lock_time = wtx.tx->nLockTime;
#      93                 :        112 :     result.is_trusted = CachedTxIsTrusted(wallet, wtx);
#      94                 :        112 :     result.is_abandoned = wtx.isAbandoned();
#      95                 :        112 :     result.is_coinbase = wtx.IsCoinBase();
#      96                 :        112 :     result.is_in_main_chain = wallet.IsTxInMainChain(wtx);
#      97                 :        112 :     return result;
#      98                 :        112 : }
#      99                 :            : 
#     100                 :            : //! Construct wallet TxOut struct.
#     101                 :            : WalletTxOut MakeWalletTxOut(const CWallet& wallet,
#     102                 :            :     const CWalletTx& wtx,
#     103                 :            :     int n,
#     104                 :            :     int depth) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
#     105                 :          0 : {
#     106                 :          0 :     WalletTxOut result;
#     107                 :          0 :     result.txout = wtx.tx->vout[n];
#     108                 :          0 :     result.time = wtx.GetTxTime();
#     109                 :          0 :     result.depth_in_main_chain = depth;
#     110                 :          0 :     result.is_spent = wallet.IsSpent(wtx.GetHash(), n);
#     111                 :          0 :     return result;
#     112                 :          0 : }
#     113                 :            : 
#     114                 :            : WalletTxOut MakeWalletTxOut(const CWallet& wallet,
#     115                 :            :     const COutput& output) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
#     116                 :          0 : {
#     117                 :          0 :     WalletTxOut result;
#     118                 :          0 :     result.txout = output.txout;
#     119                 :          0 :     result.time = output.time;
#     120                 :          0 :     result.depth_in_main_chain = output.depth;
#     121                 :          0 :     result.is_spent = wallet.IsSpent(output.outpoint.hash, output.outpoint.n);
#     122                 :          0 :     return result;
#     123                 :          0 : }
#     124                 :            : 
#     125                 :            : class WalletImpl : public Wallet
#     126                 :            : {
#     127                 :            : public:
#     128                 :          3 :     explicit WalletImpl(WalletContext& context, const std::shared_ptr<CWallet>& wallet) : m_context(context), m_wallet(wallet) {}
#     129                 :            : 
#     130                 :            :     bool encryptWallet(const SecureString& wallet_passphrase) override
#     131                 :          0 :     {
#     132                 :          0 :         return m_wallet->EncryptWallet(wallet_passphrase);
#     133                 :          0 :     }
#     134                 :          6 :     bool isCrypted() override { return m_wallet->IsCrypted(); }
#     135                 :          0 :     bool lock() override { return m_wallet->Lock(); }
#     136                 :          0 :     bool unlock(const SecureString& wallet_passphrase) override { return m_wallet->Unlock(wallet_passphrase); }
#     137                 :          0 :     bool isLocked() override { return m_wallet->IsLocked(); }
#     138                 :            :     bool changeWalletPassphrase(const SecureString& old_wallet_passphrase,
#     139                 :            :         const SecureString& new_wallet_passphrase) override
#     140                 :          0 :     {
#     141                 :          0 :         return m_wallet->ChangeWalletPassphrase(old_wallet_passphrase, new_wallet_passphrase);
#     142                 :          0 :     }
#     143                 :          0 :     void abortRescan() override { m_wallet->AbortRescan(); }
#     144                 :          0 :     bool backupWallet(const std::string& filename) override { return m_wallet->BackupWallet(filename); }
#     145                 :          1 :     std::string getWalletName() override { return m_wallet->GetName(); }
#     146                 :            :     bool getNewDestination(const OutputType type, const std::string label, CTxDestination& dest) override
#     147                 :          1 :     {
#     148                 :          1 :         LOCK(m_wallet->cs_wallet);
#     149                 :          1 :         bilingual_str error;
#     150                 :          1 :         return m_wallet->GetNewDestination(type, label, dest, error);
#     151                 :          1 :     }
#     152                 :            :     bool getPubKey(const CScript& script, const CKeyID& address, CPubKey& pub_key) override
#     153                 :          0 :     {
#     154                 :          0 :         std::unique_ptr<SigningProvider> provider = m_wallet->GetSolvingProvider(script);
#     155         [ #  # ]:          0 :         if (provider) {
#     156                 :          0 :             return provider->GetPubKey(address, pub_key);
#     157                 :          0 :         }
#     158                 :          0 :         return false;
#     159                 :          0 :     }
#     160                 :            :     SigningResult signMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) override
#     161                 :          0 :     {
#     162                 :          0 :         return m_wallet->SignMessage(message, pkhash, str_sig);
#     163                 :          0 :     }
#     164                 :            :     bool isSpendable(const CTxDestination& dest) override
#     165                 :          0 :     {
#     166                 :          0 :         LOCK(m_wallet->cs_wallet);
#     167                 :          0 :         return m_wallet->IsMine(dest) & ISMINE_SPENDABLE;
#     168                 :          0 :     }
#     169                 :            :     bool haveWatchOnly() override
#     170                 :          9 :     {
#     171                 :          9 :         auto spk_man = m_wallet->GetLegacyScriptPubKeyMan();
#     172         [ -  + ]:          9 :         if (spk_man) {
#     173                 :          0 :             return spk_man->HaveWatchOnly();
#     174                 :          0 :         }
#     175                 :          9 :         return false;
#     176                 :          9 :     };
#     177                 :            :     bool setAddressBook(const CTxDestination& dest, const std::string& name, const std::string& purpose) override
#     178                 :          2 :     {
#     179                 :          2 :         return m_wallet->SetAddressBook(dest, name, purpose);
#     180                 :          2 :     }
#     181                 :            :     bool delAddressBook(const CTxDestination& dest) override
#     182                 :          0 :     {
#     183                 :          0 :         return m_wallet->DelAddressBook(dest);
#     184                 :          0 :     }
#     185                 :            :     bool getAddress(const CTxDestination& dest,
#     186                 :            :         std::string* name,
#     187                 :            :         isminetype* is_mine,
#     188                 :            :         std::string* purpose) override
#     189                 :        231 :     {
#     190                 :        231 :         LOCK(m_wallet->cs_wallet);
#     191                 :        231 :         auto it = m_wallet->m_address_book.find(dest);
#     192 [ +  + ][ +  + ]:        231 :         if (it == m_wallet->m_address_book.end() || it->second.IsChange()) {
#                 [ -  + ]
#     193                 :        213 :             return false;
#     194                 :        213 :         }
#     195         [ +  + ]:         18 :         if (name) {
#     196                 :         14 :             *name = it->second.GetLabel();
#     197                 :         14 :         }
#     198         [ -  + ]:         18 :         if (is_mine) {
#     199                 :          0 :             *is_mine = m_wallet->IsMine(dest);
#     200                 :          0 :         }
#     201         [ +  + ]:         18 :         if (purpose) {
#     202                 :          2 :             *purpose = it->second.purpose;
#     203                 :          2 :         }
#     204                 :         18 :         return true;
#     205                 :        231 :     }
#     206                 :            :     std::vector<WalletAddress> getAddresses() override
#     207                 :          2 :     {
#     208                 :          2 :         LOCK(m_wallet->cs_wallet);
#     209                 :          2 :         std::vector<WalletAddress> result;
#     210         [ +  + ]:          3 :         for (const auto& item : m_wallet->m_address_book) {
#     211         [ -  + ]:          3 :             if (item.second.IsChange()) continue;
#     212                 :          3 :             result.emplace_back(item.first, m_wallet->IsMine(item.first), item.second.GetLabel(), item.second.purpose);
#     213                 :          3 :         }
#     214                 :          2 :         return result;
#     215                 :          2 :     }
#     216                 :          4 :     std::vector<std::string> getAddressReceiveRequests() override {
#     217                 :          4 :         LOCK(m_wallet->cs_wallet);
#     218                 :          4 :         return m_wallet->GetAddressReceiveRequests();
#     219                 :          4 :     }
#     220                 :          2 :     bool setAddressReceiveRequest(const CTxDestination& dest, const std::string& id, const std::string& value) override {
#     221                 :          2 :         LOCK(m_wallet->cs_wallet);
#     222                 :          2 :         WalletBatch batch{m_wallet->GetDatabase()};
#     223                 :          2 :         return m_wallet->SetAddressReceiveRequest(batch, dest, id, value);
#     224                 :          2 :     }
#     225                 :            :     bool displayAddress(const CTxDestination& dest) override
#     226                 :          0 :     {
#     227                 :          0 :         LOCK(m_wallet->cs_wallet);
#     228                 :          0 :         return m_wallet->DisplayAddress(dest);
#     229                 :          0 :     }
#     230                 :            :     bool lockCoin(const COutPoint& output, const bool write_to_db) override
#     231                 :          0 :     {
#     232                 :          0 :         LOCK(m_wallet->cs_wallet);
#     233         [ #  # ]:          0 :         std::unique_ptr<WalletBatch> batch = write_to_db ? std::make_unique<WalletBatch>(m_wallet->GetDatabase()) : nullptr;
#     234                 :          0 :         return m_wallet->LockCoin(output, batch.get());
#     235                 :          0 :     }
#     236                 :            :     bool unlockCoin(const COutPoint& output) override
#     237                 :          0 :     {
#     238                 :          0 :         LOCK(m_wallet->cs_wallet);
#     239                 :          0 :         std::unique_ptr<WalletBatch> batch = std::make_unique<WalletBatch>(m_wallet->GetDatabase());
#     240                 :          0 :         return m_wallet->UnlockCoin(output, batch.get());
#     241                 :          0 :     }
#     242                 :            :     bool isLockedCoin(const COutPoint& output) override
#     243                 :          0 :     {
#     244                 :          0 :         LOCK(m_wallet->cs_wallet);
#     245                 :          0 :         return m_wallet->IsLockedCoin(output.hash, output.n);
#     246                 :          0 :     }
#     247                 :            :     void listLockedCoins(std::vector<COutPoint>& outputs) override
#     248                 :          0 :     {
#     249                 :          0 :         LOCK(m_wallet->cs_wallet);
#     250                 :          0 :         return m_wallet->ListLockedCoins(outputs);
#     251                 :          0 :     }
#     252                 :            :     CTransactionRef createTransaction(const std::vector<CRecipient>& recipients,
#     253                 :            :         const CCoinControl& coin_control,
#     254                 :            :         bool sign,
#     255                 :            :         int& change_pos,
#     256                 :            :         CAmount& fee,
#     257                 :            :         bilingual_str& fail_reason) override
#     258                 :          2 :     {
#     259                 :          2 :         LOCK(m_wallet->cs_wallet);
#     260                 :          2 :         CTransactionRef tx;
#     261                 :          2 :         FeeCalculation fee_calc_out;
#     262         [ -  + ]:          2 :         if (!CreateTransaction(*m_wallet, recipients, tx, fee, change_pos,
#     263                 :          2 :                 fail_reason, coin_control, fee_calc_out, sign)) {
#     264                 :          0 :             return {};
#     265                 :          0 :         }
#     266                 :          2 :         return tx;
#     267                 :          2 :     }
#     268                 :            :     void commitTransaction(CTransactionRef tx,
#     269                 :            :         WalletValueMap value_map,
#     270                 :            :         WalletOrderForm order_form) override
#     271                 :          2 :     {
#     272                 :          2 :         LOCK(m_wallet->cs_wallet);
#     273                 :          2 :         m_wallet->CommitTransaction(std::move(tx), std::move(value_map), std::move(order_form));
#     274                 :          2 :     }
#     275                 :          4 :     bool transactionCanBeAbandoned(const uint256& txid) override { return m_wallet->TransactionCanBeAbandoned(txid); }
#     276                 :            :     bool abandonTransaction(const uint256& txid) override
#     277                 :          0 :     {
#     278                 :          0 :         LOCK(m_wallet->cs_wallet);
#     279                 :          0 :         return m_wallet->AbandonTransaction(txid);
#     280                 :          0 :     }
#     281                 :            :     bool transactionCanBeBumped(const uint256& txid) override
#     282                 :          4 :     {
#     283                 :          4 :         return feebumper::TransactionCanBeBumped(*m_wallet.get(), txid);
#     284                 :          4 :     }
#     285                 :            :     bool createBumpTransaction(const uint256& txid,
#     286                 :            :         const CCoinControl& coin_control,
#     287                 :            :         std::vector<bilingual_str>& errors,
#     288                 :            :         CAmount& old_fee,
#     289                 :            :         CAmount& new_fee,
#     290                 :            :         CMutableTransaction& mtx) override
#     291                 :          4 :     {
#     292                 :          4 :         return feebumper::CreateRateBumpTransaction(*m_wallet.get(), txid, coin_control, errors, old_fee, new_fee, mtx) == feebumper::Result::OK;
#     293                 :          4 :     }
#     294                 :          1 :     bool signBumpTransaction(CMutableTransaction& mtx) override { return feebumper::SignTransaction(*m_wallet.get(), mtx); }
#     295                 :            :     bool commitBumpTransaction(const uint256& txid,
#     296                 :            :         CMutableTransaction&& mtx,
#     297                 :            :         std::vector<bilingual_str>& errors,
#     298                 :            :         uint256& bumped_txid) override
#     299                 :          1 :     {
#     300                 :          1 :         return feebumper::CommitTransaction(*m_wallet.get(), txid, std::move(mtx), errors, bumped_txid) ==
#     301                 :          1 :                feebumper::Result::OK;
#     302                 :          1 :     }
#     303                 :            :     CTransactionRef getTx(const uint256& txid) override
#     304                 :          0 :     {
#     305                 :          0 :         LOCK(m_wallet->cs_wallet);
#     306                 :          0 :         auto mi = m_wallet->mapWallet.find(txid);
#     307         [ #  # ]:          0 :         if (mi != m_wallet->mapWallet.end()) {
#     308                 :          0 :             return mi->second.tx;
#     309                 :          0 :         }
#     310                 :          0 :         return {};
#     311                 :          0 :     }
#     312                 :            :     WalletTx getWalletTx(const uint256& txid) override
#     313                 :          3 :     {
#     314                 :          3 :         LOCK(m_wallet->cs_wallet);
#     315                 :          3 :         auto mi = m_wallet->mapWallet.find(txid);
#     316         [ +  - ]:          3 :         if (mi != m_wallet->mapWallet.end()) {
#     317                 :          3 :             return MakeWalletTx(*m_wallet, mi->second);
#     318                 :          3 :         }
#     319                 :          0 :         return {};
#     320                 :          3 :     }
#     321                 :            :     std::vector<WalletTx> getWalletTxs() override
#     322                 :          2 :     {
#     323                 :          2 :         LOCK(m_wallet->cs_wallet);
#     324                 :          2 :         std::vector<WalletTx> result;
#     325                 :          2 :         result.reserve(m_wallet->mapWallet.size());
#     326         [ +  + ]:        105 :         for (const auto& entry : m_wallet->mapWallet) {
#     327                 :        105 :             result.emplace_back(MakeWalletTx(*m_wallet, entry.second));
#     328                 :        105 :         }
#     329                 :          2 :         return result;
#     330                 :          2 :     }
#     331                 :            :     bool tryGetTxStatus(const uint256& txid,
#     332                 :            :         interfaces::WalletTxStatus& tx_status,
#     333                 :            :         int& num_blocks,
#     334                 :            :         int64_t& block_time) override
#     335                 :        112 :     {
#     336                 :        112 :         TRY_LOCK(m_wallet->cs_wallet, locked_wallet);
#     337         [ -  + ]:        112 :         if (!locked_wallet) {
#     338                 :          0 :             return false;
#     339                 :          0 :         }
#     340                 :        112 :         auto mi = m_wallet->mapWallet.find(txid);
#     341         [ -  + ]:        112 :         if (mi == m_wallet->mapWallet.end()) {
#     342                 :          0 :             return false;
#     343                 :          0 :         }
#     344                 :        112 :         num_blocks = m_wallet->GetLastBlockHeight();
#     345                 :        112 :         block_time = -1;
#     346         [ -  + ]:        112 :         CHECK_NONFATAL(m_wallet->chain().findBlock(m_wallet->GetLastBlockHash(), FoundBlock().time(block_time)));
#     347                 :        112 :         tx_status = MakeWalletTxStatus(*m_wallet, mi->second);
#     348                 :        112 :         return true;
#     349                 :        112 :     }
#     350                 :            :     WalletTx getWalletTxDetails(const uint256& txid,
#     351                 :            :         WalletTxStatus& tx_status,
#     352                 :            :         WalletOrderForm& order_form,
#     353                 :            :         bool& in_mempool,
#     354                 :            :         int& num_blocks) override
#     355                 :          0 :     {
#     356                 :          0 :         LOCK(m_wallet->cs_wallet);
#     357                 :          0 :         auto mi = m_wallet->mapWallet.find(txid);
#     358         [ #  # ]:          0 :         if (mi != m_wallet->mapWallet.end()) {
#     359                 :          0 :             num_blocks = m_wallet->GetLastBlockHeight();
#     360                 :          0 :             in_mempool = mi->second.InMempool();
#     361                 :          0 :             order_form = mi->second.vOrderForm;
#     362                 :          0 :             tx_status = MakeWalletTxStatus(*m_wallet, mi->second);
#     363                 :          0 :             return MakeWalletTx(*m_wallet, mi->second);
#     364                 :          0 :         }
#     365                 :          0 :         return {};
#     366                 :          0 :     }
#     367                 :            :     TransactionError fillPSBT(int sighash_type,
#     368                 :            :         bool sign,
#     369                 :            :         bool bip32derivs,
#     370                 :            :         size_t* n_signed,
#     371                 :            :         PartiallySignedTransaction& psbtx,
#     372                 :            :         bool& complete) override
#     373                 :          0 :     {
#     374                 :          0 :         return m_wallet->FillPSBT(psbtx, complete, sighash_type, sign, bip32derivs, n_signed);
#     375                 :          0 :     }
#     376                 :            :     WalletBalances getBalances() override
#     377                 :          5 :     {
#     378                 :          5 :         const auto bal = GetBalance(*m_wallet);
#     379                 :          5 :         WalletBalances result;
#     380                 :          5 :         result.balance = bal.m_mine_trusted;
#     381                 :          5 :         result.unconfirmed_balance = bal.m_mine_untrusted_pending;
#     382                 :          5 :         result.immature_balance = bal.m_mine_immature;
#     383                 :          5 :         result.have_watch_only = haveWatchOnly();
#     384         [ -  + ]:          5 :         if (result.have_watch_only) {
#     385                 :          0 :             result.watch_only_balance = bal.m_watchonly_trusted;
#     386                 :          0 :             result.unconfirmed_watch_only_balance = bal.m_watchonly_untrusted_pending;
#     387                 :          0 :             result.immature_watch_only_balance = bal.m_watchonly_immature;
#     388                 :          0 :         }
#     389                 :          5 :         return result;
#     390                 :          5 :     }
#     391                 :            :     bool tryGetBalances(WalletBalances& balances, uint256& block_hash) override
#     392                 :          0 :     {
#     393                 :          0 :         TRY_LOCK(m_wallet->cs_wallet, locked_wallet);
#     394         [ #  # ]:          0 :         if (!locked_wallet) {
#     395                 :          0 :             return false;
#     396                 :          0 :         }
#     397                 :          0 :         block_hash = m_wallet->GetLastBlockHash();
#     398                 :          0 :         balances = getBalances();
#     399                 :          0 :         return true;
#     400                 :          0 :     }
#     401                 :          2 :     CAmount getBalance() override { return GetBalance(*m_wallet).m_mine_trusted; }
#     402                 :            :     CAmount getAvailableBalance(const CCoinControl& coin_control) override
#     403                 :          2 :     {
#     404                 :          2 :         return GetAvailableBalance(*m_wallet, &coin_control);
#     405                 :          2 :     }
#     406                 :            :     isminetype txinIsMine(const CTxIn& txin) override
#     407                 :          0 :     {
#     408                 :          0 :         LOCK(m_wallet->cs_wallet);
#     409                 :          0 :         return InputIsMine(*m_wallet, txin);
#     410                 :          0 :     }
#     411                 :            :     isminetype txoutIsMine(const CTxOut& txout) override
#     412                 :          0 :     {
#     413                 :          0 :         LOCK(m_wallet->cs_wallet);
#     414                 :          0 :         return m_wallet->IsMine(txout);
#     415                 :          0 :     }
#     416                 :            :     CAmount getDebit(const CTxIn& txin, isminefilter filter) override
#     417                 :          0 :     {
#     418                 :          0 :         LOCK(m_wallet->cs_wallet);
#     419                 :          0 :         return m_wallet->GetDebit(txin, filter);
#     420                 :          0 :     }
#     421                 :            :     CAmount getCredit(const CTxOut& txout, isminefilter filter) override
#     422                 :          0 :     {
#     423                 :          0 :         LOCK(m_wallet->cs_wallet);
#     424                 :          0 :         return OutputGetCredit(*m_wallet, txout, filter);
#     425                 :          0 :     }
#     426                 :            :     CoinsList listCoins() override
#     427                 :          0 :     {
#     428                 :          0 :         LOCK(m_wallet->cs_wallet);
#     429                 :          0 :         CoinsList result;
#     430         [ #  # ]:          0 :         for (const auto& entry : ListCoins(*m_wallet)) {
#     431                 :          0 :             auto& group = result[entry.first];
#     432         [ #  # ]:          0 :             for (const auto& coin : entry.second) {
#     433                 :          0 :                 group.emplace_back(coin.outpoint,
#     434                 :          0 :                     MakeWalletTxOut(*m_wallet, coin));
#     435                 :          0 :             }
#     436                 :          0 :         }
#     437                 :          0 :         return result;
#     438                 :          0 :     }
#     439                 :            :     std::vector<WalletTxOut> getCoins(const std::vector<COutPoint>& outputs) override
#     440                 :          0 :     {
#     441                 :          0 :         LOCK(m_wallet->cs_wallet);
#     442                 :          0 :         std::vector<WalletTxOut> result;
#     443                 :          0 :         result.reserve(outputs.size());
#     444         [ #  # ]:          0 :         for (const auto& output : outputs) {
#     445                 :          0 :             result.emplace_back();
#     446                 :          0 :             auto it = m_wallet->mapWallet.find(output.hash);
#     447         [ #  # ]:          0 :             if (it != m_wallet->mapWallet.end()) {
#     448                 :          0 :                 int depth = m_wallet->GetTxDepthInMainChain(it->second);
#     449         [ #  # ]:          0 :                 if (depth >= 0) {
#     450                 :          0 :                     result.back() = MakeWalletTxOut(*m_wallet, it->second, output.n, depth);
#     451                 :          0 :                 }
#     452                 :          0 :             }
#     453                 :          0 :         }
#     454                 :          0 :         return result;
#     455                 :          0 :     }
#     456                 :          1 :     CAmount getRequiredFee(unsigned int tx_bytes) override { return GetRequiredFee(*m_wallet, tx_bytes); }
#     457                 :            :     CAmount getMinimumFee(unsigned int tx_bytes,
#     458                 :            :         const CCoinControl& coin_control,
#     459                 :            :         int* returned_target,
#     460                 :            :         FeeReason* reason) override
#     461                 :          6 :     {
#     462                 :          6 :         FeeCalculation fee_calc;
#     463                 :          6 :         CAmount result;
#     464                 :          6 :         result = GetMinimumFee(*m_wallet, tx_bytes, coin_control, &fee_calc);
#     465         [ +  - ]:          6 :         if (returned_target) *returned_target = fee_calc.returnedTarget;
#     466         [ +  - ]:          6 :         if (reason) *reason = fee_calc.reason;
#     467                 :          6 :         return result;
#     468                 :          6 :     }
#     469                 :          1 :     unsigned int getConfirmTarget() override { return m_wallet->m_confirm_target; }
#     470                 :          0 :     bool hdEnabled() override { return m_wallet->IsHDEnabled(); }
#     471                 :          3 :     bool canGetAddresses() override { return m_wallet->CanGetAddresses(); }
#     472                 :          8 :     bool hasExternalSigner() override { return m_wallet->IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER); }
#     473                 :         42 :     bool privateKeysDisabled() override { return m_wallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS); }
#     474                 :          1 :     bool taprootEnabled() override {
#     475         [ -  + ]:          1 :         if (m_wallet->IsLegacy()) return false;
#     476                 :          1 :         auto spk_man = m_wallet->GetScriptPubKeyMan(OutputType::BECH32M, /*internal=*/false);
#     477                 :          1 :         return spk_man != nullptr;
#     478                 :          1 :     }
#     479                 :          7 :     OutputType getDefaultAddressType() override { return m_wallet->m_default_address_type; }
#     480                 :          2 :     CAmount getDefaultMaxTxFee() override { return m_wallet->m_default_max_tx_fee; }
#     481                 :            :     void remove() override
#     482                 :          0 :     {
#     483                 :          0 :         RemoveWallet(m_context, m_wallet, false /* load_on_start */);
#     484                 :          0 :     }
#     485                 :          2 :     bool isLegacy() override { return m_wallet->IsLegacy(); }
#     486                 :            :     std::unique_ptr<Handler> handleUnload(UnloadFn fn) override
#     487                 :          2 :     {
#     488                 :          2 :         return MakeHandler(m_wallet->NotifyUnload.connect(fn));
#     489                 :          2 :     }
#     490                 :            :     std::unique_ptr<Handler> handleShowProgress(ShowProgressFn fn) override
#     491                 :          4 :     {
#     492                 :          4 :         return MakeHandler(m_wallet->ShowProgress.connect(fn));
#     493                 :          4 :     }
#     494                 :            :     std::unique_ptr<Handler> handleStatusChanged(StatusChangedFn fn) override
#     495                 :          2 :     {
#     496                 :          2 :         return MakeHandler(m_wallet->NotifyStatusChanged.connect([fn](CWallet*) { fn(); }));
#     497                 :          2 :     }
#     498                 :            :     std::unique_ptr<Handler> handleAddressBookChanged(AddressBookChangedFn fn) override
#     499                 :          2 :     {
#     500                 :          2 :         return MakeHandler(m_wallet->NotifyAddressBookChanged.connect(
#     501                 :          2 :             [fn](const CTxDestination& address, const std::string& label, bool is_mine,
#     502                 :          3 :                  const std::string& purpose, ChangeType status) { fn(address, label, is_mine, purpose, status); }));
#     503                 :          2 :     }
#     504                 :            :     std::unique_ptr<Handler> handleTransactionChanged(TransactionChangedFn fn) override
#     505                 :          4 :     {
#     506                 :          4 :         return MakeHandler(m_wallet->NotifyTransactionChanged.connect(
#     507                 :         14 :             [fn](const uint256& txid, ChangeType status) { fn(txid, status); }));
#     508                 :          4 :     }
#     509                 :            :     std::unique_ptr<Handler> handleWatchOnlyChanged(WatchOnlyChangedFn fn) override
#     510                 :          2 :     {
#     511                 :          2 :         return MakeHandler(m_wallet->NotifyWatchonlyChanged.connect(fn));
#     512                 :          2 :     }
#     513                 :            :     std::unique_ptr<Handler> handleCanGetAddressesChanged(CanGetAddressesChangedFn fn) override
#     514                 :          2 :     {
#     515                 :          2 :         return MakeHandler(m_wallet->NotifyCanGetAddressesChanged.connect(fn));
#     516                 :          2 :     }
#     517                 :          0 :     CWallet* wallet() override { return m_wallet.get(); }
#     518                 :            : 
#     519                 :            :     WalletContext& m_context;
#     520                 :            :     std::shared_ptr<CWallet> m_wallet;
#     521                 :            : };
#     522                 :            : 
#     523                 :            : class WalletLoaderImpl : public WalletLoader
#     524                 :            : {
#     525                 :            : public:
#     526                 :            :     WalletLoaderImpl(Chain& chain, ArgsManager& args)
#     527                 :        808 :     {
#     528                 :        808 :         m_context.chain = &chain;
#     529                 :        808 :         m_context.args = &args;
#     530                 :        808 :     }
#     531                 :        808 :     ~WalletLoaderImpl() override { UnloadWallets(m_context); }
#     532                 :            : 
#     533                 :            :     //! ChainClient methods
#     534                 :            :     void registerRpcs() override
#     535                 :        799 :     {
#     536         [ +  + ]:      51935 :         for (const CRPCCommand& command : GetWalletRPCCommands()) {
#     537                 :      51935 :             m_rpc_commands.emplace_back(command.category, command.name, [this, &command](const JSONRPCRequest& request, UniValue& result, bool last_handler) {
#     538                 :      27407 :                 JSONRPCRequest wallet_request = request;
#     539                 :      27407 :                 wallet_request.context = &m_context;
#     540                 :      27407 :                 return command.actor(wallet_request, result, last_handler);
#     541                 :      27407 :             }, command.argNames, command.unique_id);
#     542                 :      51935 :             m_rpc_handlers.emplace_back(m_context.chain->handleRpc(m_rpc_commands.back()));
#     543                 :      51935 :         }
#     544                 :        799 :     }
#     545                 :        792 :     bool verify() override { return VerifyWallets(m_context); }
#     546                 :        723 :     bool load() override { return LoadWallets(m_context); }
#     547                 :        715 :     void start(CScheduler& scheduler) override { return StartWallets(m_context, scheduler); }
#     548                 :        788 :     void flush() override { return FlushWallets(m_context); }
#     549                 :        788 :     void stop() override { return StopWallets(m_context); }
#     550                 :        599 :     void setMockTime(int64_t time) override { return SetMockTime(time); }
#     551                 :            : 
#     552                 :            :     //! WalletLoader methods
#     553                 :            :     std::unique_ptr<Wallet> createWallet(const std::string& name, const SecureString& passphrase, uint64_t wallet_creation_flags, bilingual_str& error, std::vector<bilingual_str>& warnings) override
#     554                 :          0 :     {
#     555                 :          0 :         std::shared_ptr<CWallet> wallet;
#     556                 :          0 :         DatabaseOptions options;
#     557                 :          0 :         DatabaseStatus status;
#     558                 :          0 :         ReadDatabaseArgs(*m_context.args, options);
#     559                 :          0 :         options.require_create = true;
#     560                 :          0 :         options.create_flags = wallet_creation_flags;
#     561                 :          0 :         options.create_passphrase = passphrase;
#     562                 :          0 :         return MakeWallet(m_context, CreateWallet(m_context, name, true /* load_on_start */, options, status, error, warnings));
#     563                 :          0 :     }
#     564                 :            :     std::unique_ptr<Wallet> loadWallet(const std::string& name, bilingual_str& error, std::vector<bilingual_str>& warnings) override
#     565                 :          0 :     {
#     566                 :          0 :         DatabaseOptions options;
#     567                 :          0 :         DatabaseStatus status;
#     568                 :          0 :         ReadDatabaseArgs(*m_context.args, options);
#     569                 :          0 :         options.require_existing = true;
#     570                 :          0 :         return MakeWallet(m_context, LoadWallet(m_context, name, true /* load_on_start */, options, status, error, warnings));
#     571                 :          0 :     }
#     572                 :            :     std::unique_ptr<Wallet> restoreWallet(const fs::path& backup_file, const std::string& wallet_name, bilingual_str& error, std::vector<bilingual_str>& warnings) override
#     573                 :          0 :     {
#     574                 :          0 :         DatabaseStatus status;
#     575                 :            : 
#     576                 :          0 :         return MakeWallet(m_context, RestoreWallet(m_context, backup_file, wallet_name, /*load_on_start=*/true, status, error, warnings));
#     577                 :          0 :     }
#     578                 :            :     std::string getWalletDir() override
#     579                 :          0 :     {
#     580                 :          0 :         return fs::PathToString(GetWalletDir());
#     581                 :          0 :     }
#     582                 :            :     std::vector<std::string> listWalletDir() override
#     583                 :          0 :     {
#     584                 :          0 :         std::vector<std::string> paths;
#     585         [ #  # ]:          0 :         for (auto& path : ListDatabases(GetWalletDir())) {
#     586                 :          0 :             paths.push_back(fs::PathToString(path));
#     587                 :          0 :         }
#     588                 :          0 :         return paths;
#     589                 :          0 :     }
#     590                 :            :     std::vector<std::unique_ptr<Wallet>> getWallets() override
#     591                 :          3 :     {
#     592                 :          3 :         std::vector<std::unique_ptr<Wallet>> wallets;
#     593         [ -  + ]:          3 :         for (const auto& wallet : GetWallets(m_context)) {
#     594                 :          0 :             wallets.emplace_back(MakeWallet(m_context, wallet));
#     595                 :          0 :         }
#     596                 :          3 :         return wallets;
#     597                 :          3 :     }
#     598                 :            :     std::unique_ptr<Handler> handleLoadWallet(LoadWalletFn fn) override
#     599                 :          1 :     {
#     600                 :          1 :         return HandleLoadWallet(m_context, std::move(fn));
#     601                 :          1 :     }
#     602                 :          2 :     WalletContext* context() override  { return &m_context; }
#     603                 :            : 
#     604                 :            :     WalletContext m_context;
#     605                 :            :     const std::vector<std::string> m_wallet_filenames;
#     606                 :            :     std::vector<std::unique_ptr<Handler>> m_rpc_handlers;
#     607                 :            :     std::list<CRPCCommand> m_rpc_commands;
#     608                 :            : };
#     609                 :            : } // namespace
#     610                 :            : } // namespace wallet
#     611                 :            : 
#     612                 :            : namespace interfaces {
#     613         [ +  - ]:          3 : 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; }
#     614                 :            : 
#     615                 :            : std::unique_ptr<WalletLoader> MakeWalletLoader(Chain& chain, ArgsManager& args)
#     616                 :        808 : {
#     617                 :        808 :     return std::make_unique<wallet::WalletLoaderImpl>(chain, args);
#     618                 :        808 : }
#     619                 :            : } // namespace interfaces

Generated by: LCOV version 0-eol-96201-ge66f56f4af6a