paymate table refactored and some tests added

pull/93/merge
moneroexamples 6 years ago
parent 1c7904c09a
commit 2763db6ca1

@ -34,7 +34,7 @@
"wallet_import" :
{
"_comment": "if fee is 0, then importing is free. fee is in base 1e12, e.g., 0.1 xmr is 0.1 x 1e12 = 100000000000",
"fee" : 0,
"fee" : 100000000000,
"testnet" :
{
"address" : "9tzmPMTViHYM3z6NAgQni1Qm1Emzxy5hQFibPgWD3LVTAz91yok5Eni1pH6zKhBHzpTU15GZooPHSGHXFvFuXEdmEG2sWAZ",

@ -59,6 +59,7 @@ CREATE TABLE IF NOT EXISTS `Inputs` (
`amount` bigint(20) UNSIGNED ZEROFILL NOT NULL DEFAULT '00000000000000000000',
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `output_id` (`output_id`,`key_image`),
KEY `account_id2` (`account_id`),
KEY `tx_id2` (`tx_id`),
KEY `output_id2` (`output_id`)

@ -76,6 +76,7 @@ CREATE TABLE IF NOT EXISTS `Inputs` (
`amount` bigint(20) UNSIGNED ZEROFILL NOT NULL DEFAULT '00000000000000000000',
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `output_id` (`output_id`,`key_image`),
KEY `account_id2` (`account_id`),
KEY `tx_id2` (`tx_id`),
KEY `output_id2` (`output_id`)
@ -265,17 +266,18 @@ INSERT INTO `Outputs` (`id`, `account_id`, `tx_id`, `out_pub_key`, `rct_outpk`,
DROP TABLE IF EXISTS `Payments`;
CREATE TABLE IF NOT EXISTS `Payments` (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`address` varchar(95) NOT NULL,
`payment_id` varchar(64) NOT NULL,
`account_id` bigint(20) UNSIGNED NOT NULL,
`payment_id` varchar(16) NOT NULL,
`tx_hash` varchar(64) NOT NULL DEFAULT '',
`request_fulfilled` tinyint(1) NOT NULL DEFAULT '0',
`payment_address` varchar(95) NOT NULL,
`import_fee` bigint(20) NOT NULL,
`payment_address` varchar(95) NOT NULL,
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `account_id` (`account_id`) USING BTREE,
UNIQUE KEY `payment_id` (`payment_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
--
-- Truncate table before insert `Payments`
@ -286,8 +288,9 @@ TRUNCATE TABLE `Payments`;
-- Dumping data for table `Payments`
--
INSERT INTO `Payments` (`id`, `address`, `payment_id`, `tx_hash`, `request_fulfilled`, `payment_address`, `import_fee`, `created`, `modified`) VALUES
(1, '57Hx8QpLUSMjhgoCNkvJ2Ch91mVyxcffESCprnRPrtbphMCv8iGUEfCUJxrpUWUeWrS9vPWnFrnMmTwnFpSKJrSKNuaXc5q', 'c3a7db070babeb64', 'be2ee71be2adf0da1b966c7a3c0573e2f340fc61374ca3c7e87e82cb0118b752', 1, '5DUWE29P72Eb8inMa41HuNJG4tj9CcaNKGr6EVSbvhWGJdpDQCiNNYBUNF1oDb8BczU5aD68d3HNKXaEsPq8cvbQLN4Ptby', 100000000000, '2018-06-14 05:20:15', '2018-06-14 05:20:15');
INSERT INTO `Payments` (`id`, `account_id`, `payment_id`, `tx_hash`, `request_fulfilled`, `import_fee`, `payment_address`, `created`, `modified`) VALUES
(1, 129, 'e410eb43e14a28fb', '', 0, 100000000000, '5DUWE29P72Eb8inMa41HuNJG4tj9CcaNKGr6EVSbvhWGJdpDQCiNNYBUNF1oDb8BczU5aD68d3HNKXaEsPq8cvbQLPHdavp', '2018-07-03 23:54:55', '2018-07-03 23:54:55'),
(2, 134, '74854c1cd490e148', '', 0, 100000000000, '5DUWE29P72Eb8inMa41HuNJG4tj9CcaNKGr6EVSbvhWGJdpDQCiNNYBUNF1oDb8BczU5aD68d3HNKXaEsPq8cvbQLK4Tiiy', '2018-07-03 23:55:57', '2018-07-03 23:55:57');
-- --------------------------------------------------------
@ -438,6 +441,12 @@ ALTER TABLE `Outputs`
ADD CONSTRAINT `account_id3_FK` FOREIGN KEY (`account_id`) REFERENCES `Accounts` (`id`) ON DELETE CASCADE,
ADD CONSTRAINT `transaction_id_FK` FOREIGN KEY (`tx_id`) REFERENCES `Transactions` (`id`) ON DELETE CASCADE;
--
-- Constraints for table `Payments`
--
ALTER TABLE `Payments`
ADD CONSTRAINT `account_id` FOREIGN KEY (`account_id`) REFERENCES `Accounts` (`id`) ON DELETE CASCADE;
--
-- Constraints for table `Transactions`
--

@ -22,7 +22,7 @@ bool
MysqlInputs::select_for_out(const uint64_t& output_id, vector<XmrInput>& ins)
{
Query query = conn->query(XmrInput::SELECT_STMT3);
Query query = conn->query(XmrInput::SELECT_STMT4);
query.parse();
try
@ -44,33 +44,6 @@ MysqlInputs::select_for_out(const uint64_t& output_id, vector<XmrInput>& ins)
MysqlOutpus::MysqlOutpus(shared_ptr<MySqlConnector> _conn): conn {_conn}
{}
bool
MysqlOutpus::select(uint64_t out_id, XmrOutput& out)
{
Query query = conn->query(XmrOutput::SELECT_STMT3);
query.parse();
try
{
vector<XmrOutput> outs;
query.storein(outs, out_id);
if (!outs.empty())
{
out = std::move(outs.at(0));
return true;
}
}
catch (std::exception& e)
{
MYSQL_EXCEPTION_MSG(e);
//throw e;
}
return false;
}
bool
@ -235,28 +208,6 @@ MysqlTransactions::get_total_recieved(const uint64_t& account_id)
MysqlPayments::MysqlPayments(shared_ptr<MySqlConnector> _conn): conn {_conn}
{}
bool
MysqlPayments::select(const string& address, vector<XmrPayment>& payments)
{
Query query = conn->query(XmrPayment::SELECT_STMT);
query.parse();
try
{
query.storein(payments, address);
return !payments.empty();
}
catch (std::exception& e)
{
MYSQL_EXCEPTION_MSG(e);
//throw e;
}
return false;
}
bool
MysqlPayments::select_by_payment_id(const string& payment_id, vector<XmrPayment>& payments)
{
@ -422,6 +373,8 @@ MySqlAccounts::select(uint64_t account_id, vector<T>& selected_data)
try
{
selected_data.clear();
query.storein(selected_data, account_id);
return !selected_data.empty();
@ -450,6 +403,9 @@ bool MySqlAccounts::select<XmrOutput, 2>(uint64_t tx_id, vector<XmrOutput>& sele
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);
@ -469,6 +425,48 @@ template // this will use SELECT_STMT2 which selectes based on transaction id, n
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)
{
Query query = conn->query(T::SELECT_STMT3);
query.parse();
try
{
vector<T> outs;
query.storein(outs, id);
if (!outs.empty())
{
selected_data = std::move(outs.at(0));
return true;
}
}
catch (std::exception& 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,
@ -568,11 +566,6 @@ MySqlAccounts::select_txs_for_account_spendability_check(
return true;
}
bool
MySqlAccounts::select_output_with_id(const uint64_t& out_id, XmrOutput& out)
{
return mysql_out->select(out_id, out);
}
bool
@ -617,33 +610,6 @@ MySqlAccounts::select_payment_by_id(const string& payment_id, vector<XmrPayment>
return mysql_payment->select_by_payment_id(payment_id, payments);
}
bool
MySqlAccounts::select_payment_by_address(const string& address, vector<XmrPayment>& payments)
{
return mysql_payment->select(address, payments);
}
bool
MySqlAccounts::select_payment_by_address(const string& address, XmrPayment& payment)
{
vector<XmrPayment> payments;
bool r = mysql_payment->select(address, payments);
if (!r)
return false;
if (payments.empty())
return false;
// always get last payment details.
payment = payments.back();
return r;
}
bool
MySqlAccounts::update_payment(XmrPayment& payment_orginal, XmrPayment& payment_new)
{

@ -42,9 +42,6 @@ public:
MysqlInputs(shared_ptr<MySqlConnector> _conn);
bool
select(const uint64_t& address_id, vector<XmrInput>& ins);
bool
select_for_out(const uint64_t& output_id, vector<XmrInput>& ins);
};
@ -60,9 +57,6 @@ public:
MysqlOutpus(shared_ptr<MySqlConnector> _conn);
bool
select(uint64_t out_id, XmrOutput& outs);
bool
exist(const string& output_public_key_str, XmrOutput& out);
};
@ -103,9 +97,6 @@ public:
MysqlPayments(shared_ptr<MySqlConnector> _conn);
bool
select(const string& address, vector<XmrPayment>& payments);
bool
select_by_payment_id(const string& payment_id, vector<XmrPayment>& payments);
@ -162,12 +153,13 @@ public:
bool
select_for_tx(uint64_t tx_id, vector<T>& selected_data);
template <typename T>
bool
select_txs_for_account_spendability_check(const uint64_t& account_id,
vector<XmrTransaction>& txs);
select_by_primary_id(uint64_t id, T& selected_data);
bool
select_output_with_id(const uint64_t& out_id, XmrOutput& out);
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);
@ -190,12 +182,6 @@ public:
bool
select_payment_by_id(const string& payment_id, vector<XmrPayment>& payments);
bool
select_payment_by_address(const string& address, vector<XmrPayment>& payments);
bool
select_payment_by_address(const string& address, XmrPayment& payment);
bool
update_payment(XmrPayment& payment_orginal, XmrPayment& payment_new);

@ -258,7 +258,7 @@ YourMoneroRequests::get_address_txs(const shared_ptr< Session > session, const B
{
XmrOutput out;
if (xmr_accounts->select_output_with_id(input.output_id, out))
if (xmr_accounts->select_by_primary_id(input.output_id, out))
{
total_spent += input.amount;
@ -887,9 +887,6 @@ YourMoneroRequests::import_wallet_request(const shared_ptr< Session > session, c
string xmr_address = j_request["address"];
// a placeholder for existing or new payment data
xmreg::XmrPayment xmr_payment;
json j_response;
j_response["request_fulfilled"] = false;
@ -923,13 +920,46 @@ YourMoneroRequests::import_wallet_request(const shared_ptr< Session > session, c
return;
}
XmrAccount acc;
if (!xmr_accounts->select(xmr_address, acc))
{
cerr << "xmr_address does not exists! " << endl;
j_response["error"] = "The account does not exists!";
string response_body = j_response.dump();
auto response_headers = make_headers({{ "Content-Length", to_string(response_body.size())}});
session->close( OK, response_body, response_headers);
return;
}
// a placeholder for existing or new payment data
vector<XmrPayment> xmr_payments;
// select this payment if its existing one
if (xmr_accounts->select_payment_by_address(xmr_address, xmr_payment))
if (xmr_accounts->select(acc.id.data, xmr_payments))
{
// payment record exists, so now we need to check if
// actually payment has been done, and updated
// mysql record accordingly.
if (xmr_payments.size() > 1)
{
cerr << "More than one payment record found! " << endl;
j_response["error"] = "TMore than one payment record found!";
string response_body = j_response.dump();
auto response_headers = make_headers({{ "Content-Length", to_string(response_body.size())}});
session->close( OK, response_body, response_headers);
return;
}
XmrPayment& xmr_payment = xmr_payments[0];
bool request_fulfilled = bool {xmr_payment.request_fulfilled};
string integrated_address =
@ -1035,8 +1065,10 @@ YourMoneroRequests::import_wallet_request(const shared_ptr< Session > session, c
CurrentBlockchainStatus::get_account_integrated_address_as_str(
random_payment_id8);
XmrPayment xmr_payment;
xmr_payment.id = mysqlpp::null;
xmr_payment.address = xmr_address;
xmr_payment.account_id = acc.id.data;
xmr_payment.payment_id = pod_to_hex(random_payment_id8);
xmr_payment.import_fee = CurrentBlockchainStatus::import_fee; // xmr
xmr_payment.request_fulfilled = false;
@ -1420,7 +1452,7 @@ YourMoneroRequests::get_tx(const shared_ptr< Session > session, const Bytes & bo
{
XmrOutput out;
if (xmr_accounts->select_output_with_id(input.output_id, out))
if (xmr_accounts->select_by_primary_id(input.output_id, out))
{
total_spent += input.amount;

@ -118,12 +118,12 @@ json
XmrPayment::to_json() const
{
json j {{"id" , id.data},
{"address" , address},
{"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},
{"import_fee" , import_fee}
};
return j;

@ -52,6 +52,11 @@ struct XmrAccount : public Accounts, Table
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`,
@ -104,6 +109,11 @@ struct XmrTransaction : public Transactions, Table
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)
)";
@ -182,7 +192,7 @@ struct XmrOutput : public Outputs, Table
)";
static constexpr const char* SELECT_STMT2 = R"(
SELECT * FROM `Outputs` WHERE `tx_id` = (%0q) ORDER BY amount
SELECT * FROM `Outputs` WHERE `tx_id` = (%0q)
)";
static constexpr const char* SELECT_STMT3 = R"(
@ -246,6 +256,10 @@ struct XmrInput : public Inputs, Table
)";
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)
)";
@ -266,12 +280,12 @@ struct XmrInput : public Inputs, Table
sql_create_9(Payments, 1, 7,
sql_bigint_unsigned_null, id,
sql_varchar , address,
sql_bigint_unsigned , account_id,
sql_varchar , payment_id,
sql_varchar , tx_hash,
sql_boolean , request_fulfilled,
sql_varchar , payment_address,
sql_bigint_unsigned , import_fee,
sql_varchar , payment_address,
sql_timestamp , created,
sql_timestamp , modified);
@ -280,19 +294,22 @@ struct XmrPayment : public Payments, Table
{
static constexpr const char* SELECT_STMT = R"(
SELECT * FROM `Payments` WHERE `address` = (%0q)
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` (`address`, `payment_id`, `tx_hash`,
`request_fulfilled`, `payment_address`, `import_fee`)
VALUES (%0q, %1q, %2q,
%3q, %4q, %5q);
INSERT IGNORE INTO `Payments` (`account_id`, `payment_id`, `tx_hash`,
`request_fulfilled`, `import_fee`,
`payment_address`)
VALUES (%0q, %1q, %2q, %3q, %4q, %5q);
)";

@ -46,6 +46,27 @@ class MYSQL_TEST : public ::testing::Test
{
public:
static void initDatabase()
{
mysqlpp::Query query = xmr_accounts
->get_connection()->get_connection().query(db_data);
query.parse();
try
{
ASSERT_TRUE(query.exec());
while(query.more_results())
query.store_next();
}
catch (std::exception &e)
{
std::cerr << e.what() << '\n';
throw e;
}
}
static void SetUpTestCase()
{
// read in confing json file and get test db info
@ -102,29 +123,16 @@ public:
db_data = xmreg::read("../sql/openmonero_test.sql");
}
static void TearDownTestCase()
{
initDatabase();
}
protected:
virtual void SetUp()
{
mysqlpp::Query query = xmr_accounts
->get_connection()->get_connection().query(db_data);
query.parse();
try
{
bool is_success = query.exec();
while(query.more_results())
query.store_next();
}
catch (std::exception &e)
{
std::cerr << e.what() << '\n';
throw e;
}
initDatabase();
}
static std::string db_data;
@ -477,7 +485,7 @@ INSTANTIATE_TEST_CASE_P(
));
xmreg::XmrOutput
auto
make_mock_output_data(string last_char_pub_key = "4")
{
xmreg::XmrOutput mock_output_data ;
@ -511,6 +519,8 @@ TEST_F(MYSQL_TEST, SelectOutputsForAccount)
ASSERT_TRUE(xmr_accounts->select(acc.id.data, outputs));
// can use this command to get list of outputs
// ./xmr2csv --stagenet -m -a 5AjfkEY7RFgNGDYvoRQkncfwHXT6Fh7oJBisqFUX5u96i3ZepxDPocQK29tmAwBDuvKRpskZnfA6N8Ra58qFzA4bSA3QZFp -v 3ee772709dcf834a881c432fc15625d84585e4462d7905c42460dd478a315008 -t 90000 -g 101610
EXPECT_EQ(outputs.size(), 9);
}
@ -552,7 +562,7 @@ TEST_F(MYSQL_TEST, InsertOneOutput)
xmreg::XmrOutput out_data2;
EXPECT_TRUE(xmr_accounts->select_output_with_id(inserted_output_id, out_data2));
EXPECT_TRUE(xmr_accounts->select_by_primary_id(inserted_output_id, out_data2));
EXPECT_EQ(out_data2.tx_id, mock_output_data.tx_id);
EXPECT_EQ(out_data2.out_pub_key, mock_output_data.out_pub_key);
@ -640,7 +650,7 @@ TEST_F(MYSQL_TEST, InsertSeverlOutputsAtOnce)
uint64_t output_id_to_get = expected_primary_id + i;
xmreg::XmrOutput out_data;
xmr_accounts->select_output_with_id(output_id_to_get, out_data);
xmr_accounts->select_by_primary_id(output_id_to_get, out_data);
EXPECT_EQ(mock_outputs_data[i].out_pub_key, out_data.out_pub_key);
}
@ -658,6 +668,8 @@ TEST_F(MYSQL_TEST, SelectInputsForAccount)
ASSERT_TRUE(xmr_accounts->select(acc.id.data, inputs));
// can use this command to get the list of ring members
// ./xmr2csv --stagenet -m -a 5AjfkEY7RFgNGDYvoRQkncfwHXT6Fh7oJBisqFUX5u96i3ZepxDPocQK29tmAwBDuvKRpskZnfA6N8Ra58qFzA4bSA3QZFp -v 3ee772709dcf834a881c432fc15625d84585e4462d7905c42460dd478a315008 -t 90000 -g 101610
EXPECT_EQ(inputs.size(), 12);
}
@ -707,7 +719,7 @@ TEST_F(MYSQL_TEST, SelectInputsForOutput)
EXPECT_EQ(inputs.size(), 3);
EXPECT_EQ(inputs.front().key_image, "7d8e2a1f1755ef12ce28185821e6b19cb6023d535411bbb7abdced139c923bad");
EXPECT_EQ(inputs.front().key_image, "00dd88b3a16b3616d342faec2bc47b24add433407ef79b9a00b55b75d96239a4");
EXPECT_EQ(inputs.back().key_image, "abc529357f90641d501d5108f822617049c19461569eafa45cb5400ee45bef33");
inputs.clear();
@ -718,22 +730,199 @@ TEST_F(MYSQL_TEST, SelectInputsForOutput)
auto
make_mock_input_data(string last_char_pub_key = "0")
{
xmreg::XmrInput mock_data;
mock_data.id = mysqlpp::null;
// mock_output_data.account_id = acc.id; need to be set when used
mock_data.tx_id = 106086; // some tx id for this output
mock_data.output_id = 428900; // some output id
mock_data.key_image = "18c6a80311d6f455ac1e5abdce7e86828d1ecf911f78da12a56ce8fdd5c716f"
+ last_char_pub_key; // out_pub_key is unique field, so to make
// few public keys, we just change its last char.
mock_data.amount = 999916984840000ull;
mock_data.timestamp = mysqlpp::DateTime(static_cast<time_t>(44434554));;
return mock_data;
}
TEST_F(MYSQL_TEST, InsertOneInput)
{
ACC_FROM_HEX(owner_addr_5Ajfk);
xmreg::XmrInput mock_input_data = make_mock_input_data();
mock_input_data.account_id = acc.id.data;
uint64_t expected_primary_id = xmr_accounts->get_next_primary_id(mock_input_data);
uint64_t inserted_id = xmr_accounts->insert(mock_input_data);
EXPECT_EQ(expected_primary_id, inserted_id);
// now we fetch the inserted input and compare its values
xmreg::XmrInput in_data2;
EXPECT_TRUE(xmr_accounts->select_by_primary_id(inserted_id, in_data2));
EXPECT_EQ(in_data2.account_id, mock_input_data.account_id);
EXPECT_EQ(in_data2.tx_id, mock_input_data.tx_id);
EXPECT_EQ(in_data2.amount, mock_input_data.amount);
EXPECT_EQ(in_data2.key_image, mock_input_data.key_image);
EXPECT_EQ(in_data2.output_id, mock_input_data.output_id);
EXPECT_EQ(in_data2.timestamp, mock_input_data.timestamp);
}
TEST_F(MYSQL_TEST, InsertSeverlInputsAtOnce)
{
ACC_FROM_HEX(owner_addr_5Ajfk);
// create vector of several inputs to be written into database
vector<xmreg::XmrInput> mock_data;
for (size_t i = 0; i < 10; ++i)
{
mock_data.push_back(make_mock_input_data(std::to_string(i)));
mock_data.back().account_id = acc.id.data;
}
uint64_t expected_primary_id = xmr_accounts->get_next_primary_id(xmreg::XmrInput());
// first time insert should be fine
uint64_t no_inserted_rows = xmr_accounts->insert(mock_data);
EXPECT_EQ(no_inserted_rows, mock_data.size());
// after inserting 10 rows, the expected ID should be before + 11
uint64_t expected_primary_id2 = xmr_accounts->get_next_primary_id(xmreg::XmrInput());
EXPECT_EQ(expected_primary_id2, expected_primary_id + mock_data.size());
for (size_t i = 0; i < 10; ++i)
{
uint64_t id_to_get = expected_primary_id + i;
xmreg::XmrInput out_data;
xmr_accounts->select_by_primary_id(id_to_get, out_data);
EXPECT_EQ(mock_data[i].key_image, out_data.key_image);
}
}
TEST_F(MYSQL_TEST, TryToInsertSameInputTwice)
{
// the input table requires a row to be unique for pair
// of key_image + output_id
ACC_FROM_HEX(owner_addr_5Ajfk);
xmreg::XmrInput mock_data = make_mock_input_data();
mock_data.account_id = acc.id.data;
// first time insert should be fine
uint64_t inserted_id = xmr_accounts->insert(mock_data);
EXPECT_GT(inserted_id, 0);
// second insert should fail and result in 0
inserted_id = xmr_accounts->insert(mock_data);
EXPECT_EQ(inserted_id, 0);
}
TEST_F(MYSQL_TEST, SelectPaymentForAccount)
{
ACC_FROM_HEX(owner_addr_5Ajfk);
vector<xmreg::XmrPayment> payments;
ASSERT_TRUE(xmr_accounts->select(acc.id.data, payments));
EXPECT_EQ(payments.size(), 1);
EXPECT_EQ(payments[0].payment_id, "74854c1cd490e148");
EXPECT_EQ(payments[0].payment_address, "5DUWE29P72Eb8inMa41HuNJG4tj9CcaNKGr6EVSbvhWGJdpDQCiNNYBUNF1oDb8BczU5aD68d3HNKXaEsPq8cvbQLK4Tiiy");
EXPECT_FALSE(static_cast<bool>(payments[0].request_fulfilled));
//check if there is no payment for the given account id
EXPECT_FALSE(xmr_accounts->select(5555, payments));
}
auto
make_mock_payment_data(string last_char_pub_key = "0")
{
xmreg::XmrPayment mock_data;
mock_data.id = mysqlpp::null;
// mock_output_data.account_id = acc.id; need to be set when used
mock_data.payment_id = pod_to_hex(crypto::rand<crypto::hash8>());
mock_data.import_fee = 10000000010ull; // xmr
mock_data.request_fulfilled = false;
mock_data.tx_hash = ""; // no tx_hash yet with the payment
mock_data.payment_address = "5DUWE29P72Eb8inMa41HuNJG4tj9CcaNKGr6EVSbvhWGJdpDQCiNNYBUNF1oDb8BczU5aD68d3HNKXaEsPq8cvbQLK4Tiiy";
return mock_data;
}
TEST_F(MYSQL_TEST, InsertOnePayment)
{
ACC_FROM_HEX(addr_55Zb);
xmreg::XmrPayment mock_data = make_mock_payment_data();
mock_data.account_id = acc.id.data;
uint64_t expected_primary_id = xmr_accounts->get_next_primary_id(mock_data);
uint64_t inserted_id = xmr_accounts->insert(mock_data);
EXPECT_EQ(expected_primary_id, inserted_id);
// now we fetch the inserted input and compare its values
xmreg::XmrPayment in_data2;
EXPECT_TRUE(xmr_accounts->select_by_primary_id(inserted_id, in_data2));
EXPECT_EQ(in_data2.account_id, mock_data.account_id);
EXPECT_EQ(in_data2.payment_id, mock_data.payment_id);
EXPECT_EQ(in_data2.import_fee, mock_data.import_fee);
EXPECT_EQ(in_data2.payment_address, mock_data.payment_address);
EXPECT_EQ(in_data2.request_fulfilled, mock_data.request_fulfilled);
}
TEST_F(MYSQL_TEST, TryToInsertSamePaymentTwice)
{
// the input table requires a row to be unique for pair
// of key_image + output_id
ACC_FROM_HEX(addr_55Zb);
xmreg::XmrPayment mock_data = make_mock_payment_data();
mock_data.account_id = acc.id.data;
uint64_t inserted_id = xmr_accounts->insert(mock_data);
EXPECT_GT(inserted_id, 0);
// second insert should fail and result in 0
inserted_id = xmr_accounts->insert(mock_data);
EXPECT_EQ(inserted_id, 0);
}

Loading…
Cancel
Save