From ea3818cf4f48568482056a3df4248205ae151fe7 Mon Sep 17 00:00:00 2001 From: Roman Olearski Date: Fri, 21 Jul 2017 13:42:15 +0200 Subject: [PATCH] extended event_update_operation --- libraries/chain/event_evaluator.cpp | 19 ++- libraries/chain/event_group_evaluator.cpp | 4 +- .../include/graphene/chain/protocol/event.hpp | 4 +- .../wallet/include/graphene/wallet/wallet.hpp | 1 + libraries/wallet/wallet.cpp | 2 + tests/betting/betting_tests.cpp | 158 ++++++++++++++---- tests/common/database_fixture.cpp | 6 +- tests/common/database_fixture.hpp | 7 +- 8 files changed, 157 insertions(+), 44 deletions(-) diff --git a/libraries/chain/event_evaluator.cpp b/libraries/chain/event_evaluator.cpp index 476af6c3..6166b937 100644 --- a/libraries/chain/event_evaluator.cpp +++ b/libraries/chain/event_evaluator.cpp @@ -48,7 +48,7 @@ void_result event_create_evaluator::do_evaluate(const event_create_operation& op resolved_event_group_id.type() == event_group_id_type::type_id, "event_group_id must refer to a event_group_id_type"); event_group_id = resolved_event_group_id; - const event_group_object& event_group = event_group_id(d); + //const event_group_object& event_group = event_group_id(d); return void_result(); } FC_CAPTURE_AND_RETHROW( (op) ) } @@ -74,7 +74,20 @@ object_id_type event_create_evaluator::do_apply(const event_create_operation& op void_result event_update_evaluator::do_evaluate(const event_update_operation& op) { try { FC_ASSERT(trx_state->_is_proposed_trx); - FC_ASSERT(op.new_name.valid() || op.new_season.valid() || op.new_start_time.valid()); + FC_ASSERT(op.new_event_group_id.valid() || op.new_name.valid() || op.new_season.valid() || op.new_start_time.valid(), "nothing to change"); + + if (op.new_event_group_id.valid()) + { + object_id_type resolved_event_group_id = *op.new_event_group_id; + if (is_relative(*op.new_event_group_id)) + resolved_event_group_id = get_relative_id(*op.new_event_group_id); + + FC_ASSERT(resolved_event_group_id.space() == event_group_id_type::space_id && + resolved_event_group_id.type() == event_group_id_type::type_id, + "event_group_id must refer to a event_group_id_type"); + event_group_id = resolved_event_group_id; + } + return void_result(); } FC_CAPTURE_AND_RETHROW( (op) ) } @@ -91,6 +104,8 @@ void_result event_update_evaluator::do_apply(const event_update_operation& op) eo.season = *op.new_season; if( op.new_start_time.valid() ) eo.start_time = *op.new_start_time; + if( op.new_event_group_id.valid() ) + eo.event_group_id = event_group_id; }); return void_result(); } FC_CAPTURE_AND_RETHROW( (op) ) } diff --git a/libraries/chain/event_group_evaluator.cpp b/libraries/chain/event_group_evaluator.cpp index ccae6786..1435bcd0 100644 --- a/libraries/chain/event_group_evaluator.cpp +++ b/libraries/chain/event_group_evaluator.cpp @@ -63,7 +63,7 @@ object_id_type event_group_create_evaluator::do_apply(const event_group_create_o void_result event_group_update_evaluator::do_evaluate(const event_group_update_operation& op) { try { FC_ASSERT(trx_state->_is_proposed_trx); - FC_ASSERT(op.new_sport_id.valid() || op.new_name.valid()); + FC_ASSERT(op.new_sport_id.valid() || op.new_name.valid(), "nothing to change"); if( op.new_sport_id.valid() ) { object_id_type resolved_id = *op.new_sport_id; @@ -74,7 +74,7 @@ void_result event_group_update_evaluator::do_evaluate(const event_group_update_o resolved_id.type() == sport_id_type::type_id, "sport_id must refer to a sport_id_type"); sport_id = resolved_id; - FC_ASSERT( db().find_object(sport_id), "Invalid sport specified" ); + FC_ASSERT( db().find_object(sport_id), "invalid sport specified" ); } return void_result(); } FC_CAPTURE_AND_RETHROW( (op) ) } diff --git a/libraries/chain/include/graphene/chain/protocol/event.hpp b/libraries/chain/include/graphene/chain/protocol/event.hpp index 02ed7085..4a1ee896 100644 --- a/libraries/chain/include/graphene/chain/protocol/event.hpp +++ b/libraries/chain/include/graphene/chain/protocol/event.hpp @@ -61,6 +61,8 @@ struct event_update_operation : public base_operation event_id_type event_id; + optional new_event_group_id; + optional new_name; optional new_season; @@ -128,7 +130,7 @@ FC_REFLECT( graphene::chain::event_create_operation, FC_REFLECT( graphene::chain::event_update_operation::fee_parameters_type, (fee) ) FC_REFLECT( graphene::chain::event_update_operation, - (fee)(event_id)(new_name)(new_season)(new_start_time)(extensions) ) + (fee)(event_id)(new_event_group_id)(new_name)(new_season)(new_start_time)(extensions) ) FC_REFLECT_ENUM( graphene::chain::event_status, (upcoming)(in_progress)(frozen)(completed)(canceled)(STATUS_COUNT) ) FC_REFLECT( graphene::chain::event_update_status_operation::fee_parameters_type, (fee) ) diff --git a/libraries/wallet/include/graphene/wallet/wallet.hpp b/libraries/wallet/include/graphene/wallet/wallet.hpp index 6826550d..2639a546 100644 --- a/libraries/wallet/include/graphene/wallet/wallet.hpp +++ b/libraries/wallet/include/graphene/wallet/wallet.hpp @@ -1617,6 +1617,7 @@ class wallet_api const string& proposing_account, event_id_type event_id, fc::time_point_sec expiration_time, + fc::optional event_group_id, fc::optional name, fc::optional season, fc::optional start_time, diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index d4d705c9..2ff4545b 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -5173,6 +5173,7 @@ signed_transaction wallet_api::propose_update_event( const string& proposing_account, event_id_type event_id, fc::time_point_sec expiration_time, + fc::optional event_group_id, fc::optional name, fc::optional season, fc::optional start_time, @@ -5183,6 +5184,7 @@ signed_transaction wallet_api::propose_update_event( event_update_operation event_update_op; event_update_op.event_id = event_id; + event_update_op.new_event_group_id = event_group_id; event_update_op.new_start_time = start_time; event_update_op.new_name = name; event_update_op.new_season = season; diff --git a/tests/betting/betting_tests.cpp b/tests/betting/betting_tests.cpp index 8a38546a..6d6042df 100644 --- a/tests/betting/betting_tests.cpp +++ b/tests/betting/betting_tests.cpp @@ -220,27 +220,6 @@ BOOST_AUTO_TEST_CASE(peerplays_event_group_update_test) update_event_group(nhl.id, sport_id, fc::optional()); update_event_group(nhl.id, sport_id, name); -#if 0 - // nothing to change - //GRAPHENE_REQUIRE_THROW(update_event_group(nhl.id, fc::optional(), fc::optional()), fc::assert_exception); - try - { - update_event_group(nhl.id, fc::optional(), fc::optional()); - FC_ASSERT(false, "expected error hasn't occured"); - } - catch (fc::exception& e) - { - edump((e.code())); - } - - // no sport object - //object_id = capitals_win_market.id; - //sport_id = object_id; - //GRAPHENE_REQUIRE_THROW(update_event_group(nhl.id, sport_id, name), fc::assert_exception); - - // sport object doesn't exist -#endif - place_bet(bob_id, capitals_win_market.id, bet_type::lay, asset(1000000, asset_id_type()), 2 * GRAPHENE_BETTING_ODDS_PRECISION, 1000000 / 50 /* chain defaults to 2% fees */); BOOST_CHECK_EQUAL(get_balance(alice_id, asset_id_type()), 10000000 - 1000000 - 20000); @@ -258,14 +237,7 @@ BOOST_AUTO_TEST_CASE(peerplays_event_group_update_test) BOOST_CHECK_EQUAL(get_balance(alice_id, asset_id_type()), 10000000 - 1000000 - 20000 + 2000000 - rake_value); BOOST_CHECK_EQUAL(get_balance(bob_id, asset_id_type()), 10000000 - 1000000 - 20000); - } - catch (fc::exception& e) - { - edump((e.to_detail_string())); - throw; - } - //} FC_LOG_AND_RETHROW() - + } FC_LOG_AND_RETHROW() } @@ -273,26 +245,49 @@ BOOST_AUTO_TEST_CASE(peerplays_event_update_test) { try { - ACTORS( (alice) ); + ACTORS( (alice)(bob) ); CREATE_ICE_HOCKEY_BETTING_MARKET(); + transfer(account_id_type(), alice_id, asset(10000000)); + transfer(account_id_type(), bob_id, asset(10000000)); + + place_bet(alice_id, capitals_win_market.id, bet_type::back, asset(1000000, asset_id_type()), 2 * GRAPHENE_BETTING_ODDS_PRECISION, 1000000 / 50 /* chain defaults to 2% fees */); + internationalized_string_type n = {{"en", "Washington Capitals vs. Chicago Blackhawks"}, {"zh_Hans", "華盛頓首都隊/芝加哥黑"}, {"ja", "ワシントン・キャピタルズ/シカゴ・ブラックホーク"}}; internationalized_string_type s = {{"en", "2017-18"}}; fc::optional empty; fc::optional name = n; fc::optional season = s; + fc::optional empty_object_id; - update_event(capitals_vs_blackhawks.id, name, empty); - update_event(capitals_vs_blackhawks.id, empty, season); - update_event(capitals_vs_blackhawks.id, name, season); + update_event(capitals_vs_blackhawks.id, empty_object_id, name, empty); + update_event(capitals_vs_blackhawks.id, empty_object_id, empty, season); + update_event(capitals_vs_blackhawks.id, empty_object_id, name, season); - transfer(account_id_type(), alice_id, asset(10000000)); - place_bet(alice_id, capitals_win_market.id, bet_type::back, asset(1000000, asset_id_type()), 2 * GRAPHENE_BETTING_ODDS_PRECISION, 1000000 / 50 /* chain defaults to 2% fees */); + const sport_object& ice_on_hockey = create_sport({{"en", "Hockey on Ice"}, {"zh_Hans", "冰球"}, {"ja", "アイスホッケー"}}); \ + const event_group_object& nhl2 = create_event_group({{"en", "NHL2"}, {"zh_Hans", "國家冰球聯盟"}, {"ja", "ナショナルホッケーリーグ"}}, ice_on_hockey.id); \ + object_id_type object_id = nhl2.id; + fc::optional event_group_id = object_id; + + update_event(capitals_vs_blackhawks.id, event_group_id , empty, empty); + + place_bet(bob_id, capitals_win_market.id, bet_type::lay, asset(1000000, asset_id_type()), 2 * GRAPHENE_BETTING_ODDS_PRECISION, 1000000 / 50 /* chain defaults to 2% fees */); BOOST_CHECK_EQUAL(get_balance(alice_id, asset_id_type()), 10000000 - 1000000 - 20000); + BOOST_CHECK_EQUAL(get_balance(bob_id, asset_id_type()), 10000000 - 1000000 - 20000); - //GRAPHENE_REQUIRE_THROW(update_event(capitals_vs_blackhawks.id, empty, empty), fc::exception); + // caps win + resolve_betting_market_group(moneyline_betting_markets.id, + {{capitals_win_market.id, betting_market_resolution_type::win}, + {blackhawks_win_market.id, betting_market_resolution_type::cancel}}); + + + uint16_t rake_fee_percentage = db.get_global_properties().parameters.betting_rake_fee_percentage; + uint32_t rake_value = (-1000000 + 2000000) * rake_fee_percentage / GRAPHENE_1_PERCENT / 100; + BOOST_TEST_MESSAGE("Rake value " + std::to_string(rake_value)); + BOOST_CHECK_EQUAL(get_balance(alice_id, asset_id_type()), 10000000 - 1000000 - 20000 + 2000000 - rake_value); + BOOST_CHECK_EQUAL(get_balance(bob_id, asset_id_type()), 10000000 - 1000000 - 20000); } FC_LOG_AND_RETHROW() } @@ -593,6 +588,97 @@ struct simple_bet_test_fixture_2 : database_fixture { } }; + +BOOST_AUTO_TEST_SUITE(other_betting_tests) + +#define TRY_EXPECT_THROW( expr, exc_type, reason ) \ +{ \ + try \ + { \ + expr; \ + FC_THROW("no error has occured"); \ + } \ + catch (exc_type& e) \ + { \ + edump(("###")); \ + edump((e.to_detail_string())); \ + edump(("###")); \ + FC_ASSERT(e.to_detail_string().find(reason) != \ + std::string::npos, "expected error hasn't occured");\ + } \ + catch (...) \ + { \ + FC_THROW("expected throw hasn't occured"); \ + } \ +} + +BOOST_FIXTURE_TEST_CASE( another_peerplays_event_group_update_test, database_fixture) +{ + try + { + ACTORS( (alice)(bob) ); + CREATE_ICE_HOCKEY_BETTING_MARKET(); + + transfer(account_id_type(), alice_id, asset(10000000)); + transfer(account_id_type(), bob_id, asset(10000000)); + + place_bet(alice_id, capitals_win_market.id, bet_type::back, asset(1000000, asset_id_type()), 2 * GRAPHENE_BETTING_ODDS_PRECISION, 1000000 / 50 /* chain defaults to 2% fees */); + + internationalized_string_type n = {{"en", "IBM"}, {"zh_Hans", "國家冰球聯"}, {"ja", "ナショナルホッケーリー"}}; + const sport_object& ice_on_hockey = create_sport({{"en", "Hockey on Ice"}, {"zh_Hans", "冰球"}, {"ja", "アイスホッケー"}}); \ + + fc::optional name = n; + + object_id_type object_id = ice_on_hockey.id; + fc::optional sport_id = object_id; + + update_event_group(nhl.id, fc::optional(), name); + update_event_group(nhl.id, sport_id, fc::optional()); + update_event_group(nhl.id, sport_id, name); + + // #! nothing to change + update_event_group(nhl.id, fc::optional(), fc::optional()); + //GRAPHENE_REQUIRE_THROW(update_event_group(nhl.id, fc::optional(), fc::optional()), fc::exception); + //TRY_EXPECT_THROW(update_event_group(nhl.id, fc::optional(), fc::optional()), fc::exception, "nothing to change" ); + + // #! sport_id must refer to a sport_id_type + object_id = capitals_win_market.id; + sport_id = object_id; + update_event_group(nhl.id, sport_id, fc::optional()); + + // #! invalid sport specified + object_id = sport_id_type(13); + sport_id = object_id; + update_event_group(nhl.id, sport_id, fc::optional()); + + place_bet(bob_id, capitals_win_market.id, bet_type::lay, asset(1000000, asset_id_type()), 2 * GRAPHENE_BETTING_ODDS_PRECISION, 1000000 / 50 /* chain defaults to 2% fees */); + + BOOST_CHECK_EQUAL(get_balance(alice_id, asset_id_type()), 10000000 - 1000000 - 20000); + BOOST_CHECK_EQUAL(get_balance(bob_id, asset_id_type()), 10000000 - 1000000 - 20000); + + // caps win + resolve_betting_market_group(moneyline_betting_markets.id, + {{capitals_win_market.id, betting_market_resolution_type::win}, + {blackhawks_win_market.id, betting_market_resolution_type::cancel}}); + + + uint16_t rake_fee_percentage = db.get_global_properties().parameters.betting_rake_fee_percentage; + uint32_t rake_value = (-1000000 + 2000000) * rake_fee_percentage / GRAPHENE_1_PERCENT / 100; + BOOST_TEST_MESSAGE("Rake value " + std::to_string(rake_value)); + BOOST_CHECK_EQUAL(get_balance(alice_id, asset_id_type()), 10000000 - 1000000 - 20000 + 2000000 - rake_value); + BOOST_CHECK_EQUAL(get_balance(bob_id, asset_id_type()), 10000000 - 1000000 - 20000); + } + catch (fc::exception& e) + { + edump((e.to_detail_string())); + throw; + } + //} FC_LOG_AND_RETHROW() +} + +BOOST_AUTO_TEST_SUITE_END() + + //#define BOOST_TEST_MODULE "C++ Unit Tests for Graphene Blockchain Database" #include #include diff --git a/tests/common/database_fixture.cpp b/tests/common/database_fixture.cpp index cf029035..caaadc21 100644 --- a/tests/common/database_fixture.cpp +++ b/tests/common/database_fixture.cpp @@ -1247,10 +1247,14 @@ const event_object& database_fixture::create_event(internationalized_string_type return *event_index.rbegin(); } FC_CAPTURE_AND_RETHROW( (event_group_id) ) } -void database_fixture::update_event(event_id_type event_id, fc::optional name, fc::optional season) +void database_fixture::update_event(event_id_type event_id, + fc::optional event_group_id, + fc::optional name, + fc::optional season) { try { event_update_operation event_update_op; event_update_op.event_id = event_id; + event_update_op.new_event_group_id = event_group_id; event_update_op.new_name = name; event_update_op.new_season = season; process_operation_by_witnesses(event_update_op); diff --git a/tests/common/database_fixture.hpp b/tests/common/database_fixture.hpp index f86bb2df..a27d5b99 100644 --- a/tests/common/database_fixture.hpp +++ b/tests/common/database_fixture.hpp @@ -290,8 +290,11 @@ struct database_fixture { const event_group_object& create_event_group(internationalized_string_type name, sport_id_type sport_id); void update_event_group(event_group_id_type event_group_id, fc::optional sport_id, fc::optional name); const event_object& create_event(internationalized_string_type name, internationalized_string_type season, event_group_id_type event_group_id); - void update_event(event_id_type event_id, fc::optional name, fc::optional season); - const betting_market_rules_object& create_betting_market_rules(internationalized_string_type name, internationalized_string_type description); + void update_event(event_id_type event_id, + fc::optional event_group_id, + fc::optional name, + fc::optional season); + const betting_market_rules_object& create_betting_market_rules(internationalized_string_type name, internationalized_string_type description); void update_betting_market_rules(betting_market_rules_id_type rules_id, fc::optional name, fc::optional description);