From 40e5d287a3db87d9e0fb3819302d24fb39ab19bd Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Thu, 19 Jul 2018 13:44:37 +0800 Subject: [PATCH] More CurrentBlockchainStatus tests added --- src/CurrentBlockchainStatus.cpp | 42 +++++-- src/CurrentBlockchainStatus.h | 13 --- src/MicroCore.h | 33 ++++-- tests/bcstatus_tests.cpp | 200 ++++++++++++++++++++++++++++++-- 4 files changed, 249 insertions(+), 39 deletions(-) diff --git a/src/CurrentBlockchainStatus.cpp b/src/CurrentBlockchainStatus.cpp index a36d68e..c34978f 100755 --- a/src/CurrentBlockchainStatus.cpp +++ b/src/CurrentBlockchainStatus.cpp @@ -234,14 +234,14 @@ CurrentBlockchainStatus::get_output_keys(const uint64_t& amount, try { mcore->get_output_key(amount, absolute_offsets, outputs); + return true; } catch (const OUTPUT_DNE& e) { - cerr << "get_output_keys: " << e.what() << endl; - return false; + cerr << "get_output_keys: " << e.what() << endl; } - return true; + return false; } @@ -291,6 +291,27 @@ CurrentBlockchainStatus::get_amount_specific_indices( return false; } +//bool +//CurrentBlockchainStatus::get_random_outputs( +// const vector& amounts, +// const uint64_t& outs_count, +// vector& found_outputs) +//{ +// rpccalls rpc {bc_setup.deamon_url}; + +// string error_msg; + +// if (!rpc.get_random_outs_for_amounts( +// amounts, outs_count, found_outputs, error_msg)) +// { +// cerr << "rpc.get_random_outs_for_amounts failed" << endl; +// return false; +// } + +// return true; +//} + bool CurrentBlockchainStatus::get_random_outputs( const vector& amounts, @@ -298,21 +319,24 @@ CurrentBlockchainStatus::get_random_outputs( vector& found_outputs) { - rpccalls rpc {bc_setup.deamon_url}; - string error_msg; + COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request req; + COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response res; - if (!rpc.get_random_outs_for_amounts( - amounts, outs_count, found_outputs, error_msg)) + req.outs_count = outs_count; + req.amounts = amounts; + + if (!mcore->get_random_outs_for_amounts(req, res)) { - cerr << "rpc.get_random_outs_for_amounts failed" << endl; + cerr << "mcore->get_random_outs_for_amounts(req, res) failed\n"; return false; } + found_outputs = res.outs; + return true; } - bool CurrentBlockchainStatus::get_output( const uint64_t amount, diff --git a/src/CurrentBlockchainStatus.h b/src/CurrentBlockchainStatus.h index 9a0ae5b..4d9869c 100755 --- a/src/CurrentBlockchainStatus.h +++ b/src/CurrentBlockchainStatus.h @@ -73,19 +73,6 @@ public: // its simplifies mocking its behavior in our // tests, as we just inject mock version of // TxUnlockChecker class -// template -// virtual bool -// is_tx_unlocked(uint64_t unlock_time, -// uint64_t block_height, -// T tx_unlock_checker = T()) -// { -// tx_unlock_checker.init(bc_setup.net_type); - -// return tx_unlock_checker.is_unlocked(current_height, -// unlock_time, -// block_height); -// } - virtual bool is_tx_unlocked(uint64_t unlock_time, uint64_t block_height, diff --git a/src/MicroCore.h b/src/MicroCore.h index aaa7aef..46bb546 100755 --- a/src/MicroCore.h +++ b/src/MicroCore.h @@ -71,10 +71,21 @@ public: virtual hw::device* const get_device() const; - template - auto get_output_key(T&&... args) + virtual void + get_output_key(const uint64_t& amount, + const vector& absolute_offsets, + vector& outputs) { - return core_storage.get_db().get_output_key(std::forward(args)...); + core_storage.get_db() + .get_output_key(amount, absolute_offsets, outputs); + } + + virtual output_data_t + get_output_key(uint64_t amount, + uint64_t global_amount_index) + { + return core_storage.get_db() + .get_output_key(amount, global_amount_index); } virtual bool @@ -116,10 +127,10 @@ public: return core_storage.get_db().get_tx_block_height(std::forward(args)...); } - template - auto get_tx_amount_output_indices(T&&... args) const + virtual std::vector + get_tx_amount_output_indices(uint64_t const& tx_id) const { - return core_storage.get_db().get_tx_amount_output_indices(std::forward(args)...); + return core_storage.get_db().get_tx_amount_output_indices(tx_id); } template @@ -134,6 +145,14 @@ public: return core_storage.get_current_blockchain_height(); } + virtual bool + get_random_outs_for_amounts( + COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request const& req, + COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res) const + { + return core_storage.get_random_outs_for_amounts(req, res); + } + virtual bool get_block_from_height(uint64_t height, block& blk) const; @@ -141,7 +160,7 @@ public: get_tx(crypto::hash const& tx_hash, transaction& tx) const; virtual bool - init_success() const; + init_success() const; virtual ~MicroCore(); }; diff --git a/tests/bcstatus_tests.cpp b/tests/bcstatus_tests.cpp index a892e28..6273c36 100644 --- a/tests/bcstatus_tests.cpp +++ b/tests/bcstatus_tests.cpp @@ -37,17 +37,48 @@ using ::testing::internal::FilePath; class MockMicroCore : public xmreg::MicroCore { public: - MOCK_METHOD2(init, bool(const string& _blockchain_path, network_type nt)); + MOCK_METHOD2(init, bool(const string& _blockchain_path, + network_type nt)); + MOCK_CONST_METHOD0(get_current_blockchain_height, uint64_t()); - MOCK_CONST_METHOD2(get_block_from_height, bool(uint64_t height, block& blk)); - MOCK_CONST_METHOD2(get_blocks_range, std::vector(const uint64_t& h1, const uint64_t& h2)); - MOCK_CONST_METHOD3(get_transactions, bool(const std::vector& txs_ids, - std::vector& txs, - std::vector& missed_txs)); + + MOCK_CONST_METHOD2(get_block_from_height, + bool(uint64_t height, block& blk)); + + MOCK_CONST_METHOD2(get_blocks_range, + std::vector(const uint64_t& h1, + const uint64_t& h2)); + + MOCK_CONST_METHOD3(get_transactions, + bool(const std::vector& txs_ids, + std::vector& txs, + std::vector& missed_txs)); + MOCK_CONST_METHOD1(have_tx, bool(crypto::hash const& tx_hash)); - MOCK_CONST_METHOD2(tx_exists, bool(crypto::hash const& tx_hash, uint64_t& tx_id)); - MOCK_CONST_METHOD2(get_output_tx_and_index, tx_out_index(uint64_t const& amount, uint64_t const& index)); - MOCK_CONST_METHOD2(get_tx, bool(crypto::hash const& tx_hash, transaction& tx)); + + MOCK_CONST_METHOD2(tx_exists, + bool(crypto::hash const& tx_hash, + uint64_t& tx_id)); + + MOCK_CONST_METHOD2(get_output_tx_and_index, + tx_out_index(uint64_t const& amount, + uint64_t const& index)); + + MOCK_CONST_METHOD2(get_tx, + bool(crypto::hash const& tx_hash, + transaction& tx)); + + MOCK_METHOD3(get_output_key, + void(const uint64_t& amount, + const vector& absolute_offsets, + vector& outputs)); + + MOCK_CONST_METHOD1(get_tx_amount_output_indices, + std::vector(uint64_t const& tx_id)); + + MOCK_CONST_METHOD2(get_random_outs_for_amounts, + bool(COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request const& req, + COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res)); }; @@ -381,7 +412,7 @@ TEST_F(BCSTATUS_TEST, IsTxSpendtimeUnlockedScenario2) EXPECT_TRUE(bcs->is_tx_unlocked(tx_unlock_time, block_height, mock_tx_unlock_checker)); - // unlock time is 1 second into the future + // unlock time is 1 second more than needed tx_unlock_time = current_timestamp + mock_tx_unlock_checker.get_leeway( block_height, bcs->get_bc_setup().net_type) + 1; @@ -391,4 +422,153 @@ TEST_F(BCSTATUS_TEST, IsTxSpendtimeUnlockedScenario2) } + +TEST_F(BCSTATUS_TEST, GetOutputKeys) +{ + // we are going to expect two outputs + vector outputs_to_return; + + outputs_to_return.push_back( + output_data_t { + crypto::rand(), + 1000, 2222, + crypto::rand()}); + + outputs_to_return.push_back( + output_data_t { + crypto::rand(), + 3333, 5555, + crypto::rand()}); + + EXPECT_CALL(*mcore_ptr, get_output_key(_, _, _)) + .WillOnce(SetArgReferee<2>(outputs_to_return)); + + const uint64_t mock_amount {1111}; + const vector mock_absolute_offsets; + vector outputs; + + EXPECT_TRUE(bcs->get_output_keys(mock_amount, + mock_absolute_offsets, + outputs)); + + EXPECT_EQ(outputs.back().pubkey, outputs_to_return.back().pubkey); + + EXPECT_CALL(*mcore_ptr, get_output_key(_, _, _)) + .WillOnce(ThrowOutputDNE()); + + EXPECT_FALSE(bcs->get_output_keys(mock_amount, + mock_absolute_offsets, + outputs)); +} + +TEST_F(BCSTATUS_TEST, GetAccountIntegratedAddressAsStr) +{ + // bcs->get_account_integrated_address_as_str only forwards + // call to cryptonote function. so we just check if + // forwarding is correct, not wether the cryptonote + // function works correctly. + + crypto::hash8 payment_id8 = crypto::rand(); + string payment_id8_str = pod_to_hex(payment_id8); + + string expected_int_addr + = cryptonote::get_account_integrated_address_as_str( + bcs->get_bc_setup().net_type, + bcs->get_bc_setup().import_payment_address.address, + payment_id8); + + string resulting_int_addr + = bcs->get_account_integrated_address_as_str(payment_id8); + + EXPECT_EQ(expected_int_addr, resulting_int_addr); + + resulting_int_addr + = bcs->get_account_integrated_address_as_str( + payment_id8_str); + + EXPECT_EQ(expected_int_addr, resulting_int_addr); + + + resulting_int_addr + = bcs->get_account_integrated_address_as_str( + "wrong_payment_id8"); + + EXPECT_TRUE(resulting_int_addr.empty()); +} + + +ACTION(ThrowTxDNE) +{ + throw TX_DNE("Mock Throw: Tx does not exist!"); +} + +TEST_F(BCSTATUS_TEST, GetAmountSpecificIndices) +{ + vector out_indices_to_return {1,2,3}; + + EXPECT_CALL(*mcore_ptr, tx_exists(_, _)) + .WillOnce(Return(true)); + + EXPECT_CALL(*mcore_ptr, get_tx_amount_output_indices(_)) + .WillOnce(Return(out_indices_to_return)); + + vector out_indices; + + RAND_TX_HASH(); + + EXPECT_TRUE(bcs->get_amount_specific_indices(tx_hash, out_indices)); + + EXPECT_EQ(out_indices, out_indices_to_return); + + EXPECT_CALL(*mcore_ptr, tx_exists(_, _)) + .WillOnce(Return(false)); + + EXPECT_FALSE(bcs->get_amount_specific_indices(tx_hash, out_indices)); + + EXPECT_CALL(*mcore_ptr, tx_exists(_, _)) + .WillOnce(ThrowTxDNE()); + + EXPECT_FALSE(bcs->get_amount_specific_indices(tx_hash, out_indices)); +} + +TEST_F(BCSTATUS_TEST, GetRandomOutputs) +{ + using out_for_amount = COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS + ::outs_for_amount; + + std::vector outputs_to_return; + + outputs_to_return.push_back(out_for_amount {22, {}}); + outputs_to_return.push_back(out_for_amount {66, {}}); + + COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response res; + + res.outs = outputs_to_return; + + EXPECT_CALL(*mcore_ptr, get_random_outs_for_amounts(_, _)) + .WillOnce(DoAll(SetArgReferee<1>(res), Return(true))); + + const vector mock_amounts {444, 556, 77}; // any + const uint64_t mock_outs_count {3}; // any + + std::vector found_outputs; + + EXPECT_TRUE(bcs->get_random_outputs( + mock_amounts, mock_outs_count, + found_outputs)); + + EXPECT_EQ(found_outputs.size(), outputs_to_return.size()); + EXPECT_EQ(found_outputs.back().amount, + outputs_to_return.back().amount); + + EXPECT_CALL(*mcore_ptr, get_random_outs_for_amounts(_, _)) + .WillOnce(Return(false)); + + EXPECT_FALSE(bcs->get_random_outputs( + mock_amounts, mock_outs_count, + found_outputs)); + +} + + }