Skip to content

Commit 363abec

Browse files
committed
[GUI][Model] Sending cold staking addresses flow fully connected. Wallet supporting contact creation, update and removal.
1 parent 4e2dc20 commit 363abec

File tree

7 files changed

+83
-68
lines changed

7 files changed

+83
-68
lines changed

src/qt/addresstablemodel.cpp

Lines changed: 48 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const QString AddressTableModel::Receive = "R";
2222
const QString AddressTableModel::Zerocoin = "X";
2323
const QString AddressTableModel::Delegators = "D";
2424
const QString AddressTableModel::ColdStaking = "C";
25+
const QString AddressTableModel::ColdStakingSend = "Csend";
2526

2627
struct AddressTableEntry {
2728
enum Type {
@@ -30,6 +31,7 @@ struct AddressTableEntry {
3031
Zerocoin,
3132
Delegators,
3233
ColdStaking,
34+
ColdStakingSend,
3335
Hidden /* QSortFilterProxyModel will filter these out */
3436
};
3537

@@ -73,6 +75,8 @@ static AddressTableEntry::Type translateTransactionType(const QString& strPurpos
7375
addressType = AddressTableEntry::Delegators;
7476
else if (strPurpose == QString::fromStdString(AddressBook::AddressBookPurpose::COLD_STAKING))
7577
addressType = AddressTableEntry::ColdStaking;
78+
else if (strPurpose == QString::fromStdString(AddressBook::AddressBookPurpose::COLD_STAKING_SEND))
79+
addressType = AddressTableEntry::ColdStakingSend;
7680
else if (strPurpose == "unknown" || strPurpose == "") // if purpose not set, guess
7781
addressType = (isMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending);
7882
return addressType;
@@ -87,6 +91,7 @@ class AddressTablePriv
8791
int sendNum = 0;
8892
int recvNum = 0;
8993
int dellNum = 0;
94+
int coldSendNum = 0;
9095
AddressTableModel* parent;
9196

9297
AddressTablePriv(CWallet* wallet, AddressTableModel* parent) : wallet(wallet), parent(parent) {}
@@ -97,39 +102,22 @@ class AddressTablePriv
97102
{
98103
LOCK(wallet->cs_wallet);
99104
for (const PAIRTYPE(CTxDestination, AddressBook::CAddressBookData) & item : wallet->mapAddressBook) {
100-
const CBitcoinAddress& address = item.first;
105+
106+
const CChainParams::Base58Type addrType =
107+
item.second.isColdStakingPurpose() ?
108+
CChainParams::STAKING_ADDRESS : CChainParams::PUBKEY_ADDRESS;
109+
const CBitcoinAddress address = CBitcoinAddress(item.first, addrType);
110+
101111
bool fMine = IsMine(*wallet, address.Get());
102112
AddressTableEntry::Type addressType = translateTransactionType(
103113
QString::fromStdString(item.second.purpose), fMine);
104114
const std::string& strName = item.second.name;
105115

106116
uint creationTime = 0;
107-
108-
if(item.second.purpose == "receive"){
117+
if(item.second.isReceivePurpose())
109118
creationTime = static_cast<uint>(wallet->GetKeyCreationTime(address));
110-
recvNum++;
111-
} else if(item.second.purpose == "send"){
112-
sendNum++;
113-
} else if (item.second.purpose == AddressBook::AddressBookPurpose::DELEGABLE
114-
|| item.second.purpose == AddressBook::AddressBookPurpose::DELEGATOR
115-
|| item.second.purpose == AddressBook::AddressBookPurpose::COLD_STAKING) {
116-
dellNum++;
117-
118-
// TODO: Remove this when addresses are well parsed, this is a dirty dirty way to fix things quickly only for testing purposes..
119-
CKeyID keyID;
120-
if (address.GetKeyID(keyID)) {
121-
CBitcoinAddress stakingAddress(keyID, CChainParams::STAKING_ADDRESS);
122-
cachedAddressTable.append(
123-
AddressTableEntry(addressType,
124-
QString::fromStdString(strName),
125-
QString::fromStdString(stakingAddress.ToString()),
126-
creationTime
127-
)
128-
);
129-
}
130-
continue;
131-
}
132119

120+
updatePurposeCachedCounted(item.second.purpose, true);
133121
cachedAddressTable.append(
134122
AddressTableEntry(addressType,
135123
QString::fromStdString(strName),
@@ -145,6 +133,20 @@ class AddressTablePriv
145133
qSort(cachedAddressTable.begin(), cachedAddressTable.end(), AddressTableEntryLessThan());
146134
}
147135

136+
void updatePurposeCachedCounted(std::string purpose, bool add) {
137+
int *var;
138+
if (purpose == AddressBook::AddressBookPurpose::RECEIVE) {
139+
var = &recvNum;
140+
} else if (purpose == AddressBook::AddressBookPurpose::SEND) {
141+
var = &sendNum;
142+
} else if (purpose == AddressBook::AddressBookPurpose::COLD_STAKING_SEND) {
143+
var = &coldSendNum;
144+
} else if (purpose == AddressBook::AddressBookPurpose::DELEGABLE || purpose == AddressBook::AddressBookPurpose::DELEGATOR) {
145+
var = &dellNum;
146+
}
147+
if (add) (*var)++; else (*var)--;
148+
}
149+
148150
void updateEntry(const QString& address, const QString& label, bool isMine, const QString& purpose, int status)
149151
{
150152
// Find address / label in model
@@ -164,12 +166,13 @@ class AddressTablePriv
164166
break;
165167
}
166168
uint creationTime = 0;
167-
if (purpose == "receive") {
169+
170+
std::string stdPurpose = purpose.toStdString();
171+
if (stdPurpose == AddressBook::AddressBookPurpose::RECEIVE)
168172
creationTime = static_cast<uint>(wallet->GetKeyCreationTime(CBitcoinAddress(address.toStdString())));
169-
recvNum++;
170-
} else if (purpose == "send") {
171-
sendNum++;
172-
}
173+
174+
updatePurposeCachedCounted(stdPurpose, true);
175+
173176
parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex);
174177
cachedAddressTable.insert(lowerIndex, AddressTableEntry(newEntryType, label, address, creationTime));
175178
parent->endInsertRows();
@@ -193,11 +196,7 @@ class AddressTablePriv
193196
parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex - 1);
194197
cachedAddressTable.erase(lower, upper);
195198
parent->endRemoveRows();
196-
if (purpose == "receive") {
197-
recvNum--;
198-
} else if (purpose == "send") {
199-
sendNum--;
200-
}
199+
updatePurposeCachedCounted(purpose.toStdString(), false);
201200
break;
202201
}
203202
}
@@ -257,6 +256,10 @@ class AddressTablePriv
257256
return dellNum;
258257
}
259258

259+
int SizeColdSend() {
260+
return coldSendNum;
261+
}
262+
260263
AddressTableEntry* index(int idx)
261264
{
262265
if (idx >= 0 && idx < cachedAddressTable.size()) {
@@ -302,6 +305,10 @@ int AddressTableModel::sizeDell() const {
302305
return priv->sizeDell();
303306
}
304307

308+
int AddressTableModel::sizeColdSend() const {
309+
return priv->SizeColdSend();
310+
}
311+
305312
QVariant AddressTableModel::data(const QModelIndex& index, int role) const
306313
{
307314
if (!index.isValid())
@@ -338,6 +345,8 @@ QVariant AddressTableModel::data(const QModelIndex& index, int role) const
338345
return Delegators;
339346
case AddressTableEntry::ColdStaking:
340347
return ColdStaking;
348+
case AddressTableEntry::ColdStakingSend:
349+
return ColdStakingSend;
341350
default:
342351
break;
343352
}
@@ -503,14 +512,15 @@ bool AddressTableModel::removeRows(int row, int count, const QModelIndex& parent
503512
{
504513
Q_UNUSED(parent);
505514
AddressTableEntry* rec = priv->index(row);
506-
if (count != 1 || !rec || rec->type == AddressTableEntry::Receiving) {
515+
if (count != 1 || !rec || rec->type == AddressTableEntry::Receiving || rec->type == AddressTableEntry::ColdStaking) {
507516
// Can only remove one row at a time, and cannot remove rows not in model.
508517
// Also refuse to remove receiving addresses.
509518
return false;
510519
}
520+
const CChainParams::Base58Type addrType = (rec->type == AddressTableEntry::ColdStakingSend) ? CChainParams::STAKING_ADDRESS : CChainParams::PUBKEY_ADDRESS;
511521
{
512522
LOCK(wallet->cs_wallet);
513-
return wallet->DelAddressBook(CBitcoinAddress(rec->address.toStdString()).Get());
523+
return wallet->DelAddressBook(CBitcoinAddress(rec->address.toStdString()).Get(), addrType);
514524
}
515525
}
516526

@@ -536,15 +546,7 @@ QString AddressTableModel::labelForAddress(const QString& address) const
536546
*/
537547
std::string AddressTableModel::purposeForAddress(const std::string& address) const
538548
{
539-
{
540-
LOCK(wallet->cs_wallet);
541-
CBitcoinAddress address_parsed(address);
542-
std::map<CTxDestination, AddressBook::CAddressBookData>::iterator mi = wallet->mapAddressBook.find(address_parsed.Get());
543-
if (mi != wallet->mapAddressBook.end()) {
544-
return mi->second.purpose;
545-
}
546-
}
547-
return "";
549+
return wallet->purposeForAddress(CBitcoinAddress(address).Get());
548550
}
549551

550552
int AddressTableModel::lookupAddress(const QString& address) const

src/qt/addresstablemodel.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,9 @@ class AddressTableModel : public QAbstractTableModel
4848
static const QString Send; /**< Specifies send address */
4949
static const QString Receive; /**< Specifies receive address */
5050
static const QString Zerocoin; /**< Specifies stealth address */
51-
static const QString Delegators;
52-
static const QString ColdStaking;
51+
static const QString Delegators; /**< Specifies cold staking addresses which delegated tokens to this wallet */
52+
static const QString ColdStaking; /**< Specifies cold staking own addresses */
53+
static const QString ColdStakingSend; /**< Specifies send cold staking addresses (simil 'contacts')*/
5354

5455
/** @name Methods overridden from QAbstractTableModel
5556
@{*/
@@ -58,6 +59,7 @@ class AddressTableModel : public QAbstractTableModel
5859
int sizeSend() const;
5960
int sizeRecv() const;
6061
int sizeDell() const;
62+
int sizeColdSend() const;
6163
void notifyChange(const QModelIndex &index);
6264
QVariant data(const QModelIndex& index, int role) const;
6365
bool setData(const QModelIndex& index, const QVariant& value, int role);

src/qt/pivx/addresseswidget.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ void AddressesWidget::handleAddressClicked(const QModelIndex &index){
153153
void AddressesWidget::loadWalletModel(){
154154
if(walletModel) {
155155
addressTablemodel = walletModel->getAddressTableModel();
156-
this->filter = new AddressFilterProxyModel(AddressTableModel::Send, this);
156+
this->filter = new AddressFilterProxyModel(QStringList({AddressTableModel::Send, AddressTableModel::ColdStakingSend}), this);
157157
this->filter->setSourceModel(addressTablemodel);
158158
ui->listAddresses->setModel(this->filter);
159159
ui->listAddresses->setModelColumn(AddressTableModel::Address);
@@ -193,7 +193,9 @@ void AddressesWidget::onStoreContactClicked(){
193193
return;
194194
}
195195

196-
if (walletModel->updateAddressBookLabels(pivAdd.Get(), label.toUtf8().constData(), "send")) {
196+
if (walletModel->updateAddressBookLabels(pivAdd.Get(), label.toUtf8().constData(),
197+
pivAdd.IsStakingAddress() ? AddressBook::AddressBookPurpose::COLD_STAKING_SEND : AddressBook::AddressBookPurpose::SEND)
198+
) {
197199
ui->lineEditAddress->setText("");
198200
ui->lineEditName->setText("");
199201
setCssEditLine(ui->lineEditAddress, true, true);
@@ -218,7 +220,7 @@ void AddressesWidget::onEditClicked(){
218220
dialog->setData(address, currentLabel);
219221
if(openDialogWithOpaqueBackground(dialog, window)){
220222
if(walletModel->updateAddressBookLabels(
221-
CBitcoinAddress(address.toStdString()).Get(), dialog->getLabel().toStdString(), "send")){
223+
CBitcoinAddress(address.toStdString()).Get(), dialog->getLabel().toStdString(), addressTablemodel->purposeForAddress(address.toStdString()))){
222224
inform(tr("Contact edited"));
223225
}else{
224226
inform(tr("Contact edit failed"));

src/qt/pivx/addressfilterproxymodel.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ bool AddressFilterProxyModel::filterAcceptsRow(int row, const QModelIndex& paren
1111
auto label = model->index(row, AddressTableModel::Label, parent);
1212

1313
auto type = model->data(label, AddressTableModel::TypeRole).toString();
14-
if (type != m_type)
14+
if (!m_types.contains(type))
1515
return false;
1616

1717
auto address = model->index(row, AddressTableModel::Address, parent);
@@ -26,7 +26,12 @@ bool AddressFilterProxyModel::filterAcceptsRow(int row, const QModelIndex& paren
2626

2727
void AddressFilterProxyModel::setType(const QString& type)
2828
{
29-
this->m_type = type;
29+
setType(QStringList(type));
30+
}
31+
32+
void AddressFilterProxyModel::setType(const QStringList& types)
33+
{
34+
this->m_types = types;
3035
invalidateFilter();
3136
}
3237

src/qt/pivx/addressfilterproxymodel.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,17 @@ class AddressFilterProxyModel final : public QSortFilterProxyModel
1515
public:
1616
AddressFilterProxyModel(const QString& type, QObject* parent)
1717
: QSortFilterProxyModel(parent)
18-
, m_type(type) {
18+
, m_types({type}) {
19+
init();
20+
}
21+
22+
AddressFilterProxyModel(const QStringList& types, QObject* parent)
23+
: QSortFilterProxyModel(parent)
24+
, m_types(types) {
25+
init();
26+
}
27+
28+
void init() {
1929
setDynamicSortFilter(true);
2030
setFilterCaseSensitivity(Qt::CaseInsensitive);
2131
setSortCaseSensitivity(Qt::CaseInsensitive);
@@ -24,12 +34,13 @@ class AddressFilterProxyModel final : public QSortFilterProxyModel
2434
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
2535

2636
void setType(const QString& type);
37+
void setType(const QStringList& types);
2738

2839
protected:
2940
bool filterAcceptsRow(int row, const QModelIndex& parent) const override;
3041

3142
private:
32-
QString m_type;
43+
QStringList m_types;
3344
};
3445

3546

src/qt/pivx/coldstakingwidget.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ void ColdStakingWidget::onContactsClicked(){
281281
menu->hide();
282282
}
283283

284-
int contactsSize = isContactOwnerSelected ? walletModel->getAddressTableModel()->sizeSend() : walletModel->getAddressTableModel()->sizeDell();
284+
int contactsSize = isContactOwnerSelected ? walletModel->getAddressTableModel()->sizeSend() : walletModel->getAddressTableModel()->sizeColdSend();
285285
if(contactsSize == 0) {
286286
inform(tr("No contacts available, you can go to the contacts screen and add some there!"));
287287
return;
@@ -327,12 +327,7 @@ void ColdStakingWidget::onContactsClicked(){
327327
return;
328328
}
329329

330-
if (isContactOwnerSelected) {
331-
menuContacts->setWalletModel(walletModel, AddressTableModel::Receive);
332-
} else {
333-
menuContacts->setWalletModel(walletModel, AddressTableModel::Delegators);
334-
}
335-
330+
menuContacts->setWalletModel(walletModel, isContactOwnerSelected ? AddressTableModel::Receive : AddressTableModel::ColdStakingSend);
336331
menuContacts->resizeList(width, height);
337332
menuContacts->setStyleSheet(styleSheet());
338333
menuContacts->adjustSize();

src/qt/walletmodel.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -506,12 +506,10 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction& tran
506506
foreach (const SendCoinsRecipient& rcp, transaction.getRecipients()) {
507507
// Don't touch the address book when we have a payment request
508508
if (!rcp.paymentRequest.IsInitialized()) {
509-
510-
std::string strAddress = rcp.address.toStdString();
511-
CTxDestination dest = CBitcoinAddress(strAddress).Get();
509+
CBitcoinAddress address = CBitcoinAddress(rcp.address.toStdString());
510+
std::string purpose = address.IsStakingAddress() ? AddressBook::AddressBookPurpose::COLD_STAKING_SEND : AddressBook::AddressBookPurpose::SEND;
512511
std::string strLabel = rcp.label.toStdString();
513-
514-
updateAddressBookLabels(dest, strLabel, "send");
512+
updateAddressBookLabels(address.Get(), strLabel, purpose);
515513
}
516514
emit coinsSent(wallet, rcp, transaction_array);
517515
}
@@ -717,7 +715,7 @@ static void NotifyKeyStoreStatusChanged(WalletModel* walletmodel, CCryptoKeyStor
717715

718716
static void NotifyAddressBookChanged(WalletModel* walletmodel, CWallet* wallet, const CTxDestination& address, const std::string& label, bool isMine, const std::string& purpose, ChangeType status)
719717
{
720-
QString strAddress = QString::fromStdString(CBitcoinAddress(address).ToString());
718+
QString strAddress = QString::fromStdString(pwalletMain->ParseIntoAddress(address, purpose).ToString());
721719
QString strLabel = QString::fromStdString(label);
722720
QString strPurpose = QString::fromStdString(purpose);
723721

0 commit comments

Comments
 (0)