2015-05-27 12:08:46 +00:00
|
|
|
// Copyright (c) 2012-2015, The CryptoNote developers, The Bytecoin developers
|
|
|
|
//
|
|
|
|
// This file is part of Bytecoin.
|
|
|
|
//
|
|
|
|
// Bytecoin is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU Lesser General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// Bytecoin is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
|
|
// along with Bytecoin. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
#include "PaymentServiceJsonRpcServer.h"
|
|
|
|
|
|
|
|
#include "PaymentServiceJsonRpcMessages.h"
|
2015-05-27 12:08:46 +00:00
|
|
|
#include "WalletService.h"
|
|
|
|
|
|
|
|
#include "Common/JsonValue.h"
|
2015-07-30 15:22:07 +00:00
|
|
|
#include "Serialization/JsonInputValueSerializer.h"
|
|
|
|
#include "Serialization/JsonOutputStreamSerializer.h"
|
2015-05-27 12:08:46 +00:00
|
|
|
|
|
|
|
namespace PaymentService {
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
PaymentServiceJsonRpcServer::PaymentServiceJsonRpcServer(System::Dispatcher& sys, System::Event& stopEvent, WalletService& service, Logging::ILogger& loggerGroup)
|
|
|
|
: JsonRpcServer(sys, stopEvent, loggerGroup)
|
|
|
|
, service(service)
|
|
|
|
, logger(loggerGroup, "PaymentServiceJsonRpcServer")
|
2015-05-27 12:08:46 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
void PaymentServiceJsonRpcServer::processJsonRpcRequest(const Common::JsonValue& req, Common::JsonValue& resp) {
|
2015-05-27 12:08:46 +00:00
|
|
|
try {
|
|
|
|
prepareJsonResponse(req, resp);
|
|
|
|
|
|
|
|
std::string method = req("method").getString();
|
|
|
|
|
2015-07-15 12:23:00 +00:00
|
|
|
CryptoNote::JsonInputValueSerializer inputSerializer(req("params"));
|
2015-05-27 12:08:46 +00:00
|
|
|
CryptoNote::JsonOutputStreamSerializer outputSerializer;
|
|
|
|
|
|
|
|
if (method == "send_transaction") {
|
|
|
|
SendTransactionRequest sendReq;
|
|
|
|
SendTransactionResponse sendResp;
|
|
|
|
|
|
|
|
//XXX: refactor it when migrate to different exception types in different subsystems!
|
|
|
|
try {
|
2015-07-15 12:23:00 +00:00
|
|
|
serialize(sendReq, inputSerializer);
|
2015-05-27 12:08:46 +00:00
|
|
|
} catch (std::exception&) {
|
|
|
|
makeGenericErrorReponse(resp, "Invalid Request", -32600);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::error_code ec = service.sendTransaction(sendReq, sendResp);
|
|
|
|
if (ec) {
|
|
|
|
makeErrorResponse(ec, resp);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-07-15 12:23:00 +00:00
|
|
|
serialize(sendResp, outputSerializer);
|
2015-05-27 12:08:46 +00:00
|
|
|
} else if (method == "get_address") {
|
2015-07-30 15:22:07 +00:00
|
|
|
GetAddressRequest getAddrReq;
|
2015-05-27 12:08:46 +00:00
|
|
|
GetAddressResponse getAddrResp;
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
//XXX: refactor it when migrate to different exception types in different subsystems!
|
|
|
|
try {
|
|
|
|
serialize(getAddrReq, inputSerializer);
|
|
|
|
} catch (std::exception&) {
|
|
|
|
makeGenericErrorReponse(resp, "Invalid Request", -32600);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::error_code ec = service.getAddress(getAddrReq.index, getAddrResp.address);
|
2015-05-27 12:08:46 +00:00
|
|
|
if (ec) {
|
|
|
|
makeErrorResponse(ec, resp);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-07-15 12:23:00 +00:00
|
|
|
serialize(getAddrResp, outputSerializer);
|
2015-07-30 15:22:07 +00:00
|
|
|
} else if (method == "create_address") {
|
|
|
|
CreateAddressResponse createAddrResp;
|
|
|
|
|
|
|
|
std::error_code ec = service.createAddress(createAddrResp.address);
|
|
|
|
if (ec) {
|
|
|
|
makeErrorResponse(ec, resp);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
serialize(createAddrResp, outputSerializer);
|
|
|
|
} else if (method == "get_address_count") {
|
|
|
|
GetAddressCountResponse addressCountResp;
|
|
|
|
|
|
|
|
std::error_code ec = service.getAddressCount(addressCountResp.count);
|
|
|
|
if (ec) {
|
|
|
|
makeErrorResponse(ec, resp);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
serialize(addressCountResp, outputSerializer);
|
|
|
|
} else if (method == "delete_address") {
|
|
|
|
DeleteAddressRequest delAddrReq;
|
|
|
|
DeleteAddressResponse delAddrResp;
|
|
|
|
|
|
|
|
//XXX: refactor it when migrate to different exception types in different subsystems!
|
|
|
|
try {
|
|
|
|
serialize(delAddrReq, inputSerializer);
|
|
|
|
} catch (std::exception&) {
|
|
|
|
makeGenericErrorReponse(resp, "Invalid Request", -32600);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::error_code ec = service.deleteAddress(delAddrReq.address);
|
|
|
|
if (ec) {
|
|
|
|
makeErrorResponse(ec, resp);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
serialize(delAddrResp, outputSerializer);
|
2015-05-27 12:08:46 +00:00
|
|
|
} else if (method == "get_actual_balance") {
|
2015-07-30 15:22:07 +00:00
|
|
|
GetActualBalanceRequest actualReq;
|
2015-05-27 12:08:46 +00:00
|
|
|
GetActualBalanceResponse actualResp;
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
//XXX: refactor it when migrate to different exception types in different subsystems!
|
|
|
|
try {
|
|
|
|
serialize(actualReq, inputSerializer);
|
|
|
|
} catch (std::exception&) {
|
|
|
|
makeGenericErrorReponse(resp, "Invalid Request", -32600);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::error_code ec;
|
|
|
|
if (actualReq.address == "") {
|
|
|
|
ec = service.getActualBalance(actualResp.actualBalance);
|
|
|
|
} else {
|
|
|
|
ec = service.getActualBalance(actualReq.address, actualResp.actualBalance);
|
|
|
|
}
|
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
if (ec) {
|
|
|
|
makeErrorResponse(ec, resp);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-07-15 12:23:00 +00:00
|
|
|
serialize(actualResp, outputSerializer);
|
2015-05-27 12:08:46 +00:00
|
|
|
} else if (method == "get_pending_balance") {
|
2015-07-30 15:22:07 +00:00
|
|
|
GetPendingBalanceRequest pendingReq;
|
2015-05-27 12:08:46 +00:00
|
|
|
GetPendingBalanceResponse pendingResp;
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
//XXX: refactor it when migrate to different exception types in different subsystems!
|
|
|
|
try {
|
|
|
|
serialize(pendingReq, inputSerializer);
|
|
|
|
} catch (std::exception&) {
|
|
|
|
makeGenericErrorReponse(resp, "Invalid Request", -32600);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::error_code ec;
|
|
|
|
if (pendingReq.address == "") {
|
|
|
|
ec = service.getPendingBalance(pendingResp.pendingBalance);
|
|
|
|
} else {
|
|
|
|
ec = service.getPendingBalance(pendingReq.address, pendingResp.pendingBalance);
|
|
|
|
}
|
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
if (ec) {
|
|
|
|
makeErrorResponse(ec, resp);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-07-15 12:23:00 +00:00
|
|
|
serialize(pendingResp, outputSerializer);
|
2015-05-27 12:08:46 +00:00
|
|
|
} else if (method == "get_transactions_count") {
|
|
|
|
GetTransactionsCountResponse txResp;
|
|
|
|
|
|
|
|
std::error_code ec = service.getTransactionsCount(txResp.transactionsCount);
|
|
|
|
if (ec) {
|
|
|
|
makeErrorResponse(ec, resp);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-07-15 12:23:00 +00:00
|
|
|
serialize(txResp, outputSerializer);
|
2015-05-27 12:08:46 +00:00
|
|
|
} else if (method == "get_transfers_count") {
|
|
|
|
GetTransfersCountResponse trResp;
|
|
|
|
|
|
|
|
std::error_code ec = service.getTransfersCount(trResp.transfersCount);
|
|
|
|
if (ec) {
|
|
|
|
makeErrorResponse(ec, resp);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-07-15 12:23:00 +00:00
|
|
|
serialize(trResp, outputSerializer);
|
2015-05-27 12:08:46 +00:00
|
|
|
} else if (method == "get_transaction_id_by_transfer_id") {
|
|
|
|
GetTransactionIdByTransferIdRequest getReq;
|
|
|
|
GetTransactionIdByTransferIdResponse getResp;
|
|
|
|
|
|
|
|
//XXX: refactor it when migrate to different exception types in different subsystems!
|
|
|
|
try {
|
2015-07-15 12:23:00 +00:00
|
|
|
serialize(getReq, inputSerializer);
|
2015-05-27 12:08:46 +00:00
|
|
|
} catch (std::exception&) {
|
|
|
|
makeGenericErrorReponse(resp, "Invalid Request", -32600);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
size_t txId;
|
2015-05-27 12:08:46 +00:00
|
|
|
std::error_code ec = service.getTransactionByTransferId(getReq.transferId, txId);
|
|
|
|
getResp.transactionid = txId;
|
|
|
|
if (ec) {
|
|
|
|
makeErrorResponse(ec, resp);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-07-15 12:23:00 +00:00
|
|
|
serialize(getResp, outputSerializer);
|
2015-05-27 12:08:46 +00:00
|
|
|
} else if (method == "get_transaction") {
|
|
|
|
GetTransactionRequest getReq;
|
|
|
|
GetTransactionResponse getResp;
|
|
|
|
|
|
|
|
//XXX: refactor it when migrate to different exception types in different subsystems!
|
|
|
|
try {
|
2015-07-15 12:23:00 +00:00
|
|
|
serialize(getReq, inputSerializer);
|
2015-05-27 12:08:46 +00:00
|
|
|
} catch (std::exception&) {
|
|
|
|
makeGenericErrorReponse(resp, "Invalid Request", -32600);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::error_code ec = service.getTransaction(getReq.transactionId, getResp.found, getResp.transactionInfo);
|
|
|
|
if (ec) {
|
|
|
|
makeErrorResponse(ec, resp);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-07-15 12:23:00 +00:00
|
|
|
serialize(getResp, outputSerializer);
|
|
|
|
} else if (method == "list_transactions") {
|
|
|
|
ListTransactionsRequest listReq;
|
|
|
|
ListTransactionsResponse listResp;
|
|
|
|
|
|
|
|
//XXX: refactor it when migrate to different exception types in different subsystems!
|
|
|
|
try {
|
|
|
|
serialize(listReq, inputSerializer);
|
|
|
|
} catch (std::exception&) {
|
|
|
|
makeGenericErrorReponse(resp, "Invalid Request", -32600);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
std::error_code ec = service.listTransactions(static_cast<size_t>(listReq.startingTransactionId), listReq.maxTransactionCount, listResp.transactions);
|
2015-07-15 12:23:00 +00:00
|
|
|
if (ec) {
|
|
|
|
makeErrorResponse(ec, resp);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
serialize(listResp, outputSerializer);
|
2015-05-27 12:08:46 +00:00
|
|
|
} else if (method == "get_transfer") {
|
|
|
|
GetTransferRequest getReq;
|
|
|
|
GetTransferResponse getResp;
|
|
|
|
|
|
|
|
//XXX: refactor it when migrate to different exception types in different subsystems!
|
|
|
|
try {
|
2015-07-15 12:23:00 +00:00
|
|
|
serialize(getReq, inputSerializer);
|
2015-05-27 12:08:46 +00:00
|
|
|
} catch (std::exception&) {
|
|
|
|
makeGenericErrorReponse(resp, "Invalid Request", -32600);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::error_code ec = service.getTransfer(getReq.transferId, getResp.found, getResp.transferInfo);
|
|
|
|
if (ec) {
|
|
|
|
makeErrorResponse(ec, resp);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-07-15 12:23:00 +00:00
|
|
|
serialize(getResp, outputSerializer);
|
2015-05-27 12:08:46 +00:00
|
|
|
} else if (method == "get_incoming_payments") {
|
|
|
|
GetIncomingPaymentsRequest getReq;
|
|
|
|
GetIncomingPaymentsResponse getResp;
|
|
|
|
|
|
|
|
//XXX: refactor it when migrate to different exception types in different subsystems!
|
|
|
|
try {
|
2015-07-15 12:23:00 +00:00
|
|
|
serialize(getReq, inputSerializer);
|
2015-05-27 12:08:46 +00:00
|
|
|
} catch (std::exception&) {
|
|
|
|
makeGenericErrorReponse(resp, "Invalid Request", -32600);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
WalletService::IncomingPayments payments;
|
|
|
|
std::error_code ec = service.getIncomingPayments(getReq.payments, payments);
|
|
|
|
if (ec) {
|
2015-07-30 15:22:07 +00:00
|
|
|
if (ec == make_error_code(std::errc::argument_out_of_domain)) {
|
2015-05-27 12:08:46 +00:00
|
|
|
makeGenericErrorReponse(resp, "Invalid Request", -32600);
|
|
|
|
} else {
|
|
|
|
makeErrorResponse(ec, resp);
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (auto p: payments) {
|
|
|
|
PaymentsById pbid;
|
|
|
|
pbid.id = std::move(p.first);
|
|
|
|
pbid.payments = std::move(p.second);
|
|
|
|
|
|
|
|
getResp.payments.push_back(std::move(pbid));
|
|
|
|
}
|
|
|
|
|
2015-07-15 12:23:00 +00:00
|
|
|
serialize(getResp, outputSerializer);
|
2015-05-27 12:08:46 +00:00
|
|
|
} else {
|
|
|
|
logger(Logging::DEBUGGING) << "Requested method not found: " << method;
|
|
|
|
makeMethodNotFoundResponse(resp);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-07-15 12:23:00 +00:00
|
|
|
fillJsonResponse(outputSerializer.getValue(), resp);
|
2015-05-27 12:08:46 +00:00
|
|
|
|
|
|
|
} catch (RequestSerializationError&) {
|
|
|
|
logger(Logging::WARNING) << "Wrong request came";
|
|
|
|
makeGenericErrorReponse(resp, "Invalid Request", -32600);
|
|
|
|
} catch (std::exception& e) {
|
2015-07-30 15:22:07 +00:00
|
|
|
logger(Logging::WARNING) << "Error occurred while processing JsonRpc request: " << e.what();
|
2015-05-27 12:08:46 +00:00
|
|
|
makeGenericErrorReponse(resp, e.what());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|