search_if_payment_made added

pull/1/head
moneroexamples 7 years ago
parent e56d6ea664
commit 123d3bb68b

@ -29,6 +29,8 @@ main(int ac, const char* av[])
// get command line options
xmreg::CmdLineOptions opts {ac, av};
auto address_opt = opts.get_option<string>("address");
auto viewkey_opt = opts.get_option<string>("viewkey");
auto help_opt = opts.get_option<bool>("help");
auto testnet_opt = opts.get_option<bool>("testnet");
auto use_ssl_opt = opts.get_option<bool>("use-ssl");
@ -39,8 +41,12 @@ if (*help_opt)
return EXIT_SUCCESS;
}
bool testnet {*testnet_opt};
bool use_ssl {*use_ssl_opt};
bool testnet = *testnet_opt;
bool use_ssl = *use_ssl_opt;
string address_str = address_opt ? *address_opt : "";
string viewkey_str = viewkey_opt ? *viewkey_opt : "";
auto port_opt = opts.get_option<string>("port");
auto bc_path_opt = opts.get_option<string>("bc-path");
@ -69,6 +75,9 @@ xmreg::MySqlConnector::dbname = "openmonero";
xmreg::CurrentBlockchainStatus::set_blockchain_path(blockchain_path.string());
xmreg::CurrentBlockchainStatus::set_testnet(testnet);
xmreg::CurrentBlockchainStatus::refresh_block_status_every_seconds = 60;
xmreg::CurrentBlockchainStatus::import_payment_address = address_str;
xmreg::CurrentBlockchainStatus::import_payment_viewkey = viewkey_str;
xmreg::CurrentBlockchainStatus::import_fee = 0.01e12;
// since CurrentBlockchainStatus class monitors current status
// of the blockchain (e.g, current height), its seems logical to

@ -25,6 +25,10 @@ namespace xmreg
"produce help message")
("testnet,t", value<bool>()->default_value(false)->implicit_value(true),
"use testnet blockchain")
("address,a", value<string>(),
"monero address string for fee of importing transactions")
("viewkey,v", value<string>(),
"private view key string corresponding to the monero address provided")
("use-ssl", value<bool>()->default_value(false)->implicit_value(true),
"whether to use ssl (i.e., https) or not.")
("port,p", value<string>()->default_value("8081"),

@ -50,6 +50,12 @@ struct CurrentBlockchainStatus
// make it static to guarantee only one such map exist.
static map<string, shared_ptr<TxSearch>> searching_threads;
static string import_payment_address;
static string import_payment_viewkey;
static uint64_t import_fee;
static account_public_address address;
static secret_key viewkey;
// vector of mempool transactions that all threads
// can refer to
@ -64,6 +70,33 @@ struct CurrentBlockchainStatus
static
void start_monitor_blockchain_thread()
{
bool testnet = CurrentBlockchainStatus::testnet;
if (!import_payment_address.empty() && !import_payment_viewkey.empty())
{
if (!xmreg::parse_str_address(
import_payment_address,
address,
testnet))
{
cerr << "Cant parse address_str: "
<< import_payment_address
<< endl;
return;
}
if (!xmreg::parse_str_secret_key(
import_payment_viewkey,
viewkey))
{
cerr << "Cant parse the viewkey_str: "
<< import_payment_viewkey
<< endl;
return;
}
}
if (!is_running)
{
m_thread = std::thread{[]()
@ -291,8 +324,127 @@ struct CurrentBlockchainStatus
return mempool_txs;
}
static bool
search_if_payment_made(
const string& payment_id_str,
const uint64_t& desired_amount,
string& tx_hash_with_payment)
{
crypto::hash payment_id;
if (!hex_to_pod(payment_id_str, payment_id))
{
cerr << "Cant parse the payment_id_str: " << payment_id_str << endl;
return false;
}
vector<transaction> txs_to_check = get_mempool_txs();
uint64_t current_blockchain_height = current_height;
// apend txs in last to blocks into the txs_to_check vector
for (uint64_t blk_i = current_blockchain_height - 2;
blk_i <= current_blockchain_height;
++blk_i)
{
// get block cointaining this tx
block blk;
if (!get_block(blk_i, blk)) {
cerr << "Cant get block of height: " + to_string(blk_i) << endl;
return false;
}
list <cryptonote::transaction> blk_txs;
if (!get_block_txs(blk, blk_txs))
{
cerr << "Cant get transactions in block: " << to_string(blk_i) << endl;
return false;
}
txs_to_check.insert(txs_to_check.end(), blk_txs.begin(), blk_txs.end());
}
for (transaction& tx: txs_to_check)
{
if (is_coinbase(tx))
{
// not interested in coinbase txs
continue;
}
public_key tx_pub_key = xmreg::get_tx_pub_key_from_received_outs(tx);
// <public_key , amount , out idx>
vector<tuple<txout_to_key, uint64_t, uint64_t>> outputs;
outputs = get_ouputs_tuple(tx);
// for each output, in a tx, check if it belongs
// to the given account of specific address and viewkey
// public transaction key is combined with our viewkey
// to create, so called, derived key.
key_derivation derivation;
if (!generate_key_derivation(tx_pub_key, viewkey, derivation))
{
cerr << "Cant get derived key for: " << "\n"
<< "pub_tx_key: " << tx_pub_key << " and "
<< "prv_view_key" << viewkey << endl;
return false;
}
string tx_hash_str = pod_to_hex(get_transaction_hash(tx));
uint64_t total_received {0};
for (auto& out: outputs)
{
txout_to_key txout_k = std::get<0>(out);
uint64_t amount = std::get<1>(out);
uint64_t output_idx_in_tx = std::get<2>(out);
// get the tx output public key
// that normally would be generated for us,
// if someone had sent us some xmr.
public_key generated_tx_pubkey;
derive_public_key(derivation,
output_idx_in_tx,
address.m_spend_public_key,
generated_tx_pubkey);
// check if generated public key matches the current output's key
bool mine_output = (txout_k.key == generated_tx_pubkey);
if (mine_output)
{
total_received += amount;
}
}
cout << " - payment id check in tx: "
<< tx_hash_str
<< " found: " << total_received << endl;
if (total_received == desired_amount)
{
// the payment has been made.
tx_hash_with_payment = tx_hash_str;
return true;
}
}
// definitions of these function are at the end of this file
return false;
}
// definitions of these function are at the end of this file
// due to forward declaraions of TxSearch
static bool
start_tx_search_thread(XmrAccount acc);
@ -907,8 +1059,11 @@ uint64_t CurrentBlockchainStatus::refresh_block_status_every_seco
xmreg::MicroCore CurrentBlockchainStatus::mcore;
cryptonote::Blockchain *CurrentBlockchainStatus::core_storage;
vector<transaction> CurrentBlockchainStatus::mempool_txs;
string CurrentBlockchainStatus::import_payment_address;
string CurrentBlockchainStatus::import_payment_viewkey;
uint64_t CurrentBlockchainStatus::import_fee {10000000000}; // 0.01 xmr
account_public_address CurrentBlockchainStatus::address;
secret_key CurrentBlockchainStatus::viewkey;
map<string, shared_ptr<TxSearch>> CurrentBlockchainStatus::searching_threads;

@ -635,6 +635,33 @@ public:
return 0;
}
bool
update(XmrPayment& payment_orginal, XmrPayment& payment_new)
{
Query query = conn->query();
try
{
query.update(payment_orginal, payment_new);
SimpleResult sr = query.execute();
if (sr.rows() == 1)
return true;
}
catch (mysqlpp::Exception& e)
{
MYSQL_EXCEPTION_MSG(e);
return false;
}
return false;
}
};
class MySqlAccounts
@ -924,6 +951,11 @@ public:
return r;
}
bool
update_payment(XmrPayment& payment_orginal, XmrPayment& payment_new)
{
return mysql_payment->update(payment_orginal, payment_new);
}
uint64_t
get_total_recieved(const uint64_t& account_id)

@ -528,7 +528,6 @@ public:
if (show_logs)
print_json_log("import_wallet_request request: ", j_request);
string xmr_address = j_request["address"];
// a placeholder for exciting or new account data
@ -539,19 +538,49 @@ public:
// select this payment if its existing one
if (xmr_accounts->select_payment_by_address(xmr_address, xmr_payment))
{
// payment record exists, so now we need to check if
// actually payment has been done, and updated
// mysql record accordingly.
bool request_fulfilled = bool {xmr_payment.request_fulfilled};
j_response["payment_id"] = xmr_payment.payment_id;
j_response["import_fee"] = xmr_payment.import_fee;
j_response["new_request"] = false;
j_response["request_fulfilled"] = bool {xmr_payment.request_fulfilled};
j_response["request_fulfilled"] = request_fulfilled;
j_response["payment_address"] = xmr_payment.payment_address;
j_response["status"] = "Payment not yet received";
if (bool {xmr_payment.request_fulfilled} == false)
string tx_hash_with_payment;
if (!request_fulfilled
&& CurrentBlockchainStatus::search_if_payment_made(
xmr_payment.payment_id,
xmr_payment.import_fee,
tx_hash_with_payment))
{
j_response["status"] = "Payment not yet received";
XmrPayment updated_xmr_payment = xmr_payment;
// updated values
updated_xmr_payment.request_fulfilled = true;
updated_xmr_payment.tx_hash = tx_hash_with_payment;
// save to mysql
if (xmr_accounts->update_payment(xmr_payment, updated_xmr_payment))
{
request_fulfilled = true;
}
else
{
cerr << "Updating payment mysql failed! " << endl;
j_response["status"] = "Updating payment mysql failed!";
}
}
else
if (request_fulfilled)
{
j_response["status"] = "Payment received";
j_response["request_fulfilled"] = request_fulfilled;
j_response["status"] = "Payment received. Thank you.";
}
}
else
@ -561,12 +590,12 @@ public:
uint64_t payment_table_id {0};
xmr_payment.address = xmr_address;
xmr_payment.payment_id = pod_to_hex(generated_payment_id());
xmr_payment.import_fee = 1000000000000; // xmr
xmr_payment.address = xmr_address;
xmr_payment.payment_id = pod_to_hex(generated_payment_id());
xmr_payment.import_fee = CurrentBlockchainStatus::import_fee; // xmr
xmr_payment.request_fulfilled = false;
xmr_payment.tx_hash = ""; // no tx_hash yet with the payment
xmr_payment.payment_address = "49tyE1AZLzDHM1JPeLeG3vMjqXDGQRQPwWij3ARjZfQMhRLDNyH8PyJVX9AxF3jzabUqjQSecbzYm1JX3MtSib1NQvodSMQ";
xmr_payment.tx_hash = ""; // no tx_hash yet with the payment
xmr_payment.payment_address = CurrentBlockchainStatus::import_payment_address;
if ((payment_table_id = xmr_accounts->insert_payment(xmr_payment)) != 0)

Loading…
Cancel
Save