Possible key_images for a given address are saved

pull/1/head
moneroexamples 8 years ago
parent 0ce55f3396
commit a056f7c891

@ -115,7 +115,7 @@ struct CurrentBlockchainStatus {
static bool static bool
get_output_keys(const uint64_t& amount, get_output_keys(const uint64_t& amount,
const vector<uint64_t>& absolute_offsets, const vector<uint64_t>& absolute_offsets,
vector<cryptonote::output_data_t> outputs) vector<cryptonote::output_data_t>& outputs)
{ {
try try
{ {

@ -183,7 +183,7 @@ public:
query.storein(outs, output_public_key_str); query.storein(outs, output_public_key_str);
if (!outs.empty()) if (outs.empty())
{ {
return false; return false;
} }
@ -200,7 +200,7 @@ public:
MYSQL_EXCEPTION_MSG(e); MYSQL_EXCEPTION_MSG(e);
} }
return false; return true;
} }
@ -230,6 +230,7 @@ public:
out_data.tx_id, out_data.tx_id,
out_data.out_pub_key, out_data.out_pub_key,
out_data.tx_pub_key, out_data.tx_pub_key,
out_data.amount,
out_data.out_index, out_data.out_index,
out_data.mixin, out_data.mixin,
out_data.timestamp); out_data.timestamp);
@ -523,6 +524,12 @@ public:
return mysql_out->insert(tx_out); return mysql_out->insert(tx_out);
} }
uint64_t
insert_input(const XmrInput& tx_in)
{
return mysql_in->insert(tx_in);
}
bool bool
select_txs(const string& xmr_address, vector<XmrTransaction>& txs) select_txs(const string& xmr_address, vector<XmrTransaction>& txs)
{ {
@ -555,6 +562,12 @@ public:
return mysql_out->select(account_id, outs); return mysql_out->select(account_id, outs);
} }
bool
select_inputs(const uint64_t& account_id, vector<XmrInput>& ins)
{
return mysql_in->select(account_id, ins);
}
bool bool
output_exists(const string& output_public_key_str, XmrOutput& out) output_exists(const string& output_public_key_str, XmrOutput& out)
{ {

@ -208,8 +208,8 @@ public:
// FIRST component: Checking for our outputs. // FIRST component: Checking for our outputs.
// <out_pub_key, index in tx> // <out_pub_key, amount , index in tx>
vector<pair<string, uint64_t>> found_mine_outputs; vector<tuple<string, uint64_t, uint64_t>> found_mine_outputs;
for (auto& out: outputs) for (auto& out: outputs)
{ {
@ -284,12 +284,18 @@ public:
total_received += amount; 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) } // 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::hash payment_id = null_hash;
crypto::hash8 payment_id8 = null_hash8; crypto::hash8 payment_id8 = null_hash8;
@ -309,9 +315,6 @@ public:
string tx_hash_str = pod_to_hex(tx_hash); string tx_hash_str = pod_to_hex(tx_hash);
DateTime blk_timestamp_mysql_format
= XmrTransaction::timestamp_to_DateTime(blk.timestamp);
XmrTransaction tx_data; XmrTransaction tx_data;
tx_data.hash = tx_hash_str; tx_data.hash = tx_hash_str;
@ -343,9 +346,10 @@ public:
out_data.account_id = acc.id; out_data.account_id = acc.id;
out_data.tx_id = tx_mysql_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.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.mixin = tx_data.mixin;
out_data.timestamp = tx_data.timestamp; out_data.timestamp = tx_data.timestamp;
@ -357,67 +361,86 @@ public:
//cerr << "out_mysql_id is zero!" << endl; //cerr << "out_mysql_id is zero!" << endl;
//throw TxSearchException("out_mysql_id is zero!"); //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<txin_to_key> 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 if (xmr_accounts->update(acc, updated_acc))
for (const txin_to_key& in_key: input_key_imgs)
{ {
// get absolute offsets of mixins // if success, set acc to updated_acc;
std::vector<uint64_t> absolute_offsets acc = updated_acc;
= cryptonote::relative_output_offsets_to_absolute( }
in_key.key_offsets);
// get public keys of outputs used in the mixins that match to the offests } // if (!found_mine_outputs.empty())
std::vector<cryptonote::output_data_t> outputs;
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 vector<txin_to_key> input_key_imgs = xmreg::get_key_images(tx);
for (const cryptonote::output_data_t& output_data: outputs)
{
string output_public_key_str = pod_to_hex(output_data.pubkey);
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<uint64_t> absolute_offsets
= cryptonote::relative_output_offsets_to_absolute(
in_key.key_offsets);
if (xmr_accounts->output_exists(output_public_key_str, out)) // get public keys of outputs used in the mixins that match to the offests
{ std::vector<cryptonote::output_data_t> mixin_outputs;
cout << "input uses some mixins which are our outputs"
<< out << endl;
// 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)) // seems that this key image is ours.
{ // so save it to database for later use.
// iff success, set acc to updated_acc;
acc = updated_acc;
}
} 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) } // for (const transaction& tx: blk_txs)

@ -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, id,
sql_bigint_unsigned, account_id, sql_bigint_unsigned, account_id,
sql_bigint_unsigned, tx_id, sql_bigint_unsigned, tx_id,
sql_varchar , out_pub_key, sql_varchar , out_pub_key,
sql_varchar , tx_pub_key, sql_varchar , tx_pub_key,
sql_bigint_unsigned, amount,
sql_bigint_unsigned, out_index, sql_bigint_unsigned, out_index,
sql_bigint_unsigned, mixin, sql_bigint_unsigned, mixin,
sql_timestamp , timestamp); sql_timestamp , timestamp);
@ -196,14 +197,14 @@ struct XmrOutput : public Outputs
)"; )";
static constexpr const char* EXIST_STMT = R"( 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"( static constexpr const char* INSERT_STMT = R"(
INSERT IGNORE INTO `Outputs` (`account_id`, `tx_id`, `out_pub_key`, `tx_pub_key`, 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, VALUES (%0q, %1q, %2q, %3q,
%4q, %5q, %6q); %4q, %5q, %6q, %7q);
)"; )";

Loading…
Cancel
Save