diff options
Diffstat (limited to 'src/wallet/interfaces.cpp')
-rw-r--r-- | src/wallet/interfaces.cpp | 157 |
1 files changed, 83 insertions, 74 deletions
diff --git a/src/wallet/interfaces.cpp b/src/wallet/interfaces.cpp index 1fb789b128..9083c304b2 100644 --- a/src/wallet/interfaces.cpp +++ b/src/wallet/interfaces.cpp @@ -1,10 +1,10 @@ -// Copyright (c) 2018-2020 The Bitcoin Core developers +// Copyright (c) 2018-2021 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <interfaces/wallet.h> -#include <amount.h> +#include <consensus/amount.h> #include <interfaces/chain.h> #include <interfaces/handler.h> #include <policy/fees.h> @@ -15,16 +15,17 @@ #include <sync.h> #include <uint256.h> #include <util/check.h> -#include <util/ref.h> #include <util/system.h> +#include <util/translation.h> #include <util/ui_change_type.h> #include <wallet/context.h> #include <wallet/feebumper.h> #include <wallet/fees.h> #include <wallet/ismine.h> #include <wallet/load.h> -#include <wallet/rpcsigner.h> -#include <wallet/rpcwallet.h> +#include <wallet/receive.h> +#include <wallet/rpc/wallet.h> +#include <wallet/spend.h> #include <wallet/wallet.h> #include <memory> @@ -39,7 +40,7 @@ using interfaces::MakeHandler; using interfaces::Wallet; using interfaces::WalletAddress; using interfaces::WalletBalances; -using interfaces::WalletClient; +using interfaces::WalletLoader; using interfaces::WalletOrderForm; using interfaces::WalletTx; using interfaces::WalletTxOut; @@ -56,7 +57,7 @@ WalletTx MakeWalletTx(CWallet& wallet, const CWalletTx& wtx) result.tx = wtx.tx; result.txin_is_mine.reserve(wtx.tx->vin.size()); for (const auto& txin : wtx.tx->vin) { - result.txin_is_mine.emplace_back(wallet.IsMine(txin)); + result.txin_is_mine.emplace_back(InputIsMine(wallet, txin)); } result.txout_is_mine.reserve(wtx.tx->vout.size()); result.txout_address.reserve(wtx.tx->vout.size()); @@ -68,9 +69,9 @@ WalletTx MakeWalletTx(CWallet& wallet, const CWalletTx& wtx) wallet.IsMine(result.txout_address.back()) : ISMINE_NO); } - result.credit = wtx.GetCredit(ISMINE_ALL); - result.debit = wtx.GetDebit(ISMINE_ALL); - result.change = wtx.GetChange(); + result.credit = CachedTxGetCredit(wallet, wtx, ISMINE_ALL); + result.debit = CachedTxGetDebit(wallet, wtx, ISMINE_ALL); + result.change = CachedTxGetChange(wallet, wtx); result.time = wtx.GetTxTime(); result.value_map = wtx.mapValue; result.is_coinbase = wtx.IsCoinBase(); @@ -81,16 +82,18 @@ WalletTx MakeWalletTx(CWallet& wallet, const CWalletTx& wtx) WalletTxStatus MakeWalletTxStatus(const CWallet& wallet, const CWalletTx& wtx) { WalletTxStatus result; - result.block_height = wtx.m_confirm.block_height > 0 ? wtx.m_confirm.block_height : std::numeric_limits<int>::max(); - result.blocks_to_maturity = wtx.GetBlocksToMaturity(); - result.depth_in_main_chain = wtx.GetDepthInMainChain(); + result.block_height = + wtx.state<TxStateConfirmed>() ? wtx.state<TxStateConfirmed>()->confirmed_block_height : + wtx.state<TxStateConflicted>() ? wtx.state<TxStateConflicted>()->conflicting_block_height : + std::numeric_limits<int>::max(); + result.blocks_to_maturity = wallet.GetTxBlocksToMaturity(wtx); + result.depth_in_main_chain = wallet.GetTxDepthInMainChain(wtx); result.time_received = wtx.nTimeReceived; result.lock_time = wtx.tx->nLockTime; - result.is_final = wallet.chain().checkFinalTx(*wtx.tx); - result.is_trusted = wtx.IsTrusted(); + result.is_trusted = CachedTxIsTrusted(wallet, wtx); result.is_abandoned = wtx.isAbandoned(); result.is_coinbase = wtx.IsCoinBase(); - result.is_in_main_chain = wtx.IsInMainChain(); + result.is_in_main_chain = wallet.IsTxInMainChain(wtx); return result; } @@ -111,7 +114,7 @@ WalletTxOut MakeWalletTxOut(const CWallet& wallet, class WalletImpl : public Wallet { public: - explicit WalletImpl(const std::shared_ptr<CWallet>& wallet) : m_wallet(wallet) {} + explicit WalletImpl(WalletContext& context, const std::shared_ptr<CWallet>& wallet) : m_context(context), m_wallet(wallet) {} bool encryptWallet(const SecureString& wallet_passphrase) override { @@ -132,7 +135,7 @@ public: bool getNewDestination(const OutputType type, const std::string label, CTxDestination& dest) override { LOCK(m_wallet->cs_wallet); - std::string error; + bilingual_str error; return m_wallet->GetNewDestination(type, label, dest, error); } bool getPubKey(const CScript& script, const CKeyID& address, CPubKey& pub_key) override @@ -199,32 +202,31 @@ public: } return result; } - bool addDestData(const CTxDestination& dest, const std::string& key, const std::string& value) override - { + std::vector<std::string> getAddressReceiveRequests() override { LOCK(m_wallet->cs_wallet); - WalletBatch batch{m_wallet->GetDatabase()}; - return m_wallet->AddDestData(batch, dest, key, value); + return m_wallet->GetAddressReceiveRequests(); } - bool eraseDestData(const CTxDestination& dest, const std::string& key) override - { + bool setAddressReceiveRequest(const CTxDestination& dest, const std::string& id, const std::string& value) override { LOCK(m_wallet->cs_wallet); WalletBatch batch{m_wallet->GetDatabase()}; - return m_wallet->EraseDestData(batch, dest, key); + return m_wallet->SetAddressReceiveRequest(batch, dest, id, value); } - std::vector<std::string> getDestValues(const std::string& prefix) override + bool displayAddress(const CTxDestination& dest) override { LOCK(m_wallet->cs_wallet); - return m_wallet->GetDestValues(prefix); + return m_wallet->DisplayAddress(dest); } - void lockCoin(const COutPoint& output) override + bool lockCoin(const COutPoint& output, const bool write_to_db) override { LOCK(m_wallet->cs_wallet); - return m_wallet->LockCoin(output); + std::unique_ptr<WalletBatch> batch = write_to_db ? std::make_unique<WalletBatch>(m_wallet->GetDatabase()) : nullptr; + return m_wallet->LockCoin(output, batch.get()); } - void unlockCoin(const COutPoint& output) override + bool unlockCoin(const COutPoint& output) override { LOCK(m_wallet->cs_wallet); - return m_wallet->UnlockCoin(output); + std::unique_ptr<WalletBatch> batch = std::make_unique<WalletBatch>(m_wallet->GetDatabase()); + return m_wallet->UnlockCoin(output, batch.get()); } bool isLockedCoin(const COutPoint& output) override { @@ -246,7 +248,7 @@ public: LOCK(m_wallet->cs_wallet); CTransactionRef tx; FeeCalculation fee_calc_out; - if (!m_wallet->CreateTransaction(recipients, tx, fee, change_pos, + if (!CreateTransaction(*m_wallet, recipients, tx, fee, change_pos, fail_reason, coin_control, fee_calc_out, sign)) { return {}; } @@ -354,15 +356,15 @@ public: TransactionError fillPSBT(int sighash_type, bool sign, bool bip32derivs, + size_t* n_signed, PartiallySignedTransaction& psbtx, - bool& complete, - size_t* n_signed) override + bool& complete) override { return m_wallet->FillPSBT(psbtx, complete, sighash_type, sign, bip32derivs, n_signed); } WalletBalances getBalances() override { - const auto bal = m_wallet->GetBalance(); + const auto bal = GetBalance(*m_wallet); WalletBalances result; result.balance = bal.m_mine_trusted; result.unconfirmed_balance = bal.m_mine_untrusted_pending; @@ -385,15 +387,15 @@ public: balances = getBalances(); return true; } - CAmount getBalance() override { return m_wallet->GetBalance().m_mine_trusted; } + CAmount getBalance() override { return GetBalance(*m_wallet).m_mine_trusted; } CAmount getAvailableBalance(const CCoinControl& coin_control) override { - return m_wallet->GetAvailableBalance(&coin_control); + return GetAvailableBalance(*m_wallet, &coin_control); } isminetype txinIsMine(const CTxIn& txin) override { LOCK(m_wallet->cs_wallet); - return m_wallet->IsMine(txin); + return InputIsMine(*m_wallet, txin); } isminetype txoutIsMine(const CTxOut& txout) override { @@ -408,13 +410,13 @@ public: CAmount getCredit(const CTxOut& txout, isminefilter filter) override { LOCK(m_wallet->cs_wallet); - return m_wallet->GetCredit(txout, filter); + return OutputGetCredit(*m_wallet, txout, filter); } CoinsList listCoins() override { LOCK(m_wallet->cs_wallet); CoinsList result; - for (const auto& entry : m_wallet->ListCoins()) { + for (const auto& entry : ListCoins(*m_wallet)) { auto& group = result[entry.first]; for (const auto& coin : entry.second) { group.emplace_back(COutPoint(coin.tx->GetHash(), coin.i), @@ -432,7 +434,7 @@ public: result.emplace_back(); auto it = m_wallet->mapWallet.find(output.hash); if (it != m_wallet->mapWallet.end()) { - int depth = it->second.GetDepthInMainChain(); + int depth = m_wallet->GetTxDepthInMainChain(it->second); if (depth >= 0) { result.back() = MakeWalletTxOut(*m_wallet, it->second, output.n, depth); } @@ -456,12 +458,18 @@ public: unsigned int getConfirmTarget() override { return m_wallet->m_confirm_target; } bool hdEnabled() override { return m_wallet->IsHDEnabled(); } bool canGetAddresses() override { return m_wallet->CanGetAddresses(); } + bool hasExternalSigner() override { return m_wallet->IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER); } bool privateKeysDisabled() override { return m_wallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS); } + bool taprootEnabled() override { + if (m_wallet->IsLegacy()) return false; + auto spk_man = m_wallet->GetScriptPubKeyMan(OutputType::BECH32M, /*internal=*/false); + return spk_man != nullptr; + } OutputType getDefaultAddressType() override { return m_wallet->m_default_address_type; } CAmount getDefaultMaxTxFee() override { return m_wallet->m_default_max_tx_fee; } void remove() override { - RemoveWallet(m_wallet, false /* load_on_start */); + RemoveWallet(m_context, m_wallet, false /* load_on_start */); } bool isLegacy() override { return m_wallet->IsLegacy(); } std::unique_ptr<Handler> handleUnload(UnloadFn fn) override @@ -479,13 +487,13 @@ public: std::unique_ptr<Handler> handleAddressBookChanged(AddressBookChangedFn fn) override { return MakeHandler(m_wallet->NotifyAddressBookChanged.connect( - [fn](CWallet*, const CTxDestination& address, const std::string& label, bool is_mine, - const std::string& purpose, ChangeType status) { fn(address, label, is_mine, purpose, status); })); + [fn](const CTxDestination& address, const std::string& label, bool is_mine, + const std::string& purpose, ChangeType status) { fn(address, label, is_mine, purpose, status); })); } std::unique_ptr<Handler> handleTransactionChanged(TransactionChangedFn fn) override { return MakeHandler(m_wallet->NotifyTransactionChanged.connect( - [fn](CWallet*, const uint256& txid, ChangeType status) { fn(txid, status); })); + [fn](const uint256& txid, ChangeType status) { fn(txid, status); })); } std::unique_ptr<Handler> handleWatchOnlyChanged(WatchOnlyChangedFn fn) override { @@ -497,46 +505,40 @@ public: } CWallet* wallet() override { return m_wallet.get(); } + WalletContext& m_context; std::shared_ptr<CWallet> m_wallet; }; -class WalletClientImpl : public WalletClient +class WalletLoaderImpl : public WalletLoader { public: - WalletClientImpl(Chain& chain, ArgsManager& args) + WalletLoaderImpl(Chain& chain, ArgsManager& args) { m_context.chain = &chain; m_context.args = &args; } - ~WalletClientImpl() override { UnloadWallets(); } + ~WalletLoaderImpl() override { UnloadWallets(m_context); } //! ChainClient methods void registerRpcs() override { for (const CRPCCommand& command : GetWalletRPCCommands()) { m_rpc_commands.emplace_back(command.category, command.name, [this, &command](const JSONRPCRequest& request, UniValue& result, bool last_handler) { - return command.actor({request, m_context}, result, last_handler); + JSONRPCRequest wallet_request = request; + wallet_request.context = &m_context; + return command.actor(wallet_request, result, last_handler); }, command.argNames, command.unique_id); m_rpc_handlers.emplace_back(m_context.chain->handleRpc(m_rpc_commands.back())); } - -#ifdef ENABLE_EXTERNAL_SIGNER - for (const CRPCCommand& command : GetSignerRPCCommands()) { - m_rpc_commands.emplace_back(command.category, command.name, [this, &command](const JSONRPCRequest& request, UniValue& result, bool last_handler) { - return command.actor({request, m_context}, result, last_handler); - }, command.argNames, command.unique_id); - m_rpc_handlers.emplace_back(m_context.chain->handleRpc(m_rpc_commands.back())); - } -#endif } - bool verify() override { return VerifyWallets(*m_context.chain); } - bool load() override { return LoadWallets(*m_context.chain); } - void start(CScheduler& scheduler) override { return StartWallets(scheduler, *Assert(m_context.args)); } - void flush() override { return FlushWallets(); } - void stop() override { return StopWallets(); } + bool verify() override { return VerifyWallets(m_context); } + bool load() override { return LoadWallets(m_context); } + void start(CScheduler& scheduler) override { return StartWallets(m_context, scheduler); } + void flush() override { return FlushWallets(m_context); } + void stop() override { return StopWallets(m_context); } void setMockTime(int64_t time) override { return SetMockTime(time); } - //! WalletClient methods + //! WalletLoader methods 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 { std::shared_ptr<CWallet> wallet; @@ -545,39 +547,46 @@ public: options.require_create = true; options.create_flags = wallet_creation_flags; options.create_passphrase = passphrase; - return MakeWallet(CreateWallet(*m_context.chain, name, true /* load_on_start */, options, status, error, warnings)); + return MakeWallet(m_context, CreateWallet(m_context, name, true /* load_on_start */, options, status, error, warnings)); } std::unique_ptr<Wallet> loadWallet(const std::string& name, bilingual_str& error, std::vector<bilingual_str>& warnings) override { DatabaseOptions options; DatabaseStatus status; options.require_existing = true; - return MakeWallet(LoadWallet(*m_context.chain, name, true /* load_on_start */, options, status, error, warnings)); + return MakeWallet(m_context, LoadWallet(m_context, name, true /* load_on_start */, options, status, error, warnings)); + } + std::unique_ptr<Wallet> restoreWallet(const fs::path& backup_file, const std::string& wallet_name, bilingual_str& error, std::vector<bilingual_str>& warnings) override + { + DatabaseStatus status; + + return MakeWallet(m_context, RestoreWallet(m_context, backup_file, wallet_name, /*load_on_start=*/true, status, error, warnings)); } std::string getWalletDir() override { - return GetWalletDir().string(); + return fs::PathToString(GetWalletDir()); } std::vector<std::string> listWalletDir() override { std::vector<std::string> paths; for (auto& path : ListDatabases(GetWalletDir())) { - paths.push_back(path.string()); + paths.push_back(fs::PathToString(path)); } return paths; } std::vector<std::unique_ptr<Wallet>> getWallets() override { std::vector<std::unique_ptr<Wallet>> wallets; - for (const auto& wallet : GetWallets()) { - wallets.emplace_back(MakeWallet(wallet)); + for (const auto& wallet : GetWallets(m_context)) { + wallets.emplace_back(MakeWallet(m_context, wallet)); } return wallets; } std::unique_ptr<Handler> handleLoadWallet(LoadWalletFn fn) override { - return HandleLoadWallet(std::move(fn)); + return HandleLoadWallet(m_context, std::move(fn)); } + WalletContext* context() override { return &m_context; } WalletContext m_context; const std::vector<std::string> m_wallet_filenames; @@ -588,10 +597,10 @@ public: } // namespace wallet namespace interfaces { -std::unique_ptr<Wallet> MakeWallet(const std::shared_ptr<CWallet>& wallet) { return wallet ? MakeUnique<wallet::WalletImpl>(wallet) : nullptr; } +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; } -std::unique_ptr<WalletClient> MakeWalletClient(Chain& chain, ArgsManager& args) +std::unique_ptr<WalletLoader> MakeWalletLoader(Chain& chain, ArgsManager& args) { - return MakeUnique<wallet::WalletClientImpl>(chain, args); + return std::make_unique<wallet::WalletLoaderImpl>(chain, args); } } // namespace interfaces |