diff --git a/libraries/app/impacted.cpp b/libraries/app/impacted.cpp index 4f35e797..61c0b0f7 100644 --- a/libraries/app/impacted.cpp +++ b/libraries/app/impacted.cpp @@ -212,6 +212,7 @@ struct get_impacted_account_visitor void operator()( const sport_create_operation& op ) {} void operator()( const sport_update_operation& op ) {} void operator()( const event_group_create_operation& op ) {} + void operator()( const event_group_update_operation& op ) {} void operator()( const event_create_operation& op ) {} void operator()( const betting_market_rules_create_operation& op ) {} void operator()( const betting_market_group_create_operation& op ) {} diff --git a/libraries/chain/db_init.cpp b/libraries/chain/db_init.cpp index 712e9d6b..f19dfa71 100644 --- a/libraries/chain/db_init.cpp +++ b/libraries/chain/db_init.cpp @@ -217,6 +217,7 @@ void database::initialize_evaluators() register_evaluator(); register_evaluator(); register_evaluator(); + register_evaluator(); register_evaluator(); register_evaluator(); register_evaluator(); diff --git a/libraries/chain/db_notify.cpp b/libraries/chain/db_notify.cpp index f83f1eb7..d42f57d5 100644 --- a/libraries/chain/db_notify.cpp +++ b/libraries/chain/db_notify.cpp @@ -194,6 +194,7 @@ struct get_impacted_account_visitor void operator()(const sport_create_operation&){} void operator()(const sport_update_operation&){} void operator()(const event_group_create_operation&){} + void operator()(const event_group_update_operation& op ) {} void operator()(const event_create_operation&){} void operator()(const betting_market_rules_create_operation&){} void operator()(const betting_market_group_create_operation&){} diff --git a/libraries/chain/event_group_evaluator.cpp b/libraries/chain/event_group_evaluator.cpp index 1f37afd9..139613eb 100644 --- a/libraries/chain/event_group_evaluator.cpp +++ b/libraries/chain/event_group_evaluator.cpp @@ -60,4 +60,25 @@ object_id_type event_group_create_evaluator::do_apply(const event_group_create_o return new_event_group.id; } FC_CAPTURE_AND_RETHROW( (op) ) } +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_name.valid()); + return void_result(); +} FC_CAPTURE_AND_RETHROW( (op) ) } + +void_result event_group_update_evaluator::do_apply(const event_group_update_operation& op) +{ try { + database& _db = db(); + _db.modify( + _db.get(op.event_group_id), + [&]( event_group_object& ego ) + { + if( op.new_name.valid() ) + ego.name = *op.new_name; + }); + return void_result(); +} FC_CAPTURE_AND_RETHROW( (op) ) } + + } } // graphene::chain diff --git a/libraries/chain/include/graphene/chain/event_group_evaluator.hpp b/libraries/chain/include/graphene/chain/event_group_evaluator.hpp index 2160a0c2..1feda1c0 100644 --- a/libraries/chain/include/graphene/chain/event_group_evaluator.hpp +++ b/libraries/chain/include/graphene/chain/event_group_evaluator.hpp @@ -41,4 +41,15 @@ namespace graphene { namespace chain { sport_id_type sport_id; }; + class event_group_update_evaluator : public evaluator + { + public: + typedef event_group_update_operation operation_type; + + void_result do_evaluate( const event_group_update_operation& o ); + void_result do_apply( const event_group_update_operation& o ); + + private: + sport_id_type sport_id; + }; } } // graphene::chain diff --git a/libraries/chain/include/graphene/chain/protocol/event_group.hpp b/libraries/chain/include/graphene/chain/protocol/event_group.hpp index bf1cf2f1..242f6432 100644 --- a/libraries/chain/include/graphene/chain/protocol/event_group.hpp +++ b/libraries/chain/include/graphene/chain/protocol/event_group.hpp @@ -50,8 +50,28 @@ struct event_group_create_operation : public base_operation void validate()const; }; +struct event_group_update_operation : public base_operation +{ + struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; }; + asset fee; + + event_group_id_type event_group_id; + + optional new_name; + + extensions_type extensions; + + account_id_type fee_payer()const { return GRAPHENE_WITNESS_ACCOUNT; } + void validate()const; +}; + + } } FC_REFLECT( graphene::chain::event_group_create_operation::fee_parameters_type, (fee) ) FC_REFLECT( graphene::chain::event_group_create_operation, (fee)(name)(sport_id)(extensions) ) + +FC_REFLECT( graphene::chain::event_group_update_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::chain::event_group_update_operation, + (fee)(new_name)(event_group_id)(extensions) ) diff --git a/libraries/chain/include/graphene/chain/protocol/operations.hpp b/libraries/chain/include/graphene/chain/protocol/operations.hpp index 9ddc4276..13a03177 100644 --- a/libraries/chain/include/graphene/chain/protocol/operations.hpp +++ b/libraries/chain/include/graphene/chain/protocol/operations.hpp @@ -102,7 +102,7 @@ namespace graphene { namespace chain { sport_create_operation, sport_update_operation, event_group_create_operation, - /*event_group_update_operation,*/ + event_group_update_operation, event_create_operation, betting_market_rules_create_operation, betting_market_group_create_operation, diff --git a/libraries/chain/include/graphene/chain/sport_evaluator.hpp b/libraries/chain/include/graphene/chain/sport_evaluator.hpp index 39a85625..a35dc4e7 100644 --- a/libraries/chain/include/graphene/chain/sport_evaluator.hpp +++ b/libraries/chain/include/graphene/chain/sport_evaluator.hpp @@ -47,5 +47,4 @@ namespace graphene { namespace chain { void_result do_apply( const sport_update_operation& o ); }; - } } // graphene::chain diff --git a/libraries/chain/protocol/event_group.cpp b/libraries/chain/protocol/event_group.cpp index 85f74aae..ed003ef6 100644 --- a/libraries/chain/protocol/event_group.cpp +++ b/libraries/chain/protocol/event_group.cpp @@ -30,6 +30,10 @@ void event_group_create_operation::validate() const FC_ASSERT( fee.amount >= 0 ); } +void event_group_update_operation::validate() const +{ + FC_ASSERT( fee.amount >= 0 ); +} } } // graphene::chain diff --git a/libraries/wallet/include/graphene/wallet/wallet.hpp b/libraries/wallet/include/graphene/wallet/wallet.hpp index 3cf260cc..d962c6aa 100644 --- a/libraries/wallet/include/graphene/wallet/wallet.hpp +++ b/libraries/wallet/include/graphene/wallet/wallet.hpp @@ -1596,6 +1596,13 @@ class wallet_api sport_id_type sport_id, bool broadcast = false); + signed_transaction propose_update_event_group( + const string& proposing_account, + fc::time_point_sec expiration_time, + event_group_id_type event_group, + fc::optional name, + bool broadcast = false); + signed_transaction propose_create_event( const string& proposing_account, fc::time_point_sec expiration_time, diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 0772e88e..957b9445 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -5105,6 +5105,35 @@ signed_transaction wallet_api::propose_create_event_group( return my->sign_transaction(tx, broadcast); } +signed_transaction wallet_api::propose_update_event_group( + const string& proposing_account, + fc::time_point_sec expiration_time, + event_group_id_type event_group, + fc::optional name, + bool broadcast /*= false*/) +{ + FC_ASSERT( !is_locked() ); + const chain_parameters& current_params = get_global_properties().parameters; + + event_group_update_operation event_group_update_op; + event_group_update_op.new_name = name; + event_group_update_op.event_group_id = event_group; + + proposal_create_operation prop_op; + prop_op.expiration_time = expiration_time; + prop_op.review_period_seconds = current_params.committee_proposal_review_period; + prop_op.fee_paying_account = get_account(proposing_account).id; + prop_op.proposed_ops.emplace_back( event_group_update_op ); + current_params.current_fees->set_fee( prop_op.proposed_ops.back().op ); + + signed_transaction tx; + tx.operations.push_back(prop_op); + my->set_operation_fees(tx, current_params.current_fees); + tx.validate(); + + return my->sign_transaction(tx, broadcast); +} + signed_transaction wallet_api::propose_create_event( const string& proposing_account, fc::time_point_sec expiration_time, diff --git a/tests/betting/betting_tests.cpp b/tests/betting/betting_tests.cpp index d78e7edb..cf1206c3 100644 --- a/tests/betting/betting_tests.cpp +++ b/tests/betting/betting_tests.cpp @@ -186,7 +186,7 @@ BOOST_AUTO_TEST_CASE(peerplays_sport_update_test) { ACTORS( (alice) ); CREATE_ICE_HOCKEY_BETTING_MARKET(); - update_sport(ice_hockey.id, {{"en", "Hockey on Ice"}, {"zh_Hans", "冰球"}, {"ja", "アイスホッケー"}}); + update_sport(ice_hockey.id, {{"en", "Hockey on Ice"}, {"zh_Hans", "冰"}, {"ja", "アイスホッケ"}}); 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 */); @@ -194,8 +194,23 @@ BOOST_AUTO_TEST_CASE(peerplays_sport_update_test) BOOST_CHECK_EQUAL(get_balance(alice_id, asset_id_type()), 10000000 - 1000000 - 20000); } FC_LOG_AND_RETHROW() - } +} +BOOST_AUTO_TEST_CASE(peerplays_event_group_update_test) +{ + try + { + ACTORS( (alice) ); + CREATE_ICE_HOCKEY_BETTING_MARKET(); + update_event_group(nhl.id, {{"en", "IBM"}, {"zh_Hans", "國家冰球聯"}, {"ja", "ナショナルホッケーリー"}}); \ + + 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 */); + + BOOST_CHECK_EQUAL(get_balance(alice_id, asset_id_type()), 10000000 - 1000000 - 20000); + + } FC_LOG_AND_RETHROW() +} BOOST_AUTO_TEST_CASE( cancel_unmatched_in_betting_group_test ) { diff --git a/tests/common/database_fixture.cpp b/tests/common/database_fixture.cpp index 5e236fa4..df5eca63 100644 --- a/tests/common/database_fixture.cpp +++ b/tests/common/database_fixture.cpp @@ -1226,6 +1226,15 @@ const event_group_object& database_fixture::create_event_group(internationalized return *event_group_index.rbegin(); } FC_CAPTURE_AND_RETHROW( (name) ) } + +void database_fixture::update_event_group(event_group_id_type event_group_id, internationalized_string_type name) +{ try { + event_group_update_operation event_group_update_op; + event_group_update_op.new_name = name; + event_group_update_op.event_group_id = event_group_id; + process_operation_by_witnesses(event_group_update_op); +} FC_CAPTURE_AND_RETHROW( (name) ) } + const event_object& database_fixture::create_event(internationalized_string_type name, internationalized_string_type season, event_group_id_type event_group_id) { try { event_create_operation event_create_op; diff --git a/tests/common/database_fixture.hpp b/tests/common/database_fixture.hpp index 3cc56fab..5af87356 100644 --- a/tests/common/database_fixture.hpp +++ b/tests/common/database_fixture.hpp @@ -284,10 +284,11 @@ struct database_fixture { account_id_type dividend_holder_account_id, asset_id_type dividend_payout_asset_type) const; vector< operation_history_object > get_operation_history( account_id_type account_id )const; - void process_operation_by_witnesses(operation op); + void process_operation_by_witnesses(operation op); const sport_object& create_sport(internationalized_string_type name); void update_sport(sport_id_type sport_id, internationalized_string_type name); 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, internationalized_string_type name); const event_object& create_event(internationalized_string_type name, internationalized_string_type season, event_group_id_type event_group_id); const betting_market_rules_object& create_betting_market_rules(internationalized_string_type name, internationalized_string_type description); const betting_market_group_object& create_betting_market_group(internationalized_string_type description, event_id_type event_id, betting_market_rules_id_type rules_id, asset_id_type asset_id);