diff --git a/CMakeLists.txt b/CMakeLists.txt index c8d39a8d..9ad64929 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,15 +48,16 @@ add_library (core ) add_executable (test - rai/test/client.cpp - rai/test/entry.cpp - rai/test/ledger.cpp rai/test/block.cpp rai/test/block_store.cpp - rai/test/test_network.cpp - rai/test/wallet_test.cpp + rai/test/client.cpp rai/test/daemon.cpp + rai/test/entry.cpp + rai/test/ledger.cpp + rai/test/processor_service.cpp + rai/test/test_network.cpp rai/test/uint256_union.cpp + rai/test/wallet_test.cpp ) add_executable (qt_test diff --git a/rai/core/core.cpp b/rai/core/core.cpp index 61ce04bc..d65ac7a1 100644 --- a/rai/core/core.cpp +++ b/rai/core/core.cpp @@ -2084,13 +2084,24 @@ void rai::bootstrap_receiver::stop () void rai::bootstrap_receiver::accept_connection () { auto socket (std::make_shared (service)); - acceptor.async_accept (*socket, [this, socket] (boost::system::error_code const & error) {accept_action (error, socket); accept_connection ();}); + acceptor.async_accept (*socket, [this, socket] (boost::system::error_code const & ec) + { + accept_action (ec, socket); + }); } void rai::bootstrap_receiver::accept_action (boost::system::error_code const & ec, std::shared_ptr socket_a) { - auto connection (std::make_shared (socket_a, client.shared ())); - connection->receive (); + if (!ec) + { + accept_connection (); + auto connection (std::make_shared (socket_a, client.shared ())); + connection->receive (); + } + else + { + client.log.add (boost::str (boost::format ("Error while accepting bootstrap connections: %1%") % ec.message ())); + } } rai::bootstrap_connection::bootstrap_connection (std::shared_ptr socket_a, std::shared_ptr client_a) : @@ -2102,7 +2113,10 @@ client (client_a) void rai::bootstrap_connection::receive () { auto this_l (shared_from_this ()); - boost::asio::async_read (*socket, boost::asio::buffer (receive_buffer.data (), 1), [this_l] (boost::system::error_code const & ec, size_t size_a) {this_l->receive_type_action (ec, size_a);}); + boost::asio::async_read (*socket, boost::asio::buffer (receive_buffer.data (), 1), [this_l] (boost::system::error_code const & ec, size_t size_a) + { + this_l->receive_type_action (ec, size_a); + }); } void rai::bootstrap_connection::receive_type_action (boost::system::error_code const & ec, size_t size_a) @@ -2118,13 +2132,19 @@ void rai::bootstrap_connection::receive_type_action (boost::system::error_code c case rai::message_type::bulk_req: { auto this_l (shared_from_this ()); - boost::asio::async_read (*socket, boost::asio::buffer (receive_buffer.data () + 1, sizeof (rai::uint256_union) + sizeof (rai::uint256_union)), [this_l] (boost::system::error_code const & ec, size_t size_a) {this_l->receive_bulk_req_action (ec, size_a);}); + boost::asio::async_read (*socket, boost::asio::buffer (receive_buffer.data () + 1, sizeof (rai::uint256_union) + sizeof (rai::uint256_union)), [this_l] (boost::system::error_code const & ec, size_t size_a) + { + this_l->receive_bulk_req_action (ec, size_a); + }); break; } case rai::message_type::frontier_req: { auto this_l (shared_from_this ()); - boost::asio::async_read (*socket, boost::asio::buffer (receive_buffer.data () + 1, sizeof (rai::uint256_union) + sizeof (uint32_t) + sizeof (uint32_t)), [this_l] (boost::system::error_code const & ec, size_t size_a) {this_l->receive_frontier_req_action (ec, size_a);}); + boost::asio::async_read (*socket, boost::asio::buffer (receive_buffer.data () + 1, sizeof (rai::uint256_union) + sizeof (uint32_t) + sizeof (uint32_t)), [this_l] (boost::system::error_code const & ec, size_t size_a) + { + this_l->receive_frontier_req_action (ec, size_a); + }); break; } default: @@ -2319,7 +2339,10 @@ void rai::bulk_req_response::send_next () { connection->client->log.add (boost::str (boost::format ("Sending block: %1%") % block->hash ().to_string ())); } - async_write (*connection->socket, boost::asio::buffer (send_buffer.data (), send_buffer.size ()), [this_l] (boost::system::error_code const & ec, size_t size_a) {this_l->sent_action (ec, size_a);}); + async_write (*connection->socket, boost::asio::buffer (send_buffer.data (), send_buffer.size ()), [this_l] (boost::system::error_code const & ec, size_t size_a) + { + this_l->sent_action (ec, size_a); + }); } else { @@ -2364,7 +2387,10 @@ void rai::bulk_req_response::send_finished () { connection->client->log.add ("Bulk sending finished"); } - async_write (*connection->socket, boost::asio::buffer (send_buffer.data (), 1), [this_l] (boost::system::error_code const & ec, size_t size_a) {this_l->no_block_sent (ec, size_a);}); + async_write (*connection->socket, boost::asio::buffer (send_buffer.data (), 1), [this_l] (boost::system::error_code const & ec, size_t size_a) + { + this_l->no_block_sent (ec, size_a); + }); } void rai::bulk_req_response::no_block_sent (boost::system::error_code const & ec, size_t size_a) @@ -2443,7 +2469,10 @@ void rai::bootstrap_initiator::run (boost::asio::ip::tcp::endpoint const & endpo client->log.add (boost::str (boost::format ("Initiating bootstrap connection to %1%") % endpoint_a)); } auto this_l (shared_from_this ()); - socket.async_connect (endpoint_a, [this_l] (boost::system::error_code const & ec) {this_l->connect_action (ec);}); + socket.async_connect (endpoint_a, [this_l] (boost::system::error_code const & ec) + { + this_l->connect_action (ec); + }); } void rai::bootstrap_initiator::connect_action (boost::system::error_code const & ec) @@ -2496,7 +2525,10 @@ void rai::bootstrap_initiator::add_request (std::unique_ptr messa run_receiver (); } auto this_l (shared_from_this ()); - boost::asio::async_write (socket, boost::asio::buffer (send_buffer.data (), send_buffer.size ()), [this_l] (boost::system::error_code const & ec, size_t size_a) {this_l->sent_request (ec, size_a);}); + boost::asio::async_write (socket, boost::asio::buffer (send_buffer.data (), send_buffer.size ()), [this_l] (boost::system::error_code const & ec, size_t size_a) + { + this_l->sent_request (ec, size_a); + }); } void rai::bootstrap_initiator::run_receiver () @@ -2521,7 +2553,10 @@ void rai::bootstrap_initiator::finish_request () void rai::bulk_req_initiator::receive_block () { auto this_l (shared_from_this ()); - boost::asio::async_read (connection->socket, boost::asio::buffer (receive_buffer.data (), 1), [this_l] (boost::system::error_code const & ec, size_t size_a) {this_l->received_type (ec, size_a);}); + boost::asio::async_read (connection->socket, boost::asio::buffer (receive_buffer.data (), 1), [this_l] (boost::system::error_code const & ec, size_t size_a) + { + this_l->received_type (ec, size_a); + }); } void rai::bulk_req_initiator::received_type (boost::system::error_code const & ec, size_t size_a) @@ -2534,22 +2569,34 @@ void rai::bulk_req_initiator::received_type (boost::system::error_code const & e { case rai::block_type::send: { - boost::asio::async_read (connection->socket, boost::asio::buffer (receive_buffer.data () + 1, sizeof (rai::signature) + sizeof (rai::block_hash) + sizeof (rai::amount) + sizeof (rai::address)), [this_l] (boost::system::error_code const & ec, size_t size_a) {this_l->received_block (ec, size_a);}); + boost::asio::async_read (connection->socket, boost::asio::buffer (receive_buffer.data () + 1, sizeof (rai::signature) + sizeof (rai::block_hash) + sizeof (rai::amount) + sizeof (rai::address)), [this_l] (boost::system::error_code const & ec, size_t size_a) + { + this_l->received_block (ec, size_a); + }); break; } case rai::block_type::receive: { - boost::asio::async_read (connection->socket, boost::asio::buffer (receive_buffer.data () + 1, sizeof (rai::signature) + sizeof (rai::block_hash) + sizeof (rai::block_hash)), [this_l] (boost::system::error_code const & ec, size_t size_a) {this_l->received_block (ec, size_a);}); + boost::asio::async_read (connection->socket, boost::asio::buffer (receive_buffer.data () + 1, sizeof (rai::signature) + sizeof (rai::block_hash) + sizeof (rai::block_hash)), [this_l] (boost::system::error_code const & ec, size_t size_a) + { + this_l->received_block (ec, size_a); + }); break; } case rai::block_type::open: { - boost::asio::async_read (connection->socket, boost::asio::buffer (receive_buffer.data () + 1, sizeof (rai::signature) + sizeof (rai::block_hash) + sizeof (rai::address)), [this_l] (boost::system::error_code const & ec, size_t size_a) {this_l->received_block (ec, size_a);}); + boost::asio::async_read (connection->socket, boost::asio::buffer (receive_buffer.data () + 1, sizeof (rai::signature) + sizeof (rai::block_hash) + sizeof (rai::address)), [this_l] (boost::system::error_code const & ec, size_t size_a) + { + this_l->received_block (ec, size_a); + }); break; } case rai::block_type::change: { - boost::asio::async_read (connection->socket, boost::asio::buffer (receive_buffer.data () + 1, sizeof (rai::signature) + sizeof (rai::block_hash) + sizeof (rai::address)), [this_l] (boost::system::error_code const & ec, size_t size_a) {this_l->received_block (ec, size_a);}); + boost::asio::async_read (connection->socket, boost::asio::buffer (receive_buffer.data () + 1, sizeof (rai::signature) + sizeof (rai::block_hash) + sizeof (rai::address)), [this_l] (boost::system::error_code const & ec, size_t size_a) + { + this_l->received_block (ec, size_a); + }); break; } case rai::block_type::not_a_block: @@ -2914,7 +2961,10 @@ void rai::network::send_buffer (uint8_t const * data_a, size_t size_a, rai::endp { client.log.add ("Sending packet"); } - socket.async_send_to (boost::asio::buffer (data_a, size_a), endpoint_a, [this] (boost::system::error_code const & ec, size_t size_a) {send_complete (ec, size_a);}); + socket.async_send_to (boost::asio::buffer (data_a, size_a), endpoint_a, [this] (boost::system::error_code const & ec, size_t size_a) + { + send_complete (ec, size_a); + }); } } @@ -2940,7 +2990,10 @@ void rai::network::send_complete (boost::system::error_code const & ec, size_t s client.log.add ("Sending packet"); } } - socket.async_send_to (boost::asio::buffer (std::get <0> (front), std::get <1> (front)), std::get <2> (front), [this] (boost::system::error_code const & ec, size_t size_a) {send_complete (ec, size_a);}); + socket.async_send_to (boost::asio::buffer (std::get <0> (front), std::get <1> (front)), std::get <2> (front), [this] (boost::system::error_code const & ec, size_t size_a) + { + send_complete (ec, size_a); + }); } } std::get <3> (self) (ec, size_a); @@ -2997,7 +3050,10 @@ void rai::frontier_req_response::send_next () { connection->client->log.add (boost::str (boost::format ("Sending frontier for %1% %2%") % pair.first.to_string () % pair.second.to_string ())); } - async_write (*connection->socket, boost::asio::buffer (send_buffer.data (), send_buffer.size ()), [this_l] (boost::system::error_code const & ec, size_t size_a) {this_l->sent_action (ec, size_a);}); + async_write (*connection->socket, boost::asio::buffer (send_buffer.data (), send_buffer.size ()), [this_l] (boost::system::error_code const & ec, size_t size_a) + { + this_l->sent_action (ec, size_a); + }); } else { @@ -3019,7 +3075,10 @@ void rai::frontier_req_response::send_finished () { connection->client->log.add ("Frontier sending finished"); } - async_write (*connection->socket, boost::asio::buffer (send_buffer.data (), send_buffer.size ()), [this_l] (boost::system::error_code const & ec, size_t size_a) {this_l->no_block_sent (ec, size_a);}); + async_write (*connection->socket, boost::asio::buffer (send_buffer.data (), send_buffer.size ()), [this_l] (boost::system::error_code const & ec, size_t size_a) + { + this_l->no_block_sent (ec, size_a); + }); } void rai::frontier_req_response::no_block_sent (boost::system::error_code const & ec, size_t size_a) @@ -3136,7 +3195,10 @@ rai::frontier_req_initiator::~frontier_req_initiator () void rai::frontier_req_initiator::receive_frontier () { auto this_l (shared_from_this ()); - boost::asio::async_read (connection->socket, boost::asio::buffer (receive_buffer.data (), sizeof (rai::uint256_union) + sizeof (rai::uint256_union)), [this_l] (boost::system::error_code const & ec, size_t size_a) {this_l->received_frontier (ec, size_a);}); + boost::asio::async_read (connection->socket, boost::asio::buffer (receive_buffer.data (), sizeof (rai::uint256_union) + sizeof (rai::uint256_union)), [this_l] (boost::system::error_code const & ec, size_t size_a) + { + this_l->received_frontier (ec, size_a); + }); } void rai::frontier_req_initiator::received_frontier (boost::system::error_code const & ec, size_t size_a) diff --git a/rai/qt_client/entry.cpp b/rai/qt_client/entry.cpp index 581c1086..07a2c0db 100644 --- a/rai/qt_client/entry.cpp +++ b/rai/qt_client/entry.cpp @@ -89,6 +89,10 @@ int main (int argc, char ** argv) rai::processor_service processor; rai::client_init init; auto client (std::make_shared (init, service, config.peering_port, boost::filesystem::system_complete (argv[0]).parent_path () / "data", processor, rai::genesis_address)); + QObject::connect (&application, &QApplication::aboutToQuit, [&] () + { + client->stop (); + }); if (!init.error ()) { client->processor.connect_bootstrap (config.bootstrap_peers); @@ -117,11 +121,6 @@ int main (int argc, char ** argv) assert (false); } }); - QObject::connect (&application, &QApplication::aboutToQuit, [&] () - { - client->stop (); - processor.stop (); - }); int result; try { diff --git a/rai/qt_test/qt.cpp b/rai/qt_test/qt.cpp index 46e030d3..ade4e06d 100644 --- a/rai/qt_test/qt.cpp +++ b/rai/qt_test/qt.cpp @@ -23,10 +23,6 @@ TEST (client, main) ASSERT_EQ (client.send_blocks_window, client.main_stack->currentWidget ()); QTest::mouseClick (client.send_blocks_back, Qt::LeftButton); ASSERT_EQ (client.entry_window, client.main_stack->currentWidget ()); - QTest::mouseClick (client.show_wallet, Qt::LeftButton); - ASSERT_EQ (client.wallet_window, client.main_stack->currentWidget ()); - QTest::mouseClick (client.wallet_back, Qt::LeftButton); - ASSERT_EQ (client.entry_window, client.main_stack->currentWidget ()); QTest::mouseClick (client.settings, Qt::LeftButton); ASSERT_EQ (client.settings_window, client.main_stack->currentWidget ()); QTest::mouseClick (client.settings_change_password_button, Qt::LeftButton); @@ -35,17 +31,21 @@ TEST (client, main) ASSERT_EQ (client.settings_window, client.main_stack->currentWidget ()); QTest::mouseClick (client.settings_back, Qt::LeftButton); ASSERT_EQ (client.entry_window, client.main_stack->currentWidget ()); - QTest::mouseClick (client.show_ledger, Qt::LeftButton); - ASSERT_EQ (client.ledger_window, client.main_stack->currentWidget ()); - QTest::mouseClick (client.ledger_back, Qt::LeftButton); - ASSERT_EQ (client.entry_window, client.main_stack->currentWidget ()); - QTest::mouseClick (client.show_peers, Qt::LeftButton); - ASSERT_EQ (client.peers_window, client.main_stack->currentWidget ()); - QTest::mouseClick (client.peers_back, Qt::LeftButton); - ASSERT_EQ (client.entry_window, client.main_stack->currentWidget ()); - QTest::mouseClick (client.show_log, Qt::LeftButton); - ASSERT_EQ (client.log_window, client.main_stack->currentWidget ()); - QTest::mouseClick (client.log_back, Qt::LeftButton); + QTest::mouseClick (client.show_advanced, Qt::LeftButton); + ASSERT_EQ (client.advanced.window, client.main_stack->currentWidget ()); + QTest::mouseClick (client.advanced.show_ledger, Qt::LeftButton); + ASSERT_EQ (client.advanced.ledger_window, client.main_stack->currentWidget ()); + QTest::mouseClick (client.advanced.ledger_back, Qt::LeftButton); + ASSERT_EQ (client.advanced.window, client.main_stack->currentWidget ()); + QTest::mouseClick (client.advanced.show_peers, Qt::LeftButton); + ASSERT_EQ (client.advanced.peers_window, client.main_stack->currentWidget ()); + QTest::mouseClick (client.advanced.peers_back, Qt::LeftButton); + ASSERT_EQ (client.advanced.window, client.main_stack->currentWidget ()); + QTest::mouseClick (client.advanced.show_log, Qt::LeftButton); + ASSERT_EQ (client.advanced.log_window, client.main_stack->currentWidget ()); + QTest::mouseClick (client.advanced.log_back, Qt::LeftButton); + ASSERT_EQ (client.advanced.window, client.main_stack->currentWidget ()); + QTest::mouseClick (client.advanced.back, Qt::LeftButton); ASSERT_EQ (client.entry_window, client.main_stack->currentWidget ()); } @@ -127,13 +127,14 @@ TEST (client, send) system.service->poll_one (); system.processor.poll_one (); } - ASSERT_EQ (2 * client.scale, client.client_m.ledger.account_balance (key1.pub)); + ASSERT_EQ (2 * client.advanced.scale, client.client_m.ledger.account_balance (key1.pub)); QTest::mouseClick (client.send_blocks_back, Qt::LeftButton); - QTest::mouseClick (client.show_ledger, Qt::LeftButton); - QTest::mouseClick (client.ledger_refresh, Qt::LeftButton); - ASSERT_EQ (2, client.ledger_model->rowCount ()); - ASSERT_EQ (3, client.ledger_model->columnCount ()); - auto item (client.ledger_model->itemFromIndex (client.ledger_model->index (1, 1))); + QTest::mouseClick (client.show_advanced, Qt::LeftButton); + QTest::mouseClick (client.advanced.show_ledger, Qt::LeftButton); + QTest::mouseClick (client.advanced.ledger_refresh, Qt::LeftButton); + ASSERT_EQ (2, client.advanced.ledger_model->rowCount ()); + ASSERT_EQ (3, client.advanced.ledger_model->columnCount ()); + auto item (client.advanced.ledger_model->itemFromIndex (client.advanced.ledger_model->index (1, 1))); ASSERT_EQ ("2", item->text ().toStdString ()); } @@ -144,11 +145,11 @@ TEST (client, scaling) QApplication application (argc, nullptr); rai_qt::client client (application, *system.clients [0]); auto max (std::numeric_limits ::max ()); - auto down (client.scale_down (max)); - auto up1 (client.scale_up (down)); - auto up2 (client.scale_up (down - 1)); + auto down (client.advanced.scale_down (max)); + auto up1 (client.advanced.scale_up (down)); + auto up2 (client.advanced.scale_up (down - 1)); ASSERT_LT (up2, up1); - ASSERT_EQ (up1 - up2, client.scale); + ASSERT_EQ (up1 - up2, client.advanced.scale); } TEST (client, scale_num) @@ -158,7 +159,7 @@ TEST (client, scale_num) QApplication application (argc, nullptr); rai_qt::client client (application, *system.clients [0]); rai::uint128_t num ("100000000000000000000000000000000000000"); - auto down (client.scale_down (num)); - auto up (client.scale_up (down)); + auto down (client.advanced.scale_down (num)); + auto up (client.advanced.scale_up (down)); ASSERT_EQ (num, up); } \ No newline at end of file diff --git a/rai/test/ledger.cpp b/rai/test/ledger.cpp index 6f231e96..6260c73d 100644 --- a/rai/test/ledger.cpp +++ b/rai/test/ledger.cpp @@ -3,10 +3,6 @@ #include #include -#include -#include -#include - TEST (ledger, store_error) { leveldb::Status init; @@ -355,129 +351,6 @@ TEST (ledger, process_duplicate) ASSERT_EQ (rai::process_result::old, ledger.process (open)); } -TEST (processor_service, bad_send_signature) -{ - leveldb::Status init; - rai::block_store store (init, rai::block_store_temp); - ASSERT_TRUE (init.ok ()); - bool init1; - rai::ledger ledger (init1, init, store); - ASSERT_FALSE (init1); - rai::genesis genesis; - genesis.initialize (store); - rai::frontier frontier1; - ASSERT_FALSE (store.latest_get (rai::test_genesis_key.pub, frontier1)); - rai::send_block send; - rai::keypair key2; - send.hashables.previous = frontier1.hash; - send.hashables.balance = 50; - send.hashables.destination = rai::test_genesis_key.pub; - rai::block_hash hash1 (send.hash ()); - rai::sign_message (rai::test_genesis_key.prv, rai::test_genesis_key.pub, hash1, send.signature); - send.signature.bytes [32] ^= 0x1; - ASSERT_EQ (rai::process_result::bad_signature, ledger.process (send)); -} - -TEST (processor_service, bad_receive_signature) -{ - leveldb::Status init; - rai::block_store store (init, rai::block_store_temp); - ASSERT_TRUE (init.ok ()); - bool init1; - rai::ledger ledger (init1, init, store); - ASSERT_FALSE (init1); - rai::genesis genesis; - genesis.initialize (store); - rai::frontier frontier1; - ASSERT_FALSE (store.latest_get (rai::test_genesis_key.pub, frontier1)); - rai::send_block send; - rai::keypair key2; - send.hashables.previous = frontier1.hash; - send.hashables.balance = 50; - send.hashables.destination = key2.pub; - rai::block_hash hash1 (send.hash ()); - rai::sign_message (rai::test_genesis_key.prv, rai::test_genesis_key.pub, hash1, send.signature); - ASSERT_EQ (rai::process_result::progress, ledger.process (send)); - rai::frontier frontier2; - ASSERT_FALSE (store.latest_get (rai::test_genesis_key.pub, frontier2)); - rai::receive_block receive; - receive.hashables.source = hash1; - receive.hashables.previous = key2.pub; - rai::block_hash hash2 (receive.hash ()); - receive.sign (key2.prv, key2.pub, hash2); - receive.signature.bytes [32] ^= 0x1; - ASSERT_EQ (rai::process_result::bad_signature, ledger.process (receive)); -} - -TEST (processor_service, empty) -{ - rai::processor_service service; - std::thread thread ([&service] () {service.run ();}); - service.stop (); - thread.join (); -} - -TEST (processor_service, one) -{ - rai::processor_service service; - std::atomic done (false); - std::mutex mutex; - std::condition_variable condition; - service.add (std::chrono::system_clock::now (), [&] () - { - std::lock_guard lock (mutex); - done = true; - condition.notify_one (); - }); - std::thread thread ([&service] () {service.run ();}); - std::unique_lock unique (mutex); - condition.wait (unique, [&] () {return !!done;}); - service.stop (); - thread.join (); -} - -TEST (processor_service, many) -{ - rai::processor_service service; - std::atomic count (0); - std::mutex mutex; - std::condition_variable condition; - for (auto i (0); i < 50; ++i) - { - service.add (std::chrono::system_clock::now (), [&] () - { - std::lock_guard lock (mutex); - count += 1; - condition.notify_one (); - }); - } - std::vector threads; - for (auto i (0); i < 50; ++i) - { - threads.push_back (std::thread ([&service] () {service.run ();})); - } - std::unique_lock unique (mutex); - condition.wait (unique, [&] () {return count == 50;}); - service.stop (); - for (auto i (threads.begin ()), j (threads.end ()); i != j; ++i) - { - i->join (); - } -} - -TEST (processor_service, top_execution) -{ - rai::processor_service service; - int value (0); - std::mutex mutex; - std::unique_lock lock1 (mutex); - service.add (std::chrono::system_clock::now (), [&] () {value = 1; service.stop (); lock1.unlock ();}); - service.add (std::chrono::system_clock::now () + std::chrono::milliseconds (1), [&] () {value = 2; service.stop (); lock1.unlock ();}); - service.run (); - std::unique_lock lock2 (mutex); - ASSERT_EQ (1, value); -} - TEST (ledger, representative_genesis) { leveldb::Status init; diff --git a/rai/test/processor_service.cpp b/rai/test/processor_service.cpp new file mode 100644 index 00000000..b03b46e7 --- /dev/null +++ b/rai/test/processor_service.cpp @@ -0,0 +1,134 @@ +#include +#include + +#include +#include +#include + +TEST (processor_service, bad_send_signature) +{ + leveldb::Status init; + rai::block_store store (init, rai::block_store_temp); + ASSERT_TRUE (init.ok ()); + bool init1; + rai::ledger ledger (init1, init, store); + ASSERT_FALSE (init1); + rai::genesis genesis; + genesis.initialize (store); + rai::frontier frontier1; + ASSERT_FALSE (store.latest_get (rai::test_genesis_key.pub, frontier1)); + rai::send_block send; + rai::keypair key2; + send.hashables.previous = frontier1.hash; + send.hashables.balance = 50; + send.hashables.destination = rai::test_genesis_key.pub; + rai::block_hash hash1 (send.hash ()); + rai::sign_message (rai::test_genesis_key.prv, rai::test_genesis_key.pub, hash1, send.signature); + send.signature.bytes [32] ^= 0x1; + ASSERT_EQ (rai::process_result::bad_signature, ledger.process (send)); +} + +TEST (processor_service, bad_receive_signature) +{ + leveldb::Status init; + rai::block_store store (init, rai::block_store_temp); + ASSERT_TRUE (init.ok ()); + bool init1; + rai::ledger ledger (init1, init, store); + ASSERT_FALSE (init1); + rai::genesis genesis; + genesis.initialize (store); + rai::frontier frontier1; + ASSERT_FALSE (store.latest_get (rai::test_genesis_key.pub, frontier1)); + rai::send_block send; + rai::keypair key2; + send.hashables.previous = frontier1.hash; + send.hashables.balance = 50; + send.hashables.destination = key2.pub; + rai::block_hash hash1 (send.hash ()); + rai::sign_message (rai::test_genesis_key.prv, rai::test_genesis_key.pub, hash1, send.signature); + ASSERT_EQ (rai::process_result::progress, ledger.process (send)); + rai::frontier frontier2; + ASSERT_FALSE (store.latest_get (rai::test_genesis_key.pub, frontier2)); + rai::receive_block receive; + receive.hashables.source = hash1; + receive.hashables.previous = key2.pub; + rai::block_hash hash2 (receive.hash ()); + receive.sign (key2.prv, key2.pub, hash2); + receive.signature.bytes [32] ^= 0x1; + ASSERT_EQ (rai::process_result::bad_signature, ledger.process (receive)); +} + +TEST (processor_service, empty) +{ + rai::processor_service service; + std::thread thread ([&service] () {service.run ();}); + service.stop (); + thread.join (); +} + +TEST (processor_service, one) +{ + rai::processor_service service; + std::atomic done (false); + std::mutex mutex; + std::condition_variable condition; + service.add (std::chrono::system_clock::now (), [&] () + { + std::lock_guard lock (mutex); + done = true; + condition.notify_one (); + }); + std::thread thread ([&service] () {service.run ();}); + std::unique_lock unique (mutex); + condition.wait (unique, [&] () {return !!done;}); + service.stop (); + thread.join (); +} + +TEST (processor_service, many) +{ + rai::processor_service service; + std::atomic count (0); + std::mutex mutex; + std::condition_variable condition; + for (auto i (0); i < 50; ++i) + { + service.add (std::chrono::system_clock::now (), [&] () + { + std::lock_guard lock (mutex); + count += 1; + condition.notify_one (); + }); + } + std::vector threads; + for (auto i (0); i < 50; ++i) + { + threads.push_back (std::thread ([&service] () {service.run ();})); + } + std::unique_lock unique (mutex); + condition.wait (unique, [&] () {return count == 50;}); + service.stop (); + for (auto i (threads.begin ()), j (threads.end ()); i != j; ++i) + { + i->join (); + } +} + +TEST (processor_service, top_execution) +{ + rai::processor_service service; + int value (0); + std::mutex mutex; + std::unique_lock lock1 (mutex); + service.add (std::chrono::system_clock::now (), [&] () {value = 1; service.stop (); lock1.unlock ();}); + service.add (std::chrono::system_clock::now () + std::chrono::milliseconds (1), [&] () {value = 2; service.stop (); lock1.unlock ();}); + service.run (); + std::unique_lock lock2 (mutex); + ASSERT_EQ (1, value); +} + +TEST (processor_service, add_stopped) +{ + +} \ No newline at end of file