Merge pull request #3145

395d0d5 rework an ugly hack in processPaymentRequest() (Philip Kaufmann)
952d2cd make processPaymentRequest() use a single SendCoinsRecipient (Philip Kaufmann)
983cef4 payment-request UI: use SendCoinsRecipient.message for memo (Philip Kaufmann)
c6c97e0 [Qt] Rework of payment request UI (mainly for insecure pr) (Philip Kaufmann)
This commit is contained in:
Wladimir J. van der Laan
2013-11-06 16:39:04 +01:00
8 changed files with 614 additions and 96 deletions

View File

@@ -280,9 +280,6 @@ PaymentServer::PaymentServer(QObject* parent, bool startLocalServer) :
connect(this, SIGNAL(receivedPaymentACK(QString)), this, SLOT(handlePaymentACK(QString)));
}
}
// netManager is null until uiReady() is called
netManager = NULL;
}
PaymentServer::~PaymentServer()
@@ -378,6 +375,7 @@ void PaymentServer::handleURIOrFile(const QString& s)
fetchRequest(fetchUrl);
else
qDebug() << "PaymentServer::handleURIOrFile : Invalid URL: " << fetchUrl;
return;
}
@@ -388,18 +386,17 @@ void PaymentServer::handleURIOrFile(const QString& s)
emit message(tr("URI handling"),
tr("URI can not be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters."),
CClientUIInterface::ICON_WARNING);
return;
}
if (QFile::exists(s))
{
PaymentRequestPlus request;
QList<SendCoinsRecipient> recipients;
if (readPaymentRequest(s, request) && processPaymentRequest(request, recipients)) {
foreach (const SendCoinsRecipient& recipient, recipients){
emit receivedPaymentRequest(recipient);
}
}
SendCoinsRecipient recipient;
if (readPaymentRequest(s, request) && processPaymentRequest(request, recipient))
emit receivedPaymentRequest(recipient);
return;
}
}
@@ -445,14 +442,37 @@ bool PaymentServer::readPaymentRequest(const QString& filename, PaymentRequestPl
return request.parse(data);
}
bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, QList<SendCoinsRecipient>& recipients)
bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoinsRecipient& recipient)
{
if (!optionsModel)
return false;
QList<std::pair<CScript,qint64> > sendingTos = request.getPayTo();
qint64 totalAmount = 0;
recipient.paymentRequest = request;
recipient.message = GUIUtil::HtmlEscape(request.getDetails().memo());
request.getMerchant(PaymentServer::certStore, recipient.authenticatedMerchant);
QList<std::pair<CScript, qint64> > sendingTos = request.getPayTo();
QStringList addresses;
foreach(const PAIRTYPE(CScript, qint64)& sendingTo, sendingTos) {
// Extract and check destination addresses
CTxDestination dest;
if (ExtractDestination(sendingTo.first, dest)) {
// Append destination address
addresses.append(QString::fromStdString(CBitcoinAddress(dest).ToString()));
}
else if (!recipient.authenticatedMerchant.isEmpty()){
// Insecure payments to custom bitcoin addresses are not supported
// (there is no good way to tell the user where they are paying in a way
// they'd have a chance of understanding).
emit message(tr("Payment request error"),
tr("Unverified payment requests to custom payment scripts are unsupported."),
CClientUIInterface::MSG_ERROR);
return false;
}
// Extract and check amounts
CTxOut txOut(sendingTo.second, sendingTo.first);
if (txOut.IsDust(CTransaction::nMinRelayTxFee)) {
QString msg = tr("Requested payment amount of %1 is too small (considered dust).")
@@ -463,43 +483,16 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, QList<Sen
return false;
}
totalAmount += sendingTo.second;
recipient.amount += sendingTo.second;
}
// Store addresses and format them to fit nicely into the GUI
recipient.address = addresses.join("<br />");
recipients.append(SendCoinsRecipient());
if (request.getMerchant(PaymentServer::certStore, recipients[0].authenticatedMerchant)) {
recipients[0].paymentRequest = request;
recipients[0].amount = totalAmount;
qDebug() << "PaymentServer::processPaymentRequest : Payment request from " << recipients[0].authenticatedMerchant;
if (!recipient.authenticatedMerchant.isEmpty()) {
qDebug() << "PaymentServer::processPaymentRequest : Secure payment request from " << recipient.authenticatedMerchant;
}
else {
recipients.clear();
// Insecure payment requests may turn into more than one recipient if
// the merchant is requesting payment to more than one address.
for (int i = 0; i < sendingTos.size(); i++) {
std::pair<CScript, qint64>& sendingTo = sendingTos[i];
recipients.append(SendCoinsRecipient());
recipients[i].amount = sendingTo.second;
QString memo = QString::fromStdString(request.getDetails().memo());
recipients[i].label = GUIUtil::HtmlEscape(memo);
CTxDestination dest;
if (ExtractDestination(sendingTo.first, dest)) {
if (i == 0) // Tie request to first pay-to, we don't want multiple ACKs
recipients[i].paymentRequest = request;
recipients[i].address = QString::fromStdString(CBitcoinAddress(dest).ToString());
qDebug() << "PaymentServer::processPaymentRequest : Payment request, insecure " << recipients[i].address;
}
else {
// Insecure payments to custom bitcoin addresses are not supported
// (there is no good way to tell the user where they are paying in a way
// they'd have a chance of understanding).
emit message(tr("Payment request error"),
tr("Insecure requests to custom payment scripts unsupported"),
CClientUIInterface::MSG_ERROR);
return false;
}
}
qDebug() << "PaymentServer::processPaymentRequest : Insecure payment request to " << addresses.join(", ");
}
return true;
@@ -590,12 +583,9 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply)
if (requestType == "PaymentRequest")
{
PaymentRequestPlus request;
QList<SendCoinsRecipient> recipients;
if (request.parse(data) && processPaymentRequest(request, recipients)) {
foreach (const SendCoinsRecipient& recipient, recipients) {
emit receivedPaymentRequest(recipient);
}
}
SendCoinsRecipient recipient;
if (request.parse(data) && processPaymentRequest(request, recipient))
emit receivedPaymentRequest(recipient);
else
qDebug() << "PaymentServer::netRequestFinished : Error processing payment request";