Changeset View
Changeset View
Standalone View
Standalone View
src/qt/paymentserver.cpp
Show First 20 Lines • Show All 193 Lines • ▼ Show 20 Lines | #endif | ||||
// Issues to consider: | // Issues to consider: | ||||
// performance (start a thread to fetch in background?) | // performance (start a thread to fetch in background?) | ||||
// privacy (fetch through tor/proxy so IP address isn't revealed) | // privacy (fetch through tor/proxy so IP address isn't revealed) | ||||
// would it be easier to just use a compiled-in blacklist? | // would it be easier to just use a compiled-in blacklist? | ||||
// or use Qt's blacklist? | // or use Qt's blacklist? | ||||
// "certificate stapling" with server-side caching is more efficient | // "certificate stapling" with server-side caching is more efficient | ||||
} | } | ||||
static std::pair<bool, std::string> ipcParseURI(const QString &arg) { | |||||
std::vector<std::string> networks = {CBaseChainParams::MAIN, | |||||
CBaseChainParams::TESTNET, | |||||
CBaseChainParams::REGTEST}; | |||||
for (std::string net : networks) { | |||||
const CChainParams ¶ms(Params(net)); | |||||
const QString scheme = GUIUtil::bitcoinURIScheme(params, true); | |||||
if (!arg.startsWith(scheme + ":", Qt::CaseInsensitive)) { | |||||
continue; | |||||
} | |||||
SendCoinsRecipient r; | |||||
if (!GUIUtil::parseBitcoinURI(scheme, arg, &r)) { | |||||
return {false, std::string{}}; | |||||
} | |||||
if (!IsValidDestinationString(r.address.toStdString(), params)) { | |||||
return {false, std::string{}}; | |||||
} | |||||
savedPaymentRequests.append(arg); | |||||
return {true, net}; | |||||
} | |||||
return {false, std::string{}}; | |||||
} | |||||
deadalnix: It doesn't seem like you need to return a pair. | |||||
// | // | ||||
// Sending to the server is done synchronously, at startup. | // Sending to the server is done synchronously, at startup. | ||||
// If the server isn't already running, startup continues, and the items in | // If the server isn't already running, startup continues, and the items in | ||||
// savedPaymentRequest will be handled when uiReady() is called. | // savedPaymentRequest will be handled when uiReady() is called. | ||||
// | // | ||||
// Warning: ipcSendCommandLine() is called early in init, so don't use "Q_EMIT | // Warning: ipcSendCommandLine() is called early in init, so don't use "Q_EMIT | ||||
// message()", but "QMessageBox::"! | // message()", but "QMessageBox::"! | ||||
// | // | ||||
void PaymentServer::ipcParseCommandLine(int argc, char *argv[]) { | std::string PaymentServer::ipcParseCommandLine(int argc, char *argv[]) { | ||||
std::string network; | |||||
for (int i = 1; i < argc; i++) { | for (int i = 1; i < argc; i++) { | ||||
QString arg(argv[i]); | QString arg(argv[i]); | ||||
if (arg.startsWith("-")) continue; | if (arg.startsWith("-")) continue; | ||||
QString scheme = GUIUtil::bitcoinURIScheme(Params(), false); | auto res = ipcParseURI(arg); | ||||
// If the bitcoincash: URI contains a payment request, we are not able | if (res.first) { | ||||
// to detect the network as that would require fetching and parsing the | if (!network.empty() && network != res.second) { | ||||
// payment request. That means clicking such an URI which contains a | qWarning() << "Addresses from incompatible networks found in " | ||||
// testnet payment request will start a mainnet instance and throw a | "command line. Last parsed network used."; | ||||
// "wrong network" error. | |||||
if (arg.startsWith(scheme + ":", | |||||
Qt::CaseInsensitive)) // bitcoincash: URI | |||||
{ | |||||
savedPaymentRequests.append(arg); | |||||
SendCoinsRecipient r; | |||||
if (GUIUtil::parseBitcoinURI(scheme, arg, &r) && | |||||
!r.address.isEmpty()) { | |||||
if (IsValidDestinationString(r.address.toStdString(), | |||||
Params(CBaseChainParams::MAIN))) { | |||||
SelectParams(CBaseChainParams::MAIN); | |||||
} else if (IsValidDestinationString( | |||||
r.address.toStdString(), | |||||
Params(CBaseChainParams::TESTNET))) { | |||||
SelectParams(CBaseChainParams::TESTNET); | |||||
} | |||||
} | } | ||||
network = res.second; | |||||
continue; | |||||
} else if (QFile::exists(arg)) { | } else if (QFile::exists(arg)) { | ||||
// Filename | // Filename | ||||
savedPaymentRequests.append(arg); | savedPaymentRequests.append(arg); | ||||
PaymentRequestPlus request; | PaymentRequestPlus request; | ||||
if (readPaymentRequestFromFile(arg, request)) { | if (readPaymentRequestFromFile(arg, request)) { | ||||
if (request.getDetails().network() == "main") { | if (request.getDetails().network() == "main") { | ||||
SelectParams(CBaseChainParams::MAIN); | SelectParams(CBaseChainParams::MAIN); | ||||
} else if (request.getDetails().network() == "test") { | } else if (request.getDetails().network() == "test") { | ||||
SelectParams(CBaseChainParams::TESTNET); | SelectParams(CBaseChainParams::TESTNET); | ||||
} | } | ||||
} | } | ||||
deadalnixAuthorUnsubmitted Not Done Inline ActionsI guess this guy should check if the network provided int he address match or not. There are clearly different source of network here and they should all be consistent. We don't want to be sending coins on the wrong network. deadalnix: I guess this guy should check if the network provided int he address match or not. There are… | |||||
} else { | } else { | ||||
// Printing to debug.log is about the best we can do here, the GUI | // Printing to debug.log is about the best we can do here, the GUI | ||||
// hasn't started yet so we can't pop up a message box. | // hasn't started yet so we can't pop up a message box. | ||||
qWarning() << "PaymentServer::ipcSendCommandLine: Payment request " | qWarning() << "PaymentServer::ipcSendCommandLine: Payment request " | ||||
"file does not exist: " | "file does not exist: " | ||||
<< arg; | << arg; | ||||
} | } | ||||
} | } | ||||
return network; | |||||
} | } | ||||
// | // | ||||
// Sending to the server is done synchronously, at startup. | // Sending to the server is done synchronously, at startup. | ||||
// If the server isn't already running, startup continues, and the items in | // If the server isn't already running, startup continues, and the items in | ||||
// savedPaymentRequest will be handled when uiReady() is called. | // savedPaymentRequest will be handled when uiReady() is called. | ||||
// | // | ||||
bool PaymentServer::ipcSendCommandLine() { | bool PaymentServer::ipcSendCommandLine() { | ||||
▲ Show 20 Lines • Show All 121 Lines • ▼ Show 20 Lines | |||||
void PaymentServer::handleURIOrFile(const QString &s) { | void PaymentServer::handleURIOrFile(const QString &s) { | ||||
if (saveURIs) { | if (saveURIs) { | ||||
savedPaymentRequests.append(s); | savedPaymentRequests.append(s); | ||||
return; | return; | ||||
} | } | ||||
// bitcoincash: URI | // bitcoincash: URI | ||||
QString scheme = GUIUtil::bitcoinURIScheme(Params(), false); | QString scheme = GUIUtil::bitcoinURIScheme(Params(), true); | ||||
if (s.startsWith(scheme + ":", Qt::CaseInsensitive)) { | if (s.startsWith(scheme + ":", Qt::CaseInsensitive)) { | ||||
#if QT_VERSION < 0x050000 | #if QT_VERSION < 0x050000 | ||||
QUrl uri(s); | QUrl uri(s); | ||||
#else | #else | ||||
QUrlQuery uri((QUrl(s))); | QUrlQuery uri((QUrl(s))); | ||||
#endif | #endif | ||||
if (uri.hasQueryItem("r")) { | if (uri.hasQueryItem("r")) { | ||||
// payment request URI | // payment request URI | ||||
▲ Show 20 Lines • Show All 418 Lines • Show Last 20 Lines |
It doesn't seem like you need to return a pair.