aboutsummaryrefslogtreecommitdiff
path: root/tests/performance_tests
diff options
context:
space:
mode:
authorAntonio Juarez <antonio.maria.juarez@live.com>2014-03-03 22:07:58 +0000
committerAntonio Juarez <antonio.maria.juarez@live.com>2014-03-03 22:07:58 +0000
commit296ae46ed8f8f6e5f986f978febad302e3df231a (patch)
tree1629164454a239308f33c9e12afb22e7f3cd8eeb /tests/performance_tests
parentchanged name (diff)
downloadmonero-296ae46ed8f8f6e5f986f978febad302e3df231a.tar.xz
moved all stuff to github
Diffstat (limited to 'tests/performance_tests')
-rw-r--r--tests/performance_tests/check_ring_signature.h57
-rw-r--r--tests/performance_tests/construct_tx.h52
-rw-r--r--tests/performance_tests/derive_public_key.h38
-rw-r--r--tests/performance_tests/derive_secret_key.h38
-rw-r--r--tests/performance_tests/generate_key_derivation.h23
-rw-r--r--tests/performance_tests/generate_key_image.h44
-rw-r--r--tests/performance_tests/generate_key_image_helper.h24
-rw-r--r--tests/performance_tests/is_out_to_acc.h23
-rw-r--r--tests/performance_tests/main.cpp62
-rw-r--r--tests/performance_tests/multi_tx_test_base.h64
-rw-r--r--tests/performance_tests/performance_tests.h118
-rw-r--r--tests/performance_tests/performance_utils.h55
-rw-r--r--tests/performance_tests/single_tx_test_base.h32
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;
+};