Remove direct bitcoin calls from qt/addresstablemodel.cpp

This commit is contained in:
Russell Yanofsky 2017-04-18 13:01:23 -04:00 committed by John Newbery
parent 827de038ab
commit 3ec2ebcd9b
5 changed files with 78 additions and 37 deletions

View file

@ -85,6 +85,10 @@ public:
} }
bool backupWallet(const std::string& filename) override { return m_wallet.BackupWallet(filename); } bool backupWallet(const std::string& filename) override { return m_wallet.BackupWallet(filename); }
std::string getWalletName() override { return m_wallet.GetName(); } std::string getWalletName() override { return m_wallet.GetName(); }
bool getKeyFromPool(bool internal, CPubKey& pub_key) override
{
return m_wallet.GetKeyFromPool(pub_key, internal);
}
bool getPubKey(const CKeyID& address, CPubKey& pub_key) override { return m_wallet.GetPubKey(address, pub_key); } 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 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 isSpendable(const CTxDestination& dest) override { return IsMine(m_wallet, dest) & ISMINE_SPENDABLE; }
@ -93,6 +97,10 @@ public:
{ {
return m_wallet.SetAddressBook(dest, name, purpose); return m_wallet.SetAddressBook(dest, name, purpose);
} }
bool delAddressBook(const CTxDestination& dest) override
{
return m_wallet.DelAddressBook(dest);
}
bool getAddress(const CTxDestination& dest, std::string* name, isminetype* is_mine) override bool getAddress(const CTxDestination& dest, std::string* name, isminetype* is_mine) override
{ {
LOCK(m_wallet.cs_wallet); LOCK(m_wallet.cs_wallet);
@ -108,6 +116,16 @@ public:
} }
return true; return true;
} }
std::vector<WalletAddress> getAddresses() override
{
LOCK(m_wallet.cs_wallet);
std::vector<WalletAddress> result;
for (const auto& item : m_wallet.mapAddressBook) {
result.emplace_back(item.first, IsMine(m_wallet, item.first), item.second.name, item.second.purpose);
}
return result;
}
void learnRelatedScripts(const CPubKey& key, OutputType type) override { m_wallet.LearnRelatedScripts(key, type); }
bool addDestData(const CTxDestination& dest, const std::string& key, const std::string& value) override bool addDestData(const CTxDestination& dest, const std::string& key, const std::string& value) override
{ {
LOCK(m_wallet.cs_wallet); LOCK(m_wallet.cs_wallet);

View file

@ -6,6 +6,7 @@
#define BITCOIN_INTERFACE_WALLET_H #define BITCOIN_INTERFACE_WALLET_H
#include <amount.h> // For CAmount #include <amount.h> // For CAmount
#include <pubkey.h> // For CTxDestination (CKeyID and CScriptID)
#include <script/ismine.h> // For isminefilter, isminetype #include <script/ismine.h> // For isminefilter, isminetype
#include <script/standard.h> // For CTxDestination #include <script/standard.h> // For CTxDestination
#include <support/allocators/secure.h> // For SecureString #include <support/allocators/secure.h> // For SecureString
@ -30,6 +31,7 @@ namespace interface {
class Handler; class Handler;
class PendingWalletTx; class PendingWalletTx;
struct WalletAddress;
struct WalletBalances; struct WalletBalances;
struct WalletTxOut; struct WalletTxOut;
@ -67,6 +69,9 @@ public:
//! Get wallet name. //! Get wallet name.
virtual std::string getWalletName() = 0; virtual std::string getWalletName() = 0;
// Get key from pool.
virtual bool getKeyFromPool(bool internal, CPubKey& pub_key) = 0;
//! Get public key. //! Get public key.
virtual bool getPubKey(const CKeyID& address, CPubKey& pub_key) = 0; virtual bool getPubKey(const CKeyID& address, CPubKey& pub_key) = 0;
@ -82,11 +87,21 @@ public:
//! Add or update address. //! Add or update address.
virtual bool setAddressBook(const CTxDestination& dest, const std::string& name, const std::string& purpose) = 0; virtual bool setAddressBook(const CTxDestination& dest, const std::string& name, const std::string& purpose) = 0;
// Remove address.
virtual bool delAddressBook(const CTxDestination& dest) = 0;
//! Look up address in wallet, return whether exists. //! Look up address in wallet, return whether exists.
virtual bool getAddress(const CTxDestination& dest, virtual bool getAddress(const CTxDestination& dest,
std::string* name = nullptr, std::string* name = nullptr,
isminetype* is_mine = nullptr) = 0; isminetype* is_mine = nullptr) = 0;
//! Get wallet address list.
virtual std::vector<WalletAddress> getAddresses() = 0;
//! Add scripts to key store so old so software versions opening the wallet
//! database can detect payments to newer address types.
virtual void learnRelatedScripts(const CPubKey& key, OutputType type) = 0;
//! Add dest data. //! Add dest data.
virtual bool addDestData(const CTxDestination& dest, const std::string& key, const std::string& value) = 0; virtual bool addDestData(const CTxDestination& dest, const std::string& key, const std::string& value) = 0;
@ -216,6 +231,20 @@ public:
std::string& reject_reason) = 0; std::string& reject_reason) = 0;
}; };
//! Information about one wallet address.
struct WalletAddress
{
CTxDestination dest;
isminetype is_mine;
std::string name;
std::string purpose;
WalletAddress(CTxDestination dest, isminetype is_mine, std::string name, std::string purpose)
: dest(std::move(dest)), is_mine(is_mine), name(std::move(name)), purpose(std::move(purpose))
{
}
};
//! Collection of wallet balances. //! Collection of wallet balances.
struct WalletBalances struct WalletBalances
{ {

View file

@ -7,6 +7,7 @@
#include <qt/guiutil.h> #include <qt/guiutil.h>
#include <qt/walletmodel.h> #include <qt/walletmodel.h>
#include <interface/node.h>
#include <key_io.h> #include <key_io.h>
#include <wallet/wallet.h> #include <wallet/wallet.h>
@ -67,28 +68,23 @@ static AddressTableEntry::Type translateTransactionType(const QString &strPurpos
class AddressTablePriv class AddressTablePriv
{ {
public: public:
CWallet *wallet;
QList<AddressTableEntry> cachedAddressTable; QList<AddressTableEntry> cachedAddressTable;
AddressTableModel *parent; AddressTableModel *parent;
AddressTablePriv(CWallet *_wallet, AddressTableModel *_parent): AddressTablePriv(AddressTableModel *_parent):
wallet(_wallet), parent(_parent) {} parent(_parent) {}
void refreshAddressTable() void refreshAddressTable(interface::Wallet& wallet)
{ {
cachedAddressTable.clear(); cachedAddressTable.clear();
{ {
LOCK(wallet->cs_wallet); for (const auto& address : wallet.getAddresses())
for (const std::pair<CTxDestination, CAddressBookData>& item : wallet->mapAddressBook)
{ {
const CTxDestination& address = item.first;
bool fMine = IsMine(*wallet, address);
AddressTableEntry::Type addressType = translateTransactionType( AddressTableEntry::Type addressType = translateTransactionType(
QString::fromStdString(item.second.purpose), fMine); QString::fromStdString(address.purpose), address.is_mine);
const std::string& strName = item.second.name;
cachedAddressTable.append(AddressTableEntry(addressType, cachedAddressTable.append(AddressTableEntry(addressType,
QString::fromStdString(strName), QString::fromStdString(address.name),
QString::fromStdString(EncodeDestination(address)))); QString::fromStdString(EncodeDestination(address.dest))));
} }
} }
// qLowerBound() and qUpperBound() require our cachedAddressTable list to be sorted in asc order // qLowerBound() and qUpperBound() require our cachedAddressTable list to be sorted in asc order
@ -162,12 +158,12 @@ public:
} }
}; };
AddressTableModel::AddressTableModel(CWallet *_wallet, WalletModel *parent) : AddressTableModel::AddressTableModel(WalletModel *parent) :
QAbstractTableModel(parent),walletModel(parent),wallet(_wallet),priv(0) QAbstractTableModel(parent),walletModel(parent),priv(0)
{ {
columns << tr("Label") << tr("Address"); columns << tr("Label") << tr("Address");
priv = new AddressTablePriv(wallet, this); priv = new AddressTablePriv(this);
priv->refreshAddressTable(); priv->refreshAddressTable(parent->wallet());
} }
AddressTableModel::~AddressTableModel() AddressTableModel::~AddressTableModel()
@ -244,7 +240,6 @@ bool AddressTableModel::setData(const QModelIndex &index, const QVariant &value,
if(role == Qt::EditRole) if(role == Qt::EditRole)
{ {
LOCK(wallet->cs_wallet); /* For SetAddressBook / DelAddressBook */
CTxDestination curAddress = DecodeDestination(rec->address.toStdString()); CTxDestination curAddress = DecodeDestination(rec->address.toStdString());
if(index.column() == Label) if(index.column() == Label)
{ {
@ -254,7 +249,7 @@ bool AddressTableModel::setData(const QModelIndex &index, const QVariant &value,
editStatus = NO_CHANGES; editStatus = NO_CHANGES;
return false; return false;
} }
wallet->SetAddressBook(curAddress, value.toString().toStdString(), strPurpose); walletModel->wallet().setAddressBook(curAddress, value.toString().toStdString(), strPurpose);
} else if(index.column() == Address) { } else if(index.column() == Address) {
CTxDestination newAddress = DecodeDestination(value.toString().toStdString()); CTxDestination newAddress = DecodeDestination(value.toString().toStdString());
// Refuse to set invalid address, set error status and return false // Refuse to set invalid address, set error status and return false
@ -271,7 +266,7 @@ bool AddressTableModel::setData(const QModelIndex &index, const QVariant &value,
} }
// Check for duplicate addresses to prevent accidental deletion of addresses, if you try // Check for duplicate addresses to prevent accidental deletion of addresses, if you try
// to paste an existing address over another address (with a different label) // to paste an existing address over another address (with a different label)
else if(wallet->mapAddressBook.count(newAddress)) if (walletModel->wallet().getAddress(newAddress))
{ {
editStatus = DUPLICATE_ADDRESS; editStatus = DUPLICATE_ADDRESS;
return false; return false;
@ -280,9 +275,9 @@ bool AddressTableModel::setData(const QModelIndex &index, const QVariant &value,
else if(rec->type == AddressTableEntry::Sending) else if(rec->type == AddressTableEntry::Sending)
{ {
// Remove old entry // Remove old entry
wallet->DelAddressBook(curAddress); walletModel->wallet().delAddressBook(curAddress);
// Add new entry with new address // Add new entry with new address
wallet->SetAddressBook(newAddress, rec->label.toStdString(), strPurpose); walletModel->wallet().setAddressBook(newAddress, value.toString().toStdString(), strPurpose);
} }
} }
return true; return true;
@ -356,8 +351,7 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
} }
// Check for duplicate addresses // Check for duplicate addresses
{ {
LOCK(wallet->cs_wallet); if(walletModel->wallet().getAddress(DecodeDestination(strAddress)))
if(wallet->mapAddressBook.count(DecodeDestination(strAddress)))
{ {
editStatus = DUPLICATE_ADDRESS; editStatus = DUPLICATE_ADDRESS;
return QString(); return QString();
@ -368,7 +362,7 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
{ {
// Generate a new address to associate with given label // Generate a new address to associate with given label
CPubKey newKey; CPubKey newKey;
if(!wallet->GetKeyFromPool(newKey)) if(!walletModel->wallet().getKeyFromPool(false /* internal */, newKey))
{ {
WalletModel::UnlockContext ctx(walletModel->requestUnlock()); WalletModel::UnlockContext ctx(walletModel->requestUnlock());
if(!ctx.isValid()) if(!ctx.isValid())
@ -377,13 +371,13 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
editStatus = WALLET_UNLOCK_FAILURE; editStatus = WALLET_UNLOCK_FAILURE;
return QString(); return QString();
} }
if(!wallet->GetKeyFromPool(newKey)) if(!walletModel->wallet().getKeyFromPool(false /* internal */, newKey))
{ {
editStatus = KEY_GENERATION_FAILURE; editStatus = KEY_GENERATION_FAILURE;
return QString(); return QString();
} }
} }
wallet->LearnRelatedScripts(newKey, address_type); walletModel->wallet().learnRelatedScripts(newKey, address_type);
strAddress = EncodeDestination(GetDestinationForKey(newKey, address_type)); strAddress = EncodeDestination(GetDestinationForKey(newKey, address_type));
} }
else else
@ -392,7 +386,7 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
} }
// Add entry // Add entry
wallet->SetAddressBook(DecodeDestination(strAddress), strLabel, walletModel->wallet().setAddressBook(DecodeDestination(strAddress), strLabel,
(type == Send ? "send" : "receive")); (type == Send ? "send" : "receive"));
return QString::fromStdString(strAddress); return QString::fromStdString(strAddress);
} }
@ -407,7 +401,7 @@ bool AddressTableModel::removeRows(int row, int count, const QModelIndex &parent
// Also refuse to remove receiving addresses. // Also refuse to remove receiving addresses.
return false; return false;
} }
wallet->DelAddressBook(DecodeDestination(rec->address.toStdString())); walletModel->wallet().delAddressBook(DecodeDestination(rec->address.toStdString()));
return true; return true;
} }
@ -416,12 +410,11 @@ bool AddressTableModel::removeRows(int row, int count, const QModelIndex &parent
QString AddressTableModel::labelForAddress(const QString &address) const QString AddressTableModel::labelForAddress(const QString &address) const
{ {
{ {
LOCK(wallet->cs_wallet);
CTxDestination destination = DecodeDestination(address.toStdString()); CTxDestination destination = DecodeDestination(address.toStdString());
std::map<CTxDestination, CAddressBookData>::iterator mi = wallet->mapAddressBook.find(destination); std::string name;
if (mi != wallet->mapAddressBook.end()) if (walletModel->wallet().getAddress(destination, &name))
{ {
return QString::fromStdString(mi->second.name); return QString::fromStdString(name);
} }
} }
return QString(); return QString();
@ -441,7 +434,7 @@ int AddressTableModel::lookupAddress(const QString &address) const
} }
} }
OutputType AddressTableModel::GetDefaultAddressType() const { return wallet->m_default_address_type; }; OutputType AddressTableModel::GetDefaultAddressType() const { return walletModel->wallet().getDefaultAddressType(); };
void AddressTableModel::emitDataChanged(int idx) void AddressTableModel::emitDataChanged(int idx)
{ {

View file

@ -13,7 +13,9 @@ enum class OutputType;
class AddressTablePriv; class AddressTablePriv;
class WalletModel; class WalletModel;
class CWallet; namespace interface {
class Wallet;
}
/** /**
Qt model of the address book in the core. This allows views to access and modify the address book. Qt model of the address book in the core. This allows views to access and modify the address book.
@ -23,7 +25,7 @@ class AddressTableModel : public QAbstractTableModel
Q_OBJECT Q_OBJECT
public: public:
explicit AddressTableModel(CWallet *wallet, WalletModel *parent = 0); explicit AddressTableModel(WalletModel *parent = 0);
~AddressTableModel(); ~AddressTableModel();
enum ColumnIndex { enum ColumnIndex {
@ -80,7 +82,6 @@ public:
private: private:
WalletModel *walletModel; WalletModel *walletModel;
CWallet *wallet;
AddressTablePriv *priv; AddressTablePriv *priv;
QStringList columns; QStringList columns;
EditStatus editStatus; EditStatus editStatus;

View file

@ -49,7 +49,7 @@ WalletModel::WalletModel(std::unique_ptr<interface::Wallet> wallet, interface::N
fHaveWatchOnly = m_wallet->haveWatchOnly(); fHaveWatchOnly = m_wallet->haveWatchOnly();
fForceCheckBalanceChanged = false; fForceCheckBalanceChanged = false;
addressTableModel = new AddressTableModel(cwallet, this); addressTableModel = new AddressTableModel(this);
transactionTableModel = new TransactionTableModel(platformStyle, cwallet, this); transactionTableModel = new TransactionTableModel(platformStyle, cwallet, this);
recentRequestsTableModel = new RecentRequestsTableModel(cwallet, this); recentRequestsTableModel = new RecentRequestsTableModel(cwallet, this);