aboutsummaryrefslogtreecommitdiff
path: root/src/interface/wallet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/interface/wallet.cpp')
-rw-r--r--src/interface/wallet.cpp212
1 files changed, 212 insertions, 0 deletions
diff --git a/src/interface/wallet.cpp b/src/interface/wallet.cpp
index 01639aa37f..8dae7ac547 100644
--- a/src/interface/wallet.cpp
+++ b/src/interface/wallet.cpp
@@ -4,7 +4,21 @@
#include <interface/wallet.h>
+#include <amount.h>
+#include <chain.h>
+#include <consensus/validation.h>
#include <interface/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 <uint256.h>
+#include <validation.h>
+#include <wallet/feebumper.h>
#include <wallet/wallet.h>
#include <memory>
@@ -12,15 +26,213 @@
namespace interface {
namespace {
+class PendingWalletTxImpl : public PendingWalletTx
+{
+public:
+ PendingWalletTxImpl(CWallet& wallet) : m_wallet(wallet), m_key(&wallet) {}
+
+ const CTransaction& get() override { return *m_tx; }
+
+ int64_t getVirtualSize() override { return GetVirtualTransactionSize(*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
{
public:
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(); }
+ 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.hash, output.n);
+ }
+ 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,
+ CAmount& fee,
+ std::string& fail_reason) override
+ {
+ LOCK2(cs_main, m_wallet.cs_wallet);
+ auto pending = MakeUnique<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 uint256& txid) override { return m_wallet.TransactionCanBeAbandoned(txid); }
+ bool abandonTransaction(const uint256& txid) override
+ {
+ LOCK2(cs_main, m_wallet.cs_wallet);
+ return m_wallet.AbandonTransaction(txid);
+ }
+ bool transactionCanBeBumped(const uint256& txid) override
+ {
+ return feebumper::TransactionCanBeBumped(&m_wallet, txid);
+ }
+ bool createBumpTransaction(const uint256& txid,
+ const CCoinControl& coin_control,
+ CAmount total_fee,
+ std::vector<std::string>& errors,
+ CAmount& old_fee,
+ CAmount& new_fee,
+ CMutableTransaction& mtx) override
+ {
+ return feebumper::CreateTransaction(&m_wallet, txid, coin_control, total_fee, errors, old_fee, new_fee, mtx) ==
+ feebumper::Result::OK;
+ }
+ bool signBumpTransaction(CMutableTransaction& mtx) override { return feebumper::SignTransaction(&m_wallet, mtx); }
+ bool commitBumpTransaction(const uint256& txid,
+ CMutableTransaction&& mtx,
+ std::vector<std::string>& errors,
+ uint256& bumped_txid) override
+ {
+ return feebumper::CommitTransaction(&m_wallet, txid, std::move(mtx), errors, bumped_txid) ==
+ feebumper::Result::OK;
+ }
+ 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;
+ }
+ CAmount getBalance() override { return m_wallet.GetBalance(); }
+ CAmount getAvailableBalance(const CCoinControl& coin_control) override
+ {
+ return m_wallet.GetAvailableBalance(&coin_control);
+ }
+ bool hdEnabled() override { return m_wallet.IsHDEnabled(); }
+ OutputType getDefaultAddressType() override { return m_wallet.m_default_address_type; }
+ OutputType getDefaultChangeType() override { return m_wallet.m_default_change_type; }
std::unique_ptr<Handler> handleShowProgress(ShowProgressFn fn) override
{
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 uint256& txid, ChangeType status) { fn(txid, status); }));
+ }
+ std::unique_ptr<Handler> handleWatchOnlyChanged(WatchOnlyChangedFn fn) override
+ {
+ return MakeHandler(m_wallet.NotifyWatchonlyChanged.connect(fn));
+ }
CWallet& m_wallet;
};