From 55255010df16f2c271a1057e6d611040f475b65f Mon Sep 17 00:00:00 2001 From: Eric Frias Date: Wed, 14 Sep 2016 11:52:22 -0400 Subject: [PATCH] Add get_upcoming_tournaments wallet call, clean up logging --- libraries/app/database_api.cpp | 12 ++-- .../app/include/graphene/app/database_api.hpp | 2 +- libraries/chain/db_update.cpp | 3 +- .../graphene/chain/tournament_object.hpp | 6 ++ libraries/chain/tournament_evaluator.cpp | 17 ------ .../wallet/include/graphene/wallet/wallet.hpp | 7 +++ libraries/wallet/wallet.cpp | 57 +++++++++++++++++++ 7 files changed, 81 insertions(+), 23 deletions(-) diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index a00da930..eea83fb4 100644 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -139,7 +139,7 @@ class database_api_impl : public std::enable_shared_from_this vector get_blinded_balances( const flat_set& commitments )const; // Tournaments - vector get_upcoming_tournaments(fc::optional account_filter)const; + vector get_upcoming_tournaments(fc::optional account_filter, uint32_t limit)const; //private: template @@ -1768,21 +1768,25 @@ vector database_api_impl::get_blinded_balances( const fl // // ////////////////////////////////////////////////////////////////////// -vector database_api::get_upcoming_tournaments(fc::optional account_filter)const +vector database_api::get_upcoming_tournaments(fc::optional account_filter, uint32_t limit)const { - return my->get_upcoming_tournaments(account_filter); + return my->get_upcoming_tournaments(account_filter, limit); } -vector database_api_impl::get_upcoming_tournaments(fc::optional account_filter)const +vector database_api_impl::get_upcoming_tournaments(fc::optional account_filter, uint32_t limit)const { vector result; const auto& registration_deadline_index = _db.get_index_type().indices().get(); const auto range = registration_deadline_index.equal_range(boost::make_tuple(tournament_state::accepting_registrations)); for (const tournament_object& tournament_obj : boost::make_iterator_range(range.first, range.second)) + { if (tournament_obj.options.whitelist.empty() || !account_filter || tournament_obj.options.whitelist.find(*account_filter) != tournament_obj.options.whitelist.end()) result.emplace_back(tournament_obj); + if (result.size() >= limit) + break; + } return result; } diff --git a/libraries/app/include/graphene/app/database_api.hpp b/libraries/app/include/graphene/app/database_api.hpp index 8d671a42..56b0573e 100644 --- a/libraries/app/include/graphene/app/database_api.hpp +++ b/libraries/app/include/graphene/app/database_api.hpp @@ -557,7 +557,7 @@ class database_api * allowed to join (public tournaments or tournaments the account is whitelisted for) * @return the list of tournaments that are still accepting new registrations */ - vector get_upcoming_tournaments(fc::optional account_filter)const; + vector get_upcoming_tournaments(fc::optional account_filter, uint32_t limit)const; private: std::shared_ptr< database_api_impl > my; diff --git a/libraries/chain/db_update.cpp b/libraries/chain/db_update.cpp index 5bb968d7..8efdf5f4 100644 --- a/libraries/chain/db_update.cpp +++ b/libraries/chain/db_update.cpp @@ -502,7 +502,8 @@ void database::update_tournaments() { // find the first tournament waiting to start; if its start time has arrived, start it auto start_iter = start_time_index.lower_bound(boost::make_tuple(tournament_state::awaiting_start)); - if (start_iter->get_state() == tournament_state::awaiting_start && + if (start_iter != start_time_index.end() && + start_iter->get_state() == tournament_state::awaiting_start && *start_iter->start_time <= head_block_time()) { modify(*start_iter, [&](tournament_object& t) { diff --git a/libraries/chain/include/graphene/chain/tournament_object.hpp b/libraries/chain/include/graphene/chain/tournament_object.hpp index 2b58cb66..6e902fdc 100644 --- a/libraries/chain/include/graphene/chain/tournament_object.hpp +++ b/libraries/chain/include/graphene/chain/tournament_object.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include namespace graphene { namespace chain { @@ -168,6 +169,9 @@ namespace graphene { namespace chain { // fc::raw::pack the contents hidden in the impl class std::ostringstream stream; tournament_obj.pack_impl(stream); + std::string stringified_stream(stream.str()); + fc_elog(fc::logger::get("tournament"), "Serialized state ${state} to bytes ${bytes}", + ("state", tournament_obj.get_state())("bytes", fc::to_hex(stringified_stream.c_str(), stringified_stream.size()))); fc::raw::pack(s, stream.str()); return s; @@ -192,6 +196,8 @@ namespace graphene { namespace chain { fc::raw::unpack(s, stringified_stream); std::istringstream stream(stringified_stream); tournament_obj.unpack_impl(stream); + fc_elog(fc::logger::get("tournament"), "Deserialized state ${state} from bytes ${bytes}", + ("state", tournament_obj.get_state())("bytes", fc::to_hex(stringified_stream.c_str(), stringified_stream.size()))); return s; } diff --git a/libraries/chain/tournament_evaluator.cpp b/libraries/chain/tournament_evaluator.cpp index 0f570cdd..8ba4d663 100644 --- a/libraries/chain/tournament_evaluator.cpp +++ b/libraries/chain/tournament_evaluator.cpp @@ -93,69 +93,52 @@ namespace graphene { namespace chain { void_result tournament_join_evaluator::do_evaluate( const tournament_join_operation& op ) { try { - fc_ilog(fc::logger::get("tournament"), ".",); const database& d = db(); - fc_ilog(fc::logger::get("tournament"), ".",); _tournament_obj = &op.tournament_id(d); fc_ilog(fc::logger::get("tournament"), "details_id = ${id}",("id", _tournament_obj->tournament_details_id)); _tournament_details_obj = &_tournament_obj->tournament_details_id(d); - fc_ilog(fc::logger::get("tournament"), ".",); _payer_account = &op.payer_account_id(d); - fc_ilog(fc::logger::get("tournament"), ".",); //const account_object& player_account = op.player_account_id(d); _buy_in_asset_type = &op.buy_in.asset_id(d); - fc_ilog(fc::logger::get("tournament"), ".",); // TODO FC_ASSERT(_tournament_obj->state == tournament_state::accepting_registrations); FC_ASSERT(_tournament_details_obj->registered_players.size() < _tournament_obj->options.number_of_players, "Tournament is already full"); - fc_ilog(fc::logger::get("tournament"), ".",); FC_ASSERT(d.head_block_time() <= _tournament_obj->options.registration_deadline, "Registration deadline has already passed"); - fc_ilog(fc::logger::get("tournament"), ".",); FC_ASSERT(_tournament_obj->options.whitelist.empty() || _tournament_obj->options.whitelist.find(op.player_account_id) == _tournament_obj->options.whitelist.end(), "Player is not on the whitelist for this tournament"); - fc_ilog(fc::logger::get("tournament"), ".",); FC_ASSERT(_tournament_details_obj->registered_players.find(op.player_account_id) == _tournament_details_obj->registered_players.end(), "Player is already registered for this tournament"); - fc_ilog(fc::logger::get("tournament"), ".",); FC_ASSERT(op.buy_in == _tournament_obj->options.buy_in, "Buy-in is incorrect"); - fc_ilog(fc::logger::get("tournament"), ".",); GRAPHENE_ASSERT(!_buy_in_asset_type->is_transfer_restricted(), transfer_restricted_transfer_asset, "Asset {asset} has transfer_restricted flag enabled", ("asset", op.buy_in.asset_id)); - fc_ilog(fc::logger::get("tournament"), ".",); GRAPHENE_ASSERT(is_authorized_asset(d, *_payer_account, *_buy_in_asset_type), transfer_from_account_not_whitelisted, "payer account ${payer} is not whitelisted for asset ${asset}", ("payer", op.payer_account_id) ("asset", op.buy_in.asset_id)); - fc_ilog(fc::logger::get("tournament"), ".",); bool sufficient_balance = d.get_balance(*_payer_account, *_buy_in_asset_type).amount >= op.buy_in.amount; - fc_ilog(fc::logger::get("tournament"), ".",); FC_ASSERT(sufficient_balance, "Insufficient Balance: paying account '${payer}' has insufficient balance to pay buy-in of ${buy_in} (balance is ${balance})", ("payer", _payer_account->name) ("buy_in", d.to_pretty_string(op.buy_in)) ("balance",d.to_pretty_string(d.get_balance(*_payer_account, *_buy_in_asset_type)))); - fc_ilog(fc::logger::get("tournament"), ".",); return void_result(); } FC_CAPTURE_AND_RETHROW( (op) ) } void_result tournament_join_evaluator::do_apply( const tournament_join_operation& op ) { try { - fc_ilog(fc::logger::get("tournament"), "in do_apply",); db().modify(*_tournament_obj, [&](tournament_object& tournament_obj){ - fc_ilog(fc::logger::get("tournament"), "in do_apply's modify",); tournament_obj.on_player_registered(db(), op.payer_account_id, op.player_account_id); - fc_ilog(fc::logger::get("tournament"), "in do_apply's modify after event",); }); return void_result(); } FC_CAPTURE_AND_RETHROW( (op) ) } diff --git a/libraries/wallet/include/graphene/wallet/wallet.hpp b/libraries/wallet/include/graphene/wallet/wallet.hpp index 6d0f3856..b226d9c5 100644 --- a/libraries/wallet/include/graphene/wallet/wallet.hpp +++ b/libraries/wallet/include/graphene/wallet/wallet.hpp @@ -1419,6 +1419,12 @@ class wallet_api */ signed_transaction tournament_join( string payer_account, string player_account, tournament_id_type tournament_id, string buy_in_amount, string buy_in_asset_symbol, bool broadcast = false ); + /** Get a list of upcoming tournaments + * @param player_accounts if non-empty, only return tournaments for which at least one of the named players is eligible. If empty, return all tournaments + * @param limit the number of tournaments to return + */ + vector get_upcoming_tournaments(optional player_accounts, uint32_t limit); + void dbg_make_uia(string creator, string symbol); void dbg_make_mia(string creator, string symbol); void flood_network(string prefix, uint32_t number_of_transactions); @@ -1608,4 +1614,5 @@ FC_API( graphene::wallet::wallet_api, (receive_blind_transfer) (tournament_create) (tournament_join) + (get_upcoming_tournaments) ) diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index a1754c3d..22ab9cef 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -2172,6 +2172,55 @@ public: } return ss.str(); }; + m["get_upcoming_tournaments"] = [this](variant result, const fc::variants& a) + { + const vector tournaments = result.as >(); + std::stringstream ss; + ss << tournaments.size() << " upcoming tournaments:\n"; + ss << "====================================================================================\n"; + for( const tournament_object& tournament_obj : tournaments ) + { + asset_object buy_in_asset = get_asset(tournament_obj.options.buy_in.asset_id); + ss << fc::variant(tournament_obj.id).as() << " " + << fc::variant(game_type(tournament_obj.options.type_of_game)).as() << " " + << buy_in_asset.amount_to_pretty_string(tournament_obj.options.buy_in.amount) << " " + << tournament_obj.options.number_of_players << " players\n"; + switch (tournament_obj.get_state()) + { + case tournament_state::accepting_registrations: + { + ss << " Waiting for players, " << tournament_obj.registered_players << " of " << tournament_obj.options.number_of_players << " have registered\n"; + ss << " If enough players register, the game will start "; + if (tournament_obj.options.start_time) + ss << "at " << tournament_obj.options.start_time->to_iso_string() << "\n"; + else + ss << *tournament_obj.options.start_delay << " seconds after the last player registers\n"; + break; + } + case tournament_state::awaiting_start: + { + ss << " All players have registered, tournament will start at " << tournament_obj.start_time->to_iso_string() << "\n"; + break; + } + case tournament_state::in_progress: + { + ss << " Tournament started at " << tournament_obj.start_time->to_iso_string() << "\n"; + break; + } + case tournament_state::registration_period_expired: + { + ss << " Tournament was canceled at " << tournament_obj.options.registration_deadline.to_iso_string() << ", not enough players registered\n"; + break; + } + case tournament_state::concluded: + { + ss << " Tournament finished at " << tournament_obj.end_time->to_iso_string() << "\n"; + break; + } + } + } + return ss.str(); + }; return m; } @@ -4143,6 +4192,14 @@ signed_transaction wallet_api::tournament_join( string payer_account, return my->sign_transaction( tx, broadcast ); } +vector wallet_api::get_upcoming_tournaments(fc::optional player_account, uint32_t limit) +{ + fc::optional player_account_id; + if (player_account) + player_account_id = get_account(*player_account).id; + return my->_remote_db->get_upcoming_tournaments(player_account_id, limit); +} + // default ctor necessary for FC_REFLECT signed_block_with_info::signed_block_with_info() {