Updates from BitShares FC #22

Closed
nathanielhourt wants to merge 693 commits from dapp-support into latest-fc
4 changed files with 86 additions and 74 deletions
Showing only changes of commit 5c0b9ed4e3 - Show all commits

View file

@ -28,6 +28,8 @@
#include <vector>
#include <openssl/bn.h>
namespace fc { namespace detail {
/** Errors thrown by the bignum class */
class bignum_error : public std::runtime_error
{
@ -605,11 +607,10 @@ inline bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vch
return DecodeBase58(str.c_str(), vchRet);
}
namespace fc {
} // detail
std::string to_base58( const char* d, size_t s ) {
return EncodeBase58( (const unsigned char*)d, (const unsigned char*)d+s ).c_str();
return fc::detail::EncodeBase58( (const unsigned char*)d, (const unsigned char*)d+s ).c_str();
}
std::string to_base58( const std::vector<char>& d )
@ -620,8 +621,9 @@ std::string to_base58( const std::vector<char>& d )
}
std::vector<char> from_base58( const std::string& base58_str ) {
std::vector<unsigned char> out;
if( !DecodeBase58( base58_str.c_str(), out ) ) {
FC_THROW_EXCEPTION( parse_error_exception, "Unable to decode base58 string ${base58_str}", ("base58_str",base58_str) );
if( !fc::detail::DecodeBase58( base58_str.c_str(), out ) ) {
FC_THROW_EXCEPTION( parse_error_exception, "Unable to decode base58 string ${base58_str}",
("base58_str",base58_str) );
}
return std::vector<char>((const char*)out.data(), ((const char*)out.data())+out.size() );
}
@ -629,10 +631,10 @@ std::vector<char> from_base58( const std::string& base58_str ) {
* @return the number of bytes decoded
*/
size_t from_base58( const std::string& base58_str, char* out_data, size_t out_data_len ) {
//slog( "%s", base58_str.c_str() );
std::vector<unsigned char> out;
if( !DecodeBase58( base58_str.c_str(), out ) ) {
FC_THROW_EXCEPTION( parse_error_exception, "Unable to decode base58 string ${base58_str}", ("base58_str",base58_str) );
if( !fc::detail::DecodeBase58( base58_str.c_str(), out ) ) {
FC_THROW_EXCEPTION( parse_error_exception, "Unable to decode base58 string ${base58_str}",
("base58_str",base58_str) );
}
FC_ASSERT( out.size() <= out_data_len );
if (!out.empty()) {
@ -640,6 +642,7 @@ size_t from_base58( const std::string& base58_str, char* out_data, size_t out_da
}
return out.size();
}
}
} // fc
#endif

View file

@ -6,6 +6,8 @@
#include <fc/rpc/api_connection.hpp>
#include <fc/rpc/websocket_api.hpp>
namespace fc { namespace test {
class calculator
{
public:
@ -15,9 +17,6 @@ class calculator
void on_result2( const std::function<void(int32_t)>& cb, int test );
};
FC_API( calculator, (add)(sub)(on_result)(on_result2) )
class login_api
{
public:
@ -29,8 +28,6 @@ class login_api
fc::optional<fc::api<calculator>> calc;
std::set<std::string> test( const std::string&, const std::string& ) { return std::set<std::string>(); }
};
FC_API( login_api, (get_calc)(test) );
class optionals_api
{
@ -44,9 +41,6 @@ public:
return fc::json::to_string(fc::variants{{first,2}, {second, 2}, {third, 2}});
}
};
FC_API( optionals_api, (foo)(bar) );
using namespace fc;
class some_calculator
{
@ -58,6 +52,12 @@ class some_calculator
std::function<void(int32_t)> _cb;
};
}} // fc::test
FC_API( fc::test::calculator, (add)(sub)(on_result)(on_result2) )
FC_API( fc::test::login_api, (get_calc)(test) );
FC_API( fc::test::optionals_api, (foo)(bar) );
using namespace fc::http;
using namespace fc::rpc;
@ -67,14 +67,14 @@ BOOST_AUTO_TEST_SUITE(api_tests)
BOOST_AUTO_TEST_CASE(login_test) {
try {
fc::api<calculator> calc_api( std::make_shared<some_calculator>() );
fc::api<fc::test::calculator> calc_api( std::make_shared<fc::test::some_calculator>() );
auto server = std::make_shared<fc::http::websocket_server>();
server->on_connection([&]( const websocket_connection_ptr& c ){
auto wsc = std::make_shared<websocket_api_connection>(c, MAX_DEPTH);
auto login = std::make_shared<login_api>();
auto login = std::make_shared<fc::test::login_api>();
login->calc = calc_api;
wsc->register_api(fc::api<login_api>(login));
wsc->register_api(fc::api<fc::test::login_api>(login));
c->set_session_data( wsc );
});
@ -86,7 +86,7 @@ BOOST_AUTO_TEST_CASE(login_test) {
auto con = client->connect( "ws://localhost:" + std::to_string(listen_port) );
server->stop_listening();
auto apic = std::make_shared<websocket_api_connection>(con, MAX_DEPTH);
auto remote_login_api = apic->get_remote_api<login_api>();
auto remote_login_api = apic->get_remote_api<fc::test::login_api>();
auto remote_calc = remote_login_api->get_calc();
bool remote_triggered = false;
remote_calc->on_result( [&remote_triggered]( uint32_t r ) { remote_triggered = true; } );
@ -103,8 +103,8 @@ BOOST_AUTO_TEST_CASE(login_test) {
BOOST_AUTO_TEST_CASE(optionals_test) {
try {
auto optionals = std::make_shared<optionals_api>();
fc::api<optionals_api> oapi(optionals);
auto optionals = std::make_shared<fc::test::optionals_api>();
fc::api<fc::test::optionals_api> oapi(optionals);
BOOST_CHECK_EQUAL(oapi->foo("a"), "[\"a\",null,null]");
BOOST_CHECK_EQUAL(oapi->foo("a", "b"), "[\"a\",\"b\",null]");
BOOST_CHECK_EQUAL(oapi->foo("a", "b", "c"), "[\"a\",\"b\",\"c\"]");
@ -119,7 +119,7 @@ BOOST_AUTO_TEST_CASE(optionals_test) {
auto server = std::make_shared<fc::http::websocket_server>();
server->on_connection([&]( const websocket_connection_ptr& c ){
auto wsc = std::make_shared<websocket_api_connection>(c, MAX_DEPTH);
wsc->register_api(fc::api<optionals_api>(optionals));
wsc->register_api(fc::api<fc::test::optionals_api>(optionals));
c->set_session_data( wsc );
});
@ -130,7 +130,7 @@ BOOST_AUTO_TEST_CASE(optionals_test) {
auto client = std::make_shared<fc::http::websocket_client>();
auto con = client->connect( "ws://localhost:" + std::to_string(listen_port) );
auto apic = std::make_shared<websocket_api_connection>(con, MAX_DEPTH);
auto remote_optionals = apic->get_remote_api<optionals_api>();
auto remote_optionals = apic->get_remote_api<fc::test::optionals_api>();
BOOST_CHECK_EQUAL(remote_optionals->foo("a"), "[\"a\",null,null]");
BOOST_CHECK_EQUAL(remote_optionals->foo("a", "b"), "[\"a\",\"b\",null]");
@ -145,8 +145,8 @@ BOOST_AUTO_TEST_CASE(optionals_test) {
auto client2 = std::make_shared<fc::http::websocket_client>();
auto con2 = client2->connect( "ws://localhost:" + std::to_string(listen_port) );
string response;
con2->on_message_handler([&](const std::string& s){
std::string response;
con2->on_message_handler([&response](const std::string& s){
response = s;
});

View file

@ -3,6 +3,16 @@
#include <fc/network/tcp_socket.hpp>
#include <fc/asio.hpp>
namespace fc { namespace test {
class my_io_class : public fc::asio::default_io_service_scope
{
public:
static void reset_num_threads() { fc::asio::default_io_service_scope::num_io_threads = 0; }
};
}} // fc::test
BOOST_AUTO_TEST_SUITE(tcp_tests)
/***
@ -15,23 +25,17 @@ BOOST_AUTO_TEST_CASE(tcpconstructor_test)
fc::tcp_socket socket;
}
class my_io_class : public fc::asio::default_io_service_scope
{
public:
static void reset_num_threads() { fc::asio::default_io_service_scope::num_io_threads = 0; }
};
/***
* Test the control of number of threads from outside
*/
BOOST_AUTO_TEST_CASE( number_threads_test )
{
// to erase leftovers from previous tests
my_io_class::reset_num_threads();
fc::test::my_io_class::reset_num_threads();
fc::asio::default_io_service_scope::set_num_threads(12);
my_io_class my_class;
fc::test::my_io_class my_class;
BOOST_CHECK_EQUAL( 12, my_class.get_num_threads() );
}
@ -42,9 +46,9 @@ BOOST_AUTO_TEST_CASE( number_threads_test )
BOOST_AUTO_TEST_CASE( default_number_threads_test )
{
// to erase leftovers from previous tests
my_io_class::reset_num_threads();
fc::test::my_io_class::reset_num_threads();
my_io_class my_class;
fc::test::my_io_class my_class;
fc::asio::default_io_service();

View file

@ -35,6 +35,8 @@
#include <iostream>
namespace fc { namespace test {
struct thread_config {
thread_config() {
for( int i = 0; i < boost::unit_test::framework::master_test_suite().argc - 1; ++i )
@ -42,13 +44,51 @@ struct thread_config {
{
uint16_t threads = atoi(boost::unit_test::framework::master_test_suite().argv[++i]);
std::cout << "Using " << threads << " pool threads\n";
fc::asio::default_io_service_scope::set_num_threads(threads);
asio::default_io_service_scope::set_num_threads(threads);
}
}
};
BOOST_GLOBAL_FIXTURE( thread_config );
const std::string TEXT = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"$%&/()=?,.-#+´{[]}`*'_:;<>|";
template<typename Hash>
class hash_test {
public:
std::string _hashname = get_typename<Hash>::name();
void run_single_threaded() {
const std::string first = Hash::hash(TEXT).str();
time_point start = time_point::now();
for( int i = 0; i < 1000; i++ )
BOOST_CHECK_EQUAL( first, Hash::hash(TEXT).str() );
time_point end = time_point::now();
ilog( "${c} single-threaded ${h}'s in ${t}µs", ("c",1000)("h",_hashname)("t",end-start) );
}
void run_multi_threaded() {
const std::string first = Hash::hash(TEXT).str();
std::vector<future<std::string>> results;
results.reserve( 10000 );
time_point start = time_point::now();
for( int i = 0; i < 10000; i++ )
results.push_back( do_parallel( [] () { return Hash::hash(TEXT).str(); } ) );
for( auto& result: results )
BOOST_CHECK_EQUAL( first, result.wait() );
time_point end = time_point::now();
ilog( "${c} multi-threaded ${h}'s in ${t}µs", ("c",10000)("h",_hashname)("t",end-start) );
}
void run() {
run_single_threaded();
run_multi_threaded();
}
};
}} // fc::test
using namespace fc::test;
BOOST_GLOBAL_FIXTURE( thread_config );
BOOST_AUTO_TEST_SUITE(parallel_tests)
@ -96,41 +136,6 @@ BOOST_AUTO_TEST_CASE( do_something_parallel )
}
}
const std::string TEXT = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"$%&/()=?,.-#+´{[]}`*'_:;<>|";
template<typename Hash>
class hash_test {
public:
std::string _hashname = fc::get_typename<Hash>::name();
void run_single_threaded() {
const std::string first = Hash::hash(TEXT).str();
fc::time_point start = fc::time_point::now();
for( int i = 0; i < 1000; i++ )
BOOST_CHECK_EQUAL( first, Hash::hash(TEXT).str() );
fc::time_point end = fc::time_point::now();
ilog( "${c} single-threaded ${h}'s in ${t}µs", ("c",1000)("h",_hashname)("t",end-start) );
}
void run_multi_threaded() {
const std::string first = Hash::hash(TEXT).str();
std::vector<fc::future<std::string>> results;
results.reserve( 10000 );
fc::time_point start = fc::time_point::now();
for( int i = 0; i < 10000; i++ )
results.push_back( fc::do_parallel( [] () { return Hash::hash(TEXT).str(); } ) );
for( auto& result: results )
BOOST_CHECK_EQUAL( first, result.wait() );
fc::time_point end = fc::time_point::now();
ilog( "${c} multi-threaded ${h}'s in ${t}µs", ("c",10000)("h",_hashname)("t",end-start) );
}
void run() {
run_single_threaded();
run_multi_threaded();
}
};
BOOST_AUTO_TEST_CASE( hash_parallel )
{
hash_test<fc::ripemd160>().run();