diff --git a/libraries/app/api.cpp b/libraries/app/api.cpp index e68c70d155..6bd4620216 100644 --- a/libraries/app/api.cpp +++ b/libraries/app/api.cpp @@ -317,7 +317,8 @@ namespace graphene { namespace app { { FC_ASSERT( _app.chain_database() ); const auto& db = *_app.chain_database(); - FC_ASSERT( limit <= 100 ); + uint64_t api_limit_get_account_history=_app.get_options().api_limit_get_account_history; + FC_ASSERT( limit <= api_limit_get_account_history ); vector result; account_id_type account; try { @@ -353,7 +354,8 @@ namespace graphene { namespace app { { FC_ASSERT( _app.chain_database() ); const auto& db = *_app.chain_database(); - FC_ASSERT( limit <= 100 ); + uint64_t api_limit_get_account_history_operations=_app.get_options().api_limit_get_account_history_operations; + FC_ASSERT(limit <= api_limit_get_account_history_operations); vector result; account_id_type account; try { @@ -392,7 +394,8 @@ namespace graphene { namespace app { { FC_ASSERT( _app.chain_database() ); const auto& db = *_app.chain_database(); - FC_ASSERT(limit <= 100); + uint64_t api_limit_get_relative_account_history=_app.get_options().api_limit_get_relative_account_history; + FC_ASSERT(limit <= api_limit_get_relative_account_history); vector result; account_id_type account; try { @@ -431,7 +434,8 @@ namespace graphene { namespace app { history_operation_detail history_api::get_account_history_by_operations(const std::string account_id_or_name, vector operation_types, uint32_t start, unsigned limit) { - FC_ASSERT(limit <= 100); + uint64_t api_limit_get_account_history_by_operations=_app.get_options().api_limit_get_account_history_by_operations; + FC_ASSERT(limit <= api_limit_get_account_history_by_operations); history_operation_detail result; vector objs = get_relative_account_history(account_id_or_name, start, limit, limit + start - 1); std::for_each(objs.begin(), objs.end(), [&](const operation_history_object &o) { @@ -530,14 +534,15 @@ namespace graphene { namespace app { // asset_api asset_api::asset_api(graphene::app::application& app) : - _db( *app.chain_database()), - database_api( std::ref(*app.chain_database()), &(app.get_options()) + _app(app), + _db( *app.chain_database()), + database_api( std::ref(*app.chain_database()), &(app.get_options()) ) { } asset_api::~asset_api() { } vector asset_api::get_asset_holders( std::string asset, uint32_t start, uint32_t limit ) const { - FC_ASSERT(limit <= 100); - + uint64_t api_limit_get_asset_holders=_app.get_options().api_limit_get_asset_holders; + FC_ASSERT(limit <= api_limit_get_asset_holders); asset_id_type asset_id = database_api.get_asset_id_from_string( asset ); const auto& bal_idx = _db.get_index_type< account_balance_index >().indices().get< by_asset_balance >(); @@ -622,8 +627,9 @@ namespace graphene { namespace app { optional start, uint32_t limit )const { - FC_ASSERT( limit <= 101 ); - auto plugin = _app.get_plugin( "grouped_orders" ); + uint64_t api_limit_get_grouped_limit_orders=_app.get_options().api_limit_get_grouped_limit_orders; + FC_ASSERT( limit <= api_limit_get_grouped_limit_orders ); + auto plugin = _app.get_plugin( "grouped_orders" ); FC_ASSERT( plugin ); const auto& limit_groups = plugin->limit_order_groups(); vector< limit_order_group > result; diff --git a/libraries/app/application.cpp b/libraries/app/application.cpp index f6607a5e2f..9d3bf3dfa0 100644 --- a/libraries/app/application.cpp +++ b/libraries/app/application.cpp @@ -316,6 +316,44 @@ void application_impl::set_dbg_init_key( graphene::chain::genesis_state_type& ge genesis.initial_witness_candidates[i].block_signing_key = init_pubkey; } + +void application_impl::set_dgb_api_limit_api() { + if (_options->count("api-limit-get-account-history-operations")) { + _app_options.api_limit_get_account_history_operations = _options->at("api-limit-get-account-history-operations").as(); + } + if(_options->count("api-limit-get-account-history")){ + _app_options.api_limit_get_account_history = _options->at("api-limit-get-account-history").as(); + } + if(_options->count("api-limit-get-grouped-limit-orders")){ + _app_options.api_limit_get_grouped_limit_orders = _options->at("api-limit-get-grouped-limit-orders").as(); + } + if(_options->count("api-limit-get-relative-account-history")){ + _app_options.api_limit_get_relative_account_history = _options->at("api-limit-get-relative-account-history").as(); + } + if(_options->count("api-limit-get-account-history-by-operations")){ + _app_options.api_limit_get_account_history_by_operations = _options->at("api-limit-get-account-history-by-operations").as(); + } + if(_options->count("api-limit-get-asset-holders")){ + _app_options.api_limit_get_asset_holders = _options->at("api-limit-get-asset-holders").as(); + } + if(_options->count("api-limit-get-limit-orders")){ + _app_options.api_limit_get_limit_orders = _options->at("api-limit-get-limit-orders").as(); + } + if(_options->count("api-limit-get-key-references")){ + _app_options.api_limit_get_key_references = _options->at("api-limit-get-key-references").as(); + } + if(_options->count("api-limit-get-call-orders")){ + _app_options.api_limit_get_call_orders = _options->at("api-limit-get-call-orders").as(); + } + if(_options->count("api-limit-get-settle-orders")){ + _app_options.api_limit_get_settle_orders = _options->at("api-limit-get-settle-orders").as(); + } + if(_options->count("api-limit-get-order-book")){ + _app_options.api_limit_get_order_book = _options->at("api-limit-get-order-book").as(); + } + +} + void application_impl::startup() { try { fc::create_directories(_data_dir / "blockchain"); @@ -437,6 +475,8 @@ void application_impl::startup() if ( _options->count("enable-subscribe-to-all") ) _app_options.enable_subscribe_to_all = _options->at( "enable-subscribe-to-all" ).as(); + set_dgb_api_limit_api(); + if( _active_plugins.find( "market_history" ) != _active_plugins.end() ) _app_options.has_market_history_plugin = true; @@ -975,6 +1015,28 @@ void application::set_program_options(boost::program_options::options_descriptio ("enable-standby-votes-tracking", bpo::value()->implicit_value(true), "Whether to enable tracking of votes of standby witnesses and committee members. " "Set it to true to provide accurate data to API clients, set to false for slightly better performance.") + ("api-limit-get-account-history-operations",boost::program_options::value()->default_value(100), + "For history_api::get_account_history_operations to set its default limit value as 100") + ("api-limit-get-account-history",boost::program_options::value()->default_value(100), + "For history_api::get_account_history to set its default limit value as 100") + ("api-limit-get-grouped-limit-orders",boost::program_options::value()->default_value(101), + "For orders_api::get_grouped_limit_orders to set its default limit value as 101") + ("api-limit-get-relative-account-history",boost::program_options::value()->default_value(100), + "For history_api::get_relative_account_history to set its default limit value as 100") + ("api-limit-get-account-history-by-operations",boost::program_options::value()->default_value(100), + "For history_api::get_account_history_by_operations to set its default limit value as 100") + ("api-limit-get-asset-holders",boost::program_options::value()->default_value(100), + "For asset_api::get_asset_holders to set its default limit value as 100") + ("api-limit-get-key-references",boost::program_options::value()->default_value(100), + "For database_api_impl::get_key_references to set its default limit value as 100") + ("api-limit-get-limit-orders",boost::program_options::value()->default_value(300), + "For database_api_impl::get_limit_orders to set its default limit value as 300") + ("api-limit-get-call-orders",boost::program_options::value()->default_value(300), + "For database_api_impl::get_call_orders to set its default limit value as 300") + ("api-limit-get-settle-orders",boost::program_options::value()->default_value(300), + "For database_api_impl::get_settle_orders to set its default limit value as 300") + ("api-limit-get-order-book",boost::program_options::value()->default_value(50), + "For database_api_impl::get_order_book to set its default limit value as 50") ; command_line_options.add(configuration_file_options); command_line_options.add_options() @@ -1013,6 +1075,18 @@ void application::startup() throw; } } +void application::set_dgb_api_limit_api() +{ + try { + my->set_dgb_api_limit_api(); + } catch ( const fc::exception& e ) { + elog( "${e}", ("e",e.to_detail_string()) ); + throw; + } catch ( ... ) { + elog( "unexpected exception" ); + throw; + } +} std::shared_ptr application::get_plugin(const string& name) const { diff --git a/libraries/app/application_impl.hxx b/libraries/app/application_impl.hxx index 2d5d48080d..6b3b106c06 100644 --- a/libraries/app/application_impl.hxx +++ b/libraries/app/application_impl.hxx @@ -41,6 +41,7 @@ class application_impl : public net::node_delegate } void set_dbg_init_key( graphene::chain::genesis_state_type& genesis, const std::string& init_key ); + void set_dgb_api_limit_api(); void startup(); diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index c97db8273b..f3fa02ab1a 100644 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -260,7 +260,9 @@ class database_api_impl : public std::enable_shared_from_this } vector get_limit_orders(const asset_id_type a, const asset_id_type b, const uint32_t limit)const { - FC_ASSERT( limit <= 300 ); + FC_ASSERT( _app_options && _app_options->api_limit_get_limit_orders, "App needs to be passed"); + uint64_t api_limit_get_limit_orders=_app_options->api_limit_get_limit_orders; + FC_ASSERT( limit <= api_limit_get_limit_orders ); const auto& limit_order_idx = _db.get_index_type(); const auto& limit_price_idx = limit_order_idx.indices().get(); @@ -649,7 +651,6 @@ dynamic_global_property_object database_api_impl::get_dynamic_global_properties( vector> database_api::get_key_references( vector key )const { - FC_ASSERT(key.size() <= 100, "Number of keys must be 100 or less"); return my->get_key_references( key ); } @@ -658,6 +659,9 @@ vector> database_api::get_key_references( vector> database_api_impl::get_key_references( vector keys )const { + FC_ASSERT( _app_options && _app_options->api_limit_get_key_references, "App needs to be passed"); + uint64_t api_limit_get_key_references=_app_options->api_limit_get_key_references; + FC_ASSERT(keys.size() <= api_limit_get_key_references); const auto& idx = _db.get_index_type(); const auto& aidx = dynamic_cast(idx); const auto& refs = aidx.get_secondary_index(); @@ -1255,7 +1259,9 @@ vector database_api::get_limit_orders(std::string a, std::st */ vector database_api_impl::get_limit_orders(const std::string& a, const std::string& b, uint32_t limit)const { - FC_ASSERT( limit <= 300 ); + FC_ASSERT( _app_options && _app_options->api_limit_get_limit_orders, "App needs to be passed"); + uint64_t api_limit_get_limit_orders=_app_options->api_limit_get_limit_orders; + FC_ASSERT( limit <= api_limit_get_limit_orders ); const asset_id_type asset_a_id = get_asset_from_string(a)->id; const asset_id_type asset_b_id = get_asset_from_string(b)->id; @@ -1270,7 +1276,9 @@ vector database_api::get_call_orders(const std::string& a, ui vector database_api_impl::get_call_orders(const std::string& a, uint32_t limit)const { - FC_ASSERT( limit <= 300 ); + FC_ASSERT( _app_options && _app_options->api_limit_get_call_orders, "App needs to be passed"); + uint64_t api_limit_get_call_orders=_app_options->api_limit_get_call_orders; + FC_ASSERT( limit <= api_limit_get_call_orders ); const asset_id_type asset_a_id = get_asset_from_string(a)->id; const auto& call_index = _db.get_index_type().indices().get(); @@ -1295,7 +1303,9 @@ vector database_api::get_settle_orders(const std::strin vector database_api_impl::get_settle_orders(const std::string& a, uint32_t limit)const { - FC_ASSERT( limit <= 300 ); + FC_ASSERT( _app_options && _app_options->api_limit_get_settle_orders, "App needs to be passed"); + uint64_t api_limit_get_settle_orders=_app_options->api_limit_get_settle_orders; + FC_ASSERT( limit <= api_limit_get_settle_orders ); const asset_id_type asset_a_id = get_asset_from_string(a)->id; const auto& settle_index = _db.get_index_type().indices().get(); @@ -1464,7 +1474,10 @@ order_book database_api::get_order_book( const string& base, const string& quote order_book database_api_impl::get_order_book( const string& base, const string& quote, unsigned limit )const { using boost::multiprecision::uint128_t; - FC_ASSERT( limit <= 50 ); + + FC_ASSERT( _app_options && _app_options->api_limit_get_order_book, "App needs to be passed"); + uint64_t api_limit_get_order_book=_app_options->api_limit_get_order_book; + FC_ASSERT( limit <= api_limit_get_order_book ); order_book result; result.base = base; diff --git a/libraries/app/include/graphene/app/api.hpp b/libraries/app/include/graphene/app/api.hpp index 7e1dc1552f..484cde78c5 100644 --- a/libraries/app/include/graphene/app/api.hpp +++ b/libraries/app/include/graphene/app/api.hpp @@ -464,6 +464,7 @@ namespace graphene { namespace app { vector get_all_asset_holders() const; private: + graphene::app::application& _app; graphene::chain::database& _db; graphene::app::database_api database_api; }; diff --git a/libraries/app/include/graphene/app/application.hpp b/libraries/app/include/graphene/app/application.hpp index 66a73f3999..07f1782631 100644 --- a/libraries/app/include/graphene/app/application.hpp +++ b/libraries/app/include/graphene/app/application.hpp @@ -40,6 +40,17 @@ namespace graphene { namespace app { public: bool enable_subscribe_to_all = false; bool has_market_history_plugin = false; + uint64_t api_limit_get_account_history_operations=100; + uint64_t api_limit_get_account_history=100; + uint64_t api_limit_get_grouped_limit_orders=101; + uint64_t api_limit_get_relative_account_history=100; + uint64_t api_limit_get_account_history_by_operations=100; + uint64_t api_limit_get_asset_holders=100; + uint64_t api_limit_get_key_references=100; + uint64_t api_limit_get_limit_orders=300; + uint64_t api_limit_get_call_orders=300; + uint64_t api_limit_get_settle_orders=300; + uint64_t api_limit_get_order_book=50; }; class application @@ -90,7 +101,7 @@ namespace graphene { namespace app { net::node_ptr p2p_node(); std::shared_ptr chain_database()const; - + void set_dgb_api_limit_api(); void set_block_production(bool producing_blocks); fc::optional< api_access_info > get_api_access_info( const string& username )const; void set_api_access_info(const string& username, api_access_info&& permissions); diff --git a/tests/common/database_fixture.cpp b/tests/common/database_fixture.cpp index d05f34ee02..886cba5048 100644 --- a/tests/common/database_fixture.cpp +++ b/tests/common/database_fixture.cpp @@ -119,6 +119,66 @@ database_fixture::database_fixture() { options.insert(std::make_pair("max-ops-per-account", boost::program_options::variable_value((uint64_t)75, false))); } + if (current_test_name == "api_limit_get_account_history_operations") + { + options.insert(std::make_pair("max-ops-per-account", boost::program_options::variable_value((uint64_t)125, false))); + options.insert(std::make_pair("api-limit-get-account-history-operations", boost::program_options::variable_value((uint64_t)300, false))); + options.insert(std::make_pair("plugins", boost::program_options::variable_value(string("account_history"), false))); + } + if(current_test_name =="api_limit_get_account_history") + { + options.insert(std::make_pair("max-ops-per-account", boost::program_options::variable_value((uint64_t)125, false))); + options.insert(std::make_pair("api-limit-get-account-history", boost::program_options::variable_value((uint64_t)250, false))); + options.insert(std::make_pair("plugins", boost::program_options::variable_value(string("account_history"), false))); + } + if(current_test_name =="api_limit_get_grouped_limit_orders") + { + options.insert(std::make_pair("api-limit-get-grouped-limit-orders", boost::program_options::variable_value((uint64_t)250, false))); + options.insert(std::make_pair("plugins", boost::program_options::variable_value(string("grouped_orders"), false))); + } + if(current_test_name =="api_limit_get_relative_account_history") + { + options.insert(std::make_pair("max-ops-per-account", boost::program_options::variable_value((uint64_t)125, false))); + options.insert(std::make_pair("api-limit-get-relative-account-history", boost::program_options::variable_value((uint64_t)250, false))); + options.insert(std::make_pair("plugins", boost::program_options::variable_value(string("account_history"), false))); + } + if(current_test_name =="api_limit_get_account_history_by_operations") + { + options.insert(std::make_pair("api-limit-get-account-history-by-operations", boost::program_options::variable_value((uint64_t)250, false))); + options.insert(std::make_pair("api-limit-get-relative-account-history", boost::program_options::variable_value((uint64_t)250, false))); + options.insert(std::make_pair("plugins", boost::program_options::variable_value(string("account_history"), false))); + } + if(current_test_name =="api_limit_get_asset_holders") + { + options.insert(std::make_pair("api-limit-get-asset-holders", boost::program_options::variable_value((uint64_t)250, false))); + options.insert(std::make_pair("plugins", boost::program_options::variable_value(string("account_history"), false))); + } + if(current_test_name =="api_limit_get_key_references") + { + options.insert(std::make_pair("api-limit-get-key-references", boost::program_options::variable_value((uint64_t)200, false))); + options.insert(std::make_pair("plugins", boost::program_options::variable_value(string("account_history"), false))); + } + if(current_test_name =="api_limit_get_limit_orders") + { + options.insert(std::make_pair("api-limit-get-limit-orders", boost::program_options::variable_value((uint64_t)350, false))); + options.insert(std::make_pair("plugins", boost::program_options::variable_value(string("account_history"), false))); + } + if(current_test_name =="api_limit_get_call_orders") + { + options.insert(std::make_pair("api-limit-get-call-orders", boost::program_options::variable_value((uint64_t)350, false))); + options.insert(std::make_pair("plugins", boost::program_options::variable_value(string("account_history"), false))); + } + if(current_test_name =="api_limit_get_settle_orders") + { + options.insert(std::make_pair("api-limit-get-settle-orders", boost::program_options::variable_value((uint64_t)350, false))); + options.insert(std::make_pair("plugins", boost::program_options::variable_value(string("account_history"), false))); + } + if(current_test_name =="api_limit_get_order_book") + { + options.insert(std::make_pair("api-limit-get-order-book", boost::program_options::variable_value((uint64_t)80, false))); + options.insert(std::make_pair("plugins", boost::program_options::variable_value(string("account_history"), false))); + } + // add account tracking for ahplugin for special test case with track-account enabled if( !options.count("track-account") && current_test_name == "track_account") { std::vector track_account; @@ -160,6 +220,16 @@ database_fixture::database_fixture() ahplugin->plugin_set_app(&app); ahplugin->plugin_initialize(options); ahplugin->plugin_startup(); + if (current_test_name == "api_limit_get_account_history_operations" || current_test_name == "api_limit_get_account_history" + || current_test_name == "api_limit_get_grouped_limit_orders" || current_test_name == "api_limit_get_relative_account_history" + || current_test_name == "api_limit_get_account_history_by_operations" || current_test_name =="api_limit_get_asset_holders" + || current_test_name =="api_limit_get_key_references" || current_test_name =="api_limit_get_limit_orders" + || current_test_name =="api_limit_get_call_orders" || current_test_name =="api_limit_get_settle_orders" + || current_test_name =="api_limit_get_order_book") + { + app.initialize(graphene::utilities::temp_directory_path(), options); + app.set_dgb_api_limit_api(); + } } if(current_test_name == "elasticsearch_objects" || current_test_name == "elasticsearch_suite") { diff --git a/tests/tests/asset_api_tests.cpp b/tests/tests/asset_api_tests.cpp index ff3eeb9785..3fec7da844 100644 --- a/tests/tests/asset_api_tests.cpp +++ b/tests/tests/asset_api_tests.cpp @@ -60,5 +60,25 @@ BOOST_AUTO_TEST_CASE( asset_holders ) BOOST_CHECK(holders[2].name == "alice"); BOOST_CHECK(holders[3].name == "dan"); } +BOOST_AUTO_TEST_CASE( api_limit_get_asset_holders ) +{ + graphene::app::asset_api asset_api(app); + + // create an asset and some accounts + create_bitasset("USD", account_id_type()); + auto dan = create_account("dan"); + auto bob = create_account("bob"); + auto alice = create_account("alice"); + + // send them some bts + transfer(account_id_type()(db), dan, asset(100)); + transfer(account_id_type()(db), alice, asset(200)); + transfer(account_id_type()(db), bob, asset(300)); + + // make call + GRAPHENE_CHECK_THROW(asset_api.get_asset_holders( std::string( static_cast(asset_id_type())), 0, 260), fc::exception) + vector holders = asset_api.get_asset_holders( std::string( static_cast(asset_id_type())), 0, 210);; + BOOST_REQUIRE_EQUAL( holders.size(), 4u ); +} BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/tests/database_api_tests.cpp b/tests/tests/database_api_tests.cpp index 1eeb177b42..e711953624 100644 --- a/tests/tests/database_api_tests.cpp +++ b/tests/tests/database_api_tests.cpp @@ -940,5 +940,97 @@ BOOST_AUTO_TEST_CASE( verify_authority_multiple_accounts ) throw; } } - +BOOST_AUTO_TEST_CASE( api_limit_get_key_references ){ + try{ + const int num_keys = 210; + const int num_keys1 = 2; + vector< private_key_type > numbered_private_keys; + vector< public_key_type > numbered_key_id; + numbered_private_keys.reserve( num_keys ); + graphene::app::database_api db_api( db, &( app.get_options() )); + for( int i=0; i > final_result=db_api.get_key_references(numbered_key_id); + BOOST_REQUIRE_EQUAL( final_result.size(), 2u ); + numbered_private_keys.reserve( num_keys ); + for( int i=num_keys1; i(asset_id_type())), std::string(static_cast(bit_jmj_id)), 370), fc::exception); + vector limit_orders =db_api.get_limit_orders(std::string(static_cast(asset_id_type())), std::string(static_cast(bit_jmj_id)), 340); + BOOST_REQUIRE_EQUAL( limit_orders.size(), 0u); + }catch (fc::exception& e) { + edump((e.to_detail_string())); + throw; + } +} +BOOST_AUTO_TEST_CASE( api_limit_get_call_orders ){ + try{ + graphene::app::database_api db_api( db, &( app.get_options() )); + create_bitasset("USD", account_id_type()); + create_account("dan"); + create_account("bob"); + generate_block(); + fc::usleep(fc::milliseconds(2000)); + GRAPHENE_CHECK_THROW(db_api.get_call_orders(std::string(static_cast(asset_id_type())), 370), fc::exception); + }catch (fc::exception& e) { + edump((e.to_detail_string())); + throw; + } +} +BOOST_AUTO_TEST_CASE( api_limit_get_settle_orders ){ + try{ + graphene::app::database_api db_api( db, &( app.get_options() )); + //account_id_type() do 3 ops + create_bitasset("USD", account_id_type()); + create_account("dan"); + create_account("bob"); + generate_block(); + fc::usleep(fc::milliseconds(2000)); + GRAPHENE_CHECK_THROW(db_api.get_settle_orders(std::string(static_cast(asset_id_type())), 370), fc::exception); + }catch (fc::exception& e) { + edump((e.to_detail_string())); + throw; + } +} +BOOST_AUTO_TEST_CASE( api_limit_get_order_book ){ + try{ + graphene::app::database_api db_api( db, &( app.get_options() )); + //account_id_type() do 3 ops + create_bitasset("USD", account_id_type()); + create_account("dan"); + create_account("bob"); + asset_id_type bit_jmj_id = create_bitasset("JMJBIT").id; + generate_block(); + fc::usleep(fc::milliseconds(2000)); + GRAPHENE_CHECK_THROW(db_api.get_order_book(std::string(static_cast(asset_id_type())), std::string(static_cast(bit_jmj_id)),89), fc::exception); + }catch (fc::exception& e) { + edump((e.to_detail_string())); + throw; + } +} BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/tests/grouped_orders_api_tests.cpp b/tests/tests/grouped_orders_api_tests.cpp new file mode 100644 index 0000000000..289a3106cc --- /dev/null +++ b/tests/tests/grouped_orders_api_tests.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2018 oxarbitrage, and contributors. + * + * The MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include +#include + +#include "../common/database_fixture.hpp" + +using namespace graphene::chain; +using namespace graphene::chain::test; +using namespace graphene::app; + +BOOST_FIXTURE_TEST_SUITE(grouped_orders_api_tests, database_fixture) +BOOST_AUTO_TEST_CASE(api_limit_get_grouped_limit_orders) { + try + { + app.enable_plugin("grouped_orders"); + graphene::app::orders_api orders_api(app); + optional< api_access_info > acc; + optional start; + + //account_id_type() do 3 ops + create_bitasset("USD", account_id_type()); + create_account("dan"); + create_account("bob"); + asset_id_type bit_jmj_id = create_bitasset("JMJBIT").id; + generate_block(); + fc::usleep(fc::milliseconds(2000)); + GRAPHENE_CHECK_THROW(orders_api.get_grouped_limit_orders(std::string( static_cast(asset_id_type())), std::string( static_cast(asset_id_type())),10, start,260), fc::exception); + vector< limit_order_group > orders =orders_api.get_grouped_limit_orders(std::string( static_cast(asset_id_type())), std::string( static_cast(bit_jmj_id)), 10,start,240); + BOOST_REQUIRE_EQUAL( orders.size(), 0u); + }catch (fc::exception &e) + { + edump((e.to_detail_string())); + throw; + } +} +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/tests/history_api_tests.cpp b/tests/tests/history_api_tests.cpp index b5b8ef8199..dd3a497a37 100644 --- a/tests/tests/history_api_tests.cpp +++ b/tests/tests/history_api_tests.cpp @@ -603,5 +603,165 @@ BOOST_AUTO_TEST_CASE(get_account_history_operations) { throw; } } +//new test case for increasing the limit based on the config file +BOOST_AUTO_TEST_CASE(api_limit_get_account_history_operations) { + try { + graphene::app::history_api hist_api(app); + //account_id_type() do 3 ops + create_bitasset("CNY", account_id_type()); + create_account("sam"); + create_account("alice"); + + generate_block(); + fc::usleep(fc::milliseconds(2000)); + + int asset_create_op_id = operation::tag::value; + int account_create_op_id = operation::tag::value; + + //account_id_type() did 1 asset_create op + vector histories = hist_api.get_account_history_operations( + "committee-account", asset_create_op_id, operation_history_id_type(), operation_history_id_type(), 200); + BOOST_CHECK_EQUAL(histories.size(), 1u); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 0u); + BOOST_CHECK_EQUAL(histories[0].op.which(), asset_create_op_id); + + //account_id_type() did 2 account_create ops + histories = hist_api.get_account_history_operations( + "committee-account", account_create_op_id, operation_history_id_type(), operation_history_id_type(), 200); + BOOST_CHECK_EQUAL(histories.size(), 2u); + BOOST_CHECK_EQUAL(histories[0].op.which(), account_create_op_id); + + // No asset_create op larger than id1 + histories = hist_api.get_account_history_operations( + "committee-account", asset_create_op_id, operation_history_id_type(), operation_history_id_type(1), 200); + BOOST_CHECK_EQUAL(histories.size(), 0u); + + // Limit 1 returns 1 result + histories = hist_api.get_account_history_operations( + "committee-account", account_create_op_id, operation_history_id_type(),operation_history_id_type(), 1); + BOOST_CHECK_EQUAL(histories.size(), 1u); + BOOST_CHECK_EQUAL(histories[0].op.which(), account_create_op_id); + + // alice has 1 op + histories = hist_api.get_account_history_operations( + "alice", account_create_op_id, operation_history_id_type(),operation_history_id_type(), 200); + BOOST_CHECK_EQUAL(histories.size(), 1u); + BOOST_CHECK_EQUAL(histories[0].op.which(), account_create_op_id); + + // create a bunch of accounts + for(int i = 0; i < 126; ++i) + { + std::string acct_name = "mytempacct" + std::to_string(i); + create_account(acct_name); + } + generate_block(); + + // history is set to limit transactions to 125 (see database_fixture.hpp) + // so asking for more should only return 125 (and not throw exception, + // see https://github.com/bitshares/bitshares-core/issues/1490 + GRAPHENE_CHECK_THROW(hist_api.get_account_history_operations("commitee-account", account_create_op_id, operation_history_id_type(),operation_history_id_type(), 301), fc::exception); + histories = hist_api.get_account_history_operations("committee-account", account_create_op_id, operation_history_id_type(), operation_history_id_type(), 200); + BOOST_REQUIRE_EQUAL( histories.size(), 125u ); + } + catch (fc::exception &e) + { + edump((e.to_detail_string())); + throw; + } +} + +BOOST_AUTO_TEST_CASE(api_limit_get_account_history) { + try{ + graphene::app::history_api hist_api(app); + //account_id_type() do 3 ops + create_bitasset("USD", account_id_type()); + create_account("dan"); + create_account("bob"); + + generate_block(); + fc::usleep(fc::milliseconds(2000)); + + int asset_create_op_id = operation::tag::value; + int account_create_op_id = operation::tag::value; + //account_id_type() did 3 ops and includes id0 + vector histories = hist_api.get_account_history("1.2.0", operation_history_id_type(), 210, operation_history_id_type()); + + BOOST_CHECK_EQUAL(histories.size(), 3u); + BOOST_CHECK_EQUAL(histories[2].id.instance(), 0u); + BOOST_CHECK_EQUAL(histories[2].op.which(), asset_create_op_id); + + // 1 account_create op larger than id1 + histories = hist_api.get_account_history("1.2.0", operation_history_id_type(1), 210, operation_history_id_type()); + BOOST_CHECK_EQUAL(histories.size(), 1u); + BOOST_CHECK(histories[0].id.instance() != 0u); + BOOST_CHECK_EQUAL(histories[0].op.which(), account_create_op_id); + + + // Limit 2 returns 2 result + histories = hist_api.get_account_history("1.2.0", operation_history_id_type(), 2, operation_history_id_type()); + BOOST_CHECK_EQUAL(histories.size(), 2u); + BOOST_CHECK(histories[1].id.instance() != 0u); + BOOST_CHECK_EQUAL(histories[1].op.which(), account_create_op_id); + // bob has 1 op + histories = hist_api.get_account_history("bob", operation_history_id_type(), 210, operation_history_id_type()); + BOOST_CHECK_EQUAL(histories.size(), 1u); + BOOST_CHECK_EQUAL(histories[0].op.which(), account_create_op_id); + + // create a bunch of accounts + for(int i = 0; i < 126; ++i) + { + std::string acct_name = "mytempacct" + std::to_string(i); + create_account(acct_name); + } + generate_block(); + + GRAPHENE_CHECK_THROW(hist_api.get_account_history("1.2.0", operation_history_id_type(), 260, operation_history_id_type()), fc::exception); + histories = hist_api.get_account_history("1.2.0", operation_history_id_type(), 210, operation_history_id_type()); + BOOST_REQUIRE_EQUAL( histories.size(), 125u ); + } catch (fc::exception &e) { + edump((e.to_detail_string())); + throw; + } +} +BOOST_AUTO_TEST_CASE(api_limit_get_relative_account_history) { + try{ + graphene::app::history_api hist_api(app); + //account_id_type() do 3 ops + create_bitasset("USD", account_id_type()); + create_account("dan"); + create_account("bob"); + + generate_block(); + fc::usleep(fc::milliseconds(2000)); + + GRAPHENE_CHECK_THROW(hist_api.get_relative_account_history("1.2.0", 126, 260, 0), fc::exception); + vector histories = hist_api.get_relative_account_history("1.2.0", 126, 210, 0); + BOOST_REQUIRE_EQUAL( histories.size(), 0u ); + + } catch (fc::exception &e) { + edump((e.to_detail_string())); + throw; + } +} + +BOOST_AUTO_TEST_CASE(api_limit_get_account_history_by_operations) { + try { + graphene::app::history_api hist_api(app); + vector operation_types; + //account_id_type() do 3 ops + create_bitasset("USD", account_id_type()); + create_account("dan"); + create_account("bob"); + generate_block(); + fc::usleep(fc::milliseconds(2000)); + GRAPHENE_CHECK_THROW(hist_api.get_account_history_by_operations("1.2.0", operation_types, 0, 260), fc::exception); + history_operation_detail histories = hist_api.get_account_history_by_operations("1.2.0", operation_types, 0, 210); + BOOST_REQUIRE_EQUAL( histories.total_count, 3u ); + } + catch (fc::exception &e) { + edump((e.to_detail_string())); + throw; + } +} BOOST_AUTO_TEST_SUITE_END()