You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
196 lines
5.0 KiB
196 lines
5.0 KiB
#pragma once
|
|
|
|
#include "db/MySqlAccounts.h"
|
|
|
|
#include <memory>
|
|
#include <mutex>
|
|
#include <atomic>
|
|
#include <algorithm>
|
|
#include <unordered_map>
|
|
|
|
namespace xmreg
|
|
{
|
|
|
|
using namespace std;
|
|
|
|
using chrono::seconds;
|
|
using namespace literals::chrono_literals;
|
|
|
|
class XmrAccount;
|
|
class MySqlAccounts;
|
|
|
|
class TxSearchException: public std::runtime_error
|
|
{
|
|
public:
|
|
using std::runtime_error::runtime_error;
|
|
};
|
|
|
|
class TxSearch
|
|
{
|
|
|
|
public:
|
|
// out_pk , amount
|
|
using known_outputs_t = std::unordered_map<public_key, uint64_t>;
|
|
using addr_view_t = std::pair<address_parse_info, secret_key>;
|
|
using pool_txs_t = std::vector<pair<uint64_t, transaction>>;
|
|
|
|
private:
|
|
|
|
// how frequently update scanned_block_height in Accounts table
|
|
//static constexpr uint64_t UPDATE_SCANNED_HEIGHT_INTERVAL = 5; // seconds
|
|
|
|
// how long should the search thread be live after no request
|
|
// are coming from the frontend. For example, when a user finishes
|
|
// using the service.
|
|
static seconds thread_search_life;
|
|
|
|
// indicate that a thread loop should keep running
|
|
std::atomic_bool continue_search {true};
|
|
|
|
// this acctually indicates whether thread loop finished
|
|
// its execution
|
|
std::atomic_bool searching_is_ongoing {false};
|
|
|
|
// marked true when we set new searched block value
|
|
// from other thread. for example, when we import account
|
|
// we set it to 0
|
|
std::atomic_bool searched_block_got_updated {false};
|
|
|
|
// to store last exception thrown in the search thread
|
|
// using this, a main thread can get info what went wrong here
|
|
std::exception_ptr eptr;
|
|
|
|
mutex getting_eptr;
|
|
mutex getting_known_outputs_keys;
|
|
mutex access_acc;
|
|
|
|
seconds last_ping_timestamp;
|
|
|
|
atomic<uint64_t> searched_blk_no;
|
|
|
|
// represents a row in mysql's Accounts table
|
|
shared_ptr<XmrAccount> acc;
|
|
|
|
// stores known output public keys.
|
|
// used as a cash to fast look up of
|
|
// our public keys in key images. Saves a lot of
|
|
// mysql queries to Outputs table.
|
|
//
|
|
|
|
known_outputs_t known_outputs_keys;
|
|
|
|
// this manages all mysql queries
|
|
// its better to when each thread has its own mysql connection object.
|
|
// this way if one thread crashes, it want take down
|
|
// connection for the entire service
|
|
std::shared_ptr<MySqlAccounts> xmr_accounts;
|
|
|
|
std::shared_ptr<CurrentBlockchainStatus> current_bc_status;
|
|
|
|
// address and viewkey for this search thread.
|
|
address_parse_info address;
|
|
secret_key viewkey;
|
|
|
|
string address_prefix;
|
|
|
|
public:
|
|
|
|
// make default constructor. useful in testing
|
|
TxSearch() = default;
|
|
|
|
TxSearch(XmrAccount const& _acc,
|
|
std::shared_ptr<CurrentBlockchainStatus> _current_bc_status);
|
|
|
|
virtual void
|
|
operator()();
|
|
|
|
virtual void
|
|
stop();
|
|
|
|
virtual void
|
|
set_searched_blk_no(uint64_t new_value);
|
|
|
|
virtual uint64_t
|
|
get_searched_blk_no() const;
|
|
|
|
virtual seconds
|
|
get_current_timestamp() const;
|
|
|
|
virtual void
|
|
ping();
|
|
|
|
virtual bool
|
|
still_searching() const;
|
|
|
|
virtual void
|
|
populate_known_outputs();
|
|
|
|
virtual known_outputs_t
|
|
get_known_outputs_keys();
|
|
|
|
virtual void
|
|
update_acc(XmrAccount const& _acc);
|
|
|
|
virtual void
|
|
set_exception_ptr()
|
|
{
|
|
std::lock_guard<std::mutex> lck (getting_eptr);
|
|
eptr = std::current_exception();
|
|
stop();
|
|
}
|
|
|
|
virtual std::exception_ptr
|
|
get_exception_ptr()
|
|
{
|
|
std::lock_guard<std::mutex> lck (getting_eptr);
|
|
return eptr;
|
|
}
|
|
|
|
/**
|
|
* Search for our txs in the mempool
|
|
*
|
|
* The method searches for our txs (outputs and inputs)
|
|
* in the mempool. It does basically same what search method
|
|
* The difference is that search method searches in a thread
|
|
* in a blockchain. It does not scan for tx in mempool. This is because
|
|
* it writes what it finds into database for permament storage.
|
|
* However txs in mempool are not permament. Also since we want to
|
|
* give the end user quick update on incoming/outging tx, this method
|
|
* will be executed whenever frontend wants. By default it is every
|
|
* 10 seconds.
|
|
* Also since we dont write here anything to the database, we
|
|
* return a json that will be appended to json produced by get_address_tx
|
|
* and similar function. The outputs here cant be spent anyway. This is
|
|
* only for end user information. The txs found here will be written
|
|
* to database later on by TxSearch thread when they will be added
|
|
* to the blockchain.
|
|
*
|
|
* we pass mempool_txs by copy because we want copy of mempool txs.
|
|
* to avoid worrying about synchronizing threads
|
|
*
|
|
* @return json
|
|
*/
|
|
virtual void
|
|
find_txs_in_mempool(pool_txs_t mempool_txs,
|
|
json* j_transactions);
|
|
|
|
virtual addr_view_t
|
|
get_xmr_address_viewkey() const;
|
|
|
|
virtual string
|
|
get_viewkey() const;
|
|
|
|
static void
|
|
set_search_thread_life(seconds life_seconds);
|
|
|
|
virtual bool
|
|
delete_existing_tx_if_exists(string const& tx_hash);
|
|
|
|
virtual ~TxSearch();
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|