diff options
Diffstat (limited to 'tests/performance_tests')
-rw-r--r-- | tests/performance_tests/check_ring_signature.h | 57 | ||||
-rw-r--r-- | tests/performance_tests/construct_tx.h | 52 | ||||
-rw-r--r-- | tests/performance_tests/derive_public_key.h | 38 | ||||
-rw-r--r-- | tests/performance_tests/derive_secret_key.h | 38 | ||||
-rw-r--r-- | tests/performance_tests/generate_key_derivation.h | 23 | ||||
-rw-r--r-- | tests/performance_tests/generate_key_image.h | 44 | ||||
-rw-r--r-- | tests/performance_tests/generate_key_image_helper.h | 24 | ||||
-rw-r--r-- | tests/performance_tests/is_out_to_acc.h | 23 | ||||
-rw-r--r-- | tests/performance_tests/main.cpp | 62 | ||||
-rw-r--r-- | tests/performance_tests/multi_tx_test_base.h | 64 | ||||
-rw-r--r-- | tests/performance_tests/performance_tests.h | 118 | ||||
-rw-r--r-- | tests/performance_tests/performance_utils.h | 55 | ||||
-rw-r--r-- | tests/performance_tests/single_tx_test_base.h | 32 |
13 files changed, 630 insertions, 0 deletions
diff --git a/tests/performance_tests/check_ring_signature.h b/tests/performance_tests/check_ring_signature.h new file mode 100644 index 000000000..fc7574f92 --- /dev/null +++ b/tests/performance_tests/check_ring_signature.h @@ -0,0 +1,57 @@ +// Copyright (c) 2012-2013 The Cryptonote developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#pragma once + +#include <vector> + +#include "cryptonote_core/account.h" +#include "cryptonote_core/cryptonote_basic.h" +#include "cryptonote_core/cryptonote_format_utils.h" +#include "crypto/crypto.h" + +#include "multi_tx_test_base.h" + +template<size_t a_ring_size> +class test_check_ring_signature : private multi_tx_test_base<a_ring_size> +{ + static_assert(0 < a_ring_size, "ring_size must be greater than 0"); + +public: + static const size_t loop_count = a_ring_size < 100 ? 100 : 10; + static const size_t ring_size = a_ring_size; + + typedef multi_tx_test_base<a_ring_size> base_class; + + bool init() + { + using namespace cryptonote; + + if (!base_class::init()) + return false; + + m_alice.generate(); + + std::vector<tx_destination_entry> destinations; + destinations.push_back(tx_destination_entry(this->m_source_amount, m_alice.get_keys().m_account_address)); + + if (!construct_tx(this->m_miners[this->real_source_idx].get_keys(), this->m_sources, destinations, m_tx, 0)) + return false; + + get_transaction_prefix_hash(m_tx, m_tx_prefix_hash); + + return true; + } + + bool test() + { + const cryptonote::txin_to_key& txin = boost::get<cryptonote::txin_to_key>(m_tx.vin[0]); + return crypto::check_ring_signature(m_tx_prefix_hash, txin.k_image, this->m_public_key_ptrs, ring_size, m_tx.signatures[0].data()); + } + +private: + cryptonote::account_base m_alice; + cryptonote::transaction m_tx; + crypto::hash m_tx_prefix_hash; +}; diff --git a/tests/performance_tests/construct_tx.h b/tests/performance_tests/construct_tx.h new file mode 100644 index 000000000..36507d6f3 --- /dev/null +++ b/tests/performance_tests/construct_tx.h @@ -0,0 +1,52 @@ +// Copyright (c) 2012-2013 The Cryptonote developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#pragma once + +#include "cryptonote_core/account.h" +#include "cryptonote_core/cryptonote_basic.h" +#include "cryptonote_core/cryptonote_format_utils.h" + +#include "multi_tx_test_base.h" + +template<size_t a_in_count, size_t a_out_count> +class test_construct_tx : private multi_tx_test_base<a_in_count> +{ + static_assert(0 < a_in_count, "in_count must be greater than 0"); + static_assert(0 < a_out_count, "out_count must be greater than 0"); + +public: + static const size_t loop_count = (a_in_count + a_out_count < 100) ? 100 : 10; + static const size_t in_count = a_in_count; + static const size_t out_count = a_out_count; + + typedef multi_tx_test_base<a_in_count> base_class; + + bool init() + { + using namespace cryptonote; + + if (!base_class::init()) + return false; + + m_alice.generate(); + + for (size_t i = 0; i < out_count; ++i) + { + m_destinations.push_back(tx_destination_entry(this->m_source_amount / out_count, m_alice.get_keys().m_account_address)); + } + + return true; + } + + bool test() + { + return cryptonote::construct_tx(this->m_miners[this->real_source_idx].get_keys(), this->m_sources, m_destinations, m_tx, 0); + } + +private: + cryptonote::account_base m_alice; + std::vector<cryptonote::tx_destination_entry> m_destinations; + cryptonote::transaction m_tx; +}; diff --git a/tests/performance_tests/derive_public_key.h b/tests/performance_tests/derive_public_key.h new file mode 100644 index 000000000..ec9d64e09 --- /dev/null +++ b/tests/performance_tests/derive_public_key.h @@ -0,0 +1,38 @@ +// Copyright (c) 2012-2013 The Cryptonote developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#pragma once + +#include "crypto/crypto.h" +#include "cryptonote_core/cryptonote_basic.h" + +#include "single_tx_test_base.h" + +class test_derive_public_key : public single_tx_test_base +{ +public: + static const size_t loop_count = 1000; + + bool init() + { + if (!single_tx_test_base::init()) + return false; + + crypto::generate_key_derivation(m_tx_pub_key, m_bob.get_keys().m_view_secret_key, m_key_derivation); + m_spend_public_key = m_bob.get_keys().m_account_address.m_spend_public_key; + + return true; + } + + bool test() + { + cryptonote::keypair in_ephemeral; + crypto::derive_public_key(m_key_derivation, 0, m_spend_public_key, in_ephemeral.pub); + return true; + } + +private: + crypto::key_derivation m_key_derivation; + crypto::public_key m_spend_public_key; +}; diff --git a/tests/performance_tests/derive_secret_key.h b/tests/performance_tests/derive_secret_key.h new file mode 100644 index 000000000..bd915846d --- /dev/null +++ b/tests/performance_tests/derive_secret_key.h @@ -0,0 +1,38 @@ +// Copyright (c) 2012-2013 The Cryptonote developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#pragma once + +#include "crypto/crypto.h" +#include "cryptonote_core/cryptonote_basic.h" + +#include "single_tx_test_base.h" + +class test_derive_secret_key : public single_tx_test_base +{ +public: + static const size_t loop_count = 1000000; + + bool init() + { + if (!single_tx_test_base::init()) + return false; + + crypto::generate_key_derivation(m_tx_pub_key, m_bob.get_keys().m_view_secret_key, m_key_derivation); + m_spend_secret_key = m_bob.get_keys().m_spend_secret_key; + + return true; + } + + bool test() + { + cryptonote::keypair in_ephemeral; + crypto::derive_secret_key(m_key_derivation, 0, m_spend_secret_key, in_ephemeral.sec); + return true; + } + +private: + crypto::key_derivation m_key_derivation; + crypto::secret_key m_spend_secret_key; +}; diff --git a/tests/performance_tests/generate_key_derivation.h b/tests/performance_tests/generate_key_derivation.h new file mode 100644 index 000000000..c2fce687d --- /dev/null +++ b/tests/performance_tests/generate_key_derivation.h @@ -0,0 +1,23 @@ +// Copyright (c) 2012-2013 The Cryptonote developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#pragma once + +#include "crypto/crypto.h" +#include "cryptonote_core/cryptonote_basic.h" + +#include "single_tx_test_base.h" + +class test_generate_key_derivation : public single_tx_test_base +{ +public: + static const size_t loop_count = 1000; + + bool test() + { + crypto::key_derivation recv_derivation; + crypto::generate_key_derivation(m_tx_pub_key, m_bob.get_keys().m_view_secret_key, recv_derivation); + return true; + } +}; diff --git a/tests/performance_tests/generate_key_image.h b/tests/performance_tests/generate_key_image.h new file mode 100644 index 000000000..f6a00ffe3 --- /dev/null +++ b/tests/performance_tests/generate_key_image.h @@ -0,0 +1,44 @@ +// Copyright (c) 2012-2013 The Cryptonote developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#pragma once + +#include "crypto/crypto.h" +#include "cryptonote_core/cryptonote_basic.h" + +#include "single_tx_test_base.h" + +class test_generate_key_image : public single_tx_test_base +{ +public: + static const size_t loop_count = 1000; + + bool init() + { + using namespace cryptonote; + + if (!single_tx_test_base::init()) + return false; + + account_keys bob_keys = m_bob.get_keys(); + + crypto::key_derivation recv_derivation; + crypto::generate_key_derivation(m_tx_pub_key, bob_keys.m_view_secret_key, recv_derivation); + + crypto::derive_public_key(recv_derivation, 0, bob_keys.m_account_address.m_spend_public_key, m_in_ephemeral.pub); + crypto::derive_secret_key(recv_derivation, 0, bob_keys.m_spend_secret_key, m_in_ephemeral.sec); + + return true; + } + + bool test() + { + crypto::key_image ki; + crypto::generate_key_image(m_in_ephemeral.pub, m_in_ephemeral.sec, ki); + return true; + } + +private: + cryptonote::keypair m_in_ephemeral; +}; diff --git a/tests/performance_tests/generate_key_image_helper.h b/tests/performance_tests/generate_key_image_helper.h new file mode 100644 index 000000000..1c072f443 --- /dev/null +++ b/tests/performance_tests/generate_key_image_helper.h @@ -0,0 +1,24 @@ +// Copyright (c) 2012-2013 The Cryptonote developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#pragma once + +#include "cryptonote_core/account.h" +#include "cryptonote_core/cryptonote_basic.h" +#include "cryptonote_core/cryptonote_format_utils.h" + +#include "single_tx_test_base.h" + +class test_generate_key_image_helper : public single_tx_test_base +{ +public: + static const size_t loop_count = 500; + + bool test() + { + cryptonote::keypair in_ephemeral; + crypto::key_image ki; + return cryptonote::generate_key_image_helper(m_bob.get_keys(), m_tx_pub_key, 0, in_ephemeral, ki); + } +}; diff --git a/tests/performance_tests/is_out_to_acc.h b/tests/performance_tests/is_out_to_acc.h new file mode 100644 index 000000000..4a33c25fb --- /dev/null +++ b/tests/performance_tests/is_out_to_acc.h @@ -0,0 +1,23 @@ +// Copyright (c) 2012-2013 The Cryptonote developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#pragma once + +#include "cryptonote_core/account.h" +#include "cryptonote_core/cryptonote_basic.h" +#include "cryptonote_core/cryptonote_format_utils.h" + +#include "single_tx_test_base.h" + +class test_is_out_to_acc : public single_tx_test_base +{ +public: + static const size_t loop_count = 1000; + + bool test() + { + const cryptonote::txout_to_key& tx_out = boost::get<cryptonote::txout_to_key>(m_tx.vout[0].target); + return cryptonote::is_out_to_acc(m_bob.get_keys(), tx_out, m_tx_pub_key, 0); + } +}; diff --git a/tests/performance_tests/main.cpp b/tests/performance_tests/main.cpp new file mode 100644 index 000000000..2ad503b83 --- /dev/null +++ b/tests/performance_tests/main.cpp @@ -0,0 +1,62 @@ +// Copyright (c) 2012-2013 The Cryptonote developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "performance_tests.h" +#include "performance_utils.h" + +// tests +#include "construct_tx.h" +#include "check_ring_signature.h" +#include "derive_public_key.h" +#include "derive_secret_key.h" +#include "generate_key_derivation.h" +#include "generate_key_image.h" +#include "generate_key_image_helper.h" +#include "is_out_to_acc.h" + +int main(int argc, char** argv) +{ + set_process_affinity(1); + set_thread_high_priority(); + + performance_timer timer; + timer.start(); + + TEST_PERFORMANCE2(test_construct_tx, 1, 1); + TEST_PERFORMANCE2(test_construct_tx, 1, 2); + TEST_PERFORMANCE2(test_construct_tx, 1, 10); + TEST_PERFORMANCE2(test_construct_tx, 1, 100); + TEST_PERFORMANCE2(test_construct_tx, 1, 1000); + + TEST_PERFORMANCE2(test_construct_tx, 2, 1); + TEST_PERFORMANCE2(test_construct_tx, 2, 2); + TEST_PERFORMANCE2(test_construct_tx, 2, 10); + TEST_PERFORMANCE2(test_construct_tx, 2, 100); + + TEST_PERFORMANCE2(test_construct_tx, 10, 1); + TEST_PERFORMANCE2(test_construct_tx, 10, 2); + TEST_PERFORMANCE2(test_construct_tx, 10, 10); + TEST_PERFORMANCE2(test_construct_tx, 10, 100); + + TEST_PERFORMANCE2(test_construct_tx, 100, 1); + TEST_PERFORMANCE2(test_construct_tx, 100, 2); + TEST_PERFORMANCE2(test_construct_tx, 100, 10); + TEST_PERFORMANCE2(test_construct_tx, 100, 100); + + TEST_PERFORMANCE1(test_check_ring_signature, 1); + TEST_PERFORMANCE1(test_check_ring_signature, 2); + TEST_PERFORMANCE1(test_check_ring_signature, 10); + TEST_PERFORMANCE1(test_check_ring_signature, 100); + + TEST_PERFORMANCE0(test_is_out_to_acc); + TEST_PERFORMANCE0(test_generate_key_image_helper); + TEST_PERFORMANCE0(test_generate_key_derivation); + TEST_PERFORMANCE0(test_generate_key_image); + TEST_PERFORMANCE0(test_derive_public_key); + TEST_PERFORMANCE0(test_derive_secret_key); + + std::cout << "Tests finished. Elapsed time: " << timer.elapsed_ms() / 1000 << " sec" << std::endl; + + return 0; +} diff --git a/tests/performance_tests/multi_tx_test_base.h b/tests/performance_tests/multi_tx_test_base.h new file mode 100644 index 000000000..a65062362 --- /dev/null +++ b/tests/performance_tests/multi_tx_test_base.h @@ -0,0 +1,64 @@ +// Copyright (c) 2012-2013 The Cryptonote developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#pragma once + +#include <vector> + +#include "cryptonote_core/account.h" +#include "cryptonote_core/cryptonote_basic.h" +#include "cryptonote_core/cryptonote_format_utils.h" +#include "crypto/crypto.h" + +template<size_t a_ring_size> +class multi_tx_test_base +{ + static_assert(0 < a_ring_size, "ring_size must be greater than 0"); + +public: + static const size_t ring_size = a_ring_size; + static const size_t real_source_idx = ring_size / 2; + + bool init() + { + using namespace cryptonote; + + std::vector<tx_source_entry::output_entry> output_entries; + for (size_t i = 0; i < ring_size; ++i) + { + m_miners[i].generate(); + + std::vector<size_t> block_sizes; + if (!construct_miner_tx(0, 0, m_miners[i].get_keys().m_account_address, m_miner_txs[i], 0, block_sizes, 2)) + return false; + + txout_to_key tx_out = boost::get<txout_to_key>(m_miner_txs[i].vout[0].target); + output_entries.push_back(std::make_pair(i, tx_out.key)); + m_public_keys[i] = tx_out.key; + m_public_key_ptrs[i] = &m_public_keys[i]; + } + + m_source_amount = m_miner_txs[0].vout[0].amount; + + tx_source_entry source_entry; + source_entry.amount = m_source_amount; + source_entry.real_out_tx_key = get_tx_pub_key_from_extra(m_miner_txs[real_source_idx]); + source_entry.real_output_in_tx_index = 0; + source_entry.outputs.swap(output_entries); + source_entry.real_output = real_source_idx; + + m_sources.push_back(source_entry); + + return true; + } + +protected: + cryptonote::account_base m_miners[ring_size]; + cryptonote::transaction m_miner_txs[ring_size]; + uint64_t m_source_amount; + + std::vector<cryptonote::tx_source_entry> m_sources; + crypto::public_key m_public_keys[ring_size]; + const crypto::public_key* m_public_key_ptrs[ring_size]; +}; diff --git a/tests/performance_tests/performance_tests.h b/tests/performance_tests/performance_tests.h new file mode 100644 index 000000000..c7efe93f1 --- /dev/null +++ b/tests/performance_tests/performance_tests.h @@ -0,0 +1,118 @@ +// Copyright (c) 2012-2013 The Cryptonote developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#pragma once + +#include <iostream> +#include <stdint.h> + +#include <boost/chrono.hpp> + +class performance_timer +{ +public: + typedef boost::chrono::high_resolution_clock clock; + + performance_timer() + { + m_base = clock::now(); + } + + void start() + { + m_start = clock::now(); + } + + int elapsed_ms() + { + clock::duration elapsed = clock::now() - m_start; + return static_cast<int>(boost::chrono::duration_cast<boost::chrono::milliseconds>(elapsed).count()); + } + +private: + clock::time_point m_base; + clock::time_point m_start; +}; + + +template <typename T> +class test_runner +{ +public: + test_runner() + : m_elapsed(0) + { + } + + bool run() + { + T test; + if (!test.init()) + return false; + + performance_timer timer; + timer.start(); + warm_up(); + std::cout << "Warm up: " << timer.elapsed_ms() << " ms" << std::endl; + + timer.start(); + for (size_t i = 0; i < T::loop_count; ++i) + { + if (!test.test()) + return false; + } + m_elapsed = timer.elapsed_ms(); + + return true; + } + + int elapsed_time() const { return m_elapsed; } + + int time_per_call() const + { + static_assert(0 < T::loop_count, "T::loop_count must be greater than 0"); + return m_elapsed / T::loop_count; + } + +private: + /** + * Warm up processor core, enabling turbo boost, etc. + */ + uint64_t warm_up() + { + const size_t warm_up_rounds = 1000 * 1000 * 1000; + m_warm_up = 0; + for (size_t i = 0; i < warm_up_rounds; ++i) + { + ++m_warm_up; + } + return m_warm_up; + } + +private: + volatile uint64_t m_warm_up; ///<! This field is intended for preclude compiler optimizations + int m_elapsed; +}; + +template <typename T> +void run_test(const char* test_name) +{ + test_runner<T> runner; + if (runner.run()) + { + std::cout << test_name << " - OK:\n"; + std::cout << " loop count: " << T::loop_count << '\n'; + std::cout << " elapsed: " << runner.elapsed_time() << " ms\n"; + std::cout << " time per call: " << runner.time_per_call() << " ms/call\n" << std::endl; + } + else + { + std::cout << test_name << " - FAILED" << std::endl; + } +} + +#define QUOTEME(x) #x +#define TEST_PERFORMANCE0(test_class) run_test< test_class >(QUOTEME(test_class)) +#define TEST_PERFORMANCE1(test_class, a0) run_test< test_class<a0> >(QUOTEME(test_class<a0>)) +#define TEST_PERFORMANCE2(test_class, a0, a1) run_test< test_class<a0, a1> >(QUOTEME(test_class) "<" QUOTEME(a0) ", " QUOTEME(a1) ">") diff --git a/tests/performance_tests/performance_utils.h b/tests/performance_tests/performance_utils.h new file mode 100644 index 000000000..b2ac4076f --- /dev/null +++ b/tests/performance_tests/performance_utils.h @@ -0,0 +1,55 @@ +// Copyright (c) 2012-2013 The Cryptonote developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#pragma once + +#include <iostream> + +#include <boost/config.hpp> + +#ifdef BOOST_WINDOWS +#include <windows.h> +#endif + +void set_process_affinity(int core) +{ +#if defined(BOOST_WINDOWS) + DWORD_PTR mask = 1; + for (int i = 0; i < core; ++i) + { + mask <<= 1; + } + ::SetProcessAffinityMask(::GetCurrentProcess(), core); +#elif defined(BOOST_HAS_PTHREADS) + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + CPU_SET(core, &cpuset); + if (0 != ::pthread_setaffinity_np(::pthread_self(), sizeof(cpuset), &cpuset)) + { + std::cout << "pthread_setaffinity_np - ERROR" << std::endl; + } +#endif +} + +void set_thread_high_priority() +{ +#if defined(BOOST_WINDOWS) + ::SetPriorityClass(::GetCurrentProcess(), HIGH_PRIORITY_CLASS); +#elif defined(BOOST_HAS_PTHREADS) + pthread_attr_t attr; + int policy = 0; + int max_prio_for_policy = 0; + + ::pthread_attr_init(&attr); + ::pthread_attr_getschedpolicy(&attr, &policy); + max_prio_for_policy = ::sched_get_priority_max(policy); + + if (0 != ::pthread_setschedprio(::pthread_self(), max_prio_for_policy)) + { + std::cout << "pthread_setschedprio - ERROR" << std::endl; + } + + ::pthread_attr_destroy(&attr); +#endif +} diff --git a/tests/performance_tests/single_tx_test_base.h b/tests/performance_tests/single_tx_test_base.h new file mode 100644 index 000000000..a622fce89 --- /dev/null +++ b/tests/performance_tests/single_tx_test_base.h @@ -0,0 +1,32 @@ +// Copyright (c) 2012-2013 The Cryptonote developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#pragma once + +#include "cryptonote_core/account.h" +#include "cryptonote_core/cryptonote_basic.h" +#include "cryptonote_core/cryptonote_format_utils.h" + +class single_tx_test_base +{ +public: + bool init() + { + using namespace cryptonote; + + m_bob.generate(); + + std::vector<size_t> block_sizes; + if (!construct_miner_tx(0, 0, m_bob.get_keys().m_account_address, m_tx, 0, block_sizes, 2)) + return false; + + m_tx_pub_key = get_tx_pub_key_from_extra(m_tx); + return true; + } + +protected: + cryptonote::account_base m_bob; + cryptonote::transaction m_tx; + crypto::public_key m_tx_pub_key; +}; |