Browse Source

Show unconfirmed addresses in the balances table

pull/14/head
Aditya Kulkarni 5 years ago
parent
commit
deff437c1d
  1. 13
      src/balancestablemodel.cpp
  2. 4
      src/balancestablemodel.h
  3. 34
      src/controller.cpp
  4. 4
      src/controller.h
  5. 1
      src/datamodel.h
  6. 47
      src/mainwindow.ui

13
src/balancestablemodel.cpp

@ -14,11 +14,11 @@ void BalancesTableModel::setNewData(const QList<QString> zaddrs, const QList<QSt
int currentRows = rowCount(QModelIndex());
// Copy over the utxos for our use
delete utxos;
utxos = new QList<UnspentOutput>();
delete unspentOutputs;
unspentOutputs = new QList<UnspentOutput>();
// This is a QList deep copy.
*utxos = outputs;
*unspentOutputs = outputs;
// Process the address balances into a list
delete modeldata;
@ -50,7 +50,7 @@ void BalancesTableModel::setNewData(const QList<QString> zaddrs, const QList<QSt
BalancesTableModel::~BalancesTableModel() {
delete modeldata;
delete utxos;
delete unspentOutputs;
}
int BalancesTableModel::rowCount(const QModelIndex&) const
@ -83,8 +83,9 @@ QVariant BalancesTableModel::data(const QModelIndex &index, int role) const
if (role == Qt::ForegroundRole) {
// If any of the UTXOs for this address has zero confirmations, paint it in red
const auto& addr = std::get<0>(modeldata->at(index.row()));
for (auto utxo : *utxos) {
if (utxo.address == addr && !utxo.spendable) {
for (auto unconfirmedOutput : *unspentOutputs) {
if (unconfirmedOutput.address == addr &&
(!unconfirmedOutput.spendable || unconfirmedOutput.pending)) {
QBrush b;
b.setColor(Qt::red);
return b;

4
src/balancestablemodel.h

@ -18,8 +18,8 @@ public:
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
private:
QList<std::tuple<QString, qint64>>* modeldata = nullptr;
QList<UnspentOutput>* utxos = nullptr;
QList<std::tuple<QString, qint64>>* modeldata = nullptr;
QList<UnspentOutput>* unspentOutputs = nullptr;
bool loading = true;
};

34
src/controller.cpp

@ -254,26 +254,30 @@ void Controller::updateUI(bool anyUnconfirmed) {
};
// Function to process reply of the listunspent and z_listunspent API calls, used below.
bool Controller::processUnspent(const json& reply, QMap<QString, qint64>* balancesMap, QList<UnspentOutput>* newUtxos) {
bool anyUnconfirmed = false;
auto processFn = [=](const json& array) {
void Controller::processUnspent(const json& reply, QMap<QString, qint64>* balancesMap, QList<UnspentOutput>* unspentOutputs) {
auto processFn = [=](const json& array) -> bool {
for (auto& it : array) {
QString qsAddr = QString::fromStdString(it["address"]);
int block = it["created_in_block"].get<json::number_unsigned_t>();
QString txid = QString::fromStdString(it["created_in_txid"]);
QString amount = Settings::getDecimalString(it["value"].get<json::number_unsigned_t>());
newUtxos->push_back(UnspentOutput{ qsAddr, txid, amount, block, true });
bool spendable = it["unconfirmed_spent"].is_null() && it["spent"].is_null(); // TODO: Wait for 4 confirmations
bool pending = !it["unconfirmed_spent"].is_null();
qDebug() << "For address" << qsAddr << "spendable, pending" << spendable << ":" << pending;
(*balancesMap)[qsAddr] = (*balancesMap)[qsAddr] + it["value"].get<json::number_unsigned_t>();
}
unspentOutputs->push_back(UnspentOutput{ qsAddr, txid, amount, block, spendable, pending });
if (spendable) {
(*balancesMap)[qsAddr] = (*balancesMap)[qsAddr] + it["value"].get<json::number_unsigned_t>();
}
}
};
processFn(reply["unspent_notes"].get<json::array_t>());
processFn(reply["utxos"].get<json::array_t>());
return anyUnconfirmed;
processFn(reply["pending_notes"].get<json::array_t>());
processFn(reply["pending_utxos"].get<json::array_t>());
};
void Controller::refreshBalances() {
@ -300,16 +304,22 @@ void Controller::refreshBalances() {
// 2. Get the UTXOs
// First, create a new UTXO list. It will be replacing the existing list when everything is processed.
auto newUtxos = new QList<UnspentOutput>();
auto newUnspentOutputs = new QList<UnspentOutput>();
auto newBalances = new QMap<QString, qint64>();
// Call the Transparent and Z unspent APIs serially and then, once they're done, update the UI
zrpc->fetchUnspent([=] (json reply) {
auto anyUnconfirmed = processUnspent(reply, newBalances, newUtxos);
processUnspent(reply, newBalances, newUnspentOutputs);
// Swap out the balances and UTXOs
model->replaceBalances(newBalances);
model->replaceUTXOs(newUtxos);
model->replaceUTXOs(newUnspentOutputs);
// Find if any output is not spendable or is pending
bool anyUnconfirmed = std::find_if(newUnspentOutputs->constBegin(), newUnspentOutputs->constEnd(),
[=](const UnspentOutput& u) -> bool {
return !u.spendable || u.pending;
}) != newUnspentOutputs->constEnd();
updateUI(anyUnconfirmed);

4
src/controller.h

@ -78,7 +78,7 @@ private:
void refreshTransactions();
bool processUnspent (const json& reply, QMap<QString, qint64>* newBalances, QList<UnspentOutput>* newUtxos);
void processUnspent (const json& reply, QMap<QString, qint64>* newBalances, QList<UnspentOutput>* newUnspentOutputs);
void updateUI (bool anyUnconfirmed);
void getInfoThenRefresh(bool force);
@ -89,7 +89,7 @@ private:
BalancesTableModel* balancesTableModel = nullptr;
DataModel* model;
LiteInterface* zrpc;
LiteInterface* zrpc;
QTimer* timer;
QTimer* txTimer;

1
src/datamodel.h

@ -10,6 +10,7 @@ struct UnspentOutput {
QString amount;
int blockCreated;
bool spendable;
bool pending;
};

47
src/mainwindow.ui

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>968</width>
<height>616</height>
<width>1274</width>
<height>779</height>
</rect>
</property>
<property name="windowTitle">
@ -22,7 +22,7 @@
<item row="0" column="0">
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>2</number>
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
@ -148,26 +148,13 @@
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="lblSyncWarning">
<property name="styleSheet">
<string notr="true">color:red;</string>
</property>
<property name="text">
<string>Your node is still syncing, balances may not be updated</string>
<string>Your node is still syncing, balances may not be updated.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
@ -186,10 +173,26 @@
<string notr="true">color: red;</string>
</property>
<property name="text">
<string>Some transactions are not yet confirmed</string>
<string>Some transactions are not yet confirmed. Balances may change.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
@ -359,8 +362,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>920</width>
<height>301</height>
<width>1162</width>
<height>344</height>
</rect>
</property>
<layout class="QVBoxLayout" name="sendToLayout">
@ -1051,8 +1054,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>968</width>
<height>22</height>
<width>1274</width>
<height>39</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">

Loading…
Cancel
Save