initial scaning for possible inputs added

pull/1/head
moneroexamples 8 years ago
parent 2d4bed3471
commit 17efa53589

@ -41,10 +41,37 @@ public:
Query query = conn->query(XmrTransactionWithOutsAndIns::SELECT_STMT);
query.parse();
try {
try
{
query.storein(txs, address_id);
if (!txs.empty()) {
if (!txs.empty())
{
return true;
}
}
catch (mysqlpp::Exception &e) {
MYSQL_EXCEPTION_MSG(e);
}
catch (std::exception &e) {
MYSQL_EXCEPTION_MSG(e);
}
return false;
}
bool
select_for_tx(const uint64_t &tx_id, vector<XmrTransactionWithOutsAndIns>& txs) {
Query query = conn->query(XmrTransactionWithOutsAndIns::SELECT_STMT2);
query.parse();
try
{
query.storein(txs, tx_id);
if (!txs.empty())
{
return true;
}
}
@ -73,16 +100,6 @@ public:
bool
select(const uint64_t& address_id, vector<XmrInput>& ins)
{
//
// static shared_ptr<Query> query;
//
// if (!query)
// {
// Query q = MySqlConnector::getInstance().query(
// XmrInput::SELECT_STMT);
// q.parse();
// query = shared_ptr<Query>(new Query(q));
// }
Query query = conn->query(XmrInput::SELECT_STMT);
query.parse();
@ -108,7 +125,33 @@ public:
return false;
}
bool
select_for_tx(const uint64_t& address_id, vector<XmrInput>& ins)
{
Query query = conn->query(XmrInput::SELECT_STMT2);
query.parse();
try
{
query.storein(ins, address_id);
if (!ins.empty())
{
return true;
}
}
catch (mysqlpp::Exception& e)
{
MYSQL_EXCEPTION_MSG(e);
}
catch (std::exception& e)
{
MYSQL_EXCEPTION_MSG(e);
}
return false;
}
uint64_t
@ -136,6 +179,7 @@ public:
in_data.tx_id,
in_data.output_id,
in_data.key_image,
in_data.amount,
in_data.timestamp);
if (sr.rows() == 1)
@ -381,6 +425,42 @@ public:
return 0;
}
bool
exist(const string& tx_hash_str, XmrTransaction& tx)
{
Query query = conn->query(XmrTransaction::EXIST_STMT);
query.parse();
try
{
vector<XmrTransaction> outs;
query.storein(outs, tx_hash_str);
if (outs.empty())
{
return false;
}
tx = outs.at(0);
}
catch (mysqlpp::Exception& e)
{
MYSQL_EXCEPTION_MSG(e);
}
catch (std::exception& e)
{
MYSQL_EXCEPTION_MSG(e);
}
return true;
}
uint64_t
get_total_recieved(const uint64_t& account_id)
{
@ -617,12 +697,24 @@ public:
return mysql_in->select(account_id, ins);
}
bool
select_inputs_for_tx(const uint64_t& tx_id, vector<XmrTransactionWithOutsAndIns>& ins)
{
return mysql_tx_inout->select_for_tx(tx_id, ins);
}
bool
output_exists(const string& output_public_key_str, XmrOutput& out)
{
return mysql_out->exist(output_public_key_str, out);
}
bool
tx_exists(const string& tx_hash_str, XmrTransaction& tx)
{
return mysql_tx->exist(tx_hash_str, tx);
}
uint64_t
get_total_recieved(const uint64_t& account_id)

@ -291,26 +291,16 @@ public:
DateTime blk_timestamp_mysql_format
= XmrTransaction::timestamp_to_DateTime(blk.timestamp);
uint64_t tx_mysql_id {0};
string tx_hash_str = pod_to_hex(tx_hash);
if (!found_mine_outputs.empty())
{
crypto::hash payment_id = null_hash;
crypto::hash8 payment_id8 = null_hash8;
get_payment_id(tx, payment_id, payment_id8);
string payment_id_str{""};
if (payment_id != null_hash)
{
payment_id_str = pod_to_hex(payment_id);
}
else if (payment_id8 != null_hash8)
{
payment_id_str = pod_to_hex(payment_id8);
}
string tx_hash_str = pod_to_hex(tx_hash);
XmrTransaction tx_data;
@ -322,12 +312,12 @@ public:
tx_data.unlock_time = 0;
tx_data.height = searched_blk_no;
tx_data.coinbase = is_coinbase(tx);
tx_data.payment_id = payment_id_str;
tx_data.payment_id = get_payment_id_as_string(tx);
tx_data.mixin = get_mixin_no(tx) - 1;
tx_data.timestamp = blk_timestamp_mysql_format;
// insert tx_data into mysql's Transactions table
uint64_t tx_mysql_id = xmr_accounts->insert_tx(tx_data);
tx_mysql_id = xmr_accounts->insert_tx(tx_data);
if (tx_mysql_id == 0)
{
@ -382,6 +372,9 @@ public:
vector<txin_to_key> input_key_imgs = xmreg::get_key_images(tx);
// here we will keep what we find.
vector<XmrInput> inputs_found;
// make timescale maps for mixins in input
for (const txin_to_key& in_key: input_key_imgs)
{
@ -403,7 +396,7 @@ public:
}
// for each found output public key find its block to get timestamp
// for each found output public key find check if its ours or not
for (const cryptonote::output_data_t& output_data: mixin_outputs)
{
string output_public_key_str = pod_to_hex(output_data.pubkey);
@ -418,19 +411,22 @@ public:
// 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.tx_id = 0; // for now zero, later we set it
in_data.output_id = out.id;
in_data.key_image = pod_to_hex(in_key.k_image);
in_data.amount = in_key.amount;
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);
inputs_found.push_back(in_data);
// a key image has only one real mixin. Rest is fake.
// so if we find a candidate, break the search
// so if we find a candidate, break the search.
// break;
} // if (xmr_accounts->output_exists(output_public_key_str, out))
@ -439,6 +435,65 @@ public:
} // for (const txin_to_key& in_key: input_key_imgs)
if (!inputs_found.empty())
{
// seems we have some inputs found. time
// to write it to mysql. But first,
// check if this tx is written in mysql.
// calculate how much we preasumply spent.
uint64_t total_sent {0};
for (const XmrInput& in_data: inputs_found)
{
total_sent += in_data.amount;
}
if (tx_mysql_id == 0)
{
// this txs hasnt been seen in step first.
// it means that it only contains potentially our
// key images. It does not have our outputs.
// so write it to mysql as ours, with
// total received of 0.
XmrTransaction tx_data;
tx_data.hash = tx_hash_str;
tx_data.account_id = acc.id;
tx_data.total_received = 0;
tx_data.total_sent = total_sent;
tx_data.unlock_time = 0;
tx_data.height = searched_blk_no;
tx_data.coinbase = is_coinbase(tx);
tx_data.payment_id = get_payment_id_as_string(tx);
tx_data.mixin = get_mixin_no(tx) - 1;
tx_data.timestamp = blk_timestamp_mysql_format;
// insert tx_data into mysql's Transactions table
tx_mysql_id = xmr_accounts->insert_tx(tx_data);
if (tx_mysql_id == 0)
{
//cerr << "tx_mysql_id is zero!" << endl;
//throw TxSearchException("tx_mysql_id is zero!");
}
}
} // if (!inputs_found.empty())
// save all input found into database
for (XmrInput& in_data: inputs_found)
{
in_data.tx_id = tx_mysql_id;
uint64_t in_mysql_id = xmr_accounts->insert_input(in_data);
}
} // for (const transaction& tx: blk_txs)
@ -480,6 +535,29 @@ public:
}
string
get_payment_id_as_string(const transaction& tx)
{
crypto::hash payment_id = null_hash;
crypto::hash8 payment_id8 = null_hash8;
get_payment_id(tx, payment_id, payment_id8);
string payment_id_str{""};
if (payment_id != null_hash)
{
payment_id_str = pod_to_hex(payment_id);
}
else if (payment_id8 != null_hash8)
{
payment_id_str = pod_to_hex(payment_id8);
}
return payment_id_str;
}
};

@ -191,6 +191,7 @@ public:
// initializa json response
json j_response {
{ "total_received", "0"},
{ "total_sent", "0"},
{ "scanned_height", 0},
{ "scanned_block_height", 0},
{ "start_height", 0},
@ -222,7 +223,31 @@ public:
for (XmrTransaction tx: txs)
{
j_txs.push_back(tx.to_json());
// get inputs associated with a given
// transaction, if any.
json j_tx = tx.to_json();
vector<XmrTransactionWithOutsAndIns> inputs;
if (xmr_accounts->select_inputs_for_tx(tx.id, inputs))
{
json j_spent_outputs = json::array();
uint64_t total_spent {0};
for (XmrTransactionWithOutsAndIns input: inputs)
{
total_spent += input.amount;
j_spent_outputs.push_back(input.spent_output());
}
j_tx["total_sent"] = total_spent;
j_tx["spent_outputs"] = j_spent_outputs;
}
j_txs.push_back(j_tx);
}
j_response["transactions"] = j_txs;
@ -294,15 +319,9 @@ public:
continue;
}
j_spent_outputs.push_back(json {
{"amount" , tx.out_amount},
{"key_image" , tx.key_image_to_string()},
{"tx_pub_key", tx.tx_pub_key},
{"out_index" , tx.out_index},
{"mixin" , tx.tx_mixin},
});
j_spent_outputs.push_back(tx.spent_output());
total_sent += tx.out_amount;
total_sent += tx.amount;
}
j_response["spent_outputs"] = j_spent_outputs;

@ -121,6 +121,10 @@ struct XmrTransaction : public Transactions
SELECT * FROM `Transactions` WHERE `id` = (%0q)
)";
static constexpr const char* EXIST_STMT = R"(
SELECT * FROM `Transactions` WHERE `hash` = (%0q)
)";
static constexpr const char* INSERT_STMT = R"(
INSERT IGNORE INTO `Transactions` (`hash`, `account_id`, `total_received`,
`total_sent`, `unlock_time`, `height`,
@ -238,12 +242,13 @@ ostream& operator<< (std::ostream& os, const XmrOutput& out) {
};
sql_create_6(Inputs, 1, 4,
sql_create_7(Inputs, 1, 4,
sql_bigint_unsigned, id,
sql_bigint_unsigned, account_id,
sql_bigint_unsigned, tx_id,
sql_bigint_unsigned, output_id,
sql_varchar , key_image,
sql_bigint_unsigned, amount,
sql_timestamp , timestamp);
@ -254,11 +259,16 @@ struct XmrInput : public Inputs
SELECT * FROM `Inputs` WHERE `account_id` = (%0q)
)";
static constexpr const char* SELECT_STMT2 = R"(
SELECT * FROM `Inputs` WHERE `tx_id` = (%0q)
)";
static constexpr const char* INSERT_STMT = R"(
INSERT IGNORE INTO `Inputs` (`account_id`, `tx_id`, `output_id`,
`key_image`, `timestamp`)
`key_image`, `amount` , `timestamp`)
VALUES (%0q, %1q, %2q,
%3q, %4q);
%3q, %4q, %5q);
)";
@ -273,6 +283,7 @@ struct XmrInput : public Inputs
{"tx_id" , tx_id},
{"output_id" , output_id},
{"key_image" , key_image},
{"amount" , amount},
{"timestamp" , timestamp}
};
@ -293,18 +304,14 @@ ostream& operator<< (std::ostream& os, const XmrInput& out) {
// this is MySQL VIEW, based on the Transactions,
// Outputs and Inputs tables
sql_create_11(TransactionsWithOutsAndIns, 1, 2,
sql_create_7(TransactionsWithOutsAndIns, 1, 2,
sql_bigint_unsigned, tx_id,
sql_bigint_unsigned, account_id,
sql_varchar , hash,
sql_bigint_unsigned, total_received,
sql_bigint_unsigned, out_amount,
sql_bigint_unsigned, height,
sql_bigint_unsigned, tx_mixin,
sql_timestamp , timestamp,
sql_bigint_unsigned, amount,
sql_varchar , tx_pub_key,
sql_bigint_unsigned, out_index,
sql_varchar_null , key_image);
sql_varchar_null , key_image,
sql_bigint_unsigned, mixin);
@ -315,6 +322,10 @@ struct XmrTransactionWithOutsAndIns : public TransactionsWithOutsAndIns
SELECT * FROM `TransactionsWithOutsAndIns` WHERE `account_id` = (%0q)
)";
static constexpr const char* SELECT_STMT2 = R"(
SELECT * FROM `TransactionsWithOutsAndIns` WHERE `tx_id` = (%0q)
)";
using TransactionsWithOutsAndIns::TransactionsWithOutsAndIns;
@ -324,17 +335,30 @@ struct XmrTransactionWithOutsAndIns : public TransactionsWithOutsAndIns
json j {{"tx_id" , tx_id},
{"account_id" , account_id},
{"hash" , hash},
{"out_amount" , out_amount},
{"amount" , amount},
{"tx_pub_key" , tx_pub_key},
{"out_index" , out_index},
{"key_image" , key_image_to_string()},
{"mixin" , tx_mixin}
{"mixin" , mixin}
};
return j;
}
json
spent_output() const
{
json j {{"amount" , amount},
{"key_image" , key_image_to_string()},
{"tx_pub_key", tx_pub_key},
{"out_index" , out_index},
{"mixin" , mixin}
};
return j;
}
string key_image_to_string() const
{
string key_image_str {"NULL"};

Loading…
Cancel
Save