From 57819bec1cd4b294e54471934a33b5f0da8ce7d1 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Wed, 28 Nov 2018 14:58:03 +0800 Subject: [PATCH 01/10] fix: get_output_key requires epee::span now --- src/page.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/page.h b/src/page.h index 3d27334..e0680ef 100644 --- a/src/page.h +++ b/src/page.h @@ -1717,7 +1717,7 @@ show_ringmembers_hex(string const& tx_hash_str) == false) continue; - core_storage->get_db().get_output_key(in_key.amount, + core_storage->get_db().get_output_key(epee::span(&in_key.amount, 1), absolute_offsets, mixin_outputs); } @@ -2276,7 +2276,7 @@ show_my_outputs(string tx_hash_str, if (are_absolute_offsets_good(absolute_offsets, in_key) == false) continue; - core_storage->get_db().get_output_key(in_key.amount, + core_storage->get_db().get_output_key(epee::span(&in_key.amount, 1), absolute_offsets, mixin_outputs); } @@ -4439,7 +4439,7 @@ json_transaction(string tx_hash_str) if (are_absolute_offsets_good(absolute_offsets, in_key) == false) continue; - core_storage->get_db().get_output_key(in_key.amount, + core_storage->get_db().get_output_key(epee::span(&in_key.amount, 1), absolute_offsets, outputs); } @@ -6115,7 +6115,7 @@ construct_tx_context(transaction tx, uint16_t with_ring_signatures = 0) // offsets seems good, so try to get the outputs for the amount and // offsets given - core_storage->get_db().get_output_key(in_key.amount, + core_storage->get_db().get_output_key(epee::span(&in_key.amount, 1), absolute_offsets, outputs); } From b96ed8de743fe5582742e1b929eec1d9e973ae9a Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Thu, 29 Nov 2018 12:48:53 +0800 Subject: [PATCH 02/10] show_ringmemberstx_jsonhex added --- CMakeLists.txt | 7 ++ main.cpp | 7 +- src/page.h | 204 ++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 213 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 375842f..1f2c67e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) endif() + + # include boost headers include_directories(${Boost_INCLUDE_DIRS}) + +# include monero +include_directories(${MONERO_SOURCE_DIR}/build) + include_directories("ext/mstch/include") +include_directories("ext/mstch/include/src") include_directories("ext/crow") # add ext/ subfolder diff --git a/main.cpp b/main.cpp index 4729298..2a7e544 100644 --- a/main.cpp +++ b/main.cpp @@ -336,9 +336,14 @@ main(int ac, const char* av[]) return crow::response(xmrblocks.show_block_hex(block_height, true)); }); +// CROW_ROUTE(app, "/ringmemberstxhex/") +// ([&](string tx_hash) { +// return crow::response(xmrblocks.show_ringmemberstx_hex(remove_bad_chars(tx_hash))); +// }); + CROW_ROUTE(app, "/ringmemberstxhex/") ([&](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))}; }); } diff --git a/src/page.h b/src/page.h index e0680ef..b3aa228 100644 --- a/src/page.h +++ b/src/page.h @@ -22,15 +22,20 @@ #include "../ext/crow/crow.h" +#include "../ext/json.hpp" + #include "../ext/vpetrigocaches/cache.hpp" #include "../ext/vpetrigocaches/lru_cache_policy.hpp" #include "../ext/vpetrigocaches/fifo_cache_policy.hpp" +#include "../ext/mstch/src/visitor/render_node.hpp" + + #include #include #include #include -#include + #define TMPL_DIR "./templates" @@ -190,8 +195,6 @@ using namespace std; using epee::string_tools::pod_to_hex; using epee::string_tools::hex_to_pod; - - /** * @brief The tx_details struct * @@ -1842,7 +1845,200 @@ show_ringmemberstx_hex(string const& tx_hash_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 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(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> all_mixin_txs; + + for (txin_to_key const& in_key: input_key_imgs) + { + // get absolute offsets of mixins + std::vector absolute_offsets + = cryptonote::relative_output_offsets_to_absolute( + in_key.key_offsets); + + //tx_out_index is pair:: + vector indices; + std::vector 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(&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 show_my_outputs(string tx_hash_str, @@ -4642,7 +4838,7 @@ json_block(string block_no_or_hash) {"data" , json {}} }; - json& j_data = j_response["data"]; + nlohmann::json& j_data = j_response["data"]; uint64_t current_blockchain_height = core_storage->get_current_blockchain_height(); From c92e5aa80eb704dee99b0fc722358926ffc6eb58 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Fri, 30 Nov 2018 11:04:08 +0800 Subject: [PATCH 03/10] sender and recipient placeholders added to show_ringmemberstx_jsonhex --- src/page.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/page.h b/src/page.h index b3aa228..ca2b8fa 100644 --- a/src/page.h +++ b/src/page.h @@ -1885,6 +1885,25 @@ show_ringmemberstx_jsonhex(string const& tx_hash_str) tx_json["nettype"] = static_cast(nettype); tx_json["_comment"] = "Just a placeholder for some comment if needed later"; + // add placeholder for sender and recipient details + // this is most useful for unit testing on stagenet/testnet + // private monero networks, so we can easly put these + // networks accounts details here. + tx_json["sender"] = json { + {"seed", ""}, + {"address", ""}, + {"viewkey", ""}, + {"spendkey", ""}, + {"_comment", ""}}; + + tx_json["recipient"] = json { + {"seed", ""}, + {"address", ""}, + {"is_subaddress", false}, + {"viewkey", ""}, + {"spendkey", ""}, + {"_comment", ""}}; + uint64_t tx_blk_height {0}; try From a61e35d4a208542312c0c18c649aeef86727e86f Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Fri, 30 Nov 2018 11:51:46 +0800 Subject: [PATCH 04/10] add amount and payment id to show_ringmemberstx_jsonhex --- src/page.h | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/page.h b/src/page.h index ca2b8fa..eb8b2c2 100644 --- a/src/page.h +++ b/src/page.h @@ -1894,15 +1894,22 @@ show_ringmemberstx_jsonhex(string const& tx_hash_str) {"address", ""}, {"viewkey", ""}, {"spendkey", ""}, + {"amount", 0ull}, + {"change", 0ull}, {"_comment", ""}}; - tx_json["recipient"] = json { - {"seed", ""}, - {"address", ""}, - {"is_subaddress", false}, - {"viewkey", ""}, - {"spendkey", ""}, - {"_comment", ""}}; + tx_json["recipient"] = json::array(); + + + tx_json["recipient"].push_back( + json { {"seed", ""}, + {"address", ""}, + {"is_subaddress", false}, + {"viewkey", ""}, + {"spendkey", ""}, + {"amount", 0ull}, + {"_comment", ""}}); + uint64_t tx_blk_height {0}; @@ -1944,6 +1951,12 @@ show_ringmemberstx_jsonhex(string const& tx_hash_str) return json {"error", "Failed to obtain complete block data"}; } + tx_details txd = get_tx_details(tx); + + tx_json["payment_id"] = pod_to_hex(txd.payment_id); + tx_json["payment_id8"] = pod_to_hex(txd.payment_id8); + tx_json["payment_id8e"] = "placeholder for decrypted value"; + tx_json["block"] = epee::string_tools ::buff_to_hex_nodelimer(complete_block_data_str); From 05f032ee362ca9b672f854299049a6541d6fb383 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Fri, 30 Nov 2018 11:58:57 +0800 Subject: [PATCH 05/10] block info added --- src/page.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/page.h b/src/page.h index eb8b2c2..be28e61 100644 --- a/src/page.h +++ b/src/page.h @@ -1883,6 +1883,9 @@ show_ringmemberstx_jsonhex(string const& tx_hash_str) tx_json["hash"] = tx_hash_str; tx_json["hex"] = tx_hex; tx_json["nettype"] = static_cast(nettype); + tx_json["is_ringct"] = (tx.version > 1); + tx_json["rct_type"] = tx.rct_signatures.type; + tx_json["_comment"] = "Just a placeholder for some comment if needed later"; // add placeholder for sender and recipient details @@ -1960,6 +1963,7 @@ show_ringmemberstx_jsonhex(string const& tx_hash_str) tx_json["block"] = epee::string_tools ::buff_to_hex_nodelimer(complete_block_data_str); + tx_json["block_version"] = json {blk.major_version, blk.minor_version}; tx_json["inputs"] = json::array(); From c2c5e0b5f03de5862c37268ceeaa012dc16a3d6b Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Fri, 30 Nov 2018 15:35:11 +0800 Subject: [PATCH 06/10] outputs fields added --- src/page.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/page.h b/src/page.h index be28e61..c7d2486 100644 --- a/src/page.h +++ b/src/page.h @@ -1899,6 +1899,12 @@ show_ringmemberstx_jsonhex(string const& tx_hash_str) {"spendkey", ""}, {"amount", 0ull}, {"change", 0ull}, + {"outputs", json::array({json::array( + {"index placeholder", + "public_key placeholder", + "amount placeholder"} + )}) + }, {"_comment", ""}}; tx_json["recipient"] = json::array(); @@ -1911,6 +1917,12 @@ show_ringmemberstx_jsonhex(string const& tx_hash_str) {"viewkey", ""}, {"spendkey", ""}, {"amount", 0ull}, + {"outputs", json::array({json::array( + {"index placeholder", + "public_key placeholder", + "amount placeholder"} + )}) + }, {"_comment", ""}}); From a654ce9ea7ce48c1691c86ef751b39724fd95c84 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Tue, 4 Dec 2018 10:12:17 +0800 Subject: [PATCH 07/10] Use zeros as default value for payment_id8e --- src/page.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/page.h b/src/page.h index c7d2486..269d974 100644 --- a/src/page.h +++ b/src/page.h @@ -1970,7 +1970,7 @@ show_ringmemberstx_jsonhex(string const& tx_hash_str) tx_json["payment_id"] = pod_to_hex(txd.payment_id); tx_json["payment_id8"] = pod_to_hex(txd.payment_id8); - tx_json["payment_id8e"] = "placeholder for decrypted value"; + tx_json["payment_id8e"] = pod_to_hex(txd.payment_id8); tx_json["block"] = epee::string_tools ::buff_to_hex_nodelimer(complete_block_data_str); @@ -2406,8 +2406,11 @@ show_my_outputs(string tx_hash_str, address_info.address.m_spend_public_key, tx_pubkey); - //cout << pod_to_hex(outp.first.key) << endl; - //cout << pod_to_hex(tx_pubkey) << endl; +// cout << pod_to_hex(derivation) << ", " << output_idx << ", " +// << pod_to_hex(address_info.address.m_spend_public_key) << ", " +// << pod_to_hex(outp.first.key) << " == " +// << pod_to_hex(tx_pubkey) << '\n' << '\n'; + // check if generated public key matches the current output's key bool mine_output = (outp.first.key == tx_pubkey); @@ -2422,6 +2425,7 @@ show_my_outputs(string tx_hash_str, address_info.address.m_spend_public_key, tx_pubkey); + mine_output = (outp.first.key == tx_pubkey); with_additional = true; From 9fa7828f39ed0cafed8fa0b90a45309316c7d40a Mon Sep 17 00:00:00 2001 From: fuwa Date: Mon, 31 Dec 2018 08:48:47 +0800 Subject: [PATCH 08/10] make more directories configurable --- CMakeLists.txt | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f2c67e..2833d93 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,12 +19,16 @@ endif() message(STATUS MONERO_DIR ": ${MONERO_DIR}") -set(MONERO_SOURCE_DIR ${MONERO_DIR} - CACHE PATH "Path to the root directory for Monero") +if (NOT MONERO_SOURCE_DIR) + set(MONERO_SOURCE_DIR ${MONERO_DIR} + CACHE PATH "Path to the root directory for Monero") +endif() -# set location of monero build tree -set(MONERO_BUILD_DIR ${MONERO_SOURCE_DIR}/build/release/ - CACHE PATH "Path to the build directory for Monero") +if (NOT MONERO_BUILD_DIR) + # set location of monero build tree + set(MONERO_BUILD_DIR ${MONERO_SOURCE_DIR}/build/release/ + CACHE PATH "Path to the build directory for Monero") +endif() set(MY_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}/cmake" CACHE PATH "The path to the cmake directory of the current project") From 12f54797421b03b76516438b8fd0279cd94c964e Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Thu, 17 Jan 2019 14:18:06 +0800 Subject: [PATCH 09/10] fix: make it compile with recent monero --- src/page.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/page.h b/src/page.h index 269d974..00b26da 100644 --- a/src/page.h +++ b/src/page.h @@ -6576,7 +6576,8 @@ construct_tx_context(transaction tx, uint16_t with_ring_signatures = 0) if (core_storage->get_db().tx_exists(txd.hash, tx_index)) { out_amount_indices = core_storage->get_db() - .get_tx_amount_output_indices(tx_index); + .get_tx_amount_output_indices(tx_index) + .front(); } else { From 6477bbaf988f9f2fc2ad86cc095766d8b969879b Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Wed, 27 Feb 2019 16:33:42 +0800 Subject: [PATCH 10/10] updated to monero branch release-v013 --- README.md | 2 +- src/page.h | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 742bd50..dc61b36 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ sudo apt install git build-essential cmake libboost-all-dev miniupnpc libunbound # go to home folder cd ~ -git clone --recursive https://github.com/monero-project/monero +git clone --recursive -b release-v0.13 https://github.com/monero-project/monero.git cd monero/ diff --git a/src/page.h b/src/page.h index 00b26da..42115ca 100644 --- a/src/page.h +++ b/src/page.h @@ -1720,7 +1720,7 @@ show_ringmembers_hex(string const& tx_hash_str) == false) continue; - core_storage->get_db().get_output_key(epee::span(&in_key.amount, 1), + core_storage->get_db().get_output_key(in_key.amount, absolute_offsets, mixin_outputs); } @@ -2009,7 +2009,7 @@ show_ringmemberstx_jsonhex(string const& tx_hash_str) // get mining ouput info core_storage->get_db().get_output_key( - epee::span(&in_key.amount, 1), + in_key.amount, absolute_offsets, mixin_outputs); } @@ -2524,7 +2524,7 @@ show_my_outputs(string tx_hash_str, if (are_absolute_offsets_good(absolute_offsets, in_key) == false) continue; - core_storage->get_db().get_output_key(epee::span(&in_key.amount, 1), + core_storage->get_db().get_output_key(in_key.amount, absolute_offsets, mixin_outputs); } @@ -4687,7 +4687,7 @@ json_transaction(string tx_hash_str) if (are_absolute_offsets_good(absolute_offsets, in_key) == false) continue; - core_storage->get_db().get_output_key(epee::span(&in_key.amount, 1), + core_storage->get_db().get_output_key(in_key.amount, absolute_offsets, outputs); } @@ -6363,7 +6363,7 @@ construct_tx_context(transaction tx, uint16_t with_ring_signatures = 0) // offsets seems good, so try to get the outputs for the amount and // offsets given - core_storage->get_db().get_output_key(epee::span(&in_key.amount, 1), + core_storage->get_db().get_output_key(in_key.amount, absolute_offsets, outputs); } @@ -6576,8 +6576,7 @@ construct_tx_context(transaction tx, uint16_t with_ring_signatures = 0) if (core_storage->get_db().tx_exists(txd.hash, tx_index)) { out_amount_indices = core_storage->get_db() - .get_tx_amount_output_indices(tx_index) - .front(); + .get_tx_amount_output_indices(tx_index); } else {