parent
afb13b144c
commit
085731f343
@ -1,636 +0,0 @@
|
||||
//
|
||||
// Created by mwo on 7/01/17.
|
||||
//
|
||||
|
||||
#define MYSQLPP_SSQLS_NO_STATICS 1
|
||||
|
||||
#include "MySqlAccounts.h"
|
||||
#include "TxSearch.h"
|
||||
#include "CurrentBlockchainStatus.h"
|
||||
|
||||
#include "ssqlses.h"
|
||||
|
||||
namespace xmreg
|
||||
{
|
||||
|
||||
|
||||
MysqlInputs::MysqlInputs(shared_ptr<MySqlConnector> _conn)
|
||||
: conn {_conn}
|
||||
{}
|
||||
|
||||
bool
|
||||
MysqlInputs::select_for_out(const uint64_t& output_id, vector<XmrInput>& ins)
|
||||
{
|
||||
try
|
||||
{
|
||||
conn->check_if_connected();
|
||||
|
||||
Query query = conn->query(XmrInput::SELECT_STMT4);
|
||||
query.parse();
|
||||
|
||||
query.storein(ins, output_id);
|
||||
|
||||
return !ins.empty();
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
MYSQL_EXCEPTION_MSG(e);
|
||||
//throw e;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
MysqlOutpus::MysqlOutpus(shared_ptr<MySqlConnector> _conn): conn {_conn}
|
||||
{}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
MysqlOutpus::exist(const string& output_public_key_str, XmrOutput& out)
|
||||
{
|
||||
try
|
||||
{
|
||||
conn->check_if_connected();
|
||||
|
||||
Query query = conn->query(XmrOutput::EXIST_STMT);
|
||||
query.parse();
|
||||
|
||||
vector<XmrOutput> outs;
|
||||
|
||||
query.storein(outs, output_public_key_str);
|
||||
|
||||
if (outs.empty())
|
||||
return false;
|
||||
|
||||
out = std::move(outs.at(0));
|
||||
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
MYSQL_EXCEPTION_MSG(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
MysqlTransactions::MysqlTransactions(shared_ptr<MySqlConnector> _conn): conn {_conn}
|
||||
{}
|
||||
|
||||
uint64_t
|
||||
MysqlTransactions::mark_spendable(const uint64_t& tx_id_no, bool spendable)
|
||||
{
|
||||
try
|
||||
{
|
||||
conn->check_if_connected();
|
||||
|
||||
Query query = conn->query(spendable ?
|
||||
XmrTransaction::MARK_AS_SPENDABLE_STMT
|
||||
: XmrTransaction::MARK_AS_NONSPENDABLE_STMT);
|
||||
query.parse();
|
||||
|
||||
|
||||
SimpleResult sr = query.execute(tx_id_no);
|
||||
|
||||
return sr.rows();
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
MYSQL_EXCEPTION_MSG(e);
|
||||
//throw e;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
MysqlTransactions::delete_tx(const uint64_t& tx_id_no)
|
||||
{
|
||||
try
|
||||
{
|
||||
conn->check_if_connected();
|
||||
|
||||
Query query = conn->query(XmrTransaction::DELETE_STMT);
|
||||
query.parse();
|
||||
|
||||
SimpleResult sr = query.execute(tx_id_no);
|
||||
|
||||
return sr.rows();
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
MYSQL_EXCEPTION_MSG(e);
|
||||
//throw e;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
MysqlTransactions::exist(const uint64_t& account_id, const string& tx_hash_str, XmrTransaction& tx)
|
||||
{
|
||||
try
|
||||
{
|
||||
conn->check_if_connected();
|
||||
|
||||
Query query = conn->query(XmrTransaction::EXIST_STMT);
|
||||
query.parse();
|
||||
|
||||
vector<XmrTransaction> outs;
|
||||
|
||||
query.storein(outs, account_id, tx_hash_str);
|
||||
|
||||
if (outs.empty())
|
||||
return false;
|
||||
|
||||
tx = outs.at(0);
|
||||
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
MYSQL_EXCEPTION_MSG(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
MysqlTransactions::get_total_recieved(const uint64_t& account_id, uint64_t& amount)
|
||||
{
|
||||
try
|
||||
{
|
||||
conn->check_if_connected();
|
||||
|
||||
Query query = conn->query(XmrTransaction::SUM_XMR_RECIEVED);
|
||||
query.parse();
|
||||
|
||||
StoreQueryResult sqr = query.store(account_id);
|
||||
|
||||
if (!sqr.empty())
|
||||
{
|
||||
amount = sqr.at(0)["total_received"];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
MYSQL_EXCEPTION_MSG(e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
MysqlPayments::MysqlPayments(shared_ptr<MySqlConnector> _conn): conn {_conn}
|
||||
{}
|
||||
|
||||
bool
|
||||
MysqlPayments::select_by_payment_id(const string& payment_id, vector<XmrPayment>& payments)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
conn->check_if_connected();
|
||||
|
||||
Query query = conn->query(XmrPayment::SELECT_STMT2);
|
||||
query.parse();
|
||||
|
||||
payments.clear();
|
||||
query.storein(payments, payment_id);
|
||||
|
||||
return !payments.empty();
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
MYSQL_EXCEPTION_MSG(e);
|
||||
//throw e;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
MySqlAccounts::MySqlAccounts(shared_ptr<CurrentBlockchainStatus> _current_bc_status)
|
||||
: current_bc_status {_current_bc_status}
|
||||
{
|
||||
// create connection to the mysql
|
||||
conn = make_shared<MySqlConnector>();
|
||||
|
||||
_init();
|
||||
}
|
||||
|
||||
MySqlAccounts::MySqlAccounts(shared_ptr<CurrentBlockchainStatus> _current_bc_status,
|
||||
shared_ptr<MySqlConnector> _conn)
|
||||
: current_bc_status {_current_bc_status}
|
||||
{
|
||||
conn = _conn;
|
||||
|
||||
_init();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
MySqlAccounts::select(const string& address, XmrAccount& account)
|
||||
{
|
||||
try
|
||||
{
|
||||
conn->check_if_connected();
|
||||
|
||||
Query query = conn->query(XmrAccount::SELECT_STMT2);
|
||||
query.parse();
|
||||
|
||||
vector<XmrAccount> res;
|
||||
query.storein(res, address);
|
||||
|
||||
if (!res.empty())
|
||||
{
|
||||
account = std::move(res.at(0));
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
MYSQL_EXCEPTION_MSG(e);
|
||||
//throw e;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
uint64_t
|
||||
MySqlAccounts::insert(const T& data_to_insert)
|
||||
{
|
||||
try
|
||||
{
|
||||
conn->check_if_connected();
|
||||
|
||||
Query query = conn->query();
|
||||
|
||||
query.insert(data_to_insert);
|
||||
|
||||
SimpleResult sr = query.execute();
|
||||
|
||||
if (sr.rows() == 1)
|
||||
return sr.insert_id();
|
||||
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
MYSQL_EXCEPTION_MSG(e);;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Explicitly instantiate insert template for our tables
|
||||
template
|
||||
uint64_t MySqlAccounts::insert<XmrAccount>(const XmrAccount& data_to_insert);
|
||||
template
|
||||
uint64_t MySqlAccounts::insert<XmrTransaction>(const XmrTransaction& data_to_insert);
|
||||
template
|
||||
uint64_t MySqlAccounts::insert<XmrOutput>(const XmrOutput& data_to_insert);
|
||||
template
|
||||
uint64_t MySqlAccounts::insert<XmrInput>(const XmrInput& data_to_insert);
|
||||
template
|
||||
uint64_t MySqlAccounts::insert<XmrPayment>(const XmrPayment& data_to_insert);
|
||||
|
||||
template <typename T>
|
||||
uint64_t
|
||||
MySqlAccounts::insert(const vector<T>& data_to_insert)
|
||||
{
|
||||
try
|
||||
{
|
||||
conn->check_if_connected();
|
||||
|
||||
Query query = conn->query();
|
||||
|
||||
query.insert(data_to_insert.begin(), data_to_insert.end());
|
||||
|
||||
SimpleResult sr = query.execute();
|
||||
|
||||
return sr.rows();
|
||||
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
MYSQL_EXCEPTION_MSG(e);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Explicitly instantiate insert template for our tables
|
||||
template
|
||||
uint64_t MySqlAccounts::insert<XmrOutput>(const vector<XmrOutput>& data_to_insert);
|
||||
template
|
||||
uint64_t MySqlAccounts::insert<XmrInput>(const vector<XmrInput>& data_to_insert);
|
||||
|
||||
template <typename T, size_t query_no>
|
||||
bool
|
||||
MySqlAccounts::select(uint64_t account_id, vector<T>& selected_data)
|
||||
{
|
||||
try
|
||||
{
|
||||
conn->check_if_connected();
|
||||
|
||||
Query query = conn->query((query_no == 1 ? T::SELECT_STMT : T::SELECT_STMT2));
|
||||
query.parse();
|
||||
|
||||
selected_data.clear();
|
||||
|
||||
query.storein(selected_data, account_id);
|
||||
|
||||
return !selected_data.empty();
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
MYSQL_EXCEPTION_MSG(e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template
|
||||
bool MySqlAccounts::select<XmrAccount>(uint64_t account_id, vector<XmrAccount>& selected_data);
|
||||
|
||||
template
|
||||
bool MySqlAccounts::select<XmrTransaction>(uint64_t account_id, vector<XmrTransaction>& selected_data);
|
||||
|
||||
template
|
||||
bool MySqlAccounts::select<XmrOutput>(uint64_t account_id, vector<XmrOutput>& selected_data);
|
||||
|
||||
template // this will use SELECT_STMT2 which selectes based on transaction id, not account_id,
|
||||
bool MySqlAccounts::select<XmrOutput, 2>(uint64_t tx_id, vector<XmrOutput>& selected_data);
|
||||
|
||||
template
|
||||
bool MySqlAccounts::select<XmrInput>(uint64_t account_id, vector<XmrInput>& selected_data);
|
||||
|
||||
template
|
||||
bool MySqlAccounts::select<XmrPayment>(uint64_t account_id, vector<XmrPayment>& selected_data);
|
||||
|
||||
template // this will use SELECT_STMT2 which selectes based on transaction id, not account_id,
|
||||
bool MySqlAccounts::select<XmrInput, 2>(uint64_t tx_id, vector<XmrInput>& selected_data);
|
||||
|
||||
|
||||
template <typename T>
|
||||
bool
|
||||
MySqlAccounts::update(T const& orginal_row, T const& new_row)
|
||||
{
|
||||
try
|
||||
{
|
||||
conn->check_if_connected();
|
||||
|
||||
Query query = conn->query();
|
||||
|
||||
query.update(orginal_row, new_row);
|
||||
|
||||
SimpleResult sr = query.execute();
|
||||
|
||||
return sr.rows() == 1;
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
MYSQL_EXCEPTION_MSG(e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template
|
||||
bool MySqlAccounts::update<XmrAccount>(XmrAccount const& orginal_row, XmrAccount const& new_row);
|
||||
|
||||
template
|
||||
bool MySqlAccounts::update<XmrPayment>(XmrPayment const& orginal_row, XmrPayment const& new_row);
|
||||
|
||||
template <typename T>
|
||||
bool
|
||||
MySqlAccounts::select_for_tx(uint64_t tx_id, vector<T>& selected_data)
|
||||
{
|
||||
return select<T, 2>(tx_id, selected_data);
|
||||
}
|
||||
|
||||
template // this will use SELECT_STMT2 which selectes based on transaction id, not account_id,
|
||||
bool MySqlAccounts::select_for_tx<XmrOutput>(uint64_t tx_id, vector<XmrOutput>& selected_data);
|
||||
|
||||
|
||||
template // this will use SELECT_STMT2 which selectes based on transaction id, not account_id,
|
||||
bool MySqlAccounts::select_for_tx<XmrInput>(uint64_t tx_id, vector<XmrInput>& selected_data);
|
||||
|
||||
template <typename T>
|
||||
bool
|
||||
MySqlAccounts::select_by_primary_id(uint64_t id, T& selected_data)
|
||||
{
|
||||
try
|
||||
{
|
||||
conn->check_if_connected();
|
||||
|
||||
Query query = conn->query(T::SELECT_STMT3);
|
||||
query.parse();
|
||||
|
||||
vector<T> outs;
|
||||
|
||||
query.storein(outs, id);
|
||||
|
||||
if (!outs.empty())
|
||||
{
|
||||
selected_data = std::move(outs.at(0));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
MYSQL_EXCEPTION_MSG(e);
|
||||
//throw e;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//template
|
||||
//bool MySqlAccounts::select_by_primary_id<XmrTransaction>(uint64_t id, XmrTransaction& selected_data);
|
||||
|
||||
template
|
||||
bool MySqlAccounts::select_by_primary_id<XmrInput>(uint64_t id, XmrInput& selected_data);
|
||||
|
||||
template
|
||||
bool MySqlAccounts::select_by_primary_id<XmrOutput>(uint64_t id, XmrOutput& selected_data);
|
||||
|
||||
template
|
||||
bool MySqlAccounts::select_by_primary_id<XmrPayment>(uint64_t id, XmrPayment& selected_data);
|
||||
|
||||
bool
|
||||
MySqlAccounts::select_txs_for_account_spendability_check(
|
||||
const uint64_t& account_id, vector<XmrTransaction>& txs)
|
||||
{
|
||||
|
||||
for (auto it = txs.begin(); it != txs.end(); )
|
||||
{
|
||||
// first we check if txs stored in db are already spendable
|
||||
// it means if they are older than 10 blocks. If yes,
|
||||
// we mark them as spendable, as we assume that blocks
|
||||
// older than 10 blocks are permanent, i.e, they wont get
|
||||
// orphaned.
|
||||
|
||||
XmrTransaction& tx = *it;
|
||||
|
||||
if (bool {tx.spendable} == false)
|
||||
{
|
||||
|
||||
if (current_bc_status->is_tx_unlocked(tx.unlock_time, tx.height))
|
||||
{
|
||||
// this tx was before marked as unspendable, but now
|
||||
// it is spendable. Meaning, that its older than 10 blocks.
|
||||
// so mark it as spendable in mysql, so that its permanet.
|
||||
|
||||
uint64_t no_row_updated = mark_tx_spendable(tx.id.data);
|
||||
|
||||
if (no_row_updated != 1)
|
||||
{
|
||||
cerr << "no_row_updated != 1 due to xmr_accounts->mark_tx_spendable(tx.id)\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
tx.spendable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// tx was marked as non-spendable, i.e., younger than 10 blocks
|
||||
// so we still are going to use this txs, but we need to double
|
||||
// check if its still valid, i.e., it's block did not get orphaned.
|
||||
// we do this by checking if txs still exists in the blockchain
|
||||
// and if its blockchain_tx_id is same as what we have in our mysql.
|
||||
|
||||
uint64_t blockchain_tx_id {0};
|
||||
|
||||
current_bc_status->tx_exist(tx.hash, blockchain_tx_id);
|
||||
|
||||
if (blockchain_tx_id != tx.blockchain_tx_id)
|
||||
{
|
||||
// tx does not exist in blockchain, or its blockchain_id changed
|
||||
// for example, it was orhpaned, and then readded.
|
||||
|
||||
uint64_t no_row_updated = delete_tx(tx.id.data);
|
||||
|
||||
if (no_row_updated != 1)
|
||||
{
|
||||
cerr << "no_row_updated != 1 due to xmr_accounts->delete_tx(tx.id)\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// because txs does not exist in blockchain anymore,
|
||||
// we assume its back to mempool, and it will be rescanned
|
||||
// by tx search thread once added again to some block.
|
||||
|
||||
// so we remove it from txs vector
|
||||
it = txs.erase(it);
|
||||
continue;
|
||||
}
|
||||
|
||||
// set unlock_time field so that frontend displies it
|
||||
// as a locked tx, if unlock_time is zero.
|
||||
// coinbtase txs have this set already. regular tx
|
||||
// have unlock_time set to zero by default, but they cant
|
||||
// be spent anyway.
|
||||
|
||||
if (tx.unlock_time == 0)
|
||||
tx.unlock_time = tx.height + CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE;
|
||||
|
||||
} // else
|
||||
|
||||
} // if (bool {tx.spendable} == false)
|
||||
|
||||
++it;
|
||||
|
||||
} // for (auto it = txs.begin(); it != txs.end(); )
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
MySqlAccounts::select_inputs_for_out(const uint64_t& output_id, vector<XmrInput>& ins)
|
||||
{
|
||||
return mysql_in->select_for_out(output_id, ins);
|
||||
}
|
||||
|
||||
bool
|
||||
MySqlAccounts::output_exists(const string& output_public_key_str, XmrOutput& out)
|
||||
{
|
||||
return mysql_out->exist(output_public_key_str, out);
|
||||
}
|
||||
|
||||
bool
|
||||
MySqlAccounts::tx_exists(const uint64_t& account_id, const string& tx_hash_str, XmrTransaction& tx)
|
||||
{
|
||||
return mysql_tx->exist(account_id, tx_hash_str, tx);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
MySqlAccounts::mark_tx_spendable(const uint64_t& tx_id_no)
|
||||
{
|
||||
return mysql_tx->mark_spendable(tx_id_no);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
MySqlAccounts::mark_tx_nonspendable(const uint64_t& tx_id_no)
|
||||
{
|
||||
return mysql_tx->mark_spendable(tx_id_no, false);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
MySqlAccounts::delete_tx(const uint64_t& tx_id_no)
|
||||
{
|
||||
return mysql_tx->delete_tx(tx_id_no);
|
||||
}
|
||||
|
||||
bool
|
||||
MySqlAccounts::select_payment_by_id(const string& payment_id, vector<XmrPayment>& payments)
|
||||
{
|
||||
return mysql_payment->select_by_payment_id(payment_id, payments);
|
||||
}
|
||||
|
||||
bool
|
||||
MySqlAccounts::get_total_recieved(const uint64_t& account_id, uint64_t& amount)
|
||||
{
|
||||
return mysql_tx->get_total_recieved(account_id, amount);
|
||||
}
|
||||
|
||||
void
|
||||
MySqlAccounts::disconnect()
|
||||
{
|
||||
get_connection()->get_connection().disconnect();
|
||||
}
|
||||
|
||||
|
||||
shared_ptr<MySqlConnector>
|
||||
MySqlAccounts::get_connection()
|
||||
{
|
||||
return conn;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MySqlAccounts::set_bc_status_provider(shared_ptr<CurrentBlockchainStatus> bc_status_provider)
|
||||
{
|
||||
current_bc_status = bc_status_provider;
|
||||
}
|
||||
|
||||
void
|
||||
MySqlAccounts::_init()
|
||||
{
|
||||
|
||||
// use same connection when working with other tables
|
||||
mysql_tx = make_shared<MysqlTransactions>(conn);
|
||||
mysql_out = make_shared<MysqlOutpus>(conn);
|
||||
mysql_in = make_shared<MysqlInputs>(conn);
|
||||
mysql_payment = make_shared<MysqlPayments>(conn);
|
||||
}
|
||||
|
||||
}
|
@ -1,250 +0,0 @@
|
||||
//
|
||||
// Created by mwo on 16/12/16.
|
||||
//
|
||||
|
||||
#ifndef RESTBED_XMR_MYSQLACCOUNTS_H
|
||||
#define RESTBED_XMR_MYSQLACCOUNTS_H
|
||||
|
||||
#include "tools.h"
|
||||
#include "MySqlConnector.h"
|
||||
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
|
||||
|
||||
namespace xmreg
|
||||
{
|
||||
|
||||
using namespace mysqlpp;
|
||||
using namespace std;
|
||||
using namespace nlohmann;
|
||||
|
||||
|
||||
class XmrTransactionWithOutsAndIns;
|
||||
class XmrInput;
|
||||
class XmrOutput;
|
||||
class XmrTransaction;
|
||||
class XmrPayment;
|
||||
class XmrAccount;
|
||||
class TxSearch;
|
||||
class Table;
|
||||
class CurrentBlockchainStatus;
|
||||
|
||||
|
||||
class MysqlInputs
|
||||
{
|
||||
|
||||
shared_ptr<MySqlConnector> conn;
|
||||
|
||||
public:
|
||||
|
||||
MysqlInputs(shared_ptr<MySqlConnector> _conn);
|
||||
|
||||
bool
|
||||
select_for_out(const uint64_t& output_id, vector<XmrInput>& ins);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class MysqlOutpus
|
||||
{
|
||||
|
||||
shared_ptr<MySqlConnector> conn;
|
||||
|
||||
public:
|
||||
|
||||
MysqlOutpus(shared_ptr<MySqlConnector> _conn);
|
||||
|
||||
bool
|
||||
exist(const string& output_public_key_str, XmrOutput& out);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class MysqlTransactions
|
||||
{
|
||||
|
||||
shared_ptr<MySqlConnector> conn;
|
||||
|
||||
public:
|
||||
|
||||
MysqlTransactions(shared_ptr<MySqlConnector> _conn);
|
||||
|
||||
uint64_t
|
||||
mark_spendable(const uint64_t& tx_id_no, bool spendable = true);
|
||||
|
||||
uint64_t
|
||||
delete_tx(const uint64_t& tx_id_no);
|
||||
|
||||
bool
|
||||
exist(const uint64_t& account_id, const string& tx_hash_str, XmrTransaction& tx);
|
||||
|
||||
bool
|
||||
get_total_recieved(const uint64_t& account_id, uint64_t& amount);
|
||||
};
|
||||
|
||||
class MysqlPayments
|
||||
{
|
||||
|
||||
shared_ptr<MySqlConnector> conn;
|
||||
|
||||
public:
|
||||
|
||||
MysqlPayments(shared_ptr<MySqlConnector> _conn);
|
||||
|
||||
bool
|
||||
select_by_payment_id(const string& payment_id, vector<XmrPayment>& payments);
|
||||
};
|
||||
|
||||
class TxSearch;
|
||||
|
||||
class MySqlAccounts
|
||||
{
|
||||
|
||||
shared_ptr<MySqlConnector> conn;
|
||||
|
||||
shared_ptr<MysqlTransactions> mysql_tx;
|
||||
|
||||
shared_ptr<MysqlOutpus> mysql_out;
|
||||
|
||||
shared_ptr<MysqlInputs> mysql_in;
|
||||
|
||||
shared_ptr<MysqlPayments> mysql_payment;
|
||||
|
||||
shared_ptr<CurrentBlockchainStatus> current_bc_status;
|
||||
|
||||
public:
|
||||
|
||||
MySqlAccounts(shared_ptr<CurrentBlockchainStatus> _current_bc_status);
|
||||
|
||||
MySqlAccounts(shared_ptr<CurrentBlockchainStatus> _current_bc_status,
|
||||
shared_ptr<MySqlConnector> _conn);
|
||||
|
||||
bool
|
||||
select(const string& address, XmrAccount& account);
|
||||
|
||||
template <typename T>
|
||||
uint64_t
|
||||
insert(const T& data_to_insert);
|
||||
|
||||
template <typename T>
|
||||
uint64_t
|
||||
insert(const vector<T>& data_to_insert);
|
||||
|
||||
/**
|
||||
*
|
||||
* @tparam T
|
||||
* @tparam query_no which query to use, for SELECT_STMT or SELECT_STMT2
|
||||
* @param account_id
|
||||
* @param selected_data
|
||||
* @return
|
||||
*/
|
||||
template <typename T, size_t query_no = 1>
|
||||
bool
|
||||
select(uint64_t account_id, vector<T>& selected_data);
|
||||
|
||||
template <typename T>
|
||||
bool
|
||||
update(T const& orginal_row, T const& new_row);
|
||||
|
||||
template <typename T>
|
||||
bool
|
||||
select_for_tx(uint64_t tx_id, vector<T>& selected_data);
|
||||
|
||||
template <typename T>
|
||||
bool
|
||||
select_by_primary_id(uint64_t id, T& selected_data);
|
||||
|
||||
bool
|
||||
select_txs_for_account_spendability_check(const uint64_t& account_id,
|
||||
vector<XmrTransaction>& txs);
|
||||
|
||||
bool
|
||||
select_inputs_for_out(const uint64_t& output_id, vector<XmrInput>& ins);
|
||||
|
||||
bool
|
||||
output_exists(const string& output_public_key_str, XmrOutput& out);
|
||||
|
||||
bool
|
||||
tx_exists(const uint64_t& account_id, const string& tx_hash_str, XmrTransaction& tx);
|
||||
|
||||
uint64_t
|
||||
mark_tx_spendable(const uint64_t& tx_id_no);
|
||||
|
||||
uint64_t
|
||||
mark_tx_nonspendable(const uint64_t& tx_id_no);
|
||||
|
||||
uint64_t
|
||||
delete_tx(const uint64_t& tx_id_no);
|
||||
|
||||
bool
|
||||
select_payment_by_id(const string& payment_id, vector<XmrPayment>& payments);
|
||||
|
||||
bool
|
||||
update_payment(XmrPayment& payment_orginal, XmrPayment& payment_new);
|
||||
|
||||
bool
|
||||
get_total_recieved(const uint64_t& account_id, uint64_t& amount);
|
||||
|
||||
void
|
||||
disconnect();
|
||||
|
||||
shared_ptr<MySqlConnector>
|
||||
get_connection();
|
||||
|
||||
/**
|
||||
* DONT use!!!
|
||||
*
|
||||
* Its only useful in unit tests when you know that nothing will insert
|
||||
* any row between calling this and using the returned id
|
||||
*
|
||||
* @tparam T
|
||||
* @param table_class
|
||||
* @return
|
||||
*/
|
||||
template <typename T>
|
||||
uint64_t
|
||||
get_next_primary_id(T&& table_class)
|
||||
{
|
||||
static_assert(std::is_base_of<Table, std::decay_t<T>>::value, "given class is not Table");
|
||||
|
||||
string sql {"SELECT `auto_increment` FROM INFORMATION_SCHEMA.TABLES WHERE table_name = '"};
|
||||
sql += table_class.table_name() + "' AND table_schema = '" + MySqlConnector::dbname + "'";
|
||||
|
||||
Query query = conn->query(sql);
|
||||
query.parse();
|
||||
|
||||
try
|
||||
{
|
||||
conn->check_if_connected();
|
||||
|
||||
StoreQueryResult sr = query.store();
|
||||
|
||||
if (!sr.empty())
|
||||
return sr[0][0];
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
MYSQL_EXCEPTION_MSG(e);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// this is useful in unit tests, as we can inject mock CurrentBlockchainStatus
|
||||
// after an instance of MySqlAccounts has been created.
|
||||
void
|
||||
set_bc_status_provider(shared_ptr<CurrentBlockchainStatus> bc_status_provider);
|
||||
|
||||
private:
|
||||
void _init();
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif //RESTBED_XMR_MYSQLACCOUNTS_H
|
@ -1,98 +0,0 @@
|
||||
//
|
||||
// Created by mwo on 7/01/17.
|
||||
//
|
||||
|
||||
#include "MySqlConnector.h"
|
||||
|
||||
#include <mysql++/mysql++.h>
|
||||
#include <mysql++/ssqls.h>
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace xmreg {
|
||||
|
||||
|
||||
string MySqlConnector::url;
|
||||
size_t MySqlConnector::port;
|
||||
string MySqlConnector::username;
|
||||
string MySqlConnector::password;
|
||||
string MySqlConnector::dbname;
|
||||
|
||||
MySqlConnector::MySqlConnector()
|
||||
{
|
||||
_init();
|
||||
}
|
||||
|
||||
MySqlConnector::MySqlConnector(Option* _option)
|
||||
{
|
||||
conn.set_option(_option);
|
||||
_init();
|
||||
}
|
||||
|
||||
bool
|
||||
MySqlConnector::connect()
|
||||
{
|
||||
if (conn.connected())
|
||||
return true;
|
||||
|
||||
try
|
||||
{
|
||||
conn.connect(dbname.c_str(),
|
||||
url.c_str(),
|
||||
username.c_str(),
|
||||
password.c_str(),
|
||||
port);
|
||||
}
|
||||
catch (mysqlpp::ConnectionFailed const& e)
|
||||
{
|
||||
MYSQL_EXCEPTION_MSG(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
MySqlConnector::ping()
|
||||
{
|
||||
return conn.ping();
|
||||
}
|
||||
|
||||
Query
|
||||
MySqlConnector::query(const char *qstr)
|
||||
{
|
||||
return conn.query(qstr);
|
||||
}
|
||||
|
||||
Query
|
||||
MySqlConnector::query(const std::string &qstr)
|
||||
{
|
||||
return conn.query(qstr);
|
||||
}
|
||||
|
||||
Connection&
|
||||
MySqlConnector::get_connection()
|
||||
{
|
||||
return conn;
|
||||
}
|
||||
|
||||
MySqlConnector::~MySqlConnector()
|
||||
{
|
||||
conn.disconnect();
|
||||
};
|
||||
|
||||
void
|
||||
MySqlConnector::_init()
|
||||
{
|
||||
if (!connect())
|
||||
{
|
||||
cerr << "Connection to Mysql failed!" << endl;
|
||||
throw std::runtime_error("Connection to Mysql failed!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
//
|
||||
// Created by mwo on 9/12/16.
|
||||
//
|
||||
|
||||
#ifndef RESTBED_XMR_MYSQLCONNECTOR_H
|
||||
#define RESTBED_XMR_MYSQLCONNECTOR_H
|
||||
|
||||
//#include "tools.h"
|
||||
|
||||
#include <mysql++/mysql++.h>
|
||||
#include <mysql++/ssqls.h>
|
||||
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace xmreg
|
||||
{
|
||||
|
||||
using namespace mysqlpp;
|
||||
using namespace std;
|
||||
|
||||
#define MYSQL_EXCEPTION_MSG(sql_excetption) cerr << "# ERR: SQLException in " << __FILE__ \
|
||||
<< "(" << __FUNCTION__ << ") on line " << __LINE__ << endl \
|
||||
<< "# ERR: " << sql_excetption.what() \
|
||||
<< endl;
|
||||
|
||||
|
||||
/*
|
||||
* This is that creates connections
|
||||
* our mysql database.
|
||||
*
|
||||
* Each thread has its own connection.
|
||||
* This way when something breaks in one thread,
|
||||
* other threads can still operate on the mysql.
|
||||
*
|
||||
*/
|
||||
class MySqlConnector
|
||||
{
|
||||
|
||||
Connection conn;
|
||||
|
||||
public:
|
||||
|
||||
static string url;
|
||||
static size_t port;
|
||||
static string username;
|
||||
static string password;
|
||||
static string dbname;
|
||||
|
||||
MySqlConnector();
|
||||
|
||||
MySqlConnector(Option* _option);
|
||||
|
||||
// dont want any copies of connection object.
|
||||
// pass it around through shared or unique pointer
|
||||
MySqlConnector (const MySqlConnector&) = delete;
|
||||
MySqlConnector& operator= (const MySqlConnector&) = delete;
|
||||
|
||||
Query
|
||||
query(const char* qstr = 0);
|
||||
|
||||
Query
|
||||
query(const std::string& qstr);
|
||||
|
||||
virtual bool
|
||||
connect();
|
||||
|
||||
bool
|
||||
ping();
|
||||
|
||||
Connection&
|
||||
get_connection();
|
||||
|
||||
// this throws exception if not connected
|
||||
inline void
|
||||
check_if_connected()
|
||||
{
|
||||
if (!conn.connected())
|
||||
throw std::runtime_error("No connection to the mysqldb");
|
||||
}
|
||||
|
||||
virtual ~MySqlConnector();
|
||||
|
||||
protected:
|
||||
|
||||
void _init();
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif //RESTBED_XMR_MYSQLCONNECTOR_H
|
@ -1,49 +0,0 @@
|
||||
//
|
||||
// Created by mwo on 12/07/18.
|
||||
//
|
||||
|
||||
#include "easylogging++.h"
|
||||
#include "om_log.h"
|
||||
|
||||
#include "MysqlPing.h"
|
||||
|
||||
|
||||
namespace xmreg
|
||||
{
|
||||
|
||||
MysqlPing::MysqlPing(
|
||||
std::shared_ptr<MySqlConnector> _conn,
|
||||
seconds _ping_time)
|
||||
: conn {_conn}, ping_time {_ping_time}
|
||||
{}
|
||||
|
||||
void
|
||||
MysqlPing::operator()()
|
||||
{
|
||||
while (keep_looping)
|
||||
{
|
||||
std::this_thread::sleep_for(chrono::seconds(ping_time));
|
||||
|
||||
if (auto c = conn.lock())
|
||||
{
|
||||
if (!c->ping())
|
||||
{
|
||||
OMERROR << "Pinging mysql failed. Stoping mysql pinging thread.";
|
||||
why_stoped = StopReason::PingFailed;
|
||||
break;
|
||||
}
|
||||
|
||||
OMINFO << "Mysql ping successful." ;
|
||||
}
|
||||
else
|
||||
{
|
||||
OMERROR << "std::weak_ptr<MySqlConnector> conn expired!";
|
||||
why_stoped = StopReason::PointerExpired;
|
||||
break;
|
||||
}
|
||||
|
||||
++counter;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
//
|
||||
// Created by mwo on 12/07/18.
|
||||
//
|
||||
|
||||
#ifndef OPENMONERO_MYSQLPING_H
|
||||
#define OPENMONERO_MYSQLPING_H
|
||||
|
||||
#include "MySqlConnector.h"
|
||||
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
|
||||
namespace xmreg
|
||||
{
|
||||
|
||||
using chrono::seconds;
|
||||
using namespace literals::chrono_literals;
|
||||
|
||||
class MysqlPing
|
||||
{
|
||||
public:
|
||||
|
||||
enum class StopReason {NotYetStopped, PingFailed, PointerExpired};
|
||||
|
||||
MysqlPing(std::shared_ptr<MySqlConnector> _conn,
|
||||
seconds _ping_time = 300s);
|
||||
|
||||
void operator()();
|
||||
void stop() {keep_looping = false;}
|
||||
|
||||
uint64_t get_counter() const {return counter;}
|
||||
StopReason get_stop_reason() const {return why_stoped;};
|
||||
|
||||
MysqlPing(MysqlPing&&) = default;
|
||||
MysqlPing& operator=(MysqlPing&&) = default;
|
||||
|
||||
private:
|
||||
std::weak_ptr<MySqlConnector> conn;
|
||||
seconds ping_time; // in seconds
|
||||
atomic<bool> keep_looping {true};
|
||||
atomic<uint64_t> counter {0};
|
||||
atomic<StopReason> why_stoped {StopReason::NotYetStopped};
|
||||
};
|
||||
}
|
||||
|
||||
#endif //OPENMONERO_MYSQLPING_H
|
@ -1,140 +0,0 @@
|
||||
//
|
||||
// Created by mwo on 7/01/17.
|
||||
//
|
||||
|
||||
#include "ssqlses.h"
|
||||
|
||||
|
||||
namespace xmreg
|
||||
{
|
||||
|
||||
|
||||
ostream& operator<< (std::ostream& os, const Table& data)
|
||||
{
|
||||
os << data.table_name() << ": " << data.to_json().dump() << '\n';
|
||||
return os;
|
||||
};
|
||||
|
||||
json
|
||||
XmrAccount::to_json() const
|
||||
{
|
||||
json j {{"id" , id.data},
|
||||
{"address" , address},
|
||||
{"viewkey" , viewkey},
|
||||
{"scanned_block_height" , scanned_block_height},
|
||||
{"scanned_block_timestamp", static_cast<uint64_t>(scanned_block_timestamp)},
|
||||
{"start_height" , start_height}
|
||||
};
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
json
|
||||
XmrTransaction::to_json() const
|
||||
{
|
||||
json j {{"id" , id.data},
|
||||
{"hash" , hash},
|
||||
{"prefix_hash" , prefix_hash},
|
||||
{"tx_pub_key" , tx_pub_key},
|
||||
{"account_id" , account_id},
|
||||
{"total_received" , total_received},
|
||||
{"total_sent" , total_sent},
|
||||
{"height" , height},
|
||||
{"payment_id" , payment_id},
|
||||
{"unlock_time" , unlock_time},
|
||||
{"coinbase" , bool {coinbase}},
|
||||
{"is_rct" , bool {is_rct}},
|
||||
{"rct_type" , rct_type},
|
||||
{"spendable" , bool {spendable}},
|
||||
{"mixin" , mixin},
|
||||
{"timestamp" , static_cast<uint64_t>(timestamp)}
|
||||
};
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
DateTime
|
||||
XmrTransaction::timestamp_to_DateTime(time_t timestamp)
|
||||
{
|
||||
return DateTime(timestamp);
|
||||
}
|
||||
|
||||
ostream& operator<< (std::ostream& os, const XmrTransaction& acc)
|
||||
{
|
||||
os << "XmrTransactions: " << acc.to_json().dump() << '\n';
|
||||
return os;
|
||||
};
|
||||
|
||||
|
||||
json
|
||||
XmrOutput::to_json() const
|
||||
{
|
||||
json j {{"id" , id.data},
|
||||
{"account_id" , account_id},
|
||||
{"tx_id" , tx_id},
|
||||
{"out_pub_key" , out_pub_key},
|
||||
{"tx_pub_key" , tx_pub_key},
|
||||
{"amount" , amount},
|
||||
{"global_index" , global_index},
|
||||
{"out_index" , out_index},
|
||||
{"mixin" , mixin},
|
||||
{"timestamp" , static_cast<uint64_t>(timestamp)}
|
||||
};
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
|
||||
ostream& operator<< (std::ostream& os, const XmrOutput& out) {
|
||||
os << "XmrOutputs: " << out.to_json().dump() << '\n';
|
||||
return os;
|
||||
};
|
||||
|
||||
|
||||
json
|
||||
XmrInput::to_json() const
|
||||
{
|
||||
json j {{"id" , id.data},
|
||||
{"account_id" , account_id},
|
||||
{"tx_id" , tx_id},
|
||||
{"output_id" , output_id},
|
||||
{"key_image" , key_image},
|
||||
{"amount" , amount},
|
||||
{"timestamp" , static_cast<uint64_t>(timestamp)}
|
||||
};
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ostream& operator<< (std::ostream& os, const XmrInput& out)
|
||||
{
|
||||
os << "XmrInput: " << out.to_json().dump() << '\n';
|
||||
return os;
|
||||
};
|
||||
|
||||
json
|
||||
XmrPayment::to_json() const
|
||||
{
|
||||
json j {{"id" , id.data},
|
||||
{"account_id" , account_id},
|
||||
{"payment_id" , payment_id},
|
||||
{"tx_hash" , tx_hash},
|
||||
{"request_fulfilled", bool {request_fulfilled}},
|
||||
{"import_fee" , import_fee},
|
||||
{"payment_address" , payment_address},
|
||||
};
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
|
||||
ostream& operator<< (std::ostream& os, const XmrPayment& out) {
|
||||
os << "XmrPayment: " << out.to_json().dump() << '\n';
|
||||
return os;
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
@ -1,329 +0,0 @@
|
||||
//
|
||||
// Created by mwo on 14/12/16.
|
||||
//
|
||||
|
||||
#ifndef RESTBED_XMR_SSQLSES_H
|
||||
#define RESTBED_XMR_SSQLSES_H
|
||||
|
||||
#include "../ext/json.hpp"
|
||||
|
||||
#include <mysql++/mysql++.h>
|
||||
#include <mysql++/ssqls.h>
|
||||
|
||||
namespace xmreg
|
||||
{
|
||||
|
||||
using namespace std;
|
||||
using namespace nlohmann;
|
||||
using namespace mysqlpp;
|
||||
|
||||
/**
|
||||
* Base class for all mysql table based classes that we use.
|
||||
*/
|
||||
class Table
|
||||
{
|
||||
public:
|
||||
|
||||
virtual string table_name() const = 0;
|
||||
virtual json to_json() const = 0;
|
||||
|
||||
friend std::ostream& operator<< (std::ostream& stream, const Table& data);
|
||||
};
|
||||
|
||||
sql_create_8(Accounts, 1, 6,
|
||||
sql_bigint_unsigned_null, id,
|
||||
sql_varchar , address,
|
||||
sql_char , viewkey_hash,
|
||||
sql_bigint_unsigned, scanned_block_height,
|
||||
sql_timestamp , scanned_block_timestamp,
|
||||
sql_bigint_unsigned, start_height,
|
||||
sql_timestamp , created,
|
||||
sql_timestamp , modified);
|
||||
|
||||
|
||||
struct XmrAccount : public Accounts, Table
|
||||
{
|
||||
static constexpr const char* SELECT_STMT = R"(
|
||||
SELECT * FROM `Accounts` WHERE `id` = (%0q)
|
||||
)";
|
||||
|
||||
|
||||
static constexpr const char* SELECT_STMT2 = R"(
|
||||
SELECT * FROM `Accounts` WHERE `address` = (%0q)
|
||||
)";
|
||||
|
||||
// SELECT_STMT3 same as SELECT_STMT which is fine
|
||||
// easier to work with templates later
|
||||
static constexpr const char* SELECT_STMT3 = R"(
|
||||
SELECT * FROM `Accounts` WHERE `id` = (%0q)
|
||||
)";
|
||||
|
||||
static constexpr const char* INSERT_STMT = R"(
|
||||
INSERT INTO `Accounts` (`address`, `viewkey_hash`,
|
||||
`scanned_block_height`,
|
||||
`scanned_block_timestamp`, `start_height`)
|
||||
VALUES
|
||||
(%0q, %1q, %2q, %3q, %4q);
|
||||
)";
|
||||
|
||||
using Accounts::Accounts;
|
||||
|
||||
// viewkey is not stored in mysql db or anywhere
|
||||
// so need to be populated when user logs in.
|
||||
string viewkey;
|
||||
|
||||
string table_name() const override { return this->table();};
|
||||
|
||||
json to_json() const override;
|
||||
|
||||
};
|
||||
|
||||
sql_create_17(Transactions, 1, 17,
|
||||
sql_bigint_unsigned_null, id,
|
||||
sql_varchar , hash,
|
||||
sql_varchar , prefix_hash,
|
||||
sql_varchar , tx_pub_key,
|
||||
sql_bigint_unsigned , account_id,
|
||||
sql_bigint_unsigned , blockchain_tx_id,
|
||||
sql_bigint_unsigned , total_received,
|
||||
sql_bigint_unsigned , total_sent,
|
||||
sql_bigint_unsigned , unlock_time,
|
||||
sql_bigint_unsigned , height,
|
||||
sql_bool , coinbase,
|
||||
sql_bool , is_rct,
|
||||
sql_int , rct_type,
|
||||
sql_bool , spendable,
|
||||
sql_varchar , payment_id,
|
||||
sql_bigint_unsigned , mixin,
|
||||
sql_timestamp , timestamp);
|
||||
|
||||
|
||||
struct XmrTransaction : public Transactions, Table
|
||||
{
|
||||
|
||||
static constexpr const char* SELECT_STMT = R"(
|
||||
SELECT * FROM `Transactions` WHERE `account_id` = (%0q)
|
||||
)";
|
||||
|
||||
static constexpr const char* SELECT_STMT2 = R"(
|
||||
SELECT * FROM `Transactions` WHERE `id` = (%0q)
|
||||
)";
|
||||
|
||||
// same as SELECT_STMT2 for similicity later on
|
||||
static constexpr const char* SELECT_STMT3 = R"(
|
||||
SELECT * FROM `Transactions` WHERE `id` = (%0q)
|
||||
)";
|
||||
|
||||
static constexpr const char* EXIST_STMT = R"(
|
||||
SELECT * FROM `Transactions` WHERE `account_id` = (%0q) AND `hash` = (%1q)
|
||||
)";
|
||||
|
||||
static constexpr const char* DELETE_STMT = R"(
|
||||
DELETE FROM `Transactions` WHERE `id` = (%0q)
|
||||
)";
|
||||
|
||||
static constexpr const char* INSERT_STMT = R"(
|
||||
INSERT IGNORE INTO `Transactions` (`hash`, `prefix_hash`, `tx_pub_key`, `account_id`,
|
||||
`blockchain_tx_id`,
|
||||
`total_received`, `total_sent`, `unlock_time`,
|
||||
`height`, `coinbase`, `is_rct`, `rct_type`,
|
||||
`spendable`,
|
||||
`payment_id`, `mixin`, `timestamp`)
|
||||
VALUES (%0q, %1q, %2q, %3q,
|
||||
%4q,
|
||||
%5q, %6q, %7q,
|
||||
%8q, %9q, %10q, %11q,
|
||||
%12q,
|
||||
%13q, %14q, %15q);
|
||||
)";
|
||||
|
||||
static constexpr const char* MARK_AS_SPENDABLE_STMT = R"(
|
||||
UPDATE `Transactions` SET `spendable` = 1, `timestamp` = CURRENT_TIMESTAMP
|
||||
WHERE `id` = %0q;
|
||||
)";
|
||||
|
||||
static constexpr const char* MARK_AS_NONSPENDABLE_STMT = R"(
|
||||
UPDATE `Transactions` SET `spendable` = 0, `timestamp` = CURRENT_TIMESTAMP
|
||||
WHERE `id` = %0q;
|
||||
)";
|
||||
|
||||
static constexpr const char* SUM_XMR_RECIEVED = R"(
|
||||
SELECT SUM(`total_received`) AS total_received
|
||||
FROM `Transactions`
|
||||
WHERE `account_id` = %0q
|
||||
GROUP BY `account_id`
|
||||
)";
|
||||
|
||||
|
||||
|
||||
|
||||
using Transactions::Transactions;
|
||||
|
||||
|
||||
static DateTime
|
||||
timestamp_to_DateTime(time_t timestamp);
|
||||
|
||||
string table_name() const override { return this->table();};
|
||||
|
||||
json to_json() const override;
|
||||
|
||||
};
|
||||
|
||||
sql_create_13(Outputs, 1, 13,
|
||||
sql_bigint_unsigned_null, id, // this is null so that we can set it to mysqlpp:null when inserting rows
|
||||
sql_bigint_unsigned, account_id, // this way auto_increment of the id will take place and we can
|
||||
sql_bigint_unsigned, tx_id, // use vector of outputs to write at once to mysql
|
||||
sql_varchar , out_pub_key,
|
||||
sql_varchar , rct_outpk,
|
||||
sql_varchar , rct_mask,
|
||||
sql_varchar , rct_amount,
|
||||
sql_varchar , tx_pub_key,
|
||||
sql_bigint_unsigned, amount,
|
||||
sql_bigint_unsigned, global_index,
|
||||
sql_bigint_unsigned, out_index,
|
||||
sql_bigint_unsigned, mixin,
|
||||
sql_timestamp , timestamp);
|
||||
|
||||
struct XmrOutput : public Outputs, Table
|
||||
{
|
||||
|
||||
static constexpr const char* SELECT_STMT = R"(
|
||||
SELECT * FROM `Outputs` WHERE `account_id` = (%0q)
|
||||
)";
|
||||
|
||||
static constexpr const char* SELECT_STMT2 = R"(
|
||||
SELECT * FROM `Outputs` WHERE `tx_id` = (%0q)
|
||||
)";
|
||||
|
||||
static constexpr const char* SELECT_STMT3 = R"(
|
||||
SELECT * FROM `Outputs` WHERE `id` = (%0q)
|
||||
)";
|
||||
|
||||
static constexpr const char* EXIST_STMT = R"(
|
||||
SELECT * FROM `Outputs` WHERE `out_pub_key` = (%0q)
|
||||
)";
|
||||
|
||||
static constexpr const char* INSERT_STMT = R"(
|
||||
INSERT IGNORE INTO `Outputs` (`account_id`, `tx_id`, `out_pub_key`,
|
||||
`tx_pub_key`,
|
||||
`rct_outpk`, `rct_mask`, `rct_amount`,
|
||||
`amount`, `global_index`,
|
||||
`out_index`, `mixin`, `timestamp`)
|
||||
VALUES (%0q, %1q, %2q,
|
||||
%3q,
|
||||
%4q, %5q, %6q,
|
||||
%7q, %8q,
|
||||
%9q, %10q, %11q);
|
||||
)";
|
||||
|
||||
|
||||
|
||||
using Outputs::Outputs;
|
||||
|
||||
string
|
||||
get_rct() const
|
||||
{
|
||||
return rct_outpk + rct_mask + rct_amount;
|
||||
}
|
||||
|
||||
|
||||
string table_name() const override { return this->table();};
|
||||
|
||||
json to_json() const override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
sql_create_7(Inputs, 1, 7,
|
||||
sql_bigint_unsigned_null, 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);
|
||||
|
||||
|
||||
struct XmrInput : public Inputs, Table
|
||||
{
|
||||
|
||||
static constexpr const char* SELECT_STMT = R"(
|
||||
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* SELECT_STMT3 = R"(
|
||||
SELECT * FROM `Inputs` WHERE `id` = (%0q)
|
||||
)";
|
||||
|
||||
static constexpr const char* SELECT_STMT4 = R"(
|
||||
SELECT * FROM `Inputs` WHERE `output_id` = (%0q)
|
||||
)";
|
||||
|
||||
static constexpr const char* INSERT_STMT = R"(
|
||||
INSERT IGNORE INTO `Inputs` (`account_id`, `tx_id`, `output_id`,
|
||||
`key_image`, `amount` , `timestamp`)
|
||||
VALUES (%0q, %1q, %2q,
|
||||
%3q, %4q, %5q);
|
||||
)";
|
||||
|
||||
using Inputs::Inputs;
|
||||
|
||||
string table_name() const override { return this->table();};
|
||||
|
||||
json to_json() const override;
|
||||
|
||||
};
|
||||
|
||||
sql_create_9(Payments, 1, 7,
|
||||
sql_bigint_unsigned_null, id,
|
||||
sql_bigint_unsigned , account_id,
|
||||
sql_varchar , payment_id,
|
||||
sql_varchar , tx_hash,
|
||||
sql_boolean , request_fulfilled,
|
||||
sql_bigint_unsigned , import_fee,
|
||||
sql_varchar , payment_address,
|
||||
sql_timestamp , created,
|
||||
sql_timestamp , modified);
|
||||
|
||||
|
||||
struct XmrPayment : public Payments, Table
|
||||
{
|
||||
|
||||
static constexpr const char* SELECT_STMT = R"(
|
||||
SELECT * FROM `Payments` WHERE `account_id` = (%0q)
|
||||
)";
|
||||
|
||||
static constexpr const char* SELECT_STMT2 = R"(
|
||||
SELECT * FROM `Payments` WHERE `payment_id` = (%0q)
|
||||
)";
|
||||
|
||||
static constexpr const char* SELECT_STMT3 = R"(
|
||||
SELECT * FROM `Payments` WHERE `id` = (%0q)
|
||||
)";
|
||||
|
||||
static constexpr const char* INSERT_STMT = R"(
|
||||
INSERT IGNORE INTO `Payments` (`account_id`, `payment_id`, `tx_hash`,
|
||||
`request_fulfilled`, `import_fee`,
|
||||
`payment_address`)
|
||||
VALUES (%0q, %1q, %2q, %3q, %4q, %5q);
|
||||
)";
|
||||
|
||||
|
||||
|
||||
using Payments::Payments;
|
||||
|
||||
string table_name() const override { return this->table();};
|
||||
|
||||
json to_json() const override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif //RESTBED_XMR_SSQLSES_H
|
Loading…
Reference in new issue