diff --git a/src/CurrentBlockchainStatus.h b/src/CurrentBlockchainStatus.h index c0cfc60..d49d050 100644 --- a/src/CurrentBlockchainStatus.h +++ b/src/CurrentBlockchainStatus.h @@ -115,7 +115,7 @@ struct CurrentBlockchainStatus { static bool get_output_keys(const uint64_t& amount, const vector& absolute_offsets, - vector outputs) + vector& outputs) { try { diff --git a/src/MySqlAccounts.h b/src/MySqlAccounts.h index c466aa8..ebaa5d9 100644 --- a/src/MySqlAccounts.h +++ b/src/MySqlAccounts.h @@ -183,7 +183,7 @@ public: query.storein(outs, output_public_key_str); - if (!outs.empty()) + if (outs.empty()) { return false; } @@ -200,7 +200,7 @@ public: MYSQL_EXCEPTION_MSG(e); } - return false; + return true; } @@ -230,6 +230,7 @@ public: out_data.tx_id, out_data.out_pub_key, out_data.tx_pub_key, + out_data.amount, out_data.out_index, out_data.mixin, out_data.timestamp); @@ -523,6 +524,12 @@ public: return mysql_out->insert(tx_out); } + uint64_t + insert_input(const XmrInput& tx_in) + { + return mysql_in->insert(tx_in); + } + bool select_txs(const string& xmr_address, vector& txs) { @@ -555,6 +562,12 @@ public: return mysql_out->select(account_id, outs); } + bool + select_inputs(const uint64_t& account_id, vector& ins) + { + return mysql_in->select(account_id, ins); + } + bool output_exists(const string& output_public_key_str, XmrOutput& out) { diff --git a/src/TxSearch.h b/src/TxSearch.h index e2291f5..23dc058 100644 --- a/src/TxSearch.h +++ b/src/TxSearch.h @@ -208,8 +208,8 @@ public: // FIRST component: Checking for our outputs. - // - vector> found_mine_outputs; + // + vector> found_mine_outputs; for (auto& out: outputs) { @@ -284,12 +284,18 @@ public: total_received += amount; - found_mine_outputs.emplace_back(out_key_str, output_idx_in_tx); + found_mine_outputs.emplace_back(out_key_str, + amount, + output_idx_in_tx); } } // for (const auto& out: outputs) - if (!found_mine_outputs.empty()) { + DateTime blk_timestamp_mysql_format + = XmrTransaction::timestamp_to_DateTime(blk.timestamp); + + if (!found_mine_outputs.empty()) + { crypto::hash payment_id = null_hash; crypto::hash8 payment_id8 = null_hash8; @@ -309,9 +315,6 @@ public: string tx_hash_str = pod_to_hex(tx_hash); - DateTime blk_timestamp_mysql_format - = XmrTransaction::timestamp_to_DateTime(blk.timestamp); - XmrTransaction tx_data; tx_data.hash = tx_hash_str; @@ -343,9 +346,10 @@ public: out_data.account_id = acc.id; out_data.tx_id = tx_mysql_id; - out_data.out_pub_key = out_k_idx.first; + out_data.out_pub_key = std::get<0>(out_k_idx); out_data.tx_pub_key = pod_to_hex(tx_pub_key); - out_data.out_index = out_k_idx.second; + out_data.amount = std::get<1>(out_k_idx); + out_data.out_index = std::get<2>(out_k_idx); out_data.mixin = tx_data.mixin; out_data.timestamp = tx_data.timestamp; @@ -357,67 +361,86 @@ public: //cerr << "out_mysql_id is zero!" << endl; //throw TxSearchException("out_mysql_id is zero!"); } - } + } // for (auto &out_k_idx: found_mine_outputs) - // SECOND component: Checking for our key images, i.e., inputs. - vector input_key_imgs = xmreg::get_key_images(tx); + // once tx and outputs were added, update Accounts table + + XmrAccount updated_acc = acc; + + updated_acc.total_received = acc.total_received + tx_data.total_received; - // make timescale maps for mixins in input - for (const txin_to_key& in_key: input_key_imgs) + if (xmr_accounts->update(acc, updated_acc)) { - // get absolute offsets of mixins - std::vector absolute_offsets - = cryptonote::relative_output_offsets_to_absolute( - in_key.key_offsets); + // if success, set acc to updated_acc; + acc = updated_acc; + } - // get public keys of outputs used in the mixins that match to the offests - std::vector outputs; + } // if (!found_mine_outputs.empty()) - if (CurrentBlockchainStatus::get_output_keys(in_key.amount, - absolute_offsets, - outputs)) { - cerr << "Mixins key images not found" << endl; - continue; - } + // SECOND component: Checking for our key images, i.e., inputs. - // for each found output public key find its block to get timestamp - for (const cryptonote::output_data_t& output_data: outputs) - { - string output_public_key_str = pod_to_hex(output_data.pubkey); + vector input_key_imgs = xmreg::get_key_images(tx); - XmrOutput out; + // make timescale maps for mixins in input + for (const txin_to_key& in_key: input_key_imgs) + { + // get absolute offsets of mixins + std::vector absolute_offsets + = cryptonote::relative_output_offsets_to_absolute( + in_key.key_offsets); - if (xmr_accounts->output_exists(output_public_key_str, out)) - { - cout << "input uses some mixins which are our outputs" - << out << endl; + // get public keys of outputs used in the mixins that match to the offests + std::vector mixin_outputs; - // seems that this key image is ours. - // so save it to database for later use. - } - } + if (!CurrentBlockchainStatus::get_output_keys(in_key.amount, + absolute_offsets, + mixin_outputs)) + { + cerr << "Mixins key images not found" << endl; + continue; } - // once tx and outputs were added, update Accounts table + // for each found output public key find its block to get timestamp + for (const cryptonote::output_data_t& output_data: mixin_outputs) + { + string output_public_key_str = pod_to_hex(output_data.pubkey); - XmrAccount updated_acc = acc; + XmrOutput out; - updated_acc.total_received = acc.total_received + tx_data.total_received; + if (xmr_accounts->output_exists(output_public_key_str, out)) + { + cout << "input uses some mixins which are our outputs" + << out << endl; - if (xmr_accounts->update(acc, updated_acc)) - { - // iff success, set acc to updated_acc; - acc = updated_acc; - } + // seems that this key image is ours. + // so save it to database for later use. - } + XmrInput in_data; + + in_data.account_id = acc.id; + in_data.tx_id = out.tx_id; + in_data.output_id = out.id; + in_data.key_image = pod_to_hex(in_key.k_image); + in_data.timestamp = blk_timestamp_mysql_format; + + // insert possible input key image into Inputs table + uint64_t in_mysql_id = xmr_accounts->insert_input(in_data); + + // a key image has only one real mixin. Rest is fake. + // so if we find a candidate, break the search + // break; + + } // if (xmr_accounts->output_exists(output_public_key_str, out)) + + } // for (const cryptonote::output_data_t& output_data: outputs) + } // for (const txin_to_key& in_key: input_key_imgs) } // for (const transaction& tx: blk_txs) diff --git a/src/ssqlses.h b/src/ssqlses.h index e52db93..1967344 100644 --- a/src/ssqlses.h +++ b/src/ssqlses.h @@ -177,12 +177,13 @@ ostream& operator<< (std::ostream& os, const XmrTransaction& acc) { }; -sql_create_8(Outputs, 1, 3, +sql_create_9(Outputs, 1, 3, sql_bigint_unsigned, id, sql_bigint_unsigned, account_id, sql_bigint_unsigned, tx_id, sql_varchar , out_pub_key, sql_varchar , tx_pub_key, + sql_bigint_unsigned, amount, sql_bigint_unsigned, out_index, sql_bigint_unsigned, mixin, sql_timestamp , timestamp); @@ -196,14 +197,14 @@ struct XmrOutput : public Outputs )"; static constexpr const char* EXIST_STMT = R"( - SELECT 1 FROM `Outputs` WHERE `out_pub_key` == (%0q) + SELECT * FROM `Outputs` WHERE `out_pub_key` = (%0q) )"; static constexpr const char* INSERT_STMT = R"( INSERT IGNORE INTO `Outputs` (`account_id`, `tx_id`, `out_pub_key`, `tx_pub_key`, - `out_index`, `mixin`, `timestamp`) + `amount`, `out_index`, `mixin`, `timestamp`) VALUES (%0q, %1q, %2q, %3q, - %4q, %5q, %6q); + %4q, %5q, %6q, %7q); )";