From 1d905bb7f3fec5630c70f901ab700fb2b33a45d6 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Tue, 29 Nov 2016 09:21:32 +0800 Subject: [PATCH] fix: key image checker shows RingCT amounts correctly for each spent key image --- src/page.h | 169 +++++++++++++++++++++++++---- src/templates/checkrawkeyimgs.html | 2 + src/tools.cpp | 15 +++ src/tools.h | 8 ++ 4 files changed, 171 insertions(+), 23 deletions(-) diff --git a/src/page.h b/src/page.h index 1d2434a..52dc5ec 100644 --- a/src/page.h +++ b/src/page.h @@ -2182,7 +2182,6 @@ public: if (!found_tx_hashes.empty()) { - string tx_hash_str = found_tx_hashes.at(0); key_img_info["tx_hash"] = tx_hash_str; @@ -2205,15 +2204,13 @@ public: vector tx_key_imgs = get_key_images(tx); - const vector::const_iterator it - = find_if(tx_key_imgs.begin(), tx_key_imgs.end(), - [&](txin_to_key tx_in) - { - return tx_in.k_image == key_image; - }); - - if (it != tx_key_imgs.end()) + for (auto it = tx_key_imgs.begin(); it != tx_key_imgs.end(); ++it) { + if ((*it).k_image != key_image) + { + continue; + } + uint64_t xmr_amount = (*it).amount; // RingCT, i.e., tx version is 2 @@ -2221,29 +2218,155 @@ public: // otherwise they all appear to be zero. // so to find the amount, first we need to find // our output in the key images's mixins, and then - + // decode it using ringct. + // this requires to loop over mixins of each key image, + // get its source txs, get mixin index in that tx, + // and check if its our mixin or not using private_view_key + // and public_spend_key_provided if (tx.version == 2) { -// bool r = decode_ringct(tx.rct_signatures, -// txd.pk, -// prv_view_key, -// i, -// tx.rct_signatures.ecdhInfo[i].mask, -// rct_amount); - } - key_img_info["amount"] = xmreg::xmr_amount_to_str(xmr_amount); + vector absolute_offsets + = relative_output_offsets_to_absolute((*it).key_offsets); + + // need to go through each mixin, fetch its tx + // find its index in that txs, obtain tx_public_key + // derive a deriviec_key, compare derived output key + // with the output key in txs, and decode rct amount + // if equal + for (uint64_t out_idx: absolute_offsets) + { + + //tx_out_index is pair + tx_out_index toi; + + try + { + // get pair + toi = core_storage->get_db() + .get_output_tx_and_index((*it).amount, out_idx); + } + catch (const OUTPUT_DNE& e) + { + string error_msg = fmt::format( + "Output with amount {:d} and index {:d} does not exist!", + (*it).amount, out_idx); + + context["has_error"] = true; + context["error_msg"] = error_msg; + + return mstch::render(full_page, context); + } + + // get actual transaction structure from tx_hash + transaction output_source_tx; + + if (!mcore->get_tx(toi.first, output_source_tx)) + { + string error_msg = fmt::format( + "Cant get tx in blockchain: {:s}", toi.first); + + context["has_error"] = true; + context["error_msg"] = error_msg; + + return mstch::render(full_page, context); + } + + uint64_t output_idx_in_tx = toi.second; + + // get tx outpout key + const txout_to_key& output_pub_key + = boost::get( + output_source_tx.vout[output_idx_in_tx].target); + + uint64_t rct_amount = output_source_tx.vout[output_idx_in_tx].amount; + + public_key tx_pub_key = xmreg::get_tx_pub_key_from_received_outs( + output_source_tx); + + // public transaction key is combined with our viewkey + // to create, so called, derived key. + key_derivation derivation; + + if (!generate_key_derivation(tx_pub_key, prv_view_key, derivation)) + { + string error_msg = fmt::format( + "Cant get derived key for " + "pub_tx_key: {:s}, prv_view_key: {:s}" + , tx_pub_key, prv_view_key); + + context["has_error"] = true; + context["error_msg"] = error_msg; + + return mstch::render(full_page, context); + } + + // get the tx output public key + // that normally would be generated for us, + // if someone had sent us some xmr. + public_key derived_output_pubkey; + + derive_public_key(derivation, + output_idx_in_tx, + xmr_address->m_spend_public_key, + derived_output_pubkey); + + // check if generated public key matches the current output's key + bool mine_output = (output_pub_key.key == derived_output_pubkey); + + if (mine_output) + { + // seems we found our output. so now lets decode its amount + // using ringct + + bool r; + + r = decode_ringct(output_source_tx.rct_signatures, + tx_pub_key, + prv_view_key, + output_idx_in_tx, + output_source_tx.rct_signatures.ecdhInfo[output_idx_in_tx].mask, + rct_amount); + + if (!r) + { + string error_msg = fmt::format( + "Cant decode ringCT for " + "pub_tx_key: {:s} " + "using prv_view_key: {:s}", + tx_pub_key, prv_view_key); + + context["has_error"] = true; + context["error_msg"] = error_msg; + + return mstch::render(full_page, context); + } + + xmr_amount = rct_amount; + + break; + + } // if (mine_output) + + } // for (uint64_t out_idx: (*it).key_offsets) + + } // if (tx.version == 2) + + key_img_info["amount"] = xmreg::xmr_amount_to_str(xmr_amount); + key_img_info["is_ringct"] = tx.version == 2 ? true: false; total_xmr += xmr_amount; - } + + } // for (it = tx_key_imgs.begin(); it != tx_key_imgs.end(); ++it) key_img_info["timestamp"] = xmreg::timestamp_to_str(blk_timestamp); - } - } + + } // if (mcore->get_tx(tx_hash_str, tx)) + + } // if (!found_tx_hashes.empty()) key_imgs_ctx.push_back(key_img_info); - //signed_key_images.push_back(make_pair(key_image, signature)); - } + } // for (size_t n = 0; n < no_key_images; ++n) if (total_xmr > 0) { diff --git a/src/templates/checkrawkeyimgs.html b/src/templates/checkrawkeyimgs.html index e592245..4588859 100644 --- a/src/templates/checkrawkeyimgs.html +++ b/src/templates/checkrawkeyimgs.html @@ -41,6 +41,7 @@ Key no. Key image Timestamp + RingCT Amount Is spent? @@ -57,6 +58,7 @@ {{/tx_hash_found}} {{timestamp}} + {{is_ringct}} {{amount}} {{#is_spent}} diff --git a/src/tools.cpp b/src/tools.cpp index 422967d..1db16d4 100644 --- a/src/tools.cpp +++ b/src/tools.cpp @@ -948,5 +948,20 @@ is_output_ours(const size_t& output_index, return false; } + +bool +get_real_output_for_key_image(const key_image& ki, + const transaction& tx, + const secret_key& private_view_key, + const public_key& public_spend_key, + uint64_t output_idx, + public_key output_pub_key) +{ + + + + return false; +} + } diff --git a/src/tools.h b/src/tools.h index 0788d24..13a7e9c 100644 --- a/src/tools.h +++ b/src/tools.h @@ -255,6 +255,14 @@ is_output_ours(const size_t& output_index, const secret_key& private_view_key, const public_key& public_spend_key); +bool +get_real_output_for_key_image(const key_image& ki, + const transaction& tx, + const secret_key& private_view_key, + const public_key& public_spend_key, + uint64_t output_idx, + public_key output_pub_key); + } #endif //XMREG01_TOOLS_H