{ "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_below", "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_below", "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_below", "marker": "uint64_t bi_coins;", "parameters": { "text": [ "uint64_t bi_txs;" ] } }, { "action": "add_below", "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(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;", "}", "" ] } } ] }, { "path": "/src/cryptonote_core/blockchain.h", "changes": [ { "action": "add_below", "marker": "Blockchain(tx_memory_pool& tx_pool);", "parameters": { "text": [ " void get_last_n_blocks_sizes_from_height(size_t h, std::vector& 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_below", "marker": "static const uint64_t testnet_hard_fork_version_1_till = 624633;", "parameters": { "text": [ "//------------------------------------------------------------------", "// get the block sizes of the last blocks, and return by reference with max height .", "void Blockchain::get_last_n_blocks_sizes_from_height(size_t h, std::vector& 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 blocks to vector (or less, if blockchain size < count)", " size_t start_offset = h - std::min(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_below", "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 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(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(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_response block_header;", " res.block.height = boost::get(blk.miner_tx.vin.front()).height;", " fill_block_header_response(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(res.block.height));", "", " res.block.reward = block_header.reward;", "", " std::vector 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 = std::to_string(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(0);", " } else {", " if (maxReward < realReward) {", " return false;", " }", " res.block.penalty = static_cast(maxReward - realReward) / static_cast(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 missed_txs;", " std::list 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 tx_ids;", " tx_ids.push_back(hash);", "", " std::list missed_txs;", " std::list 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).amount;", " input.k_image = string_tools::pod_to_hex(boost::get(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.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_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).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 vin;", " std::vector 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;", " std::string alreadyGeneratedCoins;", " uint64_t alreadyGeneratedTransactions;", " uint64_t baseReward;", " double penalty;", " uint64_t totalFeeAmount;", " std::vector 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 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 request;", "", " struct response {", " std::vector transactions; //transactions blobs as hex", " std::string status;", "", " BEGIN_KV_SERIALIZE_MAP()", " KV_SERIALIZE(transactions)", " KV_SERIALIZE(status)", " END_KV_SERIALIZE_MAP()", " };", "};", "" ] } } ] }, { "path": "/tests/unit_tests/blockchain_db.cpp", "changes": [ { "action": "add_below", "marker": "ASSERT_EQ(t_coins[0], this->m_db->get_block_already_generated_coins(0));", "parameters": { "text": [ " ASSERT_EQ(t_coins[0], this->m_db->get_block_already_generated_transactions(0));" ] } } ] }, { "path": "/tests/unit_tests/hardfork.cpp", "changes": [ { "action": "add_below", "marker": "virtual uint64_t get_block_already_generated_coins(const uint64_t& height) const { return 10000000000; }", "parameters": { "text": [ " virtual uint64_t get_block_already_generated_transactions(const uint64_t& height) const { return 100; }" ] } } ] } ] }