Commit 63754749 authored by Pierre Kim's avatar Pierre Kim

Add RPC command 'f_transaction_details'

parent 360562c7
......@@ -26,11 +26,11 @@ public:
bool fillBlockDetails(const Block& block, BlockDetails& blockDetails);
bool fillTransactionDetails(const Transaction &tx, TransactionDetails& txRpcInfo, uint64_t timestamp = 0);
bool getMixin(const Transaction& transaction, uint64_t& mixin);
static bool getPaymentId(const Transaction& transaction, Crypto::Hash& paymentId);
private:
bool getMixin(const Transaction& transaction, uint64_t& mixin);
bool fillTxExtra(const std::vector<uint8_t>& rawExtra, TransactionExtraDetails& extraDetails);
size_t median(std::vector<size_t>& v);
......
......@@ -61,6 +61,24 @@ struct f_block_short_response {
}
};
struct f_transaction_details_response {
std::string hash;
size_t size;
std::string paymentId;
uint64_t mixin;
uint64_t fee;
uint64_t amount_out;
void serialize(ISerializer &s) {
KV_MEMBER(hash)
KV_MEMBER(size)
KV_MEMBER(paymentId)
KV_MEMBER(mixin)
KV_MEMBER(fee)
KV_MEMBER(amount_out)
}
};
struct f_block_details_response {
uint8_t major_version;
uint8_t minor_version;
......@@ -109,6 +127,29 @@ struct f_block_details_response {
}
};
struct F_COMMAND_RPC_GET_TRANSACTION_DETAILS {
struct request {
std::string hash;
void serialize(ISerializer &s) {
KV_MEMBER(hash)
}
};
struct response {
Transaction tx;
f_transaction_details_response txDetails;
f_block_short_response block;
std::string status;
void serialize(ISerializer &s) {
KV_MEMBER(tx)
KV_MEMBER(txDetails)
KV_MEMBER(block)
KV_MEMBER(status)
}
};
};
struct currency_base_coin {
std::string name;
......
......@@ -135,6 +135,7 @@ bool RpcServer::processJsonRpcRequest(const HttpRequest& request, HttpResponse&
static std::unordered_map<std::string, RpcServer::RpcHandler<JsonMemberMethod>> jsonRpcHandlers = {
{ "f_blocks_list_json",{ makeMemberMethod(&RpcServer::f_on_blocks_list_json), false } },
{ "f_block_json",{ makeMemberMethod(&RpcServer::f_on_block_json), false } },
{ "f_transaction_json",{ makeMemberMethod(&RpcServer::f_on_transaction_json), false } },
{ "getblockcount", { makeMemberMethod(&RpcServer::on_getblockcount), true } },
{ "on_getblockhash", { makeMemberMethod(&RpcServer::on_getblockhash), false } },
{ "getblocktemplate", { makeMemberMethod(&RpcServer::on_getblocktemplate), false } },
......@@ -789,6 +790,85 @@ bool RpcServer::f_on_block_json(const F_COMMAND_RPC_GET_BLOCK_DETAILS::request&
return true;
}
bool RpcServer::f_on_transaction_json(const F_COMMAND_RPC_GET_TRANSACTION_DETAILS::request& req, F_COMMAND_RPC_GET_TRANSACTION_DETAILS::response& res) {
Hash hash;
if (!parse_hash256(req.hash, hash)) {
throw JsonRpc::JsonRpcError{
CORE_RPC_ERROR_CODE_WRONG_PARAM,
"Failed to parse hex representation of transaction hash. Hex = " + req.hash + '.' };
}
std::vector<Crypto::Hash> tx_ids;
tx_ids.push_back(hash);
std::list<Crypto::Hash> missed_txs;
std::list<Transaction> txs;
m_core.getTransactions(tx_ids, txs, missed_txs);
if (1 == txs.size()) {
res.tx = txs.front();
}
else {
throw JsonRpc::JsonRpcError{
CORE_RPC_ERROR_CODE_WRONG_PARAM,
"transaction wasn't found. Hash = " + req.hash + '.' };
}
TransactionDetails transactionDetails;
m_blkExplorer.fillTransactionDetails(res.tx, transactionDetails);
Crypto::Hash blockHash;
if (transactionDetails.inBlockchain) {
uint32_t blockHeight = transactionDetails.blockHeight;
if (!blockHeight) {
throw JsonRpc::JsonRpcError{
CORE_RPC_ERROR_CODE_INTERNAL_ERROR,
"Internal error: can't get transaction by hash. Hash = " + Common::podToHex(hash) + '.' };
}
blockHash = m_core.getBlockIdByHeight(blockHeight);
Block blk;
m_core.getBlockByHash(blockHash, blk);
BlockDetails blkDetails;
m_blkExplorer.fillBlockDetails(blk, blkDetails);
f_block_short_response block_short;
block_short.cumul_size = blkDetails.blockSize;
block_short.timestamp = blk.timestamp;
block_short.height = blockHeight;
block_short.hash = Common::podToHex(blockHash);
block_short.tx_count = blk.transactionHashes.size() + 1;
res.block = block_short;
}
uint64_t amount_in = getInputAmount(res.tx);
uint64_t amount_out = getOutputAmount(res.tx);
res.txDetails.hash = Common::podToHex(getObjectHash(res.tx));
res.txDetails.fee = amount_in - amount_out;
if (amount_in == 0)
res.txDetails.fee = 0;
res.txDetails.amount_out = amount_out;
res.txDetails.size = getObjectBinarySize(res.tx);
uint64_t mixin;
if (!m_blkExplorer.getMixin(res.tx, mixin)) {
return false;
}
res.txDetails.mixin = mixin;
Crypto::Hash paymentId;
if (CryptoNote::getPaymentIdFromTxExtra(res.tx.extra, paymentId)) {
res.txDetails.paymentId = Common::podToHex(paymentId);
}
else {
res.txDetails.paymentId = "";
}
res.status = CORE_RPC_STATUS_OK;
return true;
}
bool RpcServer::enableCors(const std::vector<std::string> domains) {
m_cors_domains = domains;
......
......@@ -68,6 +68,7 @@ private:
bool on_get_block_header_by_height(const COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::request& req, COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::response& res);
bool f_on_blocks_list_json(const COMMAND_RPC_BLOCKS_LIST_JSON::request& req, COMMAND_RPC_BLOCKS_LIST_JSON::response& res);
bool f_on_block_json(const F_COMMAND_RPC_GET_BLOCK_DETAILS::request& req, F_COMMAND_RPC_GET_BLOCK_DETAILS::response& res);
bool f_on_transaction_json(const F_COMMAND_RPC_GET_TRANSACTION_DETAILS::request& req, F_COMMAND_RPC_GET_TRANSACTION_DETAILS::response& res);
void fill_block_header_response(const Block& blk, bool orphan_status, uint64_t height, const Crypto::Hash& hash, block_header_response& responce);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment