show_ringmemberstx_jsonhex added

master
moneroexamples 6 years ago
parent 57819bec1c
commit b96ed8de74

@ -65,9 +65,16 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin" OR WIN32)
set_property(TARGET unbound PROPERTY IMPORTED_LOCATION ${MONERO_BUILD_DIR}/external/unbound/libunbound.a) set_property(TARGET unbound PROPERTY IMPORTED_LOCATION ${MONERO_BUILD_DIR}/external/unbound/libunbound.a)
endif() endif()
# include boost headers # include boost headers
include_directories(${Boost_INCLUDE_DIRS}) include_directories(${Boost_INCLUDE_DIRS})
# include monero
include_directories(${MONERO_SOURCE_DIR}/build)
include_directories("ext/mstch/include") include_directories("ext/mstch/include")
include_directories("ext/mstch/include/src")
include_directories("ext/crow") include_directories("ext/crow")
# add ext/ subfolder # add ext/ subfolder

@ -336,9 +336,14 @@ main(int ac, const char* av[])
return crow::response(xmrblocks.show_block_hex(block_height, true)); return crow::response(xmrblocks.show_block_hex(block_height, true));
}); });
// CROW_ROUTE(app, "/ringmemberstxhex/<string>")
// ([&](string tx_hash) {
// return crow::response(xmrblocks.show_ringmemberstx_hex(remove_bad_chars(tx_hash)));
// });
CROW_ROUTE(app, "/ringmemberstxhex/<string>") CROW_ROUTE(app, "/ringmemberstxhex/<string>")
([&](string tx_hash) { ([&](string tx_hash) {
return crow::response(xmrblocks.show_ringmemberstx_hex(remove_bad_chars(tx_hash))); return myxmr::jsonresponse {xmrblocks.show_ringmemberstx_jsonhex(remove_bad_chars(tx_hash))};
}); });
} }

@ -22,15 +22,20 @@
#include "../ext/crow/crow.h" #include "../ext/crow/crow.h"
#include "../ext/json.hpp"
#include "../ext/vpetrigocaches/cache.hpp" #include "../ext/vpetrigocaches/cache.hpp"
#include "../ext/vpetrigocaches/lru_cache_policy.hpp" #include "../ext/vpetrigocaches/lru_cache_policy.hpp"
#include "../ext/vpetrigocaches/fifo_cache_policy.hpp" #include "../ext/vpetrigocaches/fifo_cache_policy.hpp"
#include "../ext/mstch/src/visitor/render_node.hpp"
#include <algorithm> #include <algorithm>
#include <limits> #include <limits>
#include <ctime> #include <ctime>
#include <future> #include <future>
#include <visitor/render_node.hpp>
#define TMPL_DIR "./templates" #define TMPL_DIR "./templates"
@ -190,8 +195,6 @@ using namespace std;
using epee::string_tools::pod_to_hex; using epee::string_tools::pod_to_hex;
using epee::string_tools::hex_to_pod; using epee::string_tools::hex_to_pod;
/** /**
* @brief The tx_details struct * @brief The tx_details struct
* *
@ -1842,7 +1845,200 @@ show_ringmemberstx_hex(string const& tx_hash_str)
::buff_to_hex_nodelimer(oss.str()); ::buff_to_hex_nodelimer(oss.str());
} }
/**
* @brief Get ring member tx data
*
* Used for generating json file of txs used in unit testing.
* Thanks to json output from this function, we can mock
* a number of blockchain quries about key images
*
* @param tx_hash_str
* @return
*/
json
show_ringmemberstx_jsonhex(string const& tx_hash_str)
{
transaction tx;
crypto::hash tx_hash;
if (!get_tx(tx_hash_str, tx, tx_hash))
return string {"Cant get tx: "} + tx_hash_str;
vector<txin_to_key> input_key_imgs = xmreg::get_key_images(tx);
json tx_json;
string tx_hex;
try
{
tx_hex = tx_to_hex(tx);
}
catch (std::exception const& e)
{
cerr << e.what() << endl;
return json {"error", "Failed to obtain hex of tx"};
}
tx_json["hash"] = tx_hash_str;
tx_json["hex"] = tx_hex;
tx_json["nettype"] = static_cast<size_t>(nettype);
tx_json["_comment"] = "Just a placeholder for some comment if needed later";
uint64_t tx_blk_height {0};
try
{
tx_blk_height = core_storage->get_db().get_tx_block_height(tx_hash);
}
catch (exception& e)
{
cerr << "Cant get block height: " << tx_hash
<< e.what() << endl;
return json {"error", "Cant get block height"};
}
// get block cointaining this tx
block blk;
if ( !mcore->get_block_by_height(tx_blk_height, blk))
{
cerr << "Cant get block: " << tx_blk_height << endl;
return json {"error", "Cant get block"};
}
block_complete_entry complete_block_data;
if (!mcore->get_block_complete_entry(blk, complete_block_data))
{
cerr << "Failed to obtain complete block data " << endl;
return json {"error", "Failed to obtain complete block data "};
}
std::string complete_block_data_str;
if(!epee::serialization::store_t_to_binary(
complete_block_data, complete_block_data_str))
{
cerr << "Failed to serialize complete_block_data\n";
return json {"error", "Failed to obtain complete block data"};
}
tx_json["block"] = epee::string_tools
::buff_to_hex_nodelimer(complete_block_data_str);
tx_json["inputs"] = json::array();
// key: constracted from concatenation of in_key.amount and absolute_offsets,
// value: vector of string where string is transaction hash + output index + tx_hex
// will have to cut this string when de-seraializing this data
// later in the unit tests
// transaction hash and output index represent tx_out_index
std::map<string, vector<string>> all_mixin_txs;
for (txin_to_key const& in_key: input_key_imgs)
{
// get absolute offsets of mixins
std::vector<uint64_t> absolute_offsets
= cryptonote::relative_output_offsets_to_absolute(
in_key.key_offsets);
//tx_out_index is pair::<transaction hash, output index>
vector<tx_out_index> indices;
std::vector<output_data_t> mixin_outputs;
// get tx hashes and indices in the txs for the
// given outputs of mixins
// this cant THROW DB_EXCEPTION
try
{
// get tx of the real output
core_storage->get_db().get_output_tx_and_index(
in_key.amount, absolute_offsets, indices);
// get mining ouput info
core_storage->get_db().get_output_key(
epee::span<const uint64_t>(&in_key.amount, 1),
absolute_offsets,
mixin_outputs);
}
catch (exception const& e)
{
string out_msg = fmt::format(
"Cant get ring member tx_out_index for tx {:s}", tx_hash_str
);
cerr << out_msg << endl;
return json {"error", out_msg};
}
tx_json["inputs"].push_back(json {{"key_image", pod_to_hex(in_key.k_image)},
{"amount", in_key.amount},
{"absolute_offsets", absolute_offsets},
{"ring_members", json::array()}});
json& ring_members = tx_json["inputs"].back()["ring_members"];
if (indices.size() != mixin_outputs.size())
{
cerr << "indices.size() != mixin_outputs.size()\n";
return json {"error", "indices.size() != mixin_outputs.size()"};
}
// serialize each mixin tx
//for (auto const& txi : indices)
for (size_t i = 0; i < indices.size(); ++i)
{
tx_out_index const& txi = indices[i];
output_data_t const& mo = mixin_outputs[i];
auto const& mixin_tx_hash = txi.first;
auto const& output_index_in_tx = txi.second;
transaction mixin_tx;
if (!mcore->get_tx(mixin_tx_hash, mixin_tx))
{
throw std::runtime_error("Cant get tx: "
+ pod_to_hex(mixin_tx_hash));
}
// serialize tx
string tx_hex = epee::string_tools::buff_to_hex_nodelimer(
t_serializable_object_to_blob(mixin_tx));
ring_members.push_back(
json {
{"ouput_pk", pod_to_hex(mo.pubkey)},
{"tx_hash", pod_to_hex(mixin_tx_hash)},
{"output_index_in_tx", txi.second},
{"tx_hex", tx_hex},
});
}
} // for (txin_to_key const& in_key: input_key_imgs)
// archive all_mixin_outputs vector
std::ostringstream oss;
boost::archive::portable_binary_oarchive archive(oss);
archive << all_mixin_txs;
// return as all_mixin_outputs vector hex
//return epee::string_tools
// ::buff_to_hex_nodelimer(oss.str());
return tx_json;
}
string string
show_my_outputs(string tx_hash_str, show_my_outputs(string tx_hash_str,
@ -4642,7 +4838,7 @@ json_block(string block_no_or_hash)
{"data" , json {}} {"data" , json {}}
}; };
json& j_data = j_response["data"]; nlohmann::json& j_data = j_response["data"];
uint64_t current_blockchain_height uint64_t current_blockchain_height
= core_storage->get_current_blockchain_height(); = core_storage->get_current_blockchain_height();

Loading…
Cancel
Save