Scorum
post_game_results_evaluator.cpp
Go to the documentation of this file.
8 
9 #include <boost/algorithm/cxx11/any_of.hpp>
10 #include <boost/range/adaptor/filtered.hpp>
11 #include <boost/range/algorithm/transform.hpp>
12 #include <boost/range/algorithm/set_algorithm.hpp>
13 
14 namespace scorum {
15 namespace chain {
19  : evaluator_impl<data_service_factory_i, post_game_results_evaluator>(services)
20  , _account_service(services.account_service())
21  , _betting_service(betting_service)
22  , _game_service(services.game_service())
23  , _dprops_service(services.dynamic_global_property_service())
24  , _virt_op_emitter(virt_op_emitter)
25 {
26 }
27 
29 {
30  _account_service.check_account_existence(op.moderator);
31  FC_ASSERT(_betting_service.is_betting_moderator(op.moderator), "User ${u} isn't a betting moderator",
32  ("u", op.moderator));
33  FC_ASSERT(_game_service.is_exists(op.uuid), "Game with uuid '${g}' doesn't exist", ("g", op.uuid));
34 
35  const auto& game = _game_service.get_game(op.uuid);
36  FC_ASSERT(game.status != game_status::created, "The game is not started yet");
37  FC_ASSERT(game.bets_resolve_time > _dprops_service.head_block_time(),
38  "Unable to post game results after bets were resolved");
39 
40  const fc::flat_set<wincase_type> wincases(op.wincases.begin(), op.wincases.end());
41 
42  for (auto wincase : wincases)
43  {
44  FC_ASSERT(is_belong_markets(wincase, game.markets), "Wincase '${w}' doesn't belong to game markets",
45  ("w", wincase));
46  }
47 
48  validate_all_winners_present(game.markets, wincases);
49  validate_opposite_winners_absent(wincases);
50 
51  _betting_service.cancel_pending_bets(game.uuid);
52 
53  auto old_status = game.status;
54  _game_service.finish(game, wincases);
55 
56  if (old_status == game_status::started)
57  _virt_op_emitter.push_virtual_operation(
59 }
60 
61 void post_game_results_evaluator::validate_all_winners_present(const fc::shared_flat_set<market_type>& markets,
62  const fc::flat_set<wincase_type>& winners) const
63 {
64  using namespace boost::adaptors;
65  using namespace boost::algorithm;
66 
67  for (const auto& market : markets | filtered([](const auto& m) { return !has_trd_state(m); }))
68  {
69  market.visit([&](const auto& m) {
70  auto pair = create_wincases(m);
71  auto exists = any_of(winners, [&](const auto& w) { return pair.first == w || pair.second == w; });
72 
73  FC_ASSERT(exists, "Wincase winners list do not contain neither '${1}' nor '${2}'",
74  ("1", pair.first)("2", pair.second));
75  });
76  }
77 }
78 
79 void post_game_results_evaluator::validate_opposite_winners_absent(const fc::flat_set<wincase_type>& winners) const
80 {
81  std::vector<wincase_type> opposite;
82  opposite.reserve(winners.size());
83 
84  boost::transform(winners, std::back_inserter(opposite), [](const auto& w) { return create_opposite(w); });
85 
86  std::vector<wincase_type> intersection;
87  intersection.reserve(winners.size());
88 
89  boost::set_intersection(winners, opposite, std::back_inserter(intersection));
90 
91  FC_ASSERT(intersection.empty(), "You've provided opposite wincases from same market as winners");
92 }
93 }
94 }
post_game_results_evaluator(data_service_factory_i &services, betting_service_i &betting_service, database_virtual_operations_emmiter_i &virt_op_emitter)
@ market
Rate limiting for all other actions.
wincase_type create_opposite(const wincase_type &wincase)
Definition: market.cpp:61
bool has_trd_state(const market_type &market)
Definition: market.cpp:66
std::pair< wincase_type, wincase_type > create_wincases(const market_type &market)
Definition: market.cpp:51
bool is_belong_markets(const wincase_type &wincase, const T &markets)
Definition: market.hpp:148
Definition: asset.cpp:15
virtual void check_account_existence(const account_name_type &, const optional< const char * > &context_type_name=optional< const char * >()) const =0
virtual bool is_betting_moderator(const account_name_type &account_name) const =0
virtual void cancel_pending_bets(uuid_type game_uuid)=0
virtual void push_virtual_operation(const operation &op)=0
virtual fc::time_point_sec head_block_time() const =0
virtual const game_object & get_game(int64_t game_id) const =0
virtual void finish(const game_object &game, const fc::flat_set< wincase_type > &wincases)=0
virtual bool is_exists(int64_t game_id) const =0
With this operation moderator provides game results(wincases)
account_name_type moderator
moderator account name
uuid_type uuid
Universal Unique Identifier which is specified during game creation.
std::vector< wincase_type > wincases
list of wincases