Move all RPC to connection class
This commit is contained in:
161
src/rpc.cpp
161
src/rpc.cpp
@@ -71,32 +71,6 @@ void RPC::setConnection(Connection* c) {
|
||||
refresh();
|
||||
}
|
||||
|
||||
void RPC::doRPC(const json& payload, const std::function<void(json)>& cb) {
|
||||
QNetworkReply *reply = conn->restclient->post(*conn->request, QByteArray::fromStdString(payload.dump()));
|
||||
|
||||
QObject::connect(reply, &QNetworkReply::finished, [=] {
|
||||
reply->deleteLater();
|
||||
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
auto parsed = json::parse(reply->readAll(), nullptr, false);
|
||||
if (!parsed.is_discarded() && !parsed["error"]["message"].is_null()) {
|
||||
handleConnectionError(QString::fromStdString(parsed["error"]["message"]));
|
||||
} else {
|
||||
handleConnectionError(reply->errorString());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
auto parsed = json::parse(reply->readAll(), nullptr, false);
|
||||
if (parsed.is_discarded()) {
|
||||
handleConnectionError("Unknown error");
|
||||
}
|
||||
|
||||
cb(parsed["result"]);
|
||||
});
|
||||
}
|
||||
|
||||
void RPC::getZAddresses(const std::function<void(json)>& cb) {
|
||||
json payload = {
|
||||
{"jsonrpc", "1.0"},
|
||||
@@ -104,7 +78,7 @@ void RPC::getZAddresses(const std::function<void(json)>& cb) {
|
||||
{"method", "z_listaddresses"},
|
||||
};
|
||||
|
||||
doRPC(payload, cb);
|
||||
conn->doRPCWithDefaultErrorHandling(payload, cb);
|
||||
}
|
||||
|
||||
void RPC::getTransparentUnspent(const std::function<void(json)>& cb) {
|
||||
@@ -115,7 +89,7 @@ void RPC::getTransparentUnspent(const std::function<void(json)>& cb) {
|
||||
{"params", {0}} // Get UTXOs with 0 confirmations as well.
|
||||
};
|
||||
|
||||
doRPC(payload, cb);
|
||||
conn->doRPCWithDefaultErrorHandling(payload, cb);
|
||||
}
|
||||
|
||||
void RPC::getZUnspent(const std::function<void(json)>& cb) {
|
||||
@@ -126,7 +100,7 @@ void RPC::getZUnspent(const std::function<void(json)>& cb) {
|
||||
{"params", {0}} // Get UTXOs with 0 confirmations as well.
|
||||
};
|
||||
|
||||
doRPC(payload, cb);
|
||||
conn->doRPCWithDefaultErrorHandling(payload, cb);
|
||||
}
|
||||
|
||||
void RPC::newZaddr(bool sapling, const std::function<void(json)>& cb) {
|
||||
@@ -137,7 +111,7 @@ void RPC::newZaddr(bool sapling, const std::function<void(json)>& cb) {
|
||||
{"params", { sapling ? "sapling" : "sprout" }},
|
||||
};
|
||||
|
||||
doRPC(payload, cb);
|
||||
conn->doRPCWithDefaultErrorHandling(payload, cb);
|
||||
}
|
||||
|
||||
void RPC::newTaddr(const std::function<void(json)>& cb) {
|
||||
@@ -147,7 +121,7 @@ void RPC::newTaddr(const std::function<void(json)>& cb) {
|
||||
{"method", "getnewaddress"},
|
||||
};
|
||||
|
||||
doRPC(payload, cb);
|
||||
conn->doRPCWithDefaultErrorHandling(payload, cb);
|
||||
}
|
||||
|
||||
void RPC::getZPrivKey(QString addr, const std::function<void(json)>& cb) {
|
||||
@@ -158,7 +132,7 @@ void RPC::getZPrivKey(QString addr, const std::function<void(json)>& cb) {
|
||||
{"params", { addr.toStdString() }},
|
||||
};
|
||||
|
||||
doRPC(payload, cb);
|
||||
conn->doRPCWithDefaultErrorHandling(payload, cb);
|
||||
}
|
||||
|
||||
void RPC::getTPrivKey(QString addr, const std::function<void(json)>& cb) {
|
||||
@@ -169,7 +143,7 @@ void RPC::getTPrivKey(QString addr, const std::function<void(json)>& cb) {
|
||||
{"params", { addr.toStdString() }},
|
||||
};
|
||||
|
||||
doRPC(payload, cb);
|
||||
conn->doRPCWithDefaultErrorHandling(payload, cb);
|
||||
}
|
||||
|
||||
void RPC::importZPrivKey(QString addr, bool rescan, const std::function<void(json)>& cb) {
|
||||
@@ -180,7 +154,7 @@ void RPC::importZPrivKey(QString addr, bool rescan, const std::function<void(jso
|
||||
{"params", { addr.toStdString(), (rescan? "yes" : "no") }},
|
||||
};
|
||||
|
||||
doSendRPC(payload, cb);
|
||||
conn->doRPCWithDefaultErrorHandling(payload, cb);
|
||||
}
|
||||
|
||||
|
||||
@@ -192,7 +166,7 @@ void RPC::importTPrivKey(QString addr, bool rescan, const std::function<void(jso
|
||||
{"params", { addr.toStdString(), (rescan? "yes" : "no") }},
|
||||
};
|
||||
|
||||
doSendRPC(payload, cb);
|
||||
conn->doRPCWithDefaultErrorHandling(payload, cb);
|
||||
}
|
||||
|
||||
|
||||
@@ -204,7 +178,7 @@ void RPC::getBalance(const std::function<void(json)>& cb) {
|
||||
{"params", {0}} // Get Unconfirmed balance as well.
|
||||
};
|
||||
|
||||
doRPC(payload, cb);
|
||||
conn->doRPCWithDefaultErrorHandling(payload, cb);
|
||||
}
|
||||
|
||||
void RPC::getTransactions(const std::function<void(json)>& cb) {
|
||||
@@ -214,39 +188,7 @@ void RPC::getTransactions(const std::function<void(json)>& cb) {
|
||||
{"method", "listtransactions"}
|
||||
};
|
||||
|
||||
doRPC(payload, cb);
|
||||
}
|
||||
|
||||
void RPC::doSendRPC(const json& payload, const std::function<void(json)>& cb, const std::function<void(QString)>& err) {
|
||||
QNetworkReply *reply = conn->restclient->post(*conn->request, QByteArray::fromStdString(payload.dump()));
|
||||
|
||||
QObject::connect(reply, &QNetworkReply::finished, [=] {
|
||||
reply->deleteLater();
|
||||
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
auto parsed = json::parse(reply->readAll(), nullptr, false);
|
||||
if (!parsed.is_discarded() && !parsed["error"]["message"].is_null()) {
|
||||
err(QString::fromStdString(parsed["error"]["message"]));
|
||||
}
|
||||
else {
|
||||
err(reply->errorString());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
auto parsed = json::parse(reply->readAll(), nullptr, false);
|
||||
if (parsed.is_discarded()) {
|
||||
err("Unknown error");
|
||||
}
|
||||
|
||||
cb(parsed["result"]);
|
||||
});
|
||||
}
|
||||
|
||||
// Default implementation of a Send RPC that default shows an error message box with the error.
|
||||
void RPC::doSendRPC(const json& payload, const std::function<void(json)>& cb) {
|
||||
doSendRPC(payload, cb, [=](auto error) { this->handleTxError(error); });
|
||||
conn->doRPCWithDefaultErrorHandling(payload, cb);
|
||||
}
|
||||
|
||||
void RPC::sendZTransaction(json params, const std::function<void(json)>& cb) {
|
||||
@@ -257,76 +199,9 @@ void RPC::sendZTransaction(json params, const std::function<void(json)>& cb) {
|
||||
{"params", params}
|
||||
};
|
||||
|
||||
doSendRPC(payload, cb);
|
||||
conn->doRPCWithDefaultErrorHandling(payload, cb);
|
||||
}
|
||||
|
||||
void RPC::handleConnectionError(const QString& error) {
|
||||
if (error.isNull()) return;
|
||||
|
||||
QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxCritical);
|
||||
main->statusIcon->setPixmap(icon.pixmap(16, 16));
|
||||
main->statusLabel->setText("No Connection");
|
||||
|
||||
if (firstTime) {
|
||||
this->firstTime = false;
|
||||
|
||||
QMessageBox msg(main);
|
||||
msg.setIcon(QMessageBox::Icon::Critical);
|
||||
msg.setWindowTitle("Connection Error");
|
||||
|
||||
QString explanation;
|
||||
if (error.contains("authentication", Qt::CaseInsensitive)) {
|
||||
explanation = QString()
|
||||
% "\n\nThis is most likely because of misconfigured rpcuser/rpcpassword. "
|
||||
% "zcashd needs the following options set in ~/.zcash/zcash.conf\n\n"
|
||||
% "rpcuser=<someusername>\n"
|
||||
% "rpcpassword=<somepassword>\n"
|
||||
% "\nIf you're connecting to a remote note, you can change the username/password in the "
|
||||
% "File->Settings menu.";
|
||||
} else if (error.contains("connection refused", Qt::CaseInsensitive)) {
|
||||
auto confLocation = Settings::getInstance()->getZcashdConfLocation();
|
||||
if (confLocation.isEmpty()) {
|
||||
explanation = QString()
|
||||
% "\n\nA zcash.conf was not found on this machine. If you are connecting to a remote/non-standard node "
|
||||
% "please set the host/port and user/password in the File->Settings menu.";
|
||||
}
|
||||
else {
|
||||
explanation = QString()
|
||||
% "\n\nA zcash.conf was found at\n" % confLocation
|
||||
% "\nbut we can't connect to zcashd. Is rpcuser=<user> and rpcpassword=<pass> set in the zcash.conf file?";
|
||||
}
|
||||
} else if (error.contains("internal server error", Qt::CaseInsensitive) ||
|
||||
error.contains("rewinding", Qt::CaseInsensitive) ||
|
||||
error.contains("loading", Qt::CaseInsensitive)) {
|
||||
explanation = QString()
|
||||
% "\n\nIf you just started zcashd, then it's still loading and you might have to wait a while. If zcashd is ready, then you've run into "
|
||||
% "something unexpected, and might need to file a bug report here: https://github.com/adityapk00/zec-qt-wallet/issues";
|
||||
} else {
|
||||
explanation = QString()
|
||||
% "\n\nThis is most likely an internal error. Something unexpected happened. "
|
||||
% "You might need to file a bug report here: https://github.com/adityapk00/zec-qt-wallet/issues";
|
||||
}
|
||||
|
||||
msg.setText("There was a network connection error. The error was: \n\n"
|
||||
+ error + explanation);
|
||||
|
||||
msg.exec();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void RPC::handleTxError(const QString& error) {
|
||||
if (error.isNull()) return;
|
||||
|
||||
QMessageBox msg(main);
|
||||
msg.setIcon(QMessageBox::Icon::Critical);
|
||||
msg.setWindowTitle("Transaction Error");
|
||||
|
||||
msg.setText("There was an error sending the transaction. The error was: \n\n"
|
||||
+ error);
|
||||
|
||||
msg.exec();
|
||||
}
|
||||
|
||||
|
||||
// Build the RPC JSON Parameters for this tx (with the dev fee included if applicable)
|
||||
@@ -377,7 +252,7 @@ void RPC::refreshReceivedZTrans(QList<QString> zaddrs) {
|
||||
// and each z-Addr can have multiple received txs.
|
||||
|
||||
// 1. For each z-Addr, get list of received txs
|
||||
getBatchRPC<QString>(zaddrs,
|
||||
conn->doBatchRPC<QString>(zaddrs,
|
||||
[=] (QString zaddr) {
|
||||
json payload = {
|
||||
{"jsonrpc", "1.0"},
|
||||
@@ -414,7 +289,7 @@ void RPC::refreshReceivedZTrans(QList<QString> zaddrs) {
|
||||
}
|
||||
|
||||
// 2. For all txids, go and get the details of that txid.
|
||||
getBatchRPC<QString>(txids.toList(),
|
||||
conn->doBatchRPC<QString>(txids.toList(),
|
||||
[=] (QString txid) {
|
||||
json payload = {
|
||||
{"jsonrpc", "1.0"},
|
||||
@@ -488,7 +363,7 @@ void RPC::getInfoThenRefresh(bool force) {
|
||||
{"method", "getinfo"}
|
||||
};
|
||||
|
||||
doRPC(payload, [=] (const json& reply) {
|
||||
conn->doRPCIgnoreError(payload, [=] (const json& reply) {
|
||||
// Testnet?
|
||||
if (!reply["testnet"].is_null()) {
|
||||
Settings::getInstance()->setTestnet(reply["testnet"].get<json::boolean_t>());
|
||||
@@ -517,7 +392,7 @@ void RPC::getInfoThenRefresh(bool force) {
|
||||
{"method", "getblockchaininfo"}
|
||||
};
|
||||
|
||||
doRPC(payload, [=](const json& reply) {
|
||||
conn->doRPCIgnoreError(payload, [=](const json& reply) {
|
||||
auto progress = reply["verificationprogress"].get<double>();
|
||||
bool isSyncing = progress < 0.999; // 99.9%
|
||||
int blockNumber = reply["blocks"].get<json::number_unsigned_t>();
|
||||
@@ -693,7 +568,7 @@ void RPC::refreshSentZTrans() {
|
||||
}
|
||||
|
||||
// Look up all the txids to get the confirmation count for them.
|
||||
getBatchRPC<QString>(txids,
|
||||
conn->doBatchRPC<QString>(txids,
|
||||
[=] (QString txid) {
|
||||
json payload = {
|
||||
{"jsonrpc", "1.0"},
|
||||
@@ -741,7 +616,7 @@ void RPC::watchTxStatus() {
|
||||
{"method", "z_getoperationstatus"},
|
||||
};
|
||||
|
||||
doRPC(payload, [=] (const json& reply) {
|
||||
conn->doRPCWithDefaultErrorHandling(payload, [=] (const json& reply) {
|
||||
// There's an array for each item in the status
|
||||
for (auto& it : reply.get<json::array_t>()) {
|
||||
// If we were watching this Tx and it's status became "success", then we'll show a status bar alert
|
||||
|
||||
Reference in New Issue
Block a user