Changeset View
Changeset View
Standalone View
Standalone View
src/interfaces/wallet.cpp
// Copyright (c) 2018 The Bitcoin Core developers | // Copyright (c) 2018 The Bitcoin Core developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include <interfaces/wallet.h> | #include <interfaces/wallet.h> | ||||
#include <amount.h> | |||||
#include <chain.h> | |||||
#include <consensus/validation.h> | |||||
#include <interfaces/handler.h> | #include <interfaces/handler.h> | ||||
#include <net.h> | |||||
#include <policy/policy.h> | |||||
#include <primitives/transaction.h> | |||||
#include <script/ismine.h> | |||||
#include <script/standard.h> | |||||
#include <support/allocators/secure.h> | |||||
#include <sync.h> | |||||
#include <ui_interface.h> | |||||
#include <validation.h> | |||||
#include <wallet/wallet.h> | #include <wallet/wallet.h> | ||||
#include <memory> | #include <memory> | ||||
namespace interfaces { | namespace interfaces { | ||||
namespace { | namespace { | ||||
class PendingWalletTxImpl : public PendingWalletTx { | |||||
public: | |||||
PendingWalletTxImpl(CWallet &wallet) | |||||
: m_wallet(wallet), m_key(&wallet) {} | |||||
const CTransaction &get() override { return *m_tx; } | |||||
bool commit(WalletValueMap value_map, WalletOrderForm order_form, | |||||
std::string from_account, | |||||
std::string &reject_reason) override { | |||||
LOCK2(cs_main, m_wallet.cs_wallet); | |||||
CValidationState state; | |||||
if (!m_wallet.CommitTransaction( | |||||
m_tx, std::move(value_map), std::move(order_form), | |||||
std::move(from_account), m_key, g_connman.get(), state)) { | |||||
reject_reason = state.GetRejectReason(); | |||||
return false; | |||||
} | |||||
return true; | |||||
} | |||||
CTransactionRef m_tx; | |||||
CWallet &m_wallet; | |||||
CReserveKey m_key; | |||||
}; | |||||
class WalletImpl : public Wallet { | class WalletImpl : public Wallet { | ||||
public: | public: | ||||
WalletImpl(CWallet &wallet) : m_wallet(wallet) {} | WalletImpl(CWallet &wallet) : m_wallet(wallet) {} | ||||
bool encryptWallet(const SecureString &wallet_passphrase) override { | |||||
return m_wallet.EncryptWallet(wallet_passphrase); | |||||
} | |||||
bool isCrypted() override { return m_wallet.IsCrypted(); } | |||||
bool lock() override { return m_wallet.Lock(); } | |||||
bool unlock(const SecureString &wallet_passphrase) override { | |||||
return m_wallet.Unlock(wallet_passphrase); | |||||
} | |||||
bool isLocked() override { return m_wallet.IsLocked(); } | |||||
bool changeWalletPassphrase( | |||||
const SecureString &old_wallet_passphrase, | |||||
const SecureString &new_wallet_passphrase) override { | |||||
return m_wallet.ChangeWalletPassphrase(old_wallet_passphrase, | |||||
new_wallet_passphrase); | |||||
} | |||||
bool backupWallet(const std::string &filename) override { | |||||
return m_wallet.BackupWallet(filename); | |||||
} | |||||
std::string getWalletName() override { return m_wallet.GetName(); } | |||||
const CChainParams &getChainParams() override { | |||||
return m_wallet.chainParams; | |||||
} | |||||
bool getPubKey(const CKeyID &address, CPubKey &pub_key) override { | |||||
return m_wallet.GetPubKey(address, pub_key); | |||||
} | |||||
bool getPrivKey(const CKeyID &address, CKey &key) override { | |||||
return m_wallet.GetKey(address, key); | |||||
} | |||||
bool isSpendable(const CTxDestination &dest) override { | |||||
return IsMine(m_wallet, dest) & ISMINE_SPENDABLE; | |||||
} | |||||
bool haveWatchOnly() override { return m_wallet.HaveWatchOnly(); }; | |||||
bool setAddressBook(const CTxDestination &dest, const std::string &name, | |||||
const std::string &purpose) override { | |||||
return m_wallet.SetAddressBook(dest, name, purpose); | |||||
} | |||||
bool getAddress(const CTxDestination &dest, std::string *name, | |||||
isminetype *is_mine) override { | |||||
LOCK(m_wallet.cs_wallet); | |||||
auto it = m_wallet.mapAddressBook.find(dest); | |||||
if (it == m_wallet.mapAddressBook.end()) { | |||||
return false; | |||||
} | |||||
if (name) { | |||||
*name = it->second.name; | |||||
} | |||||
if (is_mine) { | |||||
*is_mine = IsMine(m_wallet, dest); | |||||
} | |||||
return true; | |||||
} | |||||
bool addDestData(const CTxDestination &dest, const std::string &key, | |||||
const std::string &value) override { | |||||
LOCK(m_wallet.cs_wallet); | |||||
return m_wallet.AddDestData(dest, key, value); | |||||
} | |||||
bool eraseDestData(const CTxDestination &dest, | |||||
const std::string &key) override { | |||||
LOCK(m_wallet.cs_wallet); | |||||
return m_wallet.EraseDestData(dest, key); | |||||
} | |||||
std::vector<std::string> | |||||
getDestValues(const std::string &prefix) override { | |||||
return m_wallet.GetDestValues(prefix); | |||||
} | |||||
void lockCoin(const COutPoint &output) override { | |||||
LOCK2(cs_main, m_wallet.cs_wallet); | |||||
return m_wallet.LockCoin(output); | |||||
} | |||||
void unlockCoin(const COutPoint &output) override { | |||||
LOCK2(cs_main, m_wallet.cs_wallet); | |||||
return m_wallet.UnlockCoin(output); | |||||
} | |||||
bool isLockedCoin(const COutPoint &output) override { | |||||
LOCK2(cs_main, m_wallet.cs_wallet); | |||||
return m_wallet.IsLockedCoin(output.GetTxId(), output.GetN()); | |||||
} | |||||
void listLockedCoins(std::vector<COutPoint> &outputs) override { | |||||
LOCK2(cs_main, m_wallet.cs_wallet); | |||||
return m_wallet.ListLockedCoins(outputs); | |||||
} | |||||
std::unique_ptr<PendingWalletTx> | |||||
createTransaction(const std::vector<CRecipient> &recipients, | |||||
const CCoinControl &coin_control, bool sign, | |||||
int &change_pos, Amount &fee, | |||||
std::string &fail_reason) override { | |||||
LOCK2(cs_main, m_wallet.cs_wallet); | |||||
auto pending = std::make_unique<PendingWalletTxImpl>(m_wallet); | |||||
if (!m_wallet.CreateTransaction(recipients, pending->m_tx, | |||||
pending->m_key, fee, change_pos, | |||||
fail_reason, coin_control, sign)) { | |||||
return {}; | |||||
} | |||||
return std::move(pending); | |||||
} | |||||
bool transactionCanBeAbandoned(const TxId &txid) override { | |||||
return m_wallet.TransactionCanBeAbandoned(txid); | |||||
} | |||||
bool abandonTransaction(const TxId &txid) override { | |||||
LOCK2(cs_main, m_wallet.cs_wallet); | |||||
return m_wallet.AbandonTransaction(txid); | |||||
} | |||||
WalletBalances getBalances() override { | |||||
WalletBalances result; | |||||
result.balance = m_wallet.GetBalance(); | |||||
result.unconfirmed_balance = m_wallet.GetUnconfirmedBalance(); | |||||
result.immature_balance = m_wallet.GetImmatureBalance(); | |||||
result.have_watch_only = m_wallet.HaveWatchOnly(); | |||||
if (result.have_watch_only) { | |||||
result.watch_only_balance = m_wallet.GetWatchOnlyBalance(); | |||||
result.unconfirmed_watch_only_balance = | |||||
m_wallet.GetUnconfirmedWatchOnlyBalance(); | |||||
result.immature_watch_only_balance = | |||||
m_wallet.GetImmatureWatchOnlyBalance(); | |||||
} | |||||
return result; | |||||
} | |||||
bool tryGetBalances(WalletBalances &balances, | |||||
int &num_blocks) override { | |||||
TRY_LOCK(cs_main, locked_chain); | |||||
if (!locked_chain) { | |||||
return false; | |||||
} | |||||
TRY_LOCK(m_wallet.cs_wallet, locked_wallet); | |||||
if (!locked_wallet) { | |||||
return false; | |||||
} | |||||
balances = getBalances(); | |||||
num_blocks = ::chainActive.Height(); | |||||
return true; | |||||
} | |||||
Amount getBalance() override { return m_wallet.GetBalance(); } | |||||
Amount getAvailableBalance(const CCoinControl &coin_control) override { | |||||
return m_wallet.GetAvailableBalance(&coin_control); | |||||
} | |||||
bool hdEnabled() override { return m_wallet.IsHDEnabled(); } | |||||
std::unique_ptr<Handler> | std::unique_ptr<Handler> | ||||
handleShowProgress(ShowProgressFn fn) override { | handleShowProgress(ShowProgressFn fn) override { | ||||
return MakeHandler(m_wallet.ShowProgress.connect(fn)); | return MakeHandler(m_wallet.ShowProgress.connect(fn)); | ||||
} | } | ||||
std::unique_ptr<Handler> | |||||
handleStatusChanged(StatusChangedFn fn) override { | |||||
return MakeHandler(m_wallet.NotifyStatusChanged.connect( | |||||
[fn](CCryptoKeyStore *) { fn(); })); | |||||
} | |||||
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); | |||||
})); | |||||
} | |||||
std::unique_ptr<Handler> | |||||
handleTransactionChanged(TransactionChangedFn fn) override { | |||||
return MakeHandler(m_wallet.NotifyTransactionChanged.connect( | |||||
[fn, this](CWallet *, const TxId &txid, ChangeType status) { | |||||
fn(txid, status); | |||||
})); | |||||
} | |||||
std::unique_ptr<Handler> | |||||
handleWatchOnlyChanged(WatchOnlyChangedFn fn) override { | |||||
return MakeHandler(m_wallet.NotifyWatchonlyChanged.connect(fn)); | |||||
} | |||||
CWallet &m_wallet; | CWallet &m_wallet; | ||||
}; | }; | ||||
} // namespace | } // namespace | ||||
std::unique_ptr<Wallet> MakeWallet(CWallet &wallet) { | std::unique_ptr<Wallet> MakeWallet(CWallet &wallet) { | ||||
return std::make_unique<WalletImpl>(wallet); | return std::make_unique<WalletImpl>(wallet); | ||||
} | } | ||||
} // namespace interfaces | } // namespace interfaces |