Remove most direct bitcoin calls from qt/walletmodel.cpp
This commit is contained in:
parent
90d4640b7e
commit
a0704a8996
18 changed files with 588 additions and 330 deletions
|
@ -5,6 +5,7 @@
|
|||
#include <interface/node.h>
|
||||
|
||||
#include <addrdb.h>
|
||||
#include <amount.h>
|
||||
#include <chain.h>
|
||||
#include <chainparams.h>
|
||||
#include <init.h>
|
||||
|
@ -28,6 +29,7 @@
|
|||
#include <config/bitcoin-config.h>
|
||||
#endif
|
||||
#ifdef ENABLE_WALLET
|
||||
#include <wallet/wallet.h>
|
||||
#define CHECK_WALLET(x) x
|
||||
#else
|
||||
#define CHECK_WALLET(x) throw std::logic_error("Wallet function called in non-wallet build.")
|
||||
|
@ -37,8 +39,6 @@
|
|||
#include <boost/thread/thread.hpp>
|
||||
#include <univalue.h>
|
||||
|
||||
class CWallet;
|
||||
|
||||
namespace interface {
|
||||
namespace {
|
||||
|
||||
|
@ -185,6 +185,8 @@ class NodeImpl : public Node
|
|||
}
|
||||
}
|
||||
bool getNetworkActive() override { return g_connman && g_connman->GetNetworkActive(); }
|
||||
unsigned int getTxConfirmTarget() override { CHECK_WALLET(return ::nTxConfirmTarget); }
|
||||
CAmount getMaxTxFee() override { return ::maxTxFee; }
|
||||
UniValue executeRpc(const std::string& command, const UniValue& params, const std::string& uri) override
|
||||
{
|
||||
JSONRPCRequest req;
|
||||
|
@ -196,6 +198,18 @@ class NodeImpl : public Node
|
|||
std::vector<std::string> listRpcCommands() override { return ::tableRPC.listCommands(); }
|
||||
void rpcSetTimerInterfaceIfUnset(RPCTimerInterface* iface) override { RPCSetTimerInterfaceIfUnset(iface); }
|
||||
void rpcUnsetTimerInterface(RPCTimerInterface* iface) override { RPCUnsetTimerInterface(iface); }
|
||||
std::vector<std::unique_ptr<Wallet>> getWallets() override
|
||||
{
|
||||
#ifdef ENABLE_WALLET
|
||||
std::vector<std::unique_ptr<Wallet>> wallets;
|
||||
for (CWalletRef wallet : ::vpwallets) {
|
||||
wallets.emplace_back(MakeWallet(*wallet));
|
||||
}
|
||||
return wallets;
|
||||
#else
|
||||
throw std::logic_error("Node::getWallets() called in non-wallet build.");
|
||||
#endif
|
||||
}
|
||||
std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn) override
|
||||
{
|
||||
return MakeHandler(::uiInterface.InitMessage.connect(fn));
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#define BITCOIN_INTERFACE_NODE_H
|
||||
|
||||
#include <addrdb.h> // For banmap_t
|
||||
#include <amount.h> // For CAmount
|
||||
#include <init.h> // For HelpMessageMode
|
||||
#include <net.h> // For CConnman::NumConnections
|
||||
#include <netaddress.h> // For Network
|
||||
|
@ -141,6 +142,12 @@ public:
|
|||
//! Get network active.
|
||||
virtual bool getNetworkActive() = 0;
|
||||
|
||||
//! Get tx confirm target.
|
||||
virtual unsigned int getTxConfirmTarget() = 0;
|
||||
|
||||
//! Get max tx fee.
|
||||
virtual CAmount getMaxTxFee() = 0;
|
||||
|
||||
//! Execute rpc command.
|
||||
virtual UniValue executeRpc(const std::string& command, const UniValue& params, const std::string& uri) = 0;
|
||||
|
||||
|
@ -153,6 +160,9 @@ public:
|
|||
//! Unset RPC timer interface.
|
||||
virtual void rpcUnsetTimerInterface(RPCTimerInterface* iface) = 0;
|
||||
|
||||
//! Return interfaces for accessing wallets (if any).
|
||||
virtual std::vector<std::unique_ptr<Wallet>> getWallets() = 0;
|
||||
|
||||
//! Register handler for init messages.
|
||||
using InitMessageFn = std::function<void(const std::string& message)>;
|
||||
virtual std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn) = 0;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -5,15 +5,34 @@
|
|||
#ifndef BITCOIN_INTERFACE_WALLET_H
|
||||
#define BITCOIN_INTERFACE_WALLET_H
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <amount.h> // For CAmount
|
||||
#include <script/ismine.h> // For isminefilter, isminetype
|
||||
#include <script/standard.h> // For CTxDestination
|
||||
#include <support/allocators/secure.h> // For SecureString
|
||||
#include <ui_interface.h> // For ChangeType
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
class CCoinControl;
|
||||
class CKey;
|
||||
class CWallet;
|
||||
enum class OutputType;
|
||||
struct CRecipient;
|
||||
|
||||
namespace interface {
|
||||
|
||||
class Handler;
|
||||
class PendingWalletTx;
|
||||
struct WalletBalances;
|
||||
|
||||
using WalletOrderForm = std::vector<std::pair<std::string, std::string>>;
|
||||
using WalletValueMap = std::map<std::string, std::string>;
|
||||
|
||||
//! Interface for accessing a wallet.
|
||||
class Wallet
|
||||
|
@ -21,9 +40,190 @@ class Wallet
|
|||
public:
|
||||
virtual ~Wallet() {}
|
||||
|
||||
//! Encrypt wallet.
|
||||
virtual bool encryptWallet(const SecureString& wallet_passphrase) = 0;
|
||||
|
||||
//! Return whether wallet is encrypted.
|
||||
virtual bool isCrypted() = 0;
|
||||
|
||||
//! Lock wallet.
|
||||
virtual bool lock() = 0;
|
||||
|
||||
//! Unlock wallet.
|
||||
virtual bool unlock(const SecureString& wallet_passphrase) = 0;
|
||||
|
||||
//! Return whether wallet is locked.
|
||||
virtual bool isLocked() = 0;
|
||||
|
||||
//! Change wallet passphrase.
|
||||
virtual bool changeWalletPassphrase(const SecureString& old_wallet_passphrase,
|
||||
const SecureString& new_wallet_passphrase) = 0;
|
||||
|
||||
//! Back up wallet.
|
||||
virtual bool backupWallet(const std::string& filename) = 0;
|
||||
|
||||
//! Get wallet name.
|
||||
virtual std::string getWalletName() = 0;
|
||||
|
||||
//! Get public key.
|
||||
virtual bool getPubKey(const CKeyID& address, CPubKey& pub_key) = 0;
|
||||
|
||||
//! Get private key.
|
||||
virtual bool getPrivKey(const CKeyID& address, CKey& key) = 0;
|
||||
|
||||
//! Return whether wallet has private key.
|
||||
virtual bool isSpendable(const CTxDestination& dest) = 0;
|
||||
|
||||
//! Return whether wallet has watch only keys.
|
||||
virtual bool haveWatchOnly() = 0;
|
||||
|
||||
//! Add or update address.
|
||||
virtual bool setAddressBook(const CTxDestination& dest, const std::string& name, const std::string& purpose) = 0;
|
||||
|
||||
//! Look up address in wallet, return whether exists.
|
||||
virtual bool getAddress(const CTxDestination& dest,
|
||||
std::string* name = nullptr,
|
||||
isminetype* is_mine = nullptr) = 0;
|
||||
|
||||
//! Add dest data.
|
||||
virtual bool addDestData(const CTxDestination& dest, const std::string& key, const std::string& value) = 0;
|
||||
|
||||
//! Erase dest data.
|
||||
virtual bool eraseDestData(const CTxDestination& dest, const std::string& key) = 0;
|
||||
|
||||
//! Get dest values with prefix.
|
||||
virtual std::vector<std::string> getDestValues(const std::string& prefix) = 0;
|
||||
|
||||
//! Lock coin.
|
||||
virtual void lockCoin(const COutPoint& output) = 0;
|
||||
|
||||
//! Unlock coin.
|
||||
virtual void unlockCoin(const COutPoint& output) = 0;
|
||||
|
||||
//! Return whether coin is locked.
|
||||
virtual bool isLockedCoin(const COutPoint& output) = 0;
|
||||
|
||||
//! List locked coins.
|
||||
virtual void listLockedCoins(std::vector<COutPoint>& outputs) = 0;
|
||||
|
||||
//! Create transaction.
|
||||
virtual 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) = 0;
|
||||
|
||||
//! Return whether transaction can be abandoned.
|
||||
virtual bool transactionCanBeAbandoned(const uint256& txid) = 0;
|
||||
|
||||
//! Abandon transaction.
|
||||
virtual bool abandonTransaction(const uint256& txid) = 0;
|
||||
|
||||
//! Return whether transaction can be bumped.
|
||||
virtual bool transactionCanBeBumped(const uint256& txid) = 0;
|
||||
|
||||
//! Create bump transaction.
|
||||
virtual 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) = 0;
|
||||
|
||||
//! Sign bump transaction.
|
||||
virtual bool signBumpTransaction(CMutableTransaction& mtx) = 0;
|
||||
|
||||
//! Commit bump transaction.
|
||||
virtual bool commitBumpTransaction(const uint256& txid,
|
||||
CMutableTransaction&& mtx,
|
||||
std::vector<std::string>& errors,
|
||||
uint256& bumped_txid) = 0;
|
||||
|
||||
//! Get balances.
|
||||
virtual WalletBalances getBalances() = 0;
|
||||
|
||||
//! Get balances if possible without blocking.
|
||||
virtual bool tryGetBalances(WalletBalances& balances, int& num_blocks) = 0;
|
||||
|
||||
//! Get balance.
|
||||
virtual CAmount getBalance() = 0;
|
||||
|
||||
//! Get available balance.
|
||||
virtual CAmount getAvailableBalance(const CCoinControl& coin_control) = 0;
|
||||
|
||||
// Return whether HD enabled.
|
||||
virtual bool hdEnabled() = 0;
|
||||
|
||||
// Get default address type.
|
||||
virtual OutputType getDefaultAddressType() = 0;
|
||||
|
||||
// Get default change type.
|
||||
virtual OutputType getDefaultChangeType() = 0;
|
||||
|
||||
//! Register handler for show progress messages.
|
||||
using ShowProgressFn = std::function<void(const std::string& title, int progress)>;
|
||||
virtual std::unique_ptr<Handler> handleShowProgress(ShowProgressFn fn) = 0;
|
||||
|
||||
//! Register handler for status changed messages.
|
||||
using StatusChangedFn = std::function<void()>;
|
||||
virtual std::unique_ptr<Handler> handleStatusChanged(StatusChangedFn fn) = 0;
|
||||
|
||||
//! Register handler for address book changed messages.
|
||||
using AddressBookChangedFn = std::function<void(const CTxDestination& address,
|
||||
const std::string& label,
|
||||
bool is_mine,
|
||||
const std::string& purpose,
|
||||
ChangeType status)>;
|
||||
virtual std::unique_ptr<Handler> handleAddressBookChanged(AddressBookChangedFn fn) = 0;
|
||||
|
||||
//! Register handler for transaction changed messages.
|
||||
using TransactionChangedFn = std::function<void(const uint256& txid, ChangeType status)>;
|
||||
virtual std::unique_ptr<Handler> handleTransactionChanged(TransactionChangedFn fn) = 0;
|
||||
|
||||
//! Register handler for watchonly changed messages.
|
||||
using WatchOnlyChangedFn = std::function<void(bool have_watch_only)>;
|
||||
virtual std::unique_ptr<Handler> handleWatchOnlyChanged(WatchOnlyChangedFn fn) = 0;
|
||||
};
|
||||
|
||||
//! Tracking object returned by CreateTransaction and passed to CommitTransaction.
|
||||
class PendingWalletTx
|
||||
{
|
||||
public:
|
||||
virtual ~PendingWalletTx() {}
|
||||
|
||||
//! Get transaction data.
|
||||
virtual const CTransaction& get() = 0;
|
||||
|
||||
//! Get virtual transaction size.
|
||||
virtual int64_t getVirtualSize() = 0;
|
||||
|
||||
//! Send pending transaction and commit to wallet.
|
||||
virtual bool commit(WalletValueMap value_map,
|
||||
WalletOrderForm order_form,
|
||||
std::string from_account,
|
||||
std::string& reject_reason) = 0;
|
||||
};
|
||||
|
||||
//! Collection of wallet balances.
|
||||
struct WalletBalances
|
||||
{
|
||||
CAmount balance = 0;
|
||||
CAmount unconfirmed_balance = 0;
|
||||
CAmount immature_balance = 0;
|
||||
bool have_watch_only = false;
|
||||
CAmount watch_only_balance = 0;
|
||||
CAmount unconfirmed_watch_only_balance = 0;
|
||||
CAmount immature_watch_only_balance = 0;
|
||||
|
||||
bool balanceChanged(const WalletBalances& prev) const
|
||||
{
|
||||
return balance != prev.balance || unconfirmed_balance != prev.unconfirmed_balance ||
|
||||
immature_balance != prev.immature_balance || watch_only_balance != prev.watch_only_balance ||
|
||||
unconfirmed_watch_only_balance != prev.unconfirmed_watch_only_balance ||
|
||||
immature_watch_only_balance != prev.immature_watch_only_balance;
|
||||
}
|
||||
};
|
||||
|
||||
//! Return implementation of Wallet interface. This function will be undefined
|
||||
|
|
|
@ -465,8 +465,10 @@ void BitcoinApplication::initializeResult(bool success)
|
|||
|
||||
#ifdef ENABLE_WALLET
|
||||
bool fFirstWallet = true;
|
||||
for (CWalletRef pwallet : vpwallets) {
|
||||
WalletModel * const walletModel = new WalletModel(platformStyle, pwallet, optionsModel);
|
||||
auto wallets = m_node.getWallets();
|
||||
auto cwallet = ::vpwallets.begin();
|
||||
for (auto& wallet : wallets) {
|
||||
WalletModel * const walletModel = new WalletModel(std::move(wallet), m_node, platformStyle, *cwallet++, optionsModel);
|
||||
|
||||
window->addWallet(walletModel);
|
||||
if (fFirstWallet) {
|
||||
|
|
|
@ -1010,7 +1010,7 @@ void BitcoinGUI::incomingTransaction(const QString& date, int unit, const CAmoun
|
|||
// On new transaction, make an info balloon
|
||||
QString msg = tr("Date: %1\n").arg(date) +
|
||||
tr("Amount: %1\n").arg(BitcoinUnits::formatWithUnit(unit, amount, true));
|
||||
if (WalletModel::isMultiwallet() && !walletName.isEmpty()) {
|
||||
if (m_node.getWallets().size() > 1 && !walletName.isEmpty()) {
|
||||
msg += tr("Wallet: %1\n").arg(walletName);
|
||||
}
|
||||
msg += tr("Type: %1\n").arg(type);
|
||||
|
@ -1116,7 +1116,7 @@ void BitcoinGUI::updateWalletStatus()
|
|||
}
|
||||
WalletModel * const walletModel = walletView->getWalletModel();
|
||||
setEncryptionStatus(walletModel->getEncryptionStatus());
|
||||
setHDStatus(walletModel->hdEnabled());
|
||||
setHDStatus(walletModel->wallet().hdEnabled());
|
||||
}
|
||||
#endif // ENABLE_WALLET
|
||||
|
||||
|
|
|
@ -209,7 +209,7 @@ void CoinControlDialog::showMenu(const QPoint &point)
|
|||
if (item->text(COLUMN_TXHASH).length() == 64) // transaction hash is 64 characters (this means it is a child node, so it is not a parent node in tree mode)
|
||||
{
|
||||
copyTransactionHashAction->setEnabled(true);
|
||||
if (model->isLockedCoin(uint256S(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt()))
|
||||
if (model->wallet().isLockedCoin(COutPoint(uint256S(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt())))
|
||||
{
|
||||
lockAction->setEnabled(false);
|
||||
unlockAction->setEnabled(true);
|
||||
|
@ -269,7 +269,7 @@ void CoinControlDialog::lockCoin()
|
|||
contextMenuItem->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
|
||||
|
||||
COutPoint outpt(uint256S(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt());
|
||||
model->lockCoin(outpt);
|
||||
model->wallet().lockCoin(outpt);
|
||||
contextMenuItem->setDisabled(true);
|
||||
contextMenuItem->setIcon(COLUMN_CHECKBOX, platformStyle->SingleColorIcon(":/icons/lock_closed"));
|
||||
updateLabelLocked();
|
||||
|
@ -279,7 +279,7 @@ void CoinControlDialog::lockCoin()
|
|||
void CoinControlDialog::unlockCoin()
|
||||
{
|
||||
COutPoint outpt(uint256S(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt());
|
||||
model->unlockCoin(outpt);
|
||||
model->wallet().unlockCoin(outpt);
|
||||
contextMenuItem->setDisabled(false);
|
||||
contextMenuItem->setIcon(COLUMN_CHECKBOX, QIcon());
|
||||
updateLabelLocked();
|
||||
|
@ -405,7 +405,7 @@ void CoinControlDialog::viewItemChanged(QTreeWidgetItem* item, int column)
|
|||
void CoinControlDialog::updateLabelLocked()
|
||||
{
|
||||
std::vector<COutPoint> vOutpts;
|
||||
model->listLockedCoins(vOutpts);
|
||||
model->wallet().listLockedCoins(vOutpts);
|
||||
if (vOutpts.size() > 0)
|
||||
{
|
||||
ui->labelLocked->setText(tr("(%1 locked)").arg(vOutpts.size()));
|
||||
|
@ -479,7 +479,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
|
|||
{
|
||||
CPubKey pubkey;
|
||||
CKeyID *keyid = boost::get<CKeyID>(&address);
|
||||
if (keyid && model->getPubKey(*keyid, pubkey))
|
||||
if (keyid && model->wallet().getPubKey(*keyid, pubkey))
|
||||
{
|
||||
nBytesInputs += (pubkey.IsCompressed() ? 148 : 180);
|
||||
}
|
||||
|
@ -706,7 +706,7 @@ void CoinControlDialog::updateView()
|
|||
itemOutput->setText(COLUMN_VOUT_INDEX, QString::number(out.i));
|
||||
|
||||
// disable locked coins
|
||||
if (model->isLockedCoin(txhash, out.i))
|
||||
if (model->wallet().isLockedCoin(COutPoint(txhash, out.i)))
|
||||
{
|
||||
COutPoint outpt(txhash, out.i);
|
||||
coinControl()->UnSelect(outpt); // just to be sure
|
||||
|
|
|
@ -231,13 +231,15 @@ void OverviewPage::setWalletModel(WalletModel *model)
|
|||
ui->listTransactions->setModelColumn(TransactionTableModel::ToAddress);
|
||||
|
||||
// Keep up to date with wallet
|
||||
setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance(),
|
||||
model->getWatchBalance(), model->getWatchUnconfirmedBalance(), model->getWatchImmatureBalance());
|
||||
interface::Wallet& wallet = model->wallet();
|
||||
interface::WalletBalances balances = wallet.getBalances();
|
||||
setBalance(balances.balance, balances.unconfirmed_balance, balances.immature_balance,
|
||||
balances.watch_only_balance, balances.unconfirmed_watch_only_balance, balances.immature_watch_only_balance);
|
||||
connect(model, SIGNAL(balanceChanged(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)), this, SLOT(setBalance(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)));
|
||||
|
||||
connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
|
||||
|
||||
updateWatchOnlyLabels(model->haveWatchOnly());
|
||||
updateWatchOnlyLabels(wallet.haveWatchOnly());
|
||||
connect(model, SIGNAL(notifyWatchonlyChanged(bool)), this, SLOT(updateWatchOnlyLabels(bool)));
|
||||
}
|
||||
|
||||
|
|
|
@ -95,13 +95,13 @@ void ReceiveCoinsDialog::setModel(WalletModel *_model)
|
|||
columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(tableView, AMOUNT_MINIMUM_COLUMN_WIDTH, DATE_COLUMN_WIDTH, this);
|
||||
|
||||
// configure bech32 checkbox, disable if launched with legacy as default:
|
||||
if (model->getDefaultAddressType() == OutputType::BECH32) {
|
||||
if (model->wallet().getDefaultAddressType() == OutputType::BECH32) {
|
||||
ui->useBech32->setCheckState(Qt::Checked);
|
||||
} else {
|
||||
ui->useBech32->setCheckState(Qt::Unchecked);
|
||||
}
|
||||
|
||||
ui->useBech32->setVisible(model->getDefaultAddressType() != OutputType::LEGACY);
|
||||
ui->useBech32->setVisible(model->wallet().getDefaultAddressType() != OutputType::LEGACY);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,7 +144,7 @@ void ReceiveCoinsDialog::on_receiveButton_clicked()
|
|||
QString address;
|
||||
QString label = ui->reqLabel->text();
|
||||
/* Generate new receiving address */
|
||||
OutputType address_type = model->getDefaultAddressType();
|
||||
OutputType address_type = model->wallet().getDefaultAddressType();
|
||||
if (address_type != OutputType::LEGACY) {
|
||||
address_type = ui->useBech32->isChecked() ? OutputType::BECH32 : OutputType::P2SH_SEGWIT;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <qt/sendcoinsentry.h>
|
||||
|
||||
#include <chainparams.h>
|
||||
#include <interface/node.h>
|
||||
#include <key_io.h>
|
||||
#include <wallet/coincontrol.h>
|
||||
#include <validation.h> // mempool and minRelayTxFee
|
||||
|
@ -149,8 +150,9 @@ void SendCoinsDialog::setModel(WalletModel *_model)
|
|||
}
|
||||
}
|
||||
|
||||
setBalance(_model->getBalance(), _model->getUnconfirmedBalance(), _model->getImmatureBalance(),
|
||||
_model->getWatchBalance(), _model->getWatchUnconfirmedBalance(), _model->getWatchImmatureBalance());
|
||||
interface::WalletBalances balances = _model->wallet().getBalances();
|
||||
setBalance(balances.balance, balances.unconfirmed_balance, balances.immature_balance,
|
||||
balances.watch_only_balance, balances.unconfirmed_watch_only_balance, balances.immature_watch_only_balance);
|
||||
connect(_model, SIGNAL(balanceChanged(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)), this, SLOT(setBalance(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)));
|
||||
connect(_model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
|
||||
updateDisplayUnit();
|
||||
|
@ -193,7 +195,7 @@ void SendCoinsDialog::setModel(WalletModel *_model)
|
|||
settings.remove("nSmartFeeSliderPosition");
|
||||
}
|
||||
if (settings.value("nConfTarget").toInt() == 0)
|
||||
ui->confTargetSelector->setCurrentIndex(getIndexForConfTarget(model->getDefaultConfirmTarget()));
|
||||
ui->confTargetSelector->setCurrentIndex(getIndexForConfTarget(model->node().getTxConfirmTarget()));
|
||||
else
|
||||
ui->confTargetSelector->setCurrentIndex(getIndexForConfTarget(settings.value("nConfTarget").toInt()));
|
||||
}
|
||||
|
@ -372,7 +374,7 @@ void SendCoinsDialog::on_sendButton_clicked()
|
|||
accept();
|
||||
CoinControlDialog::coinControl()->UnSelectAll();
|
||||
coinControlUpdateLabels();
|
||||
Q_EMIT coinsSent(currentTransaction.getTransaction()->GetHash());
|
||||
Q_EMIT coinsSent(currentTransaction.getWtx()->get().GetHash());
|
||||
}
|
||||
fNewRecipientAllowed = true;
|
||||
}
|
||||
|
@ -532,7 +534,7 @@ void SendCoinsDialog::setBalance(const CAmount& balance, const CAmount& unconfir
|
|||
|
||||
void SendCoinsDialog::updateDisplayUnit()
|
||||
{
|
||||
setBalance(model->getBalance(), 0, 0, 0, 0, 0);
|
||||
setBalance(model->wallet().getBalance(), 0, 0, 0, 0, 0);
|
||||
ui->customFee->setDisplayUnit(model->getOptionsModel()->getDisplayUnit());
|
||||
updateMinFeeLabel();
|
||||
updateSmartFeeLabel();
|
||||
|
@ -618,7 +620,7 @@ void SendCoinsDialog::useAvailableBalance(SendCoinsEntry* entry)
|
|||
}
|
||||
|
||||
// Calculate available amount to send.
|
||||
CAmount amount = model->getBalance(&coin_control);
|
||||
CAmount amount = model->wallet().getAvailableBalance(coin_control);
|
||||
for (int i = 0; i < ui->entries->count(); ++i) {
|
||||
SendCoinsEntry* e = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget());
|
||||
if (e && !e->isHidden() && e != entry) {
|
||||
|
@ -814,7 +816,7 @@ void SendCoinsDialog::coinControlChangeEdited(const QString& text)
|
|||
}
|
||||
else // Valid address
|
||||
{
|
||||
if (!model->IsSpendable(dest)) {
|
||||
if (!model->wallet().isSpendable(dest)) {
|
||||
ui->labelCoinControlChangeLabel->setText(tr("Warning: Unknown change address"));
|
||||
|
||||
// confirmation dialog
|
||||
|
|
|
@ -140,7 +140,7 @@ void SignVerifyMessageDialog::on_signMessageButton_SM_clicked()
|
|||
}
|
||||
|
||||
CKey key;
|
||||
if (!model->getPrivKey(*keyID, key))
|
||||
if (!model->wallet().getPrivKey(*keyID, key))
|
||||
{
|
||||
ui->statusLabel_SM->setStyleSheet("QLabel { color: red; }");
|
||||
ui->statusLabel_SM->setText(tr("Private key for the entered address is not available."));
|
||||
|
|
|
@ -178,7 +178,9 @@ void TestGUI()
|
|||
TransactionView transactionView(platformStyle.get());
|
||||
auto node = interface::MakeNode();
|
||||
OptionsModel optionsModel(*node);
|
||||
WalletModel walletModel(platformStyle.get(), &wallet, &optionsModel);
|
||||
vpwallets.insert(vpwallets.begin(), &wallet);
|
||||
WalletModel walletModel(std::move(node->getWallets()[0]), *node, platformStyle.get(), &wallet, &optionsModel);
|
||||
vpwallets.erase(vpwallets.begin());
|
||||
sendCoinsDialog.setModel(&walletModel);
|
||||
transactionView.setModel(&walletModel);
|
||||
|
||||
|
@ -203,7 +205,7 @@ void TestGUI()
|
|||
QLabel* balanceLabel = overviewPage.findChild<QLabel*>("labelBalance");
|
||||
QString balanceText = balanceLabel->text();
|
||||
int unit = walletModel.getOptionsModel()->getDisplayUnit();
|
||||
CAmount balance = walletModel.getBalance();
|
||||
CAmount balance = walletModel.wallet().getBalance();
|
||||
QString balanceComparison = BitcoinUnits::formatWithUnit(unit, balance, false, BitcoinUnits::separatorAlways);
|
||||
QCOMPARE(balanceText, balanceComparison);
|
||||
|
||||
|
|
|
@ -254,7 +254,7 @@ void TransactionView::setModel(WalletModel *_model)
|
|||
}
|
||||
|
||||
// show/hide column Watch-only
|
||||
updateWatchOnlyColumn(_model->haveWatchOnly());
|
||||
updateWatchOnlyColumn(_model->wallet().haveWatchOnly());
|
||||
|
||||
// Watch-only signal
|
||||
connect(_model, SIGNAL(notifyWatchonlyChanged(bool)), this, SLOT(updateWatchOnlyColumn(bool)));
|
||||
|
@ -364,7 +364,7 @@ void TransactionView::exportClicked()
|
|||
// name, column, role
|
||||
writer.setModel(transactionProxyModel);
|
||||
writer.addColumn(tr("Confirmed"), 0, TransactionTableModel::ConfirmedRole);
|
||||
if (model->haveWatchOnly())
|
||||
if (model->wallet().haveWatchOnly())
|
||||
writer.addColumn(tr("Watch-only"), TransactionTableModel::Watchonly);
|
||||
writer.addColumn(tr("Date"), 0, TransactionTableModel::DateRole);
|
||||
writer.addColumn(tr("Type"), TransactionTableModel::Type, Qt::EditRole);
|
||||
|
@ -393,8 +393,8 @@ void TransactionView::contextualMenu(const QPoint &point)
|
|||
// check if transaction can be abandoned, disable context menu action in case it doesn't
|
||||
uint256 hash;
|
||||
hash.SetHex(selection.at(0).data(TransactionTableModel::TxHashRole).toString().toStdString());
|
||||
abandonAction->setEnabled(model->transactionCanBeAbandoned(hash));
|
||||
bumpFeeAction->setEnabled(model->transactionCanBeBumped(hash));
|
||||
abandonAction->setEnabled(model->wallet().transactionCanBeAbandoned(hash));
|
||||
bumpFeeAction->setEnabled(model->wallet().transactionCanBeBumped(hash));
|
||||
|
||||
if(index.isValid())
|
||||
{
|
||||
|
@ -414,7 +414,7 @@ void TransactionView::abandonTx()
|
|||
hash.SetHex(hashQStr.toStdString());
|
||||
|
||||
// Abandon the wallet transaction over the walletModel
|
||||
model->abandonTransaction(hash);
|
||||
model->wallet().abandonTransaction(hash);
|
||||
|
||||
// Update the table
|
||||
model->getTransactionTableModel()->updateTransaction(hashQStr, CT_UPDATED, false);
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include <qt/transactiontablemodel.h>
|
||||
|
||||
#include <chain.h>
|
||||
#include <interface/handler.h>
|
||||
#include <interface/node.h>
|
||||
#include <key_io.h>
|
||||
#include <keystore.h>
|
||||
#include <validation.h>
|
||||
|
@ -37,21 +39,19 @@
|
|||
#include <QTimer>
|
||||
|
||||
|
||||
WalletModel::WalletModel(const PlatformStyle *platformStyle, CWallet *_wallet, OptionsModel *_optionsModel, QObject *parent) :
|
||||
QObject(parent), wallet(_wallet), optionsModel(_optionsModel), addressTableModel(0),
|
||||
WalletModel::WalletModel(std::unique_ptr<interface::Wallet> wallet, interface::Node& node, const PlatformStyle *platformStyle, CWallet *_wallet, OptionsModel *_optionsModel, QObject *parent) :
|
||||
QObject(parent), m_wallet(std::move(wallet)), m_node(node), cwallet(_wallet), optionsModel(_optionsModel), addressTableModel(0),
|
||||
transactionTableModel(0),
|
||||
recentRequestsTableModel(0),
|
||||
cachedBalance(0), cachedUnconfirmedBalance(0), cachedImmatureBalance(0),
|
||||
cachedWatchOnlyBalance{0}, cachedWatchUnconfBalance{0}, cachedWatchImmatureBalance{0},
|
||||
cachedEncryptionStatus(Unencrypted),
|
||||
cachedNumBlocks(0)
|
||||
{
|
||||
fHaveWatchOnly = wallet->HaveWatchOnly();
|
||||
fHaveWatchOnly = m_wallet->haveWatchOnly();
|
||||
fForceCheckBalanceChanged = false;
|
||||
|
||||
addressTableModel = new AddressTableModel(wallet, this);
|
||||
transactionTableModel = new TransactionTableModel(platformStyle, wallet, this);
|
||||
recentRequestsTableModel = new RecentRequestsTableModel(wallet, this);
|
||||
addressTableModel = new AddressTableModel(cwallet, this);
|
||||
transactionTableModel = new TransactionTableModel(platformStyle, cwallet, this);
|
||||
recentRequestsTableModel = new RecentRequestsTableModel(cwallet, this);
|
||||
|
||||
// This timer will be fired repeatedly to update the balance
|
||||
pollTimer = new QTimer(this);
|
||||
|
@ -66,46 +66,6 @@ WalletModel::~WalletModel()
|
|||
unsubscribeFromCoreSignals();
|
||||
}
|
||||
|
||||
CAmount WalletModel::getBalance(const CCoinControl *coinControl) const
|
||||
{
|
||||
if (coinControl)
|
||||
{
|
||||
return wallet->GetAvailableBalance(coinControl);
|
||||
}
|
||||
|
||||
return wallet->GetBalance();
|
||||
}
|
||||
|
||||
CAmount WalletModel::getUnconfirmedBalance() const
|
||||
{
|
||||
return wallet->GetUnconfirmedBalance();
|
||||
}
|
||||
|
||||
CAmount WalletModel::getImmatureBalance() const
|
||||
{
|
||||
return wallet->GetImmatureBalance();
|
||||
}
|
||||
|
||||
bool WalletModel::haveWatchOnly() const
|
||||
{
|
||||
return fHaveWatchOnly;
|
||||
}
|
||||
|
||||
CAmount WalletModel::getWatchBalance() const
|
||||
{
|
||||
return wallet->GetWatchOnlyBalance();
|
||||
}
|
||||
|
||||
CAmount WalletModel::getWatchUnconfirmedBalance() const
|
||||
{
|
||||
return wallet->GetUnconfirmedWatchOnlyBalance();
|
||||
}
|
||||
|
||||
CAmount WalletModel::getWatchImmatureBalance() const
|
||||
{
|
||||
return wallet->GetImmatureWatchOnlyBalance();
|
||||
}
|
||||
|
||||
void WalletModel::updateStatus()
|
||||
{
|
||||
EncryptionStatus newEncryptionStatus = getEncryptionStatus();
|
||||
|
@ -117,55 +77,34 @@ void WalletModel::updateStatus()
|
|||
|
||||
void WalletModel::pollBalanceChanged()
|
||||
{
|
||||
// Get required locks upfront. This avoids the GUI from getting stuck on
|
||||
// periodical polls if the core is holding the locks for a longer time -
|
||||
// for example, during a wallet rescan.
|
||||
TRY_LOCK(cs_main, lockMain);
|
||||
if(!lockMain)
|
||||
return;
|
||||
TRY_LOCK(wallet->cs_wallet, lockWallet);
|
||||
if(!lockWallet)
|
||||
// Try to get balances and return early if locks can't be acquired. This
|
||||
// avoids the GUI from getting stuck on periodical polls if the core is
|
||||
// holding the locks for a longer time - for example, during a wallet
|
||||
// rescan.
|
||||
interface::WalletBalances new_balances;
|
||||
int numBlocks = -1;
|
||||
if (!m_wallet->tryGetBalances(new_balances, numBlocks)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(fForceCheckBalanceChanged || chainActive.Height() != cachedNumBlocks)
|
||||
if(fForceCheckBalanceChanged || m_node.getNumBlocks() != cachedNumBlocks)
|
||||
{
|
||||
fForceCheckBalanceChanged = false;
|
||||
|
||||
// Balance and number of transactions might have changed
|
||||
cachedNumBlocks = chainActive.Height();
|
||||
cachedNumBlocks = m_node.getNumBlocks();
|
||||
|
||||
checkBalanceChanged();
|
||||
checkBalanceChanged(new_balances);
|
||||
if(transactionTableModel)
|
||||
transactionTableModel->updateConfirmations();
|
||||
}
|
||||
}
|
||||
|
||||
void WalletModel::checkBalanceChanged()
|
||||
void WalletModel::checkBalanceChanged(const interface::WalletBalances& new_balances)
|
||||
{
|
||||
CAmount newBalance = getBalance();
|
||||
CAmount newUnconfirmedBalance = getUnconfirmedBalance();
|
||||
CAmount newImmatureBalance = getImmatureBalance();
|
||||
CAmount newWatchOnlyBalance = 0;
|
||||
CAmount newWatchUnconfBalance = 0;
|
||||
CAmount newWatchImmatureBalance = 0;
|
||||
if (haveWatchOnly())
|
||||
{
|
||||
newWatchOnlyBalance = getWatchBalance();
|
||||
newWatchUnconfBalance = getWatchUnconfirmedBalance();
|
||||
newWatchImmatureBalance = getWatchImmatureBalance();
|
||||
}
|
||||
|
||||
if(cachedBalance != newBalance || cachedUnconfirmedBalance != newUnconfirmedBalance || cachedImmatureBalance != newImmatureBalance ||
|
||||
cachedWatchOnlyBalance != newWatchOnlyBalance || cachedWatchUnconfBalance != newWatchUnconfBalance || cachedWatchImmatureBalance != newWatchImmatureBalance)
|
||||
{
|
||||
cachedBalance = newBalance;
|
||||
cachedUnconfirmedBalance = newUnconfirmedBalance;
|
||||
cachedImmatureBalance = newImmatureBalance;
|
||||
cachedWatchOnlyBalance = newWatchOnlyBalance;
|
||||
cachedWatchUnconfBalance = newWatchUnconfBalance;
|
||||
cachedWatchImmatureBalance = newWatchImmatureBalance;
|
||||
Q_EMIT balanceChanged(newBalance, newUnconfirmedBalance, newImmatureBalance,
|
||||
newWatchOnlyBalance, newWatchUnconfBalance, newWatchImmatureBalance);
|
||||
if(new_balances.balanceChanged(m_cached_balances)) {
|
||||
m_cached_balances = new_balances;
|
||||
Q_EMIT balanceChanged(new_balances.balance, new_balances.unconfirmed_balance, new_balances.immature_balance, new_balances.watch_only_balance, new_balances.unconfirmed_watch_only_balance, new_balances.immature_watch_only_balance);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -260,7 +199,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
|
|||
return DuplicateAddress;
|
||||
}
|
||||
|
||||
CAmount nBalance = getBalance(&coinControl);
|
||||
CAmount nBalance = m_wallet->getAvailableBalance(coinControl);
|
||||
|
||||
if(total > nBalance)
|
||||
{
|
||||
|
@ -268,22 +207,17 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
|
|||
}
|
||||
|
||||
{
|
||||
LOCK2(cs_main, wallet->cs_wallet);
|
||||
|
||||
transaction.newPossibleKeyChange(wallet);
|
||||
|
||||
CAmount nFeeRequired = 0;
|
||||
int nChangePosRet = -1;
|
||||
std::string strFailReason;
|
||||
|
||||
CTransactionRef& newTx = transaction.getTransaction();
|
||||
CReserveKey *keyChange = transaction.getPossibleKeyChange();
|
||||
bool fCreated = wallet->CreateTransaction(vecSend, newTx, *keyChange, nFeeRequired, nChangePosRet, strFailReason, coinControl);
|
||||
auto& newTx = transaction.getWtx();
|
||||
newTx = m_wallet->createTransaction(vecSend, coinControl, true /* sign */, nChangePosRet, nFeeRequired, strFailReason);
|
||||
transaction.setTransactionFee(nFeeRequired);
|
||||
if (fSubtractFeeFromAmount && fCreated)
|
||||
if (fSubtractFeeFromAmount && newTx)
|
||||
transaction.reassignAmounts(nChangePosRet);
|
||||
|
||||
if(!fCreated)
|
||||
if(!newTx)
|
||||
{
|
||||
if(!fSubtractFeeFromAmount && (total + nFeeRequired) > nBalance)
|
||||
{
|
||||
|
@ -297,7 +231,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
|
|||
// reject absurdly high fee. (This can never happen because the
|
||||
// wallet caps the fee at maxTxFee. This merely serves as a
|
||||
// belt-and-suspenders check)
|
||||
if (nFeeRequired > maxTxFee)
|
||||
if (nFeeRequired > m_node.getMaxTxFee())
|
||||
return AbsurdFee;
|
||||
}
|
||||
|
||||
|
@ -309,8 +243,6 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran
|
|||
QByteArray transaction_array; /* store serialized transaction */
|
||||
|
||||
{
|
||||
LOCK2(cs_main, wallet->cs_wallet);
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> vOrderForm;
|
||||
for (const SendCoinsRecipient &rcp : transaction.getRecipients())
|
||||
{
|
||||
|
@ -330,14 +262,13 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran
|
|||
vOrderForm.emplace_back("Message", rcp.message.toStdString());
|
||||
}
|
||||
|
||||
CTransactionRef& newTx = transaction.getTransaction();
|
||||
CReserveKey *keyChange = transaction.getPossibleKeyChange();
|
||||
CValidationState state;
|
||||
if (!wallet->CommitTransaction(newTx, {} /* mapValue */, std::move(vOrderForm), {} /* fromAccount */, *keyChange, g_connman.get(), state))
|
||||
return SendCoinsReturn(TransactionCommitFailed, QString::fromStdString(state.GetRejectReason()));
|
||||
auto& newTx = transaction.getWtx();
|
||||
std::string rejectReason;
|
||||
if (!newTx->commit({} /* mapValue */, std::move(vOrderForm), {} /* fromAccount */, rejectReason))
|
||||
return SendCoinsReturn(TransactionCommitFailed, QString::fromStdString(rejectReason));
|
||||
|
||||
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ssTx << newTx;
|
||||
ssTx << newTx->get();
|
||||
transaction_array.append(&(ssTx[0]), ssTx.size());
|
||||
}
|
||||
|
||||
|
@ -352,24 +283,22 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran
|
|||
CTxDestination dest = DecodeDestination(strAddress);
|
||||
std::string strLabel = rcp.label.toStdString();
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
|
||||
std::map<CTxDestination, CAddressBookData>::iterator mi = wallet->mapAddressBook.find(dest);
|
||||
|
||||
// Check if we have a new address or an updated label
|
||||
if (mi == wallet->mapAddressBook.end())
|
||||
std::string name;
|
||||
if (!m_wallet->getAddress(dest, &name))
|
||||
{
|
||||
wallet->SetAddressBook(dest, strLabel, "send");
|
||||
m_wallet->setAddressBook(dest, strLabel, "send");
|
||||
}
|
||||
else if (mi->second.name != strLabel)
|
||||
else if (name != strLabel)
|
||||
{
|
||||
wallet->SetAddressBook(dest, strLabel, ""); // "" means don't change purpose
|
||||
m_wallet->setAddressBook(dest, strLabel, ""); // "" means don't change purpose
|
||||
}
|
||||
}
|
||||
}
|
||||
Q_EMIT coinsSent(wallet, rcp, transaction_array);
|
||||
Q_EMIT coinsSent(cwallet, rcp, transaction_array);
|
||||
}
|
||||
checkBalanceChanged(); // update balance immediately, otherwise there could be a short noticeable delay until pollBalanceChanged hits
|
||||
|
||||
checkBalanceChanged(m_wallet->getBalances()); // update balance immediately, otherwise there could be a short noticeable delay until pollBalanceChanged hits
|
||||
|
||||
return SendCoinsReturn(OK);
|
||||
}
|
||||
|
@ -396,11 +325,11 @@ RecentRequestsTableModel *WalletModel::getRecentRequestsTableModel()
|
|||
|
||||
WalletModel::EncryptionStatus WalletModel::getEncryptionStatus() const
|
||||
{
|
||||
if(!wallet->IsCrypted())
|
||||
if(!m_wallet->isCrypted())
|
||||
{
|
||||
return Unencrypted;
|
||||
}
|
||||
else if(wallet->IsLocked())
|
||||
else if(m_wallet->isLocked())
|
||||
{
|
||||
return Locked;
|
||||
}
|
||||
|
@ -415,7 +344,7 @@ bool WalletModel::setWalletEncrypted(bool encrypted, const SecureString &passphr
|
|||
if(encrypted)
|
||||
{
|
||||
// Encrypt
|
||||
return wallet->EncryptWallet(passphrase);
|
||||
return m_wallet->encryptWallet(passphrase);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -429,39 +358,29 @@ bool WalletModel::setWalletLocked(bool locked, const SecureString &passPhrase)
|
|||
if(locked)
|
||||
{
|
||||
// Lock
|
||||
return wallet->Lock();
|
||||
return m_wallet->lock();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unlock
|
||||
return wallet->Unlock(passPhrase);
|
||||
return m_wallet->unlock(passPhrase);
|
||||
}
|
||||
}
|
||||
|
||||
bool WalletModel::changePassphrase(const SecureString &oldPass, const SecureString &newPass)
|
||||
{
|
||||
bool retval;
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
wallet->Lock(); // Make sure wallet is locked before attempting pass change
|
||||
retval = wallet->ChangeWalletPassphrase(oldPass, newPass);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool WalletModel::backupWallet(const QString &filename)
|
||||
{
|
||||
return wallet->BackupWallet(filename.toLocal8Bit().data());
|
||||
m_wallet->lock(); // Make sure wallet is locked before attempting pass change
|
||||
return m_wallet->changeWalletPassphrase(oldPass, newPass);
|
||||
}
|
||||
|
||||
// Handlers for core signals
|
||||
static void NotifyKeyStoreStatusChanged(WalletModel *walletmodel, CCryptoKeyStore *wallet)
|
||||
static void NotifyKeyStoreStatusChanged(WalletModel *walletmodel)
|
||||
{
|
||||
qDebug() << "NotifyKeyStoreStatusChanged";
|
||||
QMetaObject::invokeMethod(walletmodel, "updateStatus", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet,
|
||||
static void NotifyAddressBookChanged(WalletModel *walletmodel,
|
||||
const CTxDestination &address, const std::string &label, bool isMine,
|
||||
const std::string &purpose, ChangeType status)
|
||||
{
|
||||
|
@ -478,9 +397,8 @@ static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet,
|
|||
Q_ARG(int, status));
|
||||
}
|
||||
|
||||
static void NotifyTransactionChanged(WalletModel *walletmodel, CWallet *wallet, const uint256 &hash, ChangeType status)
|
||||
static void NotifyTransactionChanged(WalletModel *walletmodel, const uint256 &hash, ChangeType status)
|
||||
{
|
||||
Q_UNUSED(wallet);
|
||||
Q_UNUSED(hash);
|
||||
Q_UNUSED(status);
|
||||
QMetaObject::invokeMethod(walletmodel, "updateTransaction", Qt::QueuedConnection);
|
||||
|
@ -503,21 +421,21 @@ static void NotifyWatchonlyChanged(WalletModel *walletmodel, bool fHaveWatchonly
|
|||
void WalletModel::subscribeToCoreSignals()
|
||||
{
|
||||
// Connect signals to wallet
|
||||
wallet->NotifyStatusChanged.connect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
|
||||
wallet->NotifyAddressBookChanged.connect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5, _6));
|
||||
wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
|
||||
wallet->ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
|
||||
wallet->NotifyWatchonlyChanged.connect(boost::bind(NotifyWatchonlyChanged, this, _1));
|
||||
m_handler_status_changed = m_wallet->handleStatusChanged(boost::bind(&NotifyKeyStoreStatusChanged, this));
|
||||
m_handler_address_book_changed = m_wallet->handleAddressBookChanged(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5));
|
||||
m_handler_transaction_changed = m_wallet->handleTransactionChanged(boost::bind(NotifyTransactionChanged, this, _1, _2));
|
||||
m_handler_show_progress = m_wallet->handleShowProgress(boost::bind(ShowProgress, this, _1, _2));
|
||||
m_handler_watch_only_changed = m_wallet->handleWatchOnlyChanged(boost::bind(NotifyWatchonlyChanged, this, _1));
|
||||
}
|
||||
|
||||
void WalletModel::unsubscribeFromCoreSignals()
|
||||
{
|
||||
// Disconnect signals from wallet
|
||||
wallet->NotifyStatusChanged.disconnect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
|
||||
wallet->NotifyAddressBookChanged.disconnect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5, _6));
|
||||
wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
|
||||
wallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
|
||||
wallet->NotifyWatchonlyChanged.disconnect(boost::bind(NotifyWatchonlyChanged, this, _1));
|
||||
m_handler_status_changed->disconnect();
|
||||
m_handler_address_book_changed->disconnect();
|
||||
m_handler_transaction_changed->disconnect();
|
||||
m_handler_show_progress->disconnect();
|
||||
m_handler_watch_only_changed->disconnect();
|
||||
}
|
||||
|
||||
// WalletModel::UnlockContext implementation
|
||||
|
@ -557,29 +475,14 @@ void WalletModel::UnlockContext::CopyFrom(const UnlockContext& rhs)
|
|||
rhs.relock = false;
|
||||
}
|
||||
|
||||
bool WalletModel::getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const
|
||||
{
|
||||
return wallet->GetPubKey(address, vchPubKeyOut);
|
||||
}
|
||||
|
||||
bool WalletModel::IsSpendable(const CTxDestination& dest) const
|
||||
{
|
||||
return IsMine(*wallet, dest) & ISMINE_SPENDABLE;
|
||||
}
|
||||
|
||||
bool WalletModel::getPrivKey(const CKeyID &address, CKey& vchPrivKeyOut) const
|
||||
{
|
||||
return wallet->GetKey(address, vchPrivKeyOut);
|
||||
}
|
||||
|
||||
// returns a list of COutputs from COutPoints
|
||||
void WalletModel::getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs)
|
||||
{
|
||||
LOCK2(cs_main, wallet->cs_wallet);
|
||||
LOCK2(cs_main, cwallet->cs_wallet);
|
||||
for (const COutPoint& outpoint : vOutpoints)
|
||||
{
|
||||
auto it = wallet->mapWallet.find(outpoint.hash);
|
||||
if (it == wallet->mapWallet.end()) continue;
|
||||
auto it = cwallet->mapWallet.find(outpoint.hash);
|
||||
if (it == cwallet->mapWallet.end()) continue;
|
||||
int nDepth = it->second.GetDepthInMainChain();
|
||||
if (nDepth < 0) continue;
|
||||
COutput out(&it->second, outpoint.n, nDepth, true /* spendable */, true /* solvable */, true /* safe */);
|
||||
|
@ -589,14 +492,14 @@ void WalletModel::getOutputs(const std::vector<COutPoint>& vOutpoints, std::vect
|
|||
|
||||
bool WalletModel::isSpent(const COutPoint& outpoint) const
|
||||
{
|
||||
LOCK2(cs_main, wallet->cs_wallet);
|
||||
return wallet->IsSpent(outpoint.hash, outpoint.n);
|
||||
LOCK2(cs_main, cwallet->cs_wallet);
|
||||
return cwallet->IsSpent(outpoint.hash, outpoint.n);
|
||||
}
|
||||
|
||||
// AvailableCoins + LockedCoins grouped by wallet address (put change in one group with wallet address)
|
||||
void WalletModel::listCoins(std::map<QString, std::vector<COutput> >& mapCoins) const
|
||||
{
|
||||
for (auto& group : wallet->ListCoins()) {
|
||||
for (auto& group : cwallet->ListCoins()) {
|
||||
auto& resultGroup = mapCoins[QString::fromStdString(EncodeDestination(group.first))];
|
||||
for (auto& coin : group.second) {
|
||||
resultGroup.emplace_back(std::move(coin));
|
||||
|
@ -604,33 +507,9 @@ void WalletModel::listCoins(std::map<QString, std::vector<COutput> >& mapCoins)
|
|||
}
|
||||
}
|
||||
|
||||
bool WalletModel::isLockedCoin(uint256 hash, unsigned int n) const
|
||||
{
|
||||
LOCK2(cs_main, wallet->cs_wallet);
|
||||
return wallet->IsLockedCoin(hash, n);
|
||||
}
|
||||
|
||||
void WalletModel::lockCoin(COutPoint& output)
|
||||
{
|
||||
LOCK2(cs_main, wallet->cs_wallet);
|
||||
wallet->LockCoin(output);
|
||||
}
|
||||
|
||||
void WalletModel::unlockCoin(COutPoint& output)
|
||||
{
|
||||
LOCK2(cs_main, wallet->cs_wallet);
|
||||
wallet->UnlockCoin(output);
|
||||
}
|
||||
|
||||
void WalletModel::listLockedCoins(std::vector<COutPoint>& vOutpts)
|
||||
{
|
||||
LOCK2(cs_main, wallet->cs_wallet);
|
||||
wallet->ListLockedCoins(vOutpts);
|
||||
}
|
||||
|
||||
void WalletModel::loadReceiveRequests(std::vector<std::string>& vReceiveRequests)
|
||||
{
|
||||
vReceiveRequests = wallet->GetDestValues("rr"); // receive request
|
||||
vReceiveRequests = m_wallet->getDestValues("rr"); // receive request
|
||||
}
|
||||
|
||||
bool WalletModel::saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest)
|
||||
|
@ -641,27 +520,10 @@ bool WalletModel::saveReceiveRequest(const std::string &sAddress, const int64_t
|
|||
ss << nId;
|
||||
std::string key = "rr" + ss.str(); // "rr" prefix = "receive request" in destdata
|
||||
|
||||
LOCK(wallet->cs_wallet);
|
||||
if (sRequest.empty())
|
||||
return wallet->EraseDestData(dest, key);
|
||||
return m_wallet->eraseDestData(dest, key);
|
||||
else
|
||||
return wallet->AddDestData(dest, key, sRequest);
|
||||
}
|
||||
|
||||
bool WalletModel::transactionCanBeAbandoned(uint256 hash) const
|
||||
{
|
||||
return wallet->TransactionCanBeAbandoned(hash);
|
||||
}
|
||||
|
||||
bool WalletModel::abandonTransaction(uint256 hash) const
|
||||
{
|
||||
LOCK2(cs_main, wallet->cs_wallet);
|
||||
return wallet->AbandonTransaction(hash);
|
||||
}
|
||||
|
||||
bool WalletModel::transactionCanBeBumped(uint256 hash) const
|
||||
{
|
||||
return feebumper::TransactionCanBeBumped(wallet, hash);
|
||||
return m_wallet->addDestData(dest, key, sRequest);
|
||||
}
|
||||
|
||||
bool WalletModel::bumpFee(uint256 hash)
|
||||
|
@ -672,7 +534,7 @@ bool WalletModel::bumpFee(uint256 hash)
|
|||
CAmount old_fee;
|
||||
CAmount new_fee;
|
||||
CMutableTransaction mtx;
|
||||
if (feebumper::CreateTransaction(wallet, hash, coin_control, 0 /* totalFee */, errors, old_fee, new_fee, mtx) != feebumper::Result::OK) {
|
||||
if (!m_wallet->createBumpTransaction(hash, coin_control, 0 /* totalFee */, errors, old_fee, new_fee, mtx)) {
|
||||
QMessageBox::critical(0, tr("Fee bump error"), tr("Increasing transaction fee failed") + "<br />(" +
|
||||
(errors.size() ? QString::fromStdString(errors[0]) : "") +")");
|
||||
return false;
|
||||
|
@ -711,13 +573,13 @@ bool WalletModel::bumpFee(uint256 hash)
|
|||
}
|
||||
|
||||
// sign bumped transaction
|
||||
if (!feebumper::SignTransaction(wallet, mtx)) {
|
||||
if (!m_wallet->signBumpTransaction(mtx)) {
|
||||
QMessageBox::critical(0, tr("Fee bump error"), tr("Can't sign transaction."));
|
||||
return false;
|
||||
}
|
||||
// commit the bumped transaction
|
||||
uint256 txid;
|
||||
if (feebumper::CommitTransaction(wallet, hash, std::move(mtx), errors, txid) != feebumper::Result::OK) {
|
||||
if(!m_wallet->commitBumpTransaction(hash, std::move(mtx), errors, txid)) {
|
||||
QMessageBox::critical(0, tr("Fee bump error"), tr("Could not commit transaction") + "<br />(" +
|
||||
QString::fromStdString(errors[0])+")");
|
||||
return false;
|
||||
|
@ -730,28 +592,12 @@ bool WalletModel::isWalletEnabled()
|
|||
return !gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET);
|
||||
}
|
||||
|
||||
bool WalletModel::hdEnabled() const
|
||||
{
|
||||
return wallet->IsHDEnabled();
|
||||
}
|
||||
|
||||
OutputType WalletModel::getDefaultAddressType() const
|
||||
{
|
||||
return wallet->m_default_address_type;
|
||||
}
|
||||
|
||||
int WalletModel::getDefaultConfirmTarget() const
|
||||
{
|
||||
return nTxConfirmTarget;
|
||||
}
|
||||
|
||||
QString WalletModel::getWalletName() const
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
return QString::fromStdString(wallet->GetName());
|
||||
return QString::fromStdString(m_wallet->getWalletName());
|
||||
}
|
||||
|
||||
bool WalletModel::isMultiwallet()
|
||||
{
|
||||
return gArgs.GetArgs("-wallet").size() > 1;
|
||||
return m_node.getWallets().size() > 1;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <qt/paymentrequestplus.h>
|
||||
#include <qt/walletmodeltransaction.h>
|
||||
|
||||
#include <interface/wallet.h>
|
||||
#include <support/allocators/secure.h>
|
||||
|
||||
#include <map>
|
||||
|
@ -34,9 +35,12 @@ class CKeyID;
|
|||
class COutPoint;
|
||||
class COutput;
|
||||
class CPubKey;
|
||||
class CWallet;
|
||||
class uint256;
|
||||
|
||||
namespace interface {
|
||||
class Node;
|
||||
} // namespace interface
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QTimer;
|
||||
QT_END_NAMESPACE
|
||||
|
@ -107,7 +111,7 @@ class WalletModel : public QObject
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit WalletModel(const PlatformStyle *platformStyle, CWallet *wallet, OptionsModel *optionsModel, QObject *parent = 0);
|
||||
explicit WalletModel(std::unique_ptr<interface::Wallet> wallet, interface::Node& node, const PlatformStyle *platformStyle, CWallet *cwallet, OptionsModel *optionsModel, QObject *parent = 0);
|
||||
~WalletModel();
|
||||
|
||||
enum StatusCode // Returned by sendCoins
|
||||
|
@ -136,15 +140,6 @@ public:
|
|||
TransactionTableModel *getTransactionTableModel();
|
||||
RecentRequestsTableModel *getRecentRequestsTableModel();
|
||||
|
||||
CWallet *getWallet() const { return wallet; };
|
||||
|
||||
CAmount getBalance(const CCoinControl *coinControl = nullptr) const;
|
||||
CAmount getUnconfirmedBalance() const;
|
||||
CAmount getImmatureBalance() const;
|
||||
bool haveWatchOnly() const;
|
||||
CAmount getWatchBalance() const;
|
||||
CAmount getWatchUnconfirmedBalance() const;
|
||||
CAmount getWatchImmatureBalance() const;
|
||||
EncryptionStatus getEncryptionStatus() const;
|
||||
|
||||
// Check address for validity
|
||||
|
@ -173,8 +168,6 @@ public:
|
|||
// Passphrase only needed when unlocking
|
||||
bool setWalletLocked(bool locked, const SecureString &passPhrase=SecureString());
|
||||
bool changePassphrase(const SecureString &oldPass, const SecureString &newPass);
|
||||
// Wallet backup
|
||||
bool backupWallet(const QString &filename);
|
||||
|
||||
// RAI object for unlocking wallet, returned by requestUnlock()
|
||||
class UnlockContext
|
||||
|
@ -198,40 +191,33 @@ public:
|
|||
|
||||
UnlockContext requestUnlock();
|
||||
|
||||
bool getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
|
||||
bool IsSpendable(const CTxDestination& dest) const;
|
||||
bool getPrivKey(const CKeyID &address, CKey& vchPrivKeyOut) const;
|
||||
void getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs);
|
||||
bool isSpent(const COutPoint& outpoint) const;
|
||||
void listCoins(std::map<QString, std::vector<COutput> >& mapCoins) const;
|
||||
|
||||
bool isLockedCoin(uint256 hash, unsigned int n) const;
|
||||
void lockCoin(COutPoint& output);
|
||||
void unlockCoin(COutPoint& output);
|
||||
void listLockedCoins(std::vector<COutPoint>& vOutpts);
|
||||
|
||||
void loadReceiveRequests(std::vector<std::string>& vReceiveRequests);
|
||||
bool saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest);
|
||||
|
||||
bool transactionCanBeAbandoned(uint256 hash) const;
|
||||
bool abandonTransaction(uint256 hash) const;
|
||||
|
||||
bool transactionCanBeBumped(uint256 hash) const;
|
||||
bool bumpFee(uint256 hash);
|
||||
|
||||
static bool isWalletEnabled();
|
||||
|
||||
bool hdEnabled() const;
|
||||
|
||||
OutputType getDefaultAddressType() const;
|
||||
|
||||
int getDefaultConfirmTarget() const;
|
||||
interface::Node& node() const { return m_node; }
|
||||
interface::Wallet& wallet() const { return *m_wallet; }
|
||||
|
||||
QString getWalletName() const;
|
||||
|
||||
static bool isMultiwallet();
|
||||
bool isMultiwallet();
|
||||
private:
|
||||
CWallet *wallet;
|
||||
std::unique_ptr<interface::Wallet> m_wallet;
|
||||
std::unique_ptr<interface::Handler> m_handler_status_changed;
|
||||
std::unique_ptr<interface::Handler> m_handler_address_book_changed;
|
||||
std::unique_ptr<interface::Handler> m_handler_transaction_changed;
|
||||
std::unique_ptr<interface::Handler> m_handler_show_progress;
|
||||
std::unique_ptr<interface::Handler> m_handler_watch_only_changed;
|
||||
interface::Node& m_node;
|
||||
|
||||
CWallet *cwallet;
|
||||
bool fHaveWatchOnly;
|
||||
bool fForceCheckBalanceChanged;
|
||||
|
||||
|
@ -244,12 +230,7 @@ private:
|
|||
RecentRequestsTableModel *recentRequestsTableModel;
|
||||
|
||||
// Cache some values to be able to detect changes
|
||||
CAmount cachedBalance;
|
||||
CAmount cachedUnconfirmedBalance;
|
||||
CAmount cachedImmatureBalance;
|
||||
CAmount cachedWatchOnlyBalance;
|
||||
CAmount cachedWatchUnconfBalance;
|
||||
CAmount cachedWatchImmatureBalance;
|
||||
interface::WalletBalances m_cached_balances;
|
||||
EncryptionStatus cachedEncryptionStatus;
|
||||
int cachedNumBlocks;
|
||||
|
||||
|
@ -257,7 +238,7 @@ private:
|
|||
|
||||
void subscribeToCoreSignals();
|
||||
void unsubscribeFromCoreSignals();
|
||||
void checkBalanceChanged();
|
||||
void checkBalanceChanged(const interface::WalletBalances& new_balances);
|
||||
|
||||
Q_SIGNALS:
|
||||
// Signal that balance in wallet changed
|
||||
|
|
|
@ -4,12 +4,11 @@
|
|||
|
||||
#include <qt/walletmodeltransaction.h>
|
||||
|
||||
#include <interface/node.h>
|
||||
#include <policy/policy.h>
|
||||
#include <wallet/wallet.h>
|
||||
|
||||
WalletModelTransaction::WalletModelTransaction(const QList<SendCoinsRecipient> &_recipients) :
|
||||
recipients(_recipients),
|
||||
walletTransaction(0),
|
||||
fee(0)
|
||||
{
|
||||
}
|
||||
|
@ -19,14 +18,14 @@ QList<SendCoinsRecipient> WalletModelTransaction::getRecipients() const
|
|||
return recipients;
|
||||
}
|
||||
|
||||
CTransactionRef& WalletModelTransaction::getTransaction()
|
||||
std::unique_ptr<interface::PendingWalletTx>& WalletModelTransaction::getWtx()
|
||||
{
|
||||
return walletTransaction;
|
||||
return wtx;
|
||||
}
|
||||
|
||||
unsigned int WalletModelTransaction::getTransactionSize()
|
||||
{
|
||||
return (!walletTransaction ? 0 : ::GetVirtualTransactionSize(*walletTransaction));
|
||||
return wtx ? wtx->getVirtualSize() : 0;
|
||||
}
|
||||
|
||||
CAmount WalletModelTransaction::getTransactionFee() const
|
||||
|
@ -41,6 +40,7 @@ void WalletModelTransaction::setTransactionFee(const CAmount& newFee)
|
|||
|
||||
void WalletModelTransaction::reassignAmounts(int nChangePosRet)
|
||||
{
|
||||
const CTransaction* walletTransaction = &wtx->get();
|
||||
int i = 0;
|
||||
for (QList<SendCoinsRecipient>::iterator it = recipients.begin(); it != recipients.end(); ++it)
|
||||
{
|
||||
|
@ -80,13 +80,3 @@ CAmount WalletModelTransaction::getTotalTransactionAmount() const
|
|||
}
|
||||
return totalTransactionAmount;
|
||||
}
|
||||
|
||||
void WalletModelTransaction::newPossibleKeyChange(CWallet *wallet)
|
||||
{
|
||||
keyChange.reset(new CReserveKey(wallet));
|
||||
}
|
||||
|
||||
CReserveKey *WalletModelTransaction::getPossibleKeyChange()
|
||||
{
|
||||
return keyChange.get();
|
||||
}
|
||||
|
|
|
@ -11,9 +11,10 @@
|
|||
|
||||
class SendCoinsRecipient;
|
||||
|
||||
class CReserveKey;
|
||||
class CWallet;
|
||||
class CWalletTx;
|
||||
namespace interface {
|
||||
class Node;
|
||||
class PendingWalletTx;
|
||||
}
|
||||
|
||||
/** Data model for a walletmodel transaction. */
|
||||
class WalletModelTransaction
|
||||
|
@ -23,7 +24,7 @@ public:
|
|||
|
||||
QList<SendCoinsRecipient> getRecipients() const;
|
||||
|
||||
CTransactionRef& getTransaction();
|
||||
std::unique_ptr<interface::PendingWalletTx>& getWtx();
|
||||
unsigned int getTransactionSize();
|
||||
|
||||
void setTransactionFee(const CAmount& newFee);
|
||||
|
@ -31,15 +32,11 @@ public:
|
|||
|
||||
CAmount getTotalTransactionAmount() const;
|
||||
|
||||
void newPossibleKeyChange(CWallet *wallet);
|
||||
CReserveKey *getPossibleKeyChange();
|
||||
|
||||
void reassignAmounts(int nChangePosRet); // needed for the subtract-fee-from-amount feature
|
||||
|
||||
private:
|
||||
QList<SendCoinsRecipient> recipients;
|
||||
CTransactionRef walletTransaction;
|
||||
std::unique_ptr<CReserveKey> keyChange;
|
||||
std::unique_ptr<interface::PendingWalletTx> wtx;
|
||||
CAmount fee;
|
||||
};
|
||||
|
||||
|
|
|
@ -258,7 +258,7 @@ void WalletView::backupWallet()
|
|||
if (filename.isEmpty())
|
||||
return;
|
||||
|
||||
if (!walletModel->backupWallet(filename)) {
|
||||
if (!walletModel->wallet().backupWallet(filename.toLocal8Bit().data())) {
|
||||
Q_EMIT message(tr("Backup Failed"), tr("There was an error trying to save the wallet data to %1.").arg(filename),
|
||||
CClientUIInterface::MSG_ERROR);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue