moneroexamples 7 years ago
parent 63c6d3310e
commit 6b4eddcea7

@ -813,6 +813,27 @@ CurrentBlockchainStatus::get_searched_blk_no(const string& address,
return true;
}
bool
CurrentBlockchainStatus::get_known_outputs_keys(
string const& address,
vector<pair<string, uint64_t>>& known_outputs_keys)
{
std::lock_guard<std::mutex> lck (searching_threads_map_mtx);
if (!search_thread_exist(address))
{
// thread does not exist
cout << "thread for " << address << " does not exist" << endl;
return false;
}
known_outputs_keys
= searching_threads[address].get()->get_known_outputs_keys();
return true;
}
bool
CurrentBlockchainStatus::search_thread_exist(const string& address)
{

@ -209,6 +209,10 @@ struct CurrentBlockchainStatus
get_searched_blk_no(const string& address,
uint64_t& searched_blk_no);
static bool
get_known_outputs_keys(string const& address,
vector<pair<string, uint64_t>>& known_outputs_keys);
static void
clean_search_thread_map();

@ -525,6 +525,12 @@ TxSearch::populate_known_outputs()
}
}
vector<pair<string, uint64_t>>
TxSearch::get_known_outputs_keys()
{
std::lock_guard<std::mutex> lck (getting_known_outputs_keys);
return known_outputs_keys;
};
json
TxSearch::find_txs_in_mempool(
@ -534,16 +540,7 @@ TxSearch::find_txs_in_mempool(
uint64_t current_height = CurrentBlockchainStatus::get_current_blockchain_height();
vector<pair<string, uint64_t>> known_outputs_keys_copy;
{
// copy known ouputs. mutex is needed as known_outputs_keys can
// be updated at the same time as used in this here.
// we make its copy as to keep mutex for short time,
// and read only on copy safely.
std::lock_guard<std::mutex> lck (getting_known_outputs_keys);
known_outputs_keys_copy = known_outputs_keys;
}
vector<pair<string, uint64_t>> known_outputs_keys_copy = get_known_outputs_keys();
// since find_txs_in_mempool can be called outside of this thread,
// we need to use local connection. we cant use connection that the

@ -94,6 +94,9 @@ public:
void
populate_known_outputs();
vector<pair<string, uint64_t>>
get_known_outputs_keys();
/**
* Search for our txs in the mempool

@ -1047,6 +1047,8 @@ YourMoneroRequests::get_tx(const shared_ptr< Session > session, const Bytes & bo
bool tx_found {false};
bool tx_in_mempool {false};
if (!CurrentBlockchainStatus::get_tx(tx_hash, tx))
{
// if tx not found in the blockchain, check if its in mempool
@ -1064,6 +1066,7 @@ YourMoneroRequests::get_tx(const shared_ptr< Session > session, const Bytes & bo
{
tx = mtx.second;
tx_found = true;
tx_in_mempool = true;
default_timestamp = mtx.first;
break;
}
@ -1190,7 +1193,7 @@ YourMoneroRequests::get_tx(const shared_ptr< Session > session, const Bytes & bo
// to get spendings, we need to have our key_images. but
// the backend does not have spendkey, so it cant determine
// which key images are really ours or not. this is task
// which key images are really ours or not. this is the task
// for the frontend. however, backend can only provide guesses and
// nessessery data to the frontend to filter out incorrect
// guesses.
@ -1205,47 +1208,116 @@ YourMoneroRequests::get_tx(const shared_ptr< Session > session, const Bytes & bo
// select this account if its existing one
if (xmr_accounts->select(xmr_address, acc))
{
// if user exist, get all known outputs for this user
// if user exist, get tx data from database
// this will work only for tx in the blockchain,
// not those in the mempool.
if (!tx_in_mempool)
{
// if not in mempool, but in blockchain, just
// get data aout key images from the mysql
XmrTransaction xmr_tx;
if (xmr_accounts->tx_exists(acc.id, tx_hash_str, xmr_tx))
{
j_response["payment_id"] = xmr_tx.payment_id;
j_response["timestamp"] = static_cast<uint64_t>(xmr_tx.timestamp);
vector<XmrInput> inputs;
if (xmr_accounts->select_inputs_for_tx(xmr_tx.id, inputs))
{
json j_spent_outputs = json::array();
uint64_t total_spent {0};
for (XmrInput input: inputs)
{
XmrOutput out;
XmrTransaction xmr_tx;
if (xmr_accounts->select_output_with_id(input.output_id, out))
{
total_spent += input.amount;
if (xmr_accounts->tx_exists(acc.id, tx_hash_str, xmr_tx))
{
j_response["payment_id"] = xmr_tx.payment_id;
j_response["timestamp"] = static_cast<uint64_t>(xmr_tx.timestamp);
j_spent_outputs.push_back({
{"amount" , input.amount},
{"key_image" , input.key_image},
{"tx_pub_key" , out.tx_pub_key},
{"out_index" , out.out_index},
{"mixin" , out.mixin}});
}
vector<XmrInput> inputs;
} // for (XmrInput input: inputs)
if (xmr_accounts->select_inputs_for_tx(xmr_tx.id, inputs))
{
json j_spent_outputs = json::array();
j_response["total_sent"] = total_spent;
uint64_t total_spent {0};
j_response["spent_outputs"] = j_spent_outputs;
for (XmrInput input: inputs)
{
XmrOutput out;
} // if (xmr_accounts->select_inputs_for_tx(tx.id, inputs))
} // if (xmr_accounts->tx_exists(acc.id, tx_hash_str, xmr_tx))
} // if (!tx_in_mempool)
else
{
// if tx in mempool, mysql will not have this tx, so
// we cant pull info about key images from mysql for this tx.
if (xmr_accounts->select_output_with_id(input.output_id, out))
{
total_spent += input.amount;
// we have to redo this info from basically from scrach.
vector<pair<string, uint64_t>> known_outputs_keys;
if (CurrentBlockchainStatus::get_known_outputs_keys(
xmr_address, known_outputs_keys))
{
// we got known_outputs_keys from the search thread.
// so now we can use OutputInputIdentification to
// get info about inputs.
// Class that is resposnible for idenficitaction of our outputs
// and inputs in a given tx.
OutputInputIdentification oi_identification
{&address, &viewkey, &tx};
// no need mutex here, as this will be exectued only after
// the above. there is no threads here.
oi_identification.identify_inputs(known_outputs_keys);
json j_spent_outputs = json::array();
uint64_t total_spent {0};
for (auto& in_info: oi_identification.identified_inputs)
{
// need to get output info from mysql, as we need
// to know output's amount, its orginal
// tx public key and its index in that tx
XmrOutput out;
if (xmr_accounts->output_exists(in_info.out_pub_key, out))
{
total_spent += out.amount;
j_spent_outputs.push_back({
{"amount" , in_info.amount},
{"key_image" , in_info.key_img},
{"tx_pub_key" , out.tx_pub_key},
{"out_index" , out.out_index},
{"mixin" , out.mixin}});
}
j_spent_outputs.push_back({
{"amount" , input.amount},
{"key_image" , input.key_image},
{"tx_pub_key" , out.tx_pub_key},
{"out_index" , out.out_index},
{"mixin" , out.mixin}});
}
}
} // for (auto& in_info: oi_identification.identified_inputs)
j_response["total_sent"] = total_spent;
j_response["total_sent"] = total_spent;
j_response["spent_outputs"] = j_spent_outputs;
j_response["spent_outputs"] = j_spent_outputs;
} // if (xmr_accounts->select_inputs_for_tx(tx.id, inputs))
} //if (CurrentBlockchainStatus::get_known_outputs_keys(
// xmr_address, known_outputs_keys))
} // if (xmr_accounts->tx_exists(acc.id, tx_hash_str, xmr_tx))
} // else
} // if (xmr_accounts->select(xmr_address, acc))

Loading…
Cancel
Save