mirror of
https://git.wownero.com/wownero/onion-wownero-blockchain-explorer.git
synced 2024-08-15 00:33:12 +00:00
Merge pull request #58 from moneroexamples/json_mempool_add_limit
Some new json api added
This commit is contained in:
commit
a6c530bffc
5 changed files with 517 additions and 43 deletions
98
README.md
98
README.md
|
@ -380,9 +380,9 @@ Partial results shown:
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
#### api/mempool
|
#### api/mempool
|
||||||
|
|
||||||
|
Return all txs in the mempool.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -w "\n" -X GET "http://139.162.32.245:8081/api/mempool"
|
curl -w "\n" -X GET "http://139.162.32.245:8081/api/mempool"
|
||||||
|
@ -392,28 +392,47 @@ Partial results shown:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"data": [
|
"data": {
|
||||||
|
"limit": 100000000,
|
||||||
|
"page": 0,
|
||||||
|
"total_page_no": 0,
|
||||||
|
"txs": [
|
||||||
{
|
{
|
||||||
"coinbase": false,
|
"coinbase": false,
|
||||||
"extra": "02210001c32d313b74a859b904079c69dbc04ea6e37eddcf4aeb34e9400cc12831da5401b34082a9ff7476fe29a19fa6a1735a9c59db226b9ddcf715928aa71625b13062",
|
"extra": "022100325f677d96f94155a4840a84d8e0c905f7a4697a25744633bcb438feb1e51fb2012eda81bf552c53c2168f4130dbe0265c3a7898f3a7eee7c1fed955a778167b5d",
|
||||||
"mixin": 7,
|
"mixin": 3,
|
||||||
"payment_id": "01c32d313b74a859b904079c69dbc04ea6e37eddcf4aeb34e9400cc12831da54",
|
"payment_id": "325f677d96f94155a4840a84d8e0c905f7a4697a25744633bcb438feb1e51fb2",
|
||||||
"payment_id8": "",
|
"payment_id8": "",
|
||||||
"rct_type": 1,
|
"rct_type": 2,
|
||||||
"timestamp": 1492763220,
|
"timestamp": 1494470894,
|
||||||
"timestamp_utc": "2017-04-21 08:27:00",
|
"timestamp_utc": "2017-05-11 02:48:14",
|
||||||
"tx_fee": 4083040000,
|
"tx_fee": 15894840000,
|
||||||
"tx_hash": "6751e0029558fdc4ab4528896529e32b2864c6ad43c5d8838c8ebe156ada0514",
|
"tx_hash": "9f3374f8ac67febaab153eab297937a3d0d2c706601e496bf5028146da0c9aef",
|
||||||
"tx_size": 13224,
|
"tx_size": 13291,
|
||||||
"tx_version": 2,
|
"tx_version": 2,
|
||||||
"xmr_inputs": 0,
|
"xmr_inputs": 0,
|
||||||
"xmr_outputs": 0
|
"xmr_outputs": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"txs_no": 7
|
||||||
|
},
|
||||||
"status": "success"
|
"status": "success"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Limit of 100000000 is just default value above to ensure that all mempool txs are fetched
|
||||||
|
if no specific limit given.
|
||||||
|
|
||||||
|
#### api/mempool?limit=<no_of_top_txs>
|
||||||
|
|
||||||
|
Return number of newest mempool txs, e.g., only 10.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -w "\n" -X GET "http://139.162.32.245:8081/api/mempool?limit=10"
|
||||||
|
```
|
||||||
|
|
||||||
|
Result analogical to the one above.
|
||||||
|
|
||||||
#### api/search/<block_number|tx_hash|block_hash>
|
#### api/search/<block_number|tx_hash|block_hash>
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
@ -453,6 +472,7 @@ Partial results shown:
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
#### api/outputs?txhash=<tx_hash>&address=<address>&viewkey=<viewkey>&txprove=<0|1>
|
#### api/outputs?txhash=<tx_hash>&address=<address>&viewkey=<viewkey>&txprove=<0|1>
|
||||||
|
|
||||||
For `txprove=0` we check which outputs belong to given address and corresponding viewkey.
|
For `txprove=0` we check which outputs belong to given address and corresponding viewkey.
|
||||||
|
@ -529,6 +549,62 @@ curl -w "\n" -X GET "http://139.162.32.245:8082/api/outputs?txhash=94782a8c0aa8
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Result analogical to the one above.
|
||||||
|
|
||||||
|
#### api/networkinfo
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -w "\n" -X GET "http://139.162.32.245:8081/api/networkinfo"
|
||||||
|
```
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"alt_blocks_count": 0,
|
||||||
|
"block_size_limit": 600000,
|
||||||
|
"cumulative_difficulty": 2067724366624367,
|
||||||
|
"difficulty": 7530486740,
|
||||||
|
"grey_peerlist_size": 4987,
|
||||||
|
"hash_rate": 62754056,
|
||||||
|
"height": 1307537,
|
||||||
|
"incoming_connections_count": 0,
|
||||||
|
"outgoing_connections_count": 8,
|
||||||
|
"start_time": 1494473774,
|
||||||
|
"status": "OK",
|
||||||
|
"target": 120,
|
||||||
|
"target_height": 1307518,
|
||||||
|
"testnet": false,
|
||||||
|
"top_block_hash": "0726de5b86f431547fc64fc2c8e1c11d76843ada0561993ee540e4eee29d83c3",
|
||||||
|
"tx_count": 1210222,
|
||||||
|
"tx_pool_size": 5,
|
||||||
|
"white_peerlist_size": 1000
|
||||||
|
},
|
||||||
|
"status": "success"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### api/rawblock/<block_number|block_hash>
|
||||||
|
|
||||||
|
Return raw json block data, as represented in Monero.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -w "\n" -X GET "http://139.162.32.245:8081/api/rawblock/1293257"
|
||||||
|
```
|
||||||
|
|
||||||
|
Example result not shown.
|
||||||
|
|
||||||
|
#### api/rawtransaction/<tx_hash>
|
||||||
|
|
||||||
|
Return raw json tx data, as represented in Monero.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -w "\n" -X GET "http://139.162.32.245:8081/api/rawtransaction/6093260dbe79fd6277694d14789dc8718f1bd54457df8bab338c2efa3bb0f03d"
|
||||||
|
```
|
||||||
|
|
||||||
|
Example result not shown.
|
||||||
|
|
||||||
## Other monero examples
|
## Other monero examples
|
||||||
|
|
||||||
Other examples can be found on [github](https://github.com/moneroexamples?tab=repositories).
|
Other examples can be found on [github](https://github.com/moneroexamples?tab=repositories).
|
||||||
|
|
36
main.cpp
36
main.cpp
|
@ -363,6 +363,14 @@ int main(int ac, const char* av[]) {
|
||||||
return r;
|
return r;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
CROW_ROUTE(app, "/api/rawtransaction/<string>")
|
||||||
|
([&](const crow::request &req, string tx_hash) {
|
||||||
|
|
||||||
|
myxmr::jsonresponse r{xmrblocks.json_rawtransaction(tx_hash)};
|
||||||
|
|
||||||
|
return r;
|
||||||
|
});
|
||||||
|
|
||||||
CROW_ROUTE(app, "/api/block/<string>")
|
CROW_ROUTE(app, "/api/block/<string>")
|
||||||
([&](const crow::request &req, string block_no_or_hash) {
|
([&](const crow::request &req, string block_no_or_hash) {
|
||||||
|
|
||||||
|
@ -371,6 +379,13 @@ int main(int ac, const char* av[]) {
|
||||||
return r;
|
return r;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
CROW_ROUTE(app, "/api/rawblock/<string>")
|
||||||
|
([&](const crow::request &req, string block_no_or_hash) {
|
||||||
|
|
||||||
|
myxmr::jsonresponse r{xmrblocks.json_rawblock(block_no_or_hash)};
|
||||||
|
|
||||||
|
return r;
|
||||||
|
});
|
||||||
|
|
||||||
CROW_ROUTE(app, "/api/transactions").methods("GET"_method)
|
CROW_ROUTE(app, "/api/transactions").methods("GET"_method)
|
||||||
([&](const crow::request &req) {
|
([&](const crow::request &req) {
|
||||||
|
@ -386,10 +401,19 @@ int main(int ac, const char* av[]) {
|
||||||
return r;
|
return r;
|
||||||
});
|
});
|
||||||
|
|
||||||
CROW_ROUTE(app, "/api/mempool")
|
CROW_ROUTE(app, "/api/mempool").methods("GET"_method)
|
||||||
([&](const crow::request &req) {
|
([&](const crow::request &req) {
|
||||||
|
|
||||||
myxmr::jsonresponse r{xmrblocks.json_mempool()};
|
string page = regex_search(req.raw_url, regex {"page=\\d+"}) ?
|
||||||
|
req.url_params.get("page") : "0";
|
||||||
|
|
||||||
|
// default value for limit is some large number, so that
|
||||||
|
// a call to api/mempool without any limit return all
|
||||||
|
// mempool txs
|
||||||
|
string limit = regex_search(req.raw_url, regex {"limit=\\d+"}) ?
|
||||||
|
req.url_params.get("limit") : "100000000";
|
||||||
|
|
||||||
|
myxmr::jsonresponse r{xmrblocks.json_mempool(page, limit)};
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
});
|
});
|
||||||
|
@ -402,6 +426,14 @@ int main(int ac, const char* av[]) {
|
||||||
return r;
|
return r;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
CROW_ROUTE(app, "/api/networkinfo")
|
||||||
|
([&](const crow::request &req) {
|
||||||
|
|
||||||
|
myxmr::jsonresponse r{xmrblocks.json_networkinfo()};
|
||||||
|
|
||||||
|
return r;
|
||||||
|
});
|
||||||
|
|
||||||
CROW_ROUTE(app, "/api/outputs").methods("GET"_method)
|
CROW_ROUTE(app, "/api/outputs").methods("GET"_method)
|
||||||
([&](const crow::request &req) {
|
([&](const crow::request &req) {
|
||||||
|
|
||||||
|
|
324
src/page.h
324
src/page.h
|
@ -3834,6 +3834,91 @@ namespace xmreg
|
||||||
return j_response;
|
return j_response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lets use this json api convention for success and error
|
||||||
|
* https://labs.omniti.com/labs/jsend
|
||||||
|
*/
|
||||||
|
json
|
||||||
|
json_rawtransaction(string tx_hash_str)
|
||||||
|
{
|
||||||
|
json j_response {
|
||||||
|
{"status", "fail"},
|
||||||
|
{"data" , json {}}
|
||||||
|
};
|
||||||
|
|
||||||
|
json& j_data = j_response["data"];
|
||||||
|
|
||||||
|
// parse tx hash string to hash object
|
||||||
|
crypto::hash tx_hash;
|
||||||
|
|
||||||
|
if (!xmreg::parse_str_secret_key(tx_hash_str, tx_hash))
|
||||||
|
{
|
||||||
|
j_data["title"] = fmt::format("Cant parse tx hash: {:s}", tx_hash_str);
|
||||||
|
return j_response;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get transaction
|
||||||
|
transaction tx;
|
||||||
|
|
||||||
|
// flag to indicate if tx is in mempool
|
||||||
|
bool found_in_mempool {false};
|
||||||
|
|
||||||
|
// for tx in blocks we get block timestamp
|
||||||
|
// for tx in mempool we get recievive time
|
||||||
|
uint64_t tx_timestamp {0};
|
||||||
|
|
||||||
|
if (!find_tx(tx_hash, tx, found_in_mempool, tx_timestamp))
|
||||||
|
{
|
||||||
|
j_data["title"] = fmt::format("Cant find tx hash: {:s}", tx_hash_str);
|
||||||
|
return j_response;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found_in_mempool == false)
|
||||||
|
{
|
||||||
|
|
||||||
|
block blk;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// get block cointaining this tx
|
||||||
|
uint64_t block_height = core_storage->get_db().get_tx_block_height(tx_hash);
|
||||||
|
|
||||||
|
if (!mcore->get_block_by_height(block_height, blk))
|
||||||
|
{
|
||||||
|
j_data["title"] = fmt::format("Cant get block: {:d}", block_height);
|
||||||
|
return j_response;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const exception& e)
|
||||||
|
{
|
||||||
|
j_response["status"] = "error";
|
||||||
|
j_response["message"] = fmt::format("Tx does not exist in blockchain, "
|
||||||
|
"but was there before: {:s}",
|
||||||
|
tx_hash_str);
|
||||||
|
return j_response;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get raw tx json as in monero
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
j_data = json::parse(obj_to_json_str(tx));
|
||||||
|
}
|
||||||
|
catch (std::invalid_argument& e)
|
||||||
|
{
|
||||||
|
j_response["status"] = "error";
|
||||||
|
j_response["message"] = "Faild parsing raw tx data into json";
|
||||||
|
return j_response;
|
||||||
|
}
|
||||||
|
|
||||||
|
j_response["status"] = "success";
|
||||||
|
|
||||||
|
return j_response;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lets use this json api convention for success and error
|
* Lets use this json api convention for success and error
|
||||||
* https://labs.omniti.com/labs/jsend
|
* https://labs.omniti.com/labs/jsend
|
||||||
|
@ -3977,6 +4062,102 @@ namespace xmreg
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lets use this json api convention for success and error
|
||||||
|
* https://labs.omniti.com/labs/jsend
|
||||||
|
*/
|
||||||
|
json
|
||||||
|
json_rawblock(string block_no_or_hash)
|
||||||
|
{
|
||||||
|
json j_response {
|
||||||
|
{"status", "fail"},
|
||||||
|
{"data" , json {}}
|
||||||
|
};
|
||||||
|
|
||||||
|
json& j_data = j_response["data"];
|
||||||
|
|
||||||
|
uint64_t current_blockchain_height
|
||||||
|
= core_storage->get_current_blockchain_height();
|
||||||
|
|
||||||
|
uint64_t block_height {0};
|
||||||
|
|
||||||
|
crypto::hash blk_hash;
|
||||||
|
|
||||||
|
block blk;
|
||||||
|
|
||||||
|
if (block_no_or_hash.length() <= 8)
|
||||||
|
{
|
||||||
|
// we have something that seems to be a block number
|
||||||
|
try
|
||||||
|
{
|
||||||
|
block_height = boost::lexical_cast<uint64_t>(block_no_or_hash);
|
||||||
|
}
|
||||||
|
catch (const boost::bad_lexical_cast& e)
|
||||||
|
{
|
||||||
|
j_data["title"] = fmt::format(
|
||||||
|
"Cant parse block number: {:s}", block_no_or_hash);
|
||||||
|
return j_response;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block_height > current_blockchain_height)
|
||||||
|
{
|
||||||
|
j_data["title"] = fmt::format(
|
||||||
|
"Requested block is higher than blockchain:"
|
||||||
|
" {:d}, {:d}", block_height,current_blockchain_height);
|
||||||
|
return j_response;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mcore->get_block_by_height(block_height, blk))
|
||||||
|
{
|
||||||
|
j_data["title"] = fmt::format("Cant get block: {:d}", block_height);
|
||||||
|
return j_response;
|
||||||
|
}
|
||||||
|
|
||||||
|
blk_hash = core_storage->get_block_id_by_height(block_height);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (block_no_or_hash.length() == 64)
|
||||||
|
{
|
||||||
|
// this seems to be block hash
|
||||||
|
if (!xmreg::parse_str_secret_key(block_no_or_hash, blk_hash))
|
||||||
|
{
|
||||||
|
j_data["title"] = fmt::format("Cant parse blk hash: {:s}", block_no_or_hash);
|
||||||
|
return j_response;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!core_storage->get_block_by_hash(blk_hash, blk))
|
||||||
|
{
|
||||||
|
j_data["title"] = fmt::format("Cant get block: {:s}", blk_hash);
|
||||||
|
return j_response;
|
||||||
|
}
|
||||||
|
|
||||||
|
block_height = core_storage->get_db().get_block_height(blk_hash);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
j_data["title"] = fmt::format("Cant find blk using search string: {:s}", block_no_or_hash);
|
||||||
|
return j_response;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get raw tx json as in monero
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
j_data = json::parse(obj_to_json_str(blk));
|
||||||
|
}
|
||||||
|
catch (std::invalid_argument& e)
|
||||||
|
{
|
||||||
|
j_response["status"] = "error";
|
||||||
|
j_response["message"] = "Faild parsing raw blk data into json";
|
||||||
|
return j_response;
|
||||||
|
}
|
||||||
|
|
||||||
|
j_response["status"] = "success";
|
||||||
|
|
||||||
|
return j_response;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lets use this json api convention for success and error
|
* Lets use this json api convention for success and error
|
||||||
* https://labs.omniti.com/labs/jsend
|
* https://labs.omniti.com/labs/jsend
|
||||||
|
@ -4092,7 +4273,8 @@ namespace xmreg
|
||||||
j_data["page"] = page;
|
j_data["page"] = page;
|
||||||
j_data["limit"] = limit;
|
j_data["limit"] = limit;
|
||||||
j_data["current_height"] = height;
|
j_data["current_height"] = height;
|
||||||
j_data["total_page_no"] = (limit == 0 ? 0 : height / limit);
|
|
||||||
|
j_data["total_page_no"] = limit > 0 ? (height / limit) : 0;
|
||||||
|
|
||||||
j_response["status"] = "success";
|
j_response["status"] = "success";
|
||||||
|
|
||||||
|
@ -4105,7 +4287,7 @@ namespace xmreg
|
||||||
* https://labs.omniti.com/labs/jsend
|
* https://labs.omniti.com/labs/jsend
|
||||||
*/
|
*/
|
||||||
json
|
json
|
||||||
json_mempool()
|
json_mempool(string _page, string _limit)
|
||||||
{
|
{
|
||||||
json j_response {
|
json j_response {
|
||||||
{"status", "fail"},
|
{"status", "fail"},
|
||||||
|
@ -4114,6 +4296,23 @@ namespace xmreg
|
||||||
|
|
||||||
json& j_data = j_response["data"];
|
json& j_data = j_response["data"];
|
||||||
|
|
||||||
|
// parse page and limit into numbers
|
||||||
|
|
||||||
|
uint64_t page {0};
|
||||||
|
uint64_t limit {0};
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
page = boost::lexical_cast<uint64_t>(_page);
|
||||||
|
limit = boost::lexical_cast<uint64_t>(_limit);
|
||||||
|
}
|
||||||
|
catch (const boost::bad_lexical_cast& e)
|
||||||
|
{
|
||||||
|
j_data["title"] = fmt::format(
|
||||||
|
"Cant parse page and/or limit numbers: {:s}, {:s}", _page, _limit);
|
||||||
|
return j_response;
|
||||||
|
}
|
||||||
|
|
||||||
//get current server timestamp
|
//get current server timestamp
|
||||||
server_timestamp = std::time(nullptr);
|
server_timestamp = std::time(nullptr);
|
||||||
|
|
||||||
|
@ -4135,21 +4334,62 @@ namespace xmreg
|
||||||
|
|
||||||
(void) tx_hash_dummy;
|
(void) tx_hash_dummy;
|
||||||
|
|
||||||
// for each transaction in the memory pool
|
uint64_t no_mempool_txs = mempool_data.size();
|
||||||
for (const auto& a_pair: mempool_data)
|
|
||||||
|
// calculate starting and ending block numbers to show
|
||||||
|
int64_t start_height = limit * page;
|
||||||
|
|
||||||
|
int64_t end_height = start_height + limit;
|
||||||
|
|
||||||
|
end_height = end_height > no_mempool_txs ? no_mempool_txs : end_height;
|
||||||
|
|
||||||
|
// check if start height is not below range
|
||||||
|
start_height = start_height > end_height ? end_height - limit : start_height;
|
||||||
|
|
||||||
|
start_height = start_height < 0 ? 0 : start_height;
|
||||||
|
|
||||||
|
// loop index
|
||||||
|
int64_t i = start_height;
|
||||||
|
|
||||||
|
json j_txs = json::array();
|
||||||
|
|
||||||
|
// for each transaction in the memory pool in current page
|
||||||
|
while (i < end_height)
|
||||||
{
|
{
|
||||||
const tx_details& txd = get_tx_details(a_pair.second, false, 1, height); // 1 is dummy here
|
const pair<tx_info, transaction>* a_pair {nullptr};
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
a_pair = &(mempool_data.at(i));
|
||||||
|
}
|
||||||
|
catch (const std::out_of_range& e)
|
||||||
|
{
|
||||||
|
j_response["status"] = "error";
|
||||||
|
j_response["message"] = fmt::format("Getting mempool txs failed due to std::out_of_range");
|
||||||
|
|
||||||
|
return j_response;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tx_details& txd = get_tx_details(a_pair->second, false, 1, height); // 1 is dummy here
|
||||||
|
|
||||||
// get basic tx info
|
// get basic tx info
|
||||||
json j_tx = get_tx_json(a_pair.second, txd);
|
json j_tx = get_tx_json(a_pair->second, txd);
|
||||||
|
|
||||||
// we add some extra data, for mempool txs, such as recieve timestamp
|
// we add some extra data, for mempool txs, such as recieve timestamp
|
||||||
j_tx["timestamp"] = a_pair.first.receive_time;
|
j_tx["timestamp"] = a_pair->first.receive_time;
|
||||||
j_tx["timestamp_utc"] = xmreg::timestamp_to_str_gm(a_pair.first.receive_time);
|
j_tx["timestamp_utc"] = xmreg::timestamp_to_str_gm(a_pair->first.receive_time);
|
||||||
|
|
||||||
j_data.push_back(j_tx);
|
j_txs.push_back(j_tx);
|
||||||
|
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
j_data["txs"] = j_txs;
|
||||||
|
j_data["page"] = page;
|
||||||
|
j_data["limit"] = limit;
|
||||||
|
j_data["txs_no"] = no_mempool_txs;
|
||||||
|
j_data["total_page_no"] = limit > 0 ? (no_mempool_txs / limit) : 0;
|
||||||
|
|
||||||
j_response["status"] = "success";
|
j_response["status"] = "success";
|
||||||
|
|
||||||
return j_response;
|
return j_response;
|
||||||
|
@ -4420,6 +4660,38 @@ namespace xmreg
|
||||||
|
|
||||||
return j_response;
|
return j_response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lets use this json api convention for success and error
|
||||||
|
* https://labs.omniti.com/labs/jsend
|
||||||
|
*/
|
||||||
|
json
|
||||||
|
json_networkinfo()
|
||||||
|
{
|
||||||
|
json j_response {
|
||||||
|
{"status", "fail"},
|
||||||
|
{"data", json {}}
|
||||||
|
};
|
||||||
|
|
||||||
|
json& j_data = j_response["data"];
|
||||||
|
|
||||||
|
json j_info;
|
||||||
|
|
||||||
|
if (!get_monero_network_info(j_info))
|
||||||
|
{
|
||||||
|
j_response["status"] = "error";
|
||||||
|
j_response["message"] = "Cant get monero network info";
|
||||||
|
return j_response;
|
||||||
|
}
|
||||||
|
|
||||||
|
j_data = j_info;
|
||||||
|
|
||||||
|
j_response["status"] = "success";
|
||||||
|
|
||||||
|
return j_response;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
json
|
json
|
||||||
|
@ -5192,6 +5464,40 @@ namespace xmreg
|
||||||
+ template_file["footer"];
|
+ template_file["footer"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
get_monero_network_info(json& j_info)
|
||||||
|
{
|
||||||
|
COMMAND_RPC_GET_INFO::response network_info;
|
||||||
|
|
||||||
|
if (!rpc.get_network_info(network_info))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
j_info = json {
|
||||||
|
{"status" , network_info.status},
|
||||||
|
{"height" , network_info.height},
|
||||||
|
{"target_height" , network_info.target_height},
|
||||||
|
{"difficulty" , network_info.difficulty},
|
||||||
|
{"target" , network_info.target},
|
||||||
|
{"hash_rate" , (network_info.difficulty/network_info.target)},
|
||||||
|
{"tx_count" , network_info.tx_count},
|
||||||
|
{"tx_pool_size" , network_info.tx_pool_size},
|
||||||
|
{"alt_blocks_count" , network_info.alt_blocks_count},
|
||||||
|
{"outgoing_connections_count", network_info.outgoing_connections_count},
|
||||||
|
{"incoming_connections_count", network_info.incoming_connections_count},
|
||||||
|
{"white_peerlist_size" , network_info.white_peerlist_size},
|
||||||
|
{"grey_peerlist_size" , network_info.grey_peerlist_size},
|
||||||
|
{"testnet" , network_info.testnet},
|
||||||
|
{"top_block_hash" , network_info.top_block_hash},
|
||||||
|
{"cumulative_difficulty" , network_info.cumulative_difficulty},
|
||||||
|
{"block_size_limit" , network_info.block_size_limit},
|
||||||
|
{"start_time" , network_info.start_time}
|
||||||
|
};
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
string
|
string
|
||||||
get_footer()
|
get_footer()
|
||||||
{
|
{
|
||||||
|
|
|
@ -147,6 +147,64 @@ rpccalls::commit_tx(tools::wallet2::pending_tx& ptx, string& error_msg)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rpccalls::get_network_info(COMMAND_RPC_GET_INFO::response& response)
|
||||||
|
{
|
||||||
|
|
||||||
|
epee::json_rpc::request<cryptonote::COMMAND_RPC_GET_INFO::request> req_t = AUTO_VAL_INIT(req_t);
|
||||||
|
epee::json_rpc::response<cryptonote::COMMAND_RPC_GET_INFO::response, std::string> resp_t = AUTO_VAL_INIT(resp_t);
|
||||||
|
|
||||||
|
bool r {false};
|
||||||
|
|
||||||
|
req_t.jsonrpc = "2.0";
|
||||||
|
req_t.id = epee::serialization::storage_entry(0);
|
||||||
|
req_t.method = "get_info";
|
||||||
|
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> guard(m_daemon_rpc_mutex);
|
||||||
|
|
||||||
|
if (!connect_to_monero_deamon())
|
||||||
|
{
|
||||||
|
cerr << "get_mempool: not connected to deamon" << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = epee::net_utils::invoke_http_json("/json_rpc",
|
||||||
|
req_t, resp_t,
|
||||||
|
m_http_client);
|
||||||
|
}
|
||||||
|
|
||||||
|
string err;
|
||||||
|
|
||||||
|
if (r)
|
||||||
|
{
|
||||||
|
if (resp_t.result.status == CORE_RPC_STATUS_BUSY)
|
||||||
|
{
|
||||||
|
err = "daemon is busy. Please try again later.";
|
||||||
|
}
|
||||||
|
else if (resp_t.result.status != CORE_RPC_STATUS_OK)
|
||||||
|
{
|
||||||
|
err = resp_t.result.status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!err.empty())
|
||||||
|
{
|
||||||
|
cerr << "Error connecting to Monero deamon due to "
|
||||||
|
<< err << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cerr << "Error connecting to Monero deamon at "
|
||||||
|
<< deamon_url << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
response = resp_t.result;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,10 +46,12 @@ public:
|
||||||
bool
|
bool
|
||||||
get_mempool(vector<tx_info>& mempool_txs);
|
get_mempool(vector<tx_info>& mempool_txs);
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
commit_tx(tools::wallet2::pending_tx& ptx, string& error_msg);
|
commit_tx(tools::wallet2::pending_tx& ptx, string& error_msg);
|
||||||
|
|
||||||
|
bool
|
||||||
|
get_network_info(COMMAND_RPC_GET_INFO::response& info);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue