|
4 | 4 |
|
5 | 5 | #include <interface/wallet.h>
|
6 | 6 |
|
| 7 | +#include <amount.h> |
| 8 | +#include <chain.h> |
| 9 | +#include <consensus/validation.h> |
7 | 10 | #include <interface/handler.h>
|
| 11 | +#include <net.h> |
| 12 | +#include <policy/policy.h> |
| 13 | +#include <primitives/transaction.h> |
| 14 | +#include <script/ismine.h> |
| 15 | +#include <script/standard.h> |
| 16 | +#include <support/allocators/secure.h> |
| 17 | +#include <sync.h> |
| 18 | +#include <ui_interface.h> |
| 19 | +#include <uint256.h> |
| 20 | +#include <validation.h> |
| 21 | +#include <wallet/feebumper.h> |
8 | 22 | #include <wallet/wallet.h>
|
9 | 23 |
|
10 | 24 | #include <memory>
|
11 | 25 |
|
12 | 26 | namespace interface {
|
13 | 27 | namespace {
|
14 | 28 |
|
| 29 | +class PendingWalletTxImpl : public PendingWalletTx |
| 30 | +{ |
| 31 | +public: |
| 32 | + PendingWalletTxImpl(CWallet& wallet) : m_wallet(wallet), m_key(&wallet) {} |
| 33 | + |
| 34 | + const CTransaction& get() override { return *m_tx; } |
| 35 | + |
| 36 | + int64_t getVirtualSize() override { return GetVirtualTransactionSize(*m_tx); } |
| 37 | + |
| 38 | + bool commit(WalletValueMap value_map, |
| 39 | + WalletOrderForm order_form, |
| 40 | + std::string from_account, |
| 41 | + std::string& reject_reason) override |
| 42 | + { |
| 43 | + LOCK2(cs_main, m_wallet.cs_wallet); |
| 44 | + CValidationState state; |
| 45 | + if (!m_wallet.CommitTransaction(m_tx, std::move(value_map), std::move(order_form), std::move(from_account), m_key, g_connman.get(), state)) { |
| 46 | + reject_reason = state.GetRejectReason(); |
| 47 | + return false; |
| 48 | + } |
| 49 | + return true; |
| 50 | + } |
| 51 | + |
| 52 | + CTransactionRef m_tx; |
| 53 | + CWallet& m_wallet; |
| 54 | + CReserveKey m_key; |
| 55 | +}; |
| 56 | + |
15 | 57 | class WalletImpl : public Wallet
|
16 | 58 | {
|
17 | 59 | public:
|
18 | 60 | WalletImpl(CWallet& wallet) : m_wallet(wallet) {}
|
19 | 61 |
|
| 62 | + bool encryptWallet(const SecureString& wallet_passphrase) override |
| 63 | + { |
| 64 | + return m_wallet.EncryptWallet(wallet_passphrase); |
| 65 | + } |
| 66 | + bool isCrypted() override { return m_wallet.IsCrypted(); } |
| 67 | + bool lock() override { return m_wallet.Lock(); } |
| 68 | + bool unlock(const SecureString& wallet_passphrase) override { return m_wallet.Unlock(wallet_passphrase); } |
| 69 | + bool isLocked() override { return m_wallet.IsLocked(); } |
| 70 | + bool changeWalletPassphrase(const SecureString& old_wallet_passphrase, |
| 71 | + const SecureString& new_wallet_passphrase) override |
| 72 | + { |
| 73 | + return m_wallet.ChangeWalletPassphrase(old_wallet_passphrase, new_wallet_passphrase); |
| 74 | + } |
| 75 | + bool backupWallet(const std::string& filename) override { return m_wallet.BackupWallet(filename); } |
| 76 | + std::string getWalletName() override { return m_wallet.GetName(); } |
| 77 | + bool getPubKey(const CKeyID& address, CPubKey& pub_key) override { return m_wallet.GetPubKey(address, pub_key); } |
| 78 | + bool getPrivKey(const CKeyID& address, CKey& key) override { return m_wallet.GetKey(address, key); } |
| 79 | + bool isSpendable(const CTxDestination& dest) override { return IsMine(m_wallet, dest) & ISMINE_SPENDABLE; } |
| 80 | + bool haveWatchOnly() override { return m_wallet.HaveWatchOnly(); }; |
| 81 | + bool setAddressBook(const CTxDestination& dest, const std::string& name, const std::string& purpose) override |
| 82 | + { |
| 83 | + return m_wallet.SetAddressBook(dest, name, purpose); |
| 84 | + } |
| 85 | + bool getAddress(const CTxDestination& dest, std::string* name, isminetype* is_mine) override |
| 86 | + { |
| 87 | + LOCK(m_wallet.cs_wallet); |
| 88 | + auto it = m_wallet.mapAddressBook.find(dest); |
| 89 | + if (it == m_wallet.mapAddressBook.end()) { |
| 90 | + return false; |
| 91 | + } |
| 92 | + if (name) { |
| 93 | + *name = it->second.name; |
| 94 | + } |
| 95 | + if (is_mine) { |
| 96 | + *is_mine = IsMine(m_wallet, dest); |
| 97 | + } |
| 98 | + return true; |
| 99 | + } |
| 100 | + bool addDestData(const CTxDestination& dest, const std::string& key, const std::string& value) override |
| 101 | + { |
| 102 | + LOCK(m_wallet.cs_wallet); |
| 103 | + return m_wallet.AddDestData(dest, key, value); |
| 104 | + } |
| 105 | + bool eraseDestData(const CTxDestination& dest, const std::string& key) override |
| 106 | + { |
| 107 | + LOCK(m_wallet.cs_wallet); |
| 108 | + return m_wallet.EraseDestData(dest, key); |
| 109 | + } |
| 110 | + std::vector<std::string> getDestValues(const std::string& prefix) override |
| 111 | + { |
| 112 | + return m_wallet.GetDestValues(prefix); |
| 113 | + } |
| 114 | + void lockCoin(const COutPoint& output) override |
| 115 | + { |
| 116 | + LOCK2(cs_main, m_wallet.cs_wallet); |
| 117 | + return m_wallet.LockCoin(output); |
| 118 | + } |
| 119 | + void unlockCoin(const COutPoint& output) override |
| 120 | + { |
| 121 | + LOCK2(cs_main, m_wallet.cs_wallet); |
| 122 | + return m_wallet.UnlockCoin(output); |
| 123 | + } |
| 124 | + bool isLockedCoin(const COutPoint& output) override |
| 125 | + { |
| 126 | + LOCK2(cs_main, m_wallet.cs_wallet); |
| 127 | + return m_wallet.IsLockedCoin(output.hash, output.n); |
| 128 | + } |
| 129 | + void listLockedCoins(std::vector<COutPoint>& outputs) override |
| 130 | + { |
| 131 | + LOCK2(cs_main, m_wallet.cs_wallet); |
| 132 | + return m_wallet.ListLockedCoins(outputs); |
| 133 | + } |
| 134 | + std::unique_ptr<PendingWalletTx> createTransaction(const std::vector<CRecipient>& recipients, |
| 135 | + const CCoinControl& coin_control, |
| 136 | + bool sign, |
| 137 | + int& change_pos, |
| 138 | + CAmount& fee, |
| 139 | + std::string& fail_reason) override |
| 140 | + { |
| 141 | + LOCK2(cs_main, m_wallet.cs_wallet); |
| 142 | + auto pending = MakeUnique<PendingWalletTxImpl>(m_wallet); |
| 143 | + if (!m_wallet.CreateTransaction(recipients, pending->m_tx, pending->m_key, fee, change_pos, |
| 144 | + fail_reason, coin_control, sign)) { |
| 145 | + return {}; |
| 146 | + } |
| 147 | + return std::move(pending); |
| 148 | + } |
| 149 | + bool transactionCanBeAbandoned(const uint256& txid) override { return m_wallet.TransactionCanBeAbandoned(txid); } |
| 150 | + bool abandonTransaction(const uint256& txid) override |
| 151 | + { |
| 152 | + LOCK2(cs_main, m_wallet.cs_wallet); |
| 153 | + return m_wallet.AbandonTransaction(txid); |
| 154 | + } |
| 155 | + bool transactionCanBeBumped(const uint256& txid) override |
| 156 | + { |
| 157 | + return feebumper::TransactionCanBeBumped(&m_wallet, txid); |
| 158 | + } |
| 159 | + bool createBumpTransaction(const uint256& txid, |
| 160 | + const CCoinControl& coin_control, |
| 161 | + CAmount total_fee, |
| 162 | + std::vector<std::string>& errors, |
| 163 | + CAmount& old_fee, |
| 164 | + CAmount& new_fee, |
| 165 | + CMutableTransaction& mtx) override |
| 166 | + { |
| 167 | + return feebumper::CreateTransaction(&m_wallet, txid, coin_control, total_fee, errors, old_fee, new_fee, mtx) == |
| 168 | + feebumper::Result::OK; |
| 169 | + } |
| 170 | + bool signBumpTransaction(CMutableTransaction& mtx) override { return feebumper::SignTransaction(&m_wallet, mtx); } |
| 171 | + bool commitBumpTransaction(const uint256& txid, |
| 172 | + CMutableTransaction&& mtx, |
| 173 | + std::vector<std::string>& errors, |
| 174 | + uint256& bumped_txid) override |
| 175 | + { |
| 176 | + return feebumper::CommitTransaction(&m_wallet, txid, std::move(mtx), errors, bumped_txid) == |
| 177 | + feebumper::Result::OK; |
| 178 | + } |
| 179 | + WalletBalances getBalances() override |
| 180 | + { |
| 181 | + WalletBalances result; |
| 182 | + result.balance = m_wallet.GetBalance(); |
| 183 | + result.unconfirmed_balance = m_wallet.GetUnconfirmedBalance(); |
| 184 | + result.immature_balance = m_wallet.GetImmatureBalance(); |
| 185 | + result.have_watch_only = m_wallet.HaveWatchOnly(); |
| 186 | + if (result.have_watch_only) { |
| 187 | + result.watch_only_balance = m_wallet.GetWatchOnlyBalance(); |
| 188 | + result.unconfirmed_watch_only_balance = m_wallet.GetUnconfirmedWatchOnlyBalance(); |
| 189 | + result.immature_watch_only_balance = m_wallet.GetImmatureWatchOnlyBalance(); |
| 190 | + } |
| 191 | + return result; |
| 192 | + } |
| 193 | + bool tryGetBalances(WalletBalances& balances, int& num_blocks) override |
| 194 | + { |
| 195 | + TRY_LOCK(cs_main, locked_chain); |
| 196 | + if (!locked_chain) return false; |
| 197 | + TRY_LOCK(m_wallet.cs_wallet, locked_wallet); |
| 198 | + if (!locked_wallet) { |
| 199 | + return false; |
| 200 | + } |
| 201 | + balances = getBalances(); |
| 202 | + num_blocks = ::chainActive.Height(); |
| 203 | + return true; |
| 204 | + } |
| 205 | + CAmount getBalance() override { return m_wallet.GetBalance(); } |
| 206 | + CAmount getAvailableBalance(const CCoinControl& coin_control) override |
| 207 | + { |
| 208 | + return m_wallet.GetAvailableBalance(&coin_control); |
| 209 | + } |
| 210 | + bool hdEnabled() override { return m_wallet.IsHDEnabled(); } |
| 211 | + OutputType getDefaultAddressType() override { return m_wallet.m_default_address_type; } |
| 212 | + OutputType getDefaultChangeType() override { return m_wallet.m_default_change_type; } |
20 | 213 | std::unique_ptr<Handler> handleShowProgress(ShowProgressFn fn) override
|
21 | 214 | {
|
22 | 215 | return MakeHandler(m_wallet.ShowProgress.connect(fn));
|
23 | 216 | }
|
| 217 | + std::unique_ptr<Handler> handleStatusChanged(StatusChangedFn fn) override |
| 218 | + { |
| 219 | + return MakeHandler(m_wallet.NotifyStatusChanged.connect([fn](CCryptoKeyStore*) { fn(); })); |
| 220 | + } |
| 221 | + std::unique_ptr<Handler> handleAddressBookChanged(AddressBookChangedFn fn) override |
| 222 | + { |
| 223 | + return MakeHandler(m_wallet.NotifyAddressBookChanged.connect( |
| 224 | + [fn](CWallet*, const CTxDestination& address, const std::string& label, bool is_mine, |
| 225 | + const std::string& purpose, ChangeType status) { fn(address, label, is_mine, purpose, status); })); |
| 226 | + } |
| 227 | + std::unique_ptr<Handler> handleTransactionChanged(TransactionChangedFn fn) override |
| 228 | + { |
| 229 | + return MakeHandler(m_wallet.NotifyTransactionChanged.connect( |
| 230 | + [fn, this](CWallet*, const uint256& txid, ChangeType status) { fn(txid, status); })); |
| 231 | + } |
| 232 | + std::unique_ptr<Handler> handleWatchOnlyChanged(WatchOnlyChangedFn fn) override |
| 233 | + { |
| 234 | + return MakeHandler(m_wallet.NotifyWatchonlyChanged.connect(fn)); |
| 235 | + } |
24 | 236 |
|
25 | 237 | CWallet& m_wallet;
|
26 | 238 | };
|
|
0 commit comments