config()->set(Config::donateBeg, -1);
});
- connect(m_wallet, &Wallet::multiBroadcast, this, [this](PendingTransaction *tx){
- quint64 count = tx->txCount();
- for (quint64 i = 0; i < count; i++) {
- QString txData = tx->signedTxToHex(i);
-
- for (const auto& node: m_nodes->nodes()) {
- QString address = node.toURL();
- qDebug() << QString("Relaying %1 to: %2").arg(tx->txid()[i], address);
- m_rpc->setDaemonAddress(address);
- m_rpc->sendRawTransaction(txData);
- }
- }
- });
+ connect(m_wallet, &Wallet::multiBroadcast, this, &MainWindow::onMultiBroadcast);
}
void MainWindow::menuToggleTabVisible(const QString &key){
this->onConnectionStatusChanged(Wallet::ConnectionStatus_Disconnected);
}
+void MainWindow::onMultiBroadcast(const QMap<QString, QString> &txHexMap) {
+ QMapIterator<QString, QString> i(txHexMap);
+ while (i.hasNext()) {
+ i.next();
+ for (const auto& node: m_nodes->nodes()) {
+ QString address = node.toURL();
+ qDebug() << QString("Relaying %1 to: %2").arg(i.key(), address);
+ m_rpc->setDaemonAddress(address);
+ m_rpc->sendRawTransaction(i.value());
+ }
+ }
+}
+
void MainWindow::onSynchronized() {
this->updateNetStats();
this->setStatusText("Synchronized");
}
}
-void MainWindow::onTransactionCommitted(bool status, PendingTransaction *tx, const QStringList& txid) {
- if (status) { // success
+void MainWindow::onTransactionCommitted(bool success, PendingTransaction *tx, const QStringList& txid) {
+ if (success) {
QMessageBox msgBox{this};
QPushButton *showDetailsButton = msgBox.addButton("Show details", QMessageBox::ActionRole);
msgBox.addButton(QMessageBox::Ok);
connect(this, &Wallet::updated, this, &Wallet::onUpdated);
connect(this, &Wallet::heightsRefreshed, this, &Wallet::onHeightsRefreshed);
connect(this, &Wallet::transactionCreated, this, &Wallet::onTransactionCreated);
+ connect(this, &Wallet::transactionCommitted, this, &Wallet::onTransactionCommitted);
}
// #################### Status ####################
}
qInfo() << "Creating transaction";
-
m_scheduler.run([this, all, address, amount] {
std::set<uint32_t> subaddr_indices;
- Monero::PendingTransaction * ptImpl = m_walletImpl->createTransaction(address.toStdString(), "", all ? Monero::optional<uint64_t>() : Monero::optional<uint64_t>(amount), constants::mixin,
- static_cast<Monero::PendingTransaction::Priority>(this->tx_priority),
- currentSubaddressAccount(), subaddr_indices, m_selectedInputs);
- PendingTransaction *tx = new PendingTransaction(ptImpl, this);
+ Monero::PendingTransaction *ptImpl = m_walletImpl->createTransaction(address.toStdString(), "", all ? Monero::optional<uint64_t>() : Monero::optional<uint64_t>(amount), constants::mixin,
+ static_cast<Monero::PendingTransaction::Priority>(this->tx_priority),
+ currentSubaddressAccount(), subaddr_indices, m_selectedInputs);
QVector<QString> addresses{address};
- emit transactionCreated(tx, addresses);
+ emit transactionCreated(ptImpl, addresses);
});
emit initiateTransaction();
Monero::PendingTransaction *ptImpl = m_walletImpl->createTransactionMultDest(dests, "", amount, constants::mixin,
static_cast<Monero::PendingTransaction::Priority>(this->tx_priority),
currentSubaddressAccount(), subaddr_indices, m_selectedInputs);
- PendingTransaction *tx = new PendingTransaction(ptImpl);
- emit transactionCreated(tx, addresses);
+
+ emit transactionCreated(ptImpl, addresses);
});
emit initiateTransaction();
kis.push_back(key_image.toStdString());
}
Monero::PendingTransaction *ptImpl = m_walletImpl->createTransactionSelected(kis, address.toStdString(), outputs, static_cast<Monero::PendingTransaction::Priority>(this->tx_priority));
- PendingTransaction *tx = new PendingTransaction(ptImpl, this);
QVector<QString> addresses {address};
- emit transactionCreated(tx, addresses);
+ emit transactionCreated(ptImpl, addresses);
});
emit initiateTransaction();
emit endTransaction();
}
-void Wallet::onTransactionCreated(PendingTransaction *tx, const QVector<QString> &address) {
+void Wallet::onTransactionCreated(Monero::PendingTransaction *mtx, const QVector<QString> &address) {
qDebug() << Q_FUNC_INFO;
+ PendingTransaction *tx = new PendingTransaction(mtx, this);
+
for (auto &addr : address) {
if (addr == constants::donationAddress) {
this->donationSending = true;
// Clear list of selected transfers
this->setSelectedInputs({});
- // Nodes - even well-connected, properly configured ones - consistently fail to relay transactions
- // To mitigate transactions failing we just send the transaction to every node we know about over Tor
- if (config()->get(Config::multiBroadcast).toBool()) {
- // Let MainWindow handle this
- emit multiBroadcast(tx);
+ QMap<QString, QString> txHexMap;
+ for (int i = 0; i < tx->txCount(); i++) {
+ txHexMap[tx->txid()[i]] = tx->signedTxToHex(i);
}
- m_scheduler.run([this, tx, description] {
+ m_scheduler.run([this, tx, description, txHexMap] {
auto txIdList = tx->txid(); // retrieve before commit
bool success = tx->commit();
}
}
- // Store wallet immediately, so we don't risk losing tx key if wallet crashes
- this->storeSafer();
+ emit transactionCommitted(success, tx, txIdList, txHexMap);
+ });
+}
- this->history()->refresh(this->currentSubaddressAccount());
- this->coins()->refresh(this->currentSubaddressAccount());
+void Wallet::onTransactionCommitted(bool success, PendingTransaction *tx, const QStringList &txid, const QMap<QString, QString> &txHexMap) {
+ // Store wallet immediately, so we don't risk losing tx key if wallet crashes
+ this->storeSafer();
- this->updateBalance();
+ this->history()->refresh(this->currentSubaddressAccount());
+ this->coins()->refresh(this->currentSubaddressAccount());
+ this->updateBalance();
- // this tx was a donation to Feather, stop our nagging
- if (this->donationSending) {
- this->donationSending = false;
- emit donationSent();
- }
+ if (!success) {
+ return;
+ }
- emit transactionCommitted(success, tx, txIdList);
- });
+ // Nodes - even well-connected, properly configured ones - consistently fail to relay transactions
+ // To mitigate transactions failing we just send the transaction to every node we know about over Tor
+ if (config()->get(Config::multiBroadcast).toBool()) {
+ // Let MainWindow handle this
+ emit multiBroadcast(txHexMap);
+ }
+
+ // this tx was a donation to Feather, stop our nagging
+ if (this->donationSending) {
+ this->donationSending = false;
+ emit donationSent();
+ }
}
void Wallet::disposeTransaction(PendingTransaction *t) {
void onCreateTransactionError(const QString &msg);
void commitTransaction(PendingTransaction *tx, const QString &description="");
+ void onTransactionCommitted(bool success, PendingTransaction *tx, const QStringList& txid, const QMap<QString, QString> &txHexMap);
//! deletes transaction and frees memory
void disposeTransaction(PendingTransaction * t);
void deviceButtonPressed();
void deviceError(const QString &message);
void walletPassphraseNeeded(bool onDevice);
- void transactionCommitted(bool status, PendingTransaction *t, const QStringList& txid);
+ void transactionCommitted(bool status, PendingTransaction *t, const QStringList& txid, const QMap<QString, QString> &txHexMap);
void deviceShowAddressShowed();
void transactionProofVerified(TxProofResult result);
void spendProofVerified(QPair<bool, bool> result);
// emitted when transaction is created async
- void transactionCreated(PendingTransaction * transaction, QVector<QString> address);
+ void transactionCreated(Monero::PendingTransaction *ptImpl, QVector<QString> address);
void connectionStatusChanged(int status) const;
void currentSubaddressAccountChanged() const;
void selectedInputsChanged(const QStringList &selectedInputs);
- void multiBroadcast(PendingTransaction *tx);
+ void multiBroadcast(const QMap<QString, QString> &txHexMap);
void heightsRefreshed(bool success, quint64 daemonHeight, quint64 targetHeight);
private:
void onRefreshed(bool success, const QString &message);
// ##### Transactions #####
- void onTransactionCreated(PendingTransaction *tx, const QVector<QString> &address);
+ void onTransactionCreated(Monero::PendingTransaction *mtx, const QVector<QString> &address);
private:
friend class WalletManager;