Files
monero-generator/extensions/blockchain-explorer.json
T
2016-09-16 23:17:24 +03:00

740 lines
33 KiB
JSON

{
"file": "blockchain-explorer.json",
"description": "Adds json rpc methods for block and transaction actions",
"required": [
"core/monero.json"
],
"files": [
{
"path": "/src/blockchain_db/blockchain_db.h",
"changes": [
{
"action": "add_bellow",
"marker": "virtual uint64_t get_block_already_generated_coins(const uint64_t& height) const = 0;",
"parameters": {
"text": [
"virtual uint64_t get_block_already_generated_transactions(const uint64_t& height) const = 0;"
]
}
}
]
},
{
"path": "/src/blockchain_db/lmdb/db_lmdb.h",
"changes": [
{
"action": "add_bellow",
"marker": "virtual uint64_t get_block_already_generated_coins(const uint64_t& height) const;",
"parameters": {
"text": [
"virtual uint64_t get_block_already_generated_transactions(const uint64_t& height) const;"
]
}
}
]
},
{
"path": "/src/blockchain_db/lmdb/db_lmdb.cpp",
"changes": [
{
"action": "add_bellow",
"marker": "uint64_t bi_coins;",
"parameters": {
"text": [
"uint64_t bi_txs;"
]
}
},
{
"action": "add_bellow",
"marker": "bi.bi_coins = coins_generated;",
"parameters": {
"text": [
" bi.bi_txs = m_num_txs;"
]
}
},
{
"action": "add_above",
"marker": "crypto::hash BlockchainLMDB::get_block_hash_from_height(const uint64_t& height) const",
"parameters": {
"text": [
"uint64_t BlockchainLMDB::get_block_already_generated_transactions(const uint64_t& height) const",
"{",
" LOG_PRINT_L3(\"BlockchainLMDB::\" << __func__);",
" check_open();",
"",
" TXN_PREFIX_RDONLY();",
" RCURSOR(block_info);",
"",
" MDB_val_set(result, height);",
" auto get_result = mdb_cursor_get(m_cur_block_info, (MDB_val *)&zerokval, &result, MDB_GET_BOTH);",
" if (get_result == MDB_NOTFOUND)",
" {",
" throw0(BLOCK_DNE(std::string(\"Attempt to get generated coins from height \").append(boost::lexical_cast<std::string>(height)).append(\" failed -- block size not in db\").c_str()));",
" }",
" else if (get_result)",
" throw0(DB_ERROR(\"Error attempting to retrieve a total generated coins from the db\"));",
"",
" mdb_block_info *bi = (mdb_block_info *)result.mv_data;",
" uint64_t ret = bi->bi_txs;",
" TXN_POSTFIX_RDONLY();",
" return ret;",
"}",
""
]
}
},
{
"action": "add_bellow",
"marker": "bi.bi_coins = *(uint64_t *)v.mv_data;",
"parameters": {
"text": [
" // Don't really need this",
" bi.bi_txs = 0;"
]
}
}
]
},
{
"path": "/src/cryptonote_core/blockchain.h",
"changes": [
{
"action": "add_bellow",
"marker": "Blockchain(tx_memory_pool& tx_pool);",
"parameters": {
"text": [
" void get_last_n_blocks_sizes_from_height(size_t h, std::vector<size_t>& sz, size_t count) const;",
" uint64_t get_block_granted_full_reward_zone_by_block_version(size_t major_version);"
]
}
}
]
},
{
"path": "/src/cryptonote_core/blockchain.cpp",
"changes": [
{
"action": "add_bellow",
"marker": "static const uint64_t testnet_hard_fork_version_1_till = 624633;",
"parameters": {
"text": [
"//------------------------------------------------------------------",
"// get the block sizes of the last <count> blocks, and return by reference <sz> with max height <h>.",
"void Blockchain::get_last_n_blocks_sizes_from_height(size_t h, std::vector<size_t>& sz, size_t count) const",
"{",
" LOG_PRINT_L3(\"Blockchain::\" << __func__);",
" CRITICAL_REGION_LOCAL(m_blockchain_lock);",
"",
" // this function is meaningless for an empty blockchain...granted it should never be empty",
" if(h == 0)",
" return;",
"",
" m_db->block_txn_start(true);",
" // add size of last <count> blocks to vector <sz> (or less, if blockchain size < count)",
" size_t start_offset = h - std::min<size_t>(h, count);",
" for(size_t i = start_offset; i < h; i++)",
" {",
" sz.push_back(m_db->get_block_size(i));",
" }",
" m_db->block_txn_stop();",
"}",
"",
"uint64_t Blockchain::get_block_granted_full_reward_zone_by_block_version(size_t major_version)",
"{",
" uint64_t full_reward_zone = major_version < 2 ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1 : CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2;",
"",
" return full_reward_zone;",
"}",
""
]
}
}
]
},
{
"path": "/src/rpc/core_rpc_server.h",
"changes": [
{
"action": "add_bellow",
"marker": "MAP_JON_RPC_WE(\"get_version\", on_get_version, COMMAND_RPC_GET_VERSION)",
"parameters": {
"text": [
" MAP_JON_RPC_WE(\"f_blocks_list_json\", f_on_blocks_list_json, F_COMMAND_RPC_GET_BLOCKS_LIST)",
" MAP_JON_RPC_WE(\"f_block_json\", f_on_block_json, F_COMMAND_RPC_GET_BLOCK_DETAILS)",
" MAP_JON_RPC_WE(\"f_transaction_json\", f_on_transaction_json, F_COMMAND_RPC_GET_TRANSACTION_DETAILS)",
" MAP_JON_RPC_WE(\"f_pool_json\", f_on_transactions_pool_json, F_COMMAND_RPC_GET_POOL)"
]
}
},
{
"action": "add_above",
"marker": "private:",
"parameters": {
"text": [
" bool f_on_blocks_list_json(const F_COMMAND_RPC_GET_BLOCKS_LIST::request& req, F_COMMAND_RPC_GET_BLOCKS_LIST::response& res, epee::json_rpc::error& error_resp);",
" bool f_on_block_json(const F_COMMAND_RPC_GET_BLOCK_DETAILS::request& req, F_COMMAND_RPC_GET_BLOCK_DETAILS::response& res, epee::json_rpc::error& error_resp);",
" bool f_on_transaction_json(const F_COMMAND_RPC_GET_TRANSACTION_DETAILS::request& req, F_COMMAND_RPC_GET_TRANSACTION_DETAILS::response& res, epee::json_rpc::error& error_resp);",
" bool f_on_transactions_pool_json(const F_COMMAND_RPC_GET_POOL::request& req, F_COMMAND_RPC_GET_POOL::response& res, epee::json_rpc::error& error_resp);",
" bool f_getMixin(const transaction& transaction, uint64_t& mixin);",
""
]
}
}
]
},
{
"path": "/src/rpc/core_rpc_server.cpp",
"changes": [
{
"action": "add_above",
"marker": "const command_line::arg_descriptor<std::string> core_rpc_server::arg_rpc_bind_ip = {",
"parameters": {
"text": [
" bool core_rpc_server::f_on_blocks_list_json(const F_COMMAND_RPC_GET_BLOCKS_LIST::request& req, F_COMMAND_RPC_GET_BLOCKS_LIST::response& res, epee::json_rpc::error& error_resp) {",
" if (m_core.get_current_blockchain_height() <= req.height) {",
" error_resp.code = CORE_RPC_ERROR_CODE_TOO_BIG_HEIGHT;",
" error_resp.message = std::string(\"To big height: \") + std::to_string(req.height) + \", current blockchain height = \" + std::to_string(m_core.get_current_blockchain_height());",
" return false;",
" }",
"",
" uint32_t print_blocks_count = 30;",
" uint32_t last_height = req.height - print_blocks_count;",
" if (req.height <= print_blocks_count) {",
" last_height = 0;",
" }",
"",
" for (uint32_t i = req.height; i >= last_height; i--) {",
" crypto::hash block_hash = m_core.get_block_id_by_height(static_cast<uint32_t>(i));",
" block blk;",
" if (!m_core.get_block_by_hash(block_hash, blk)) {",
" error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;",
" error_resp.message = \"Internal error: can't get block by height. Height = \" + std::to_string(i) + '.';",
" return false;",
" }",
"",
" size_t blokBlobSize = m_core.get_blockchain_storage().get_db().get_block_size(i);",
"",
" f_block_short_response block_short;",
" block_short.cumul_size = blokBlobSize;",
" block_short.timestamp = blk.timestamp;",
" block_short.height = i;",
" block_short.hash = string_tools::pod_to_hex(block_hash);",
" block_short.tx_count = blk.tx_hashes.size() + 1;",
"",
" res.blocks.push_back(block_short);",
"",
" if (i == 0)",
" break;",
" }",
"",
" res.status = CORE_RPC_STATUS_OK;",
" return true;",
" }",
"",
" bool core_rpc_server::f_on_block_json(const F_COMMAND_RPC_GET_BLOCK_DETAILS::request& req, F_COMMAND_RPC_GET_BLOCK_DETAILS::response& res, epee::json_rpc::error& error_resp) {",
" crypto::hash hash;",
"",
" if(!check_core_busy())",
" {",
" error_resp.code = CORE_RPC_ERROR_CODE_CORE_BUSY;",
" error_resp.message = \"Core is busy.\";",
" return false;",
" }",
"",
" try {",
" uint32_t height = boost::lexical_cast<uint32_t>(req.hash);",
" hash = m_core.get_block_id_by_height(height);",
" } catch (boost::bad_lexical_cast &) {",
" if (!parse_hash256(req.hash, hash)) {",
" error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM;",
" error_resp.message = \"Failed to parse hex representation of block hash. Hex = \" + req.hash + '.';",
" return false;",
" }",
" }",
"",
" block blk;",
" if (!m_core.get_block_by_hash(hash, blk)) {",
" error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;",
" error_resp.message = \"Internal error: can't get block by hash. Hash = \" + req.hash + '.';",
" return false;",
" }",
"",
" if (blk.miner_tx.vin.front().type() != typeid(txin_gen)) {",
" error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;",
" error_resp.message = \"Internal error: coinbase transaction in the block has the wrong type\";",
" return false;",
" }",
"",
" block_header_responce block_header;",
" res.block.height = boost::get<txin_gen>(blk.miner_tx.vin.front()).height;",
" fill_block_header_responce(blk, false, res.block.height, hash, block_header);",
"",
" res.block.major_version = block_header.major_version;",
" res.block.minor_version = block_header.minor_version;",
" res.block.timestamp = block_header.timestamp;",
" res.block.prev_hash = block_header.prev_hash;",
" res.block.nonce = block_header.nonce;",
" res.block.hash = string_tools::pod_to_hex(hash);",
" res.block.depth = m_core.get_current_blockchain_height() - res.block.height - 1;",
" res.block.difficulty = m_core.get_blockchain_storage().block_difficulty(static_cast<uint32_t>(res.block.height));",
"",
" res.block.reward = block_header.reward;",
"",
" std::vector<size_t> blocksSizes;",
" m_core.get_blockchain_storage().get_last_n_blocks_sizes_from_height(res.block.height + 1, blocksSizes, CRYPTONOTE_REWARD_BLOCKS_WINDOW);",
" res.block.sizeMedian = epee::misc_utils::median(blocksSizes);",
"",
" uint64_t blockSize = m_core.get_blockchain_storage().get_db().get_block_size(res.block.height);",
" if (!blockSize) {",
" return false;",
" }",
" res.block.blockSize = blockSize;",
"",
" uint64_t alreadyGeneratedCoins = m_core.get_blockchain_storage().get_db().get_block_already_generated_coins(res.block.height);",
" if (!alreadyGeneratedCoins) {",
" return false;",
" }",
" res.block.alreadyGeneratedCoins = alreadyGeneratedCoins;",
"",
" uint64_t alreadyGeneratedTransactions = m_core.get_blockchain_storage().get_db().get_block_already_generated_transactions(res.block.height);",
" if (!alreadyGeneratedTransactions) {",
" return false;",
" }",
" // +1 for coinbase tx",
" res.block.alreadyGeneratedTransactions = alreadyGeneratedTransactions + blk.tx_hashes.size() + 1;",
"",
" uint64_t prevBlockGeneratedCoins = 0;",
" if (res.block.height > 0) {",
" prevBlockGeneratedCoins = m_core.get_blockchain_storage().get_db().get_block_already_generated_coins(res.block.height - 1);",
" if (!prevBlockGeneratedCoins) {",
" return false;",
" }",
" }",
" uint64_t maxReward = 0;",
" uint64_t realReward = 0;",
" int64_t emissionChange = 0;",
" uint64_t blockGrantedFullRewardZone = m_core.get_blockchain_storage().get_block_granted_full_reward_zone_by_block_version(block_header.major_version);",
" res.block.effectiveSizeMedian = std::max(res.block.sizeMedian, blockGrantedFullRewardZone);",
"",
" if (!cryptonote::get_block_reward(0, 0, prevBlockGeneratedCoins, maxReward, res.block.major_version)) {",
" return false;",
" }",
" if (!cryptonote::get_block_reward(res.block.sizeMedian, res.block.blockSize, prevBlockGeneratedCoins, realReward, res.block.major_version)) {",
" return false;",
" }",
"",
" // This is base_reward + tx fees",
" // uint64_t currentReward = get_block_reward(blk);",
"",
" res.block.baseReward = maxReward;",
" if (maxReward == 0 && realReward == 0) {",
" res.block.penalty = static_cast<double>(0);",
" } else {",
" if (maxReward < realReward) {",
" return false;",
" }",
" res.block.penalty = static_cast<double>(maxReward - realReward) / static_cast<double>(maxReward);",
" }",
"",
" res.block.transactionsCumulativeSize = 0;",
"",
" // Base transaction adding",
" f_transaction_short_response transaction_short;",
" transaction_short.hash = string_tools::pod_to_hex(get_transaction_hash(blk.miner_tx));",
" transaction_short.fee = 0;",
" transaction_short.amount_out = get_outs_money_amount(blk.miner_tx);",
" transaction_short.size = get_object_blobsize(blk.miner_tx);",
" res.block.transactions.push_back(transaction_short);",
"",
" res.block.transactionsCumulativeSize += get_object_blobsize(blk.miner_tx);",
"",
" std::list<crypto::hash> missed_txs;",
" std::list<transaction> txs;",
" m_core.get_transactions(blk.tx_hashes, txs, missed_txs);",
"",
" res.block.totalFeeAmount = 0;",
"",
" for (const transaction& tx : txs) {",
" f_transaction_short_response transaction_short;",
" uint64_t amount_in = 0;",
" get_inputs_money_amount(tx, amount_in);",
" uint64_t amount_out = get_outs_money_amount(tx);",
"",
" transaction_short.hash = string_tools::pod_to_hex(get_transaction_hash(tx));",
" transaction_short.fee = amount_in - amount_out;",
" transaction_short.amount_out = amount_out;",
" transaction_short.size = get_object_blobsize(tx);",
" res.block.transactions.push_back(transaction_short);",
"",
" res.block.transactionsCumulativeSize += get_object_blobsize(tx);",
" res.block.totalFeeAmount += transaction_short.fee;",
" }",
"",
" res.status = CORE_RPC_STATUS_OK;",
" return true;",
" }",
"",
" bool core_rpc_server::f_on_transaction_json(const F_COMMAND_RPC_GET_TRANSACTION_DETAILS::request& req, F_COMMAND_RPC_GET_TRANSACTION_DETAILS::response& res, epee::json_rpc::error& error_resp) {",
" crypto::hash hash;",
"",
" if (!parse_hash256(req.hash, hash)) {",
" error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM;",
" error_resp.message = \"Failed to parse hex representation of transaction hash. Hex = \" + req.hash + '.';",
" return false;",
" }",
"",
" std::vector<crypto::hash> tx_ids;",
" tx_ids.push_back(hash);",
"",
" std::list<crypto::hash> missed_txs;",
" std::list<transaction> txs;",
" m_core.get_transactions(tx_ids, txs, missed_txs);",
"",
" transaction tx;",
"",
" if (1 == txs.size()) {",
" tx = txs.front();",
" } else {",
" error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM;",
" error_resp.message = \"transaction wasn't found. Hash = \" + req.hash + '.';",
" return false;",
" }",
"",
" res.tx.version = tx.version;",
" res.tx.unlock_time = tx.unlock_time;",
"",
" for (const txin_v& txin : tx.vin) {",
" if (txin.type() != typeid(txin_to_key)) {",
" continue;",
" }",
" f_tx_vin input;",
" input.amount = boost::get<txin_to_key>(txin).amount;",
" input.k_image = string_tools::pod_to_hex(boost::get<txin_to_key>(txin).k_image);",
" res.tx.vin.push_back(input);",
" }",
"",
" for (const tx_out& txout : tx.vout) {",
" f_tx_vout output;",
" output.amount = txout.amount;",
" txout_to_key tx_out_to_key = boost::get<txout_to_key>(txout.target);",
" output.key = string_tools::pod_to_hex(tx_out_to_key.key);",
" res.tx.vout.push_back(output);",
" }",
"",
" uint32_t blockHeight = m_core.get_blockchain_storage().get_db().get_tx_block_height(hash);",
" crypto::hash blockHash = m_core.get_block_id_by_height(blockHeight);",
" if (blockHeight) {",
" block blk;",
" if (m_core.get_block_by_hash(blockHash, blk)) {",
" uint64_t tx_cumulative_block_size = m_core.get_blockchain_storage().get_db().get_block_size(blockHeight);",
" uint64_t blokBlobSize = get_object_blobsize(blk);",
" uint64_t minerTxBlobSize = get_object_blobsize(blk.miner_tx);",
" f_block_short_response block_short;",
"",
" block_short.cumul_size = blokBlobSize + tx_cumulative_block_size - minerTxBlobSize;",
" block_short.timestamp = blk.timestamp;",
" block_short.height = blockHeight;",
" block_short.hash = string_tools::pod_to_hex(blockHash);",
" block_short.tx_count = blk.tx_hashes.size() + 1;",
" res.block = block_short;",
" }",
" }",
"",
" uint64_t amount_in = 0;",
" get_inputs_money_amount(tx, amount_in);",
" uint64_t amount_out = get_outs_money_amount(tx);",
"",
" crypto::hash tx_hash = get_transaction_hash(tx);",
" res.txDetails.hash = string_tools::pod_to_hex(tx_hash);",
" res.txDetails.fee = amount_in - amount_out;",
" if (amount_in == 0)",
" res.txDetails.fee = 0;",
" res.txDetails.amount_out = amount_out;",
" res.txDetails.size = get_object_blobsize(tx);",
"",
" uint64_t mixin;",
" if (!f_getMixin(tx, mixin)) {",
" return false;",
" }",
" res.txDetails.mixin = mixin;",
"",
" std::vector<tx_extra_field> tx_extra_fields;",
" parse_tx_extra(tx.extra, tx_extra_fields);",
"",
" tx_extra_nonce extra_nonce;",
" crypto::hash paymentId;",
"",
" // EDIT THIS PART FOR ENCRYPTED PAYMENT_ID",
" if (find_tx_extra_field_by_type(tx_extra_fields, extra_nonce)) {",
" if (get_payment_id_from_tx_extra_nonce(extra_nonce.nonce, paymentId)) {",
" res.txDetails.paymentId = string_tools::pod_to_hex(paymentId);",
" } else {",
" res.txDetails.paymentId = \"\";",
" }",
" }",
"",
" res.status = CORE_RPC_STATUS_OK;",
" return true;",
" }",
"",
" bool core_rpc_server::f_on_transactions_pool_json(const F_COMMAND_RPC_GET_POOL::request& req, F_COMMAND_RPC_GET_POOL::response& res, epee::json_rpc::error& error_resp) {",
" // res.transactions = m_core.print_pool(true);",
" res.status = CORE_RPC_STATUS_OK;",
" return true;",
" }",
"",
" bool core_rpc_server::f_getMixin(const transaction& transaction, uint64_t& mixin) {",
" mixin = 0;",
" for (const txin_v& txin : transaction.vin) {",
" if (txin.type() != typeid(txin_to_key)) {",
" continue;",
" }",
" uint64_t currentMixin = boost::get<txin_to_key>(txin).key_offsets.size();",
" if (currentMixin > mixin) {",
" mixin = currentMixin;",
" }",
" }",
" return true;",
" }",
""
]
}
}
]
},
{
"path": "/src/rpc/core_rpc_server_commands_defs.h",
"changes": [
{
"action": "add_above",
"marker": "struct COMMAND_RPC_GET_HEIGHT",
"parameters": {
"text": [
"",
" struct f_transaction_short_response {",
" std::string hash;",
" uint64_t fee;",
" uint64_t amount_out;",
" uint64_t size;",
"",
" BEGIN_KV_SERIALIZE_MAP()",
" KV_SERIALIZE(hash)",
" KV_SERIALIZE(fee)",
" KV_SERIALIZE(amount_out)",
" KV_SERIALIZE(size)",
" END_KV_SERIALIZE_MAP()",
" };",
"",
" struct f_tx_vin",
" {",
" uint64_t amount;",
" std::string k_image;",
"",
" BEGIN_KV_SERIALIZE_MAP()",
" KV_SERIALIZE(amount)",
" KV_SERIALIZE(k_image)",
" END_KV_SERIALIZE_MAP()",
" };",
"",
" struct f_tx_vout",
" {",
" uint64_t amount;",
" std::string key;",
"",
" BEGIN_KV_SERIALIZE_MAP()",
" KV_SERIALIZE(amount)",
" KV_SERIALIZE(key)",
" END_KV_SERIALIZE_MAP()",
" };",
"",
" struct f_transaction {",
" uint64_t version;",
" uint64_t unlock_time;",
" std::vector<f_tx_vin> vin;",
" std::vector<f_tx_vout> vout;",
"",
" BEGIN_KV_SERIALIZE_MAP()",
" KV_SERIALIZE(version)",
" KV_SERIALIZE(unlock_time)",
" KV_SERIALIZE(vin)",
" KV_SERIALIZE(vout)",
" END_KV_SERIALIZE_MAP()",
" };",
"",
" struct f_transaction_details_response {",
" std::string hash;",
" uint64_t size;",
" std::string paymentId;",
" uint64_t mixin;",
" uint64_t fee;",
" uint64_t amount_out;",
"",
" BEGIN_KV_SERIALIZE_MAP()",
" KV_SERIALIZE(hash)",
" KV_SERIALIZE(size)",
" KV_SERIALIZE(paymentId)",
" KV_SERIALIZE(mixin)",
" KV_SERIALIZE(fee)",
" KV_SERIALIZE(amount_out)",
" END_KV_SERIALIZE_MAP()",
" };",
"",
" struct f_block_short_response {",
" uint64_t timestamp;",
" uint32_t height;",
" std::string hash;",
" uint64_t tx_count;",
" uint64_t cumul_size;",
"",
" BEGIN_KV_SERIALIZE_MAP()",
" KV_SERIALIZE(timestamp)",
" KV_SERIALIZE(height)",
" KV_SERIALIZE(hash)",
" KV_SERIALIZE(cumul_size)",
" KV_SERIALIZE(tx_count)",
" END_KV_SERIALIZE_MAP()",
" };",
"",
" struct f_block_details_response {",
" uint8_t major_version;",
" uint8_t minor_version; ",
" uint64_t timestamp;",
" std::string prev_hash;",
" uint32_t nonce;",
" bool orphan_status;",
" uint32_t height;",
" uint64_t depth;",
" std::string hash;",
" uint64_t difficulty;",
" uint64_t reward;",
" uint64_t blockSize;",
" uint64_t sizeMedian;",
" uint64_t effectiveSizeMedian;",
" uint64_t transactionsCumulativeSize;",
" uint64_t alreadyGeneratedCoins;",
" uint64_t alreadyGeneratedTransactions;",
" uint64_t baseReward;",
" double penalty;",
" uint64_t totalFeeAmount;",
" std::vector<f_transaction_short_response> transactions;",
"",
" BEGIN_KV_SERIALIZE_MAP()",
" KV_SERIALIZE(major_version)",
" KV_SERIALIZE(minor_version)",
" KV_SERIALIZE(timestamp)",
" KV_SERIALIZE(prev_hash)",
" KV_SERIALIZE(nonce)",
" KV_SERIALIZE(orphan_status)",
" KV_SERIALIZE(height)",
" KV_SERIALIZE(depth)",
" KV_SERIALIZE(hash)",
" KV_SERIALIZE(difficulty)",
" KV_SERIALIZE(reward)",
" KV_SERIALIZE(blockSize)",
" KV_SERIALIZE(sizeMedian)",
" KV_SERIALIZE(effectiveSizeMedian)",
" KV_SERIALIZE(transactionsCumulativeSize)",
" KV_SERIALIZE(alreadyGeneratedCoins)",
" KV_SERIALIZE(alreadyGeneratedTransactions)",
" KV_SERIALIZE(baseReward)",
" KV_SERIALIZE(penalty)",
" KV_SERIALIZE(transactions)",
" KV_SERIALIZE(totalFeeAmount)",
" END_KV_SERIALIZE_MAP()",
" };",
""
]
}
},
{
"action": "add_above",
"marker": "struct COMMAND_RPC_GET_VERSION",
"parameters": {
"text": [
"struct F_COMMAND_RPC_GET_BLOCKS_LIST {",
" struct request {",
" uint64_t height;",
"",
" BEGIN_KV_SERIALIZE_MAP()",
" KV_SERIALIZE(height)",
" END_KV_SERIALIZE_MAP()",
" };",
"",
" struct response {",
" std::vector<f_block_short_response> blocks; //transactions blobs as hex",
" std::string status;",
"",
" BEGIN_KV_SERIALIZE_MAP()",
" KV_SERIALIZE(blocks)",
" KV_SERIALIZE(status)",
" END_KV_SERIALIZE_MAP()",
" };",
"};",
"",
"struct F_COMMAND_RPC_GET_BLOCK_DETAILS {",
" struct request {",
" std::string hash;",
"",
" BEGIN_KV_SERIALIZE_MAP()",
" KV_SERIALIZE(hash)",
" END_KV_SERIALIZE_MAP()",
" };",
"",
" struct response {",
" f_block_details_response block;",
" std::string status;",
"",
" BEGIN_KV_SERIALIZE_MAP()",
" KV_SERIALIZE(block)",
" KV_SERIALIZE(status)",
" END_KV_SERIALIZE_MAP()",
" };",
"};",
"",
"struct F_COMMAND_RPC_GET_TRANSACTION_DETAILS {",
" struct request {",
" std::string hash;",
"",
" BEGIN_KV_SERIALIZE_MAP()",
" KV_SERIALIZE(hash)",
" END_KV_SERIALIZE_MAP()",
" };",
"",
" struct response {",
" f_transaction tx;",
" f_transaction_details_response txDetails;",
" f_block_short_response block;",
" std::string status;",
"",
" BEGIN_KV_SERIALIZE_MAP()",
" KV_SERIALIZE(tx)",
" KV_SERIALIZE(txDetails)",
" KV_SERIALIZE(block)",
" KV_SERIALIZE(status)",
" END_KV_SERIALIZE_MAP()",
" };",
"};",
"",
"struct F_COMMAND_RPC_GET_POOL {",
" typedef std::vector<std::string> request;",
"",
" struct response {",
" std::vector<f_transaction_short_response> transactions; //transactions blobs as hex",
" std::string status;",
"",
" BEGIN_KV_SERIALIZE_MAP()",
" KV_SERIALIZE(transactions)",
" KV_SERIALIZE(status)",
" END_KV_SERIALIZE_MAP()",
" };",
"};",
""
]
}
}
]
}
]
}