#235 Delete small objects for game_object, tournament_object, match_object,...

This commit is contained in:
serkixenos 2022-02-28 22:56:20 +00:00
parent 7d25589499
commit 8dc8ac0aec
16 changed files with 629 additions and 399 deletions

View file

@ -541,7 +541,7 @@ void betting_market_group_object::dispatch_new_status(database& db, betting_mark
} } // graphene::chain
namespace fc {
namespace fc {
// Manually reflect betting_market_group_object to variant to properly reflect "state"
void to_variant(const graphene::chain::betting_market_group_object& betting_market_group_obj, fc::variant& v, uint32_t max_depth)
{

View file

@ -466,7 +466,7 @@ void betting_market_object::on_canceled_event(database& db)
} } // graphene::chain
namespace fc {
namespace fc {
// Manually reflect betting_market_object to variant to properly reflect "state"
void to_variant(const graphene::chain::betting_market_object& event_obj, fc::variant& v, uint32_t max_depth)
{
@ -493,4 +493,3 @@ namespace fc {
const_cast<int*>(event_obj.my->state_machine.current_state())[0] = (int)status;
}
} //end namespace fc

View file

@ -47,7 +47,7 @@ namespace graphene { namespace chain {
};
} }
FC_REFLECT_ENUM(graphene::chain::event_state,
FC_REFLECT_ENUM(graphene::chain::event_state,
(upcoming)
(frozen_upcoming)
(in_progress)
@ -61,12 +61,12 @@ namespace graphene { namespace chain {
namespace msm = boost::msm;
namespace mpl = boost::mpl;
namespace
namespace
{
// Events -- most events happen when the witnesses publish an event_update operation with a new
// status, so if they publish an event with the status set to `frozen`, we'll generate a `frozen_event`
struct upcoming_event
struct upcoming_event
{
database& db;
upcoming_event(database& db) : db(db) {}
@ -76,12 +76,12 @@ namespace graphene { namespace chain {
database& db;
in_progress_event(database& db) : db(db) {}
};
struct frozen_event
struct frozen_event
{
database& db;
frozen_event(database& db) : db(db) {}
};
struct finished_event
struct finished_event
{
database& db;
finished_event(database& db) : db(db) {}
@ -104,7 +104,7 @@ namespace graphene { namespace chain {
betting_market_group_resolved_event(database& db, betting_market_group_id_type resolved_group, bool was_canceled) : db(db), resolved_group(resolved_group), was_canceled(was_canceled) {}
};
// event triggered when a betting market group is closed. When we get this,
// event triggered when a betting market group is closed. When we get this,
// if all child betting market groups are closed, transition to finished
struct betting_market_group_closed_event
{
@ -127,7 +127,7 @@ namespace graphene { namespace chain {
void on_entry(const upcoming_event& event, event_state_machine_& fsm) {
dlog("event ${id} -> upcoming", ("id", fsm.event_obj->id));
auto& betting_market_group_index = event.db.get_index_type<betting_market_group_object_index>().indices().get<by_event_id>();
for (const betting_market_group_object& betting_market_group :
for (const betting_market_group_object& betting_market_group :
boost::make_iterator_range(betting_market_group_index.equal_range(fsm.event_obj->id)))
try
{
@ -147,7 +147,7 @@ namespace graphene { namespace chain {
void on_entry(const in_progress_event& event, event_state_machine_& fsm) {
dlog("event ${id} -> in_progress", ("id", fsm.event_obj->id));
auto& betting_market_group_index = event.db.get_index_type<betting_market_group_object_index>().indices().get<by_event_id>();
for (const betting_market_group_object& betting_market_group :
for (const betting_market_group_object& betting_market_group :
boost::make_iterator_range(betting_market_group_index.equal_range(fsm.event_obj->id)))
try
{
@ -203,7 +203,7 @@ namespace graphene { namespace chain {
void freeze_betting_market_groups(const frozen_event& event) {
auto& betting_market_group_index = event.db.get_index_type<betting_market_group_object_index>().indices().get<by_event_id>();
for (const betting_market_group_object& betting_market_group :
for (const betting_market_group_object& betting_market_group :
boost::make_iterator_range(betting_market_group_index.equal_range(event_obj->id)))
{
try
@ -222,7 +222,7 @@ namespace graphene { namespace chain {
void close_all_betting_market_groups(const finished_event& event) {
auto& betting_market_group_index = event.db.get_index_type<betting_market_group_object_index>().indices().get<by_event_id>();
for (const betting_market_group_object& betting_market_group :
for (const betting_market_group_object& betting_market_group :
boost::make_iterator_range(betting_market_group_index.equal_range(event_obj->id)))
{
try
@ -241,7 +241,7 @@ namespace graphene { namespace chain {
void cancel_all_betting_market_groups(const canceled_event& event) {
auto& betting_market_group_index = event.db.template get_index_type<betting_market_group_object_index>().indices().template get<by_event_id>();
for (const betting_market_group_object& betting_market_group :
for (const betting_market_group_object& betting_market_group :
boost::make_iterator_range(betting_market_group_index.equal_range(event_obj->id)))
event.db.modify(betting_market_group, [&event](betting_market_group_object& betting_market_group_obj) {
betting_market_group_obj.on_canceled_event(event.db, true);
@ -252,15 +252,15 @@ namespace graphene { namespace chain {
bool all_betting_market_groups_are_closed(const betting_market_group_closed_event& event)
{
auto& betting_market_group_index = event.db.get_index_type<betting_market_group_object_index>().indices().get<by_event_id>();
for (const betting_market_group_object& betting_market_group :
for (const betting_market_group_object& betting_market_group :
boost::make_iterator_range(betting_market_group_index.equal_range(event_obj->id)))
if (betting_market_group.id != event.closed_group)
{
betting_market_group_status status = betting_market_group.get_status();
if (status != betting_market_group_status::closed &&
status != betting_market_group_status::graded &&
status != betting_market_group_status::re_grading &&
status != betting_market_group_status::settled &&
if (status != betting_market_group_status::closed &&
status != betting_market_group_status::graded &&
status != betting_market_group_status::re_grading &&
status != betting_market_group_status::settled &&
status != betting_market_group_status::canceled)
return false;
}
@ -276,7 +276,7 @@ namespace graphene { namespace chain {
if (event_obj->at_least_one_betting_market_group_settled)
return false;
auto& betting_market_group_index = event.db.get_index_type<betting_market_group_object_index>().indices().get<by_event_id>();
for (const betting_market_group_object& betting_market_group :
for (const betting_market_group_object& betting_market_group :
boost::make_iterator_range(betting_market_group_index.equal_range(event_obj->id)))
if (betting_market_group.id != event.resolved_group)
if (betting_market_group.get_status() != betting_market_group_status::canceled)
@ -290,7 +290,7 @@ namespace graphene { namespace chain {
event_obj->at_least_one_betting_market_group_settled = true;
auto& betting_market_group_index = event.db.get_index_type<betting_market_group_object_index>().indices().get<by_event_id>();
for (const betting_market_group_object& betting_market_group :
for (const betting_market_group_object& betting_market_group :
boost::make_iterator_range(betting_market_group_index.equal_range(event_obj->id))) {
if (betting_market_group.id != event.resolved_group) {
betting_market_group_status status = betting_market_group.get_status();
@ -344,7 +344,6 @@ namespace graphene { namespace chain {
{
FC_THROW_EXCEPTION(graphene::chain::no_transition, "No transition");
}
template <class Fsm>
void no_transition(canceled_event const& e, Fsm&, int state)
{
@ -372,7 +371,7 @@ namespace graphene { namespace chain {
{
}
event_object::event_object(const event_object& rhs) :
event_object::event_object(const event_object& rhs) :
graphene::db::abstract_object<event_object>(rhs),
name(rhs.name),
season(rhs.season),
@ -408,7 +407,7 @@ namespace graphene { namespace chain {
}
namespace {
bool verify_event_status_constants()
{
unsigned error_count = 0;
@ -443,19 +442,19 @@ namespace graphene { namespace chain {
dlog("Event status constants are correct");
else
wlog("There were ${count} errors in the event status constants", ("count", error_count));
return error_count == 0;
}
} // end anonymous namespace
event_status event_object::get_status() const
{
static bool state_constants_are_correct = verify_event_status_constants();
(void)&state_constants_are_correct;
event_state state = (event_state)my->state_machine.current_state()[0];
ddump((state));
switch (state)
{
case event_state::upcoming:
@ -523,8 +522,8 @@ namespace graphene { namespace chain {
my->state_machine.process_event(betting_market_group_closed_event(db, closed_group));
}
// These are the only statuses that can be explicitly set by witness operations. The missing
// status, 'settled', is automatically set when all of the betting market groups have
// These are the only statuses that can be explicitly set by witness operations. The missing
// status, 'settled', is automatically set when all of the betting market groups have
// settled/canceled
void event_object::dispatch_new_status(database& db, event_status new_status)
{
@ -533,16 +532,16 @@ namespace graphene { namespace chain {
on_upcoming_event(db);
break;
case event_status::in_progress: // by witnesses when the event starts
on_in_progress_event(db);
on_in_progress_event(db);
break;
case event_status::frozen: // by witnesses when the event needs to be frozen
on_frozen_event(db);
on_frozen_event(db);
break;
case event_status::finished: // by witnesses when the event is complete
on_finished_event(db);
on_finished_event(db);
break;
case event_status::canceled: // by witnesses to cancel the event
on_canceled_event(db);
on_canceled_event(db);
break;
default:
FC_THROW("Status ${new_status} cannot be explicitly set", ("new_status", new_status));
@ -551,7 +550,7 @@ namespace graphene { namespace chain {
} } // graphene::chain
namespace fc {
namespace fc {
// Manually reflect event_object to variant to properly reflect "state"
void to_variant(const graphene::chain::event_object& event_obj, fc::variant& v, uint32_t max_depth)
{

View file

@ -547,7 +547,7 @@ namespace graphene { namespace chain {
} } // graphene::chain
namespace fc {
namespace fc {
// Manually reflect game_object to variant to properly reflect "state"
void to_variant(const graphene::chain::game_object& game_obj, fc::variant& v, uint32_t max_depth)
{

View file

@ -24,19 +24,18 @@
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/protocol/betting_market.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
#include <graphene/chain/protocol/betting_market.hpp>
#include <sstream>
#include <boost/multi_index/composite_key.hpp>
#include <sstream>
namespace graphene { namespace chain {
class betting_market_object;
class betting_market_group_object;
} }
namespace fc {
namespace fc {
void to_variant(const graphene::chain::betting_market_object& betting_market_obj, fc::variant& v, uint32_t max_depth = 1);
void from_variant(const fc::variant& v, graphene::chain::betting_market_object& betting_market_obj, uint32_t max_depth = 1);
void to_variant(const graphene::chain::betting_market_group_object& betting_market_group_obj, fc::variant& v, uint32_t max_depth = 1);
@ -626,10 +625,9 @@ typedef multi_index_container<
typedef generic_index<betting_market_position_object, betting_market_position_multi_index_type> betting_market_position_index;
template<typename Stream>
inline Stream& operator<<( Stream& s, const betting_market_object& betting_market_obj )
{
{
// pack all fields exposed in the header in the usual way
// instead of calling the derived pack, just serialize the one field in the base class
// fc::raw::pack<Stream, const graphene::db::abstract_object<betting_market_object> >(s, betting_market_obj);
@ -649,7 +647,7 @@ inline Stream& operator<<( Stream& s, const betting_market_object& betting_marke
}
template<typename Stream>
inline Stream& operator>>( Stream& s, betting_market_object& betting_market_obj )
{
{
// unpack all fields exposed in the header in the usual way
//fc::raw::unpack<Stream, graphene::db::abstract_object<betting_market_object> >(s, betting_market_obj);
fc::raw::unpack(s, betting_market_obj.id);
@ -663,14 +661,14 @@ inline Stream& operator>>( Stream& s, betting_market_object& betting_market_obj
fc::raw::unpack(s, stringified_stream);
std::istringstream stream(stringified_stream);
betting_market_obj.unpack_impl(stream);
return s;
}
template<typename Stream>
inline Stream& operator<<( Stream& s, const betting_market_group_object& betting_market_group_obj )
{
{
// pack all fields exposed in the header in the usual way
// instead of calling the derived pack, just serialize the one field in the base class
// fc::raw::pack<Stream, const graphene::db::abstract_object<betting_market_group_object> >(s, betting_market_group_obj);
@ -693,7 +691,7 @@ inline Stream& operator<<( Stream& s, const betting_market_group_object& betting
}
template<typename Stream>
inline Stream& operator>>( Stream& s, betting_market_group_object& betting_market_group_obj )
{
{
// unpack all fields exposed in the header in the usual way
//fc::raw::unpack<Stream, graphene::db::abstract_object<betting_market_group_object> >(s, betting_market_group_obj);
fc::raw::unpack(s, betting_market_group_obj.id);
@ -711,15 +709,113 @@ inline Stream& operator>>( Stream& s, betting_market_group_object& betting_marke
fc::raw::unpack(s, stringified_stream);
std::istringstream stream(stringified_stream);
betting_market_group_obj.unpack_impl(stream);
return s;
}
} } // graphene::chain
FC_REFLECT_DERIVED( graphene::chain::betting_market_rules_object, (graphene::db::object), (name)(description) )
FC_REFLECT_DERIVED( graphene::chain::betting_market_group_object, (graphene::db::object), (description)(event_id)(rules_id)(asset_id)(total_matched_bets_amount)(never_in_play)(delay_before_settling)(settling_time) )
FC_REFLECT_DERIVED( graphene::chain::betting_market_object, (graphene::db::object), (group_id)(description)(payout_condition)(resolution) )
FC_REFLECT_DERIVED( graphene::chain::bet_object, (graphene::db::object), (bettor_id)(betting_market_id)(amount_to_bet)(backer_multiplier)(back_or_lay)(end_of_delay) )
FC_REFLECT_DERIVED( graphene::chain::betting_market_position_object, (graphene::db::object), (bettor_id)(betting_market_id)(pay_if_payout_condition)(pay_if_not_payout_condition)(pay_if_canceled)(pay_if_not_canceled)(fees_collected) )
namespace fc {
template<>
template<>
inline void if_enum<fc::false_type>::from_variant(const variant &vo, graphene::chain::betting_market_object &v, uint32_t max_depth) {
from_variant(vo, v, max_depth);
}
template<>
template<>
inline void if_enum<fc::false_type>::to_variant(const graphene::chain::betting_market_object &v, variant &vo, uint32_t max_depth) {
to_variant(v, vo, max_depth);
}
namespace raw { namespace detail {
template<>
template<>
inline void if_enum<fc::false_type>::pack(fc::datastream<size_t> &s, const graphene::chain::betting_market_object &v, uint32_t) {
s << v;
}
template<>
template<>
inline void if_enum<fc::false_type>::pack(fc::datastream<char*> &s, const graphene::chain::betting_market_object &v, uint32_t) {
s << v;
}
template<>
template<>
inline void if_enum<fc::false_type>::unpack(fc::datastream<const char*> &s, graphene::chain::betting_market_object &v, uint32_t) {
s >> v;
}
} } // namespace fc::raw::detail
template <>
struct get_typename<graphene::chain::betting_market_object> {
static const char *name() {
return "graphene::chain::betting_market_object";
}
};
template <>
struct reflector<graphene::chain::betting_market_object> {
typedef graphene::chain::betting_market_object type;
typedef fc::true_type is_defined;
typedef fc::false_type is_enum;
};
} // namespace fc
namespace fc {
template<>
template<>
inline void if_enum<fc::false_type>::from_variant(const variant &vo, graphene::chain::betting_market_group_object &v, uint32_t max_depth) {
from_variant(vo, v, max_depth);
}
template<>
template<>
inline void if_enum<fc::false_type>::to_variant(const graphene::chain::betting_market_group_object &v, variant &vo, uint32_t max_depth) {
to_variant(v, vo, max_depth);
}
namespace raw { namespace detail {
template<>
template<>
inline void if_enum<fc::false_type>::pack(fc::datastream<size_t> &s, const graphene::chain::betting_market_group_object &v, uint32_t) {
s << v;
}
template<>
template<>
inline void if_enum<fc::false_type>::pack(fc::datastream<char*> &s, const graphene::chain::betting_market_group_object &v, uint32_t) {
s << v;
}
template<>
template<>
inline void if_enum<fc::false_type>::unpack(fc::datastream<const char*> &s, graphene::chain::betting_market_group_object &v, uint32_t) {
s >> v;
}
} } // namespace fc::raw:detail
template <>
struct get_typename<graphene::chain::betting_market_group_object> {
static const char *name() {
return "graphene::chain::betting_market_group_object";
}
};
template <>
struct reflector<graphene::chain::betting_market_group_object> {
typedef graphene::chain::betting_market_group_object type;
typedef fc::true_type is_defined;
typedef fc::false_type is_enum;
};
} // namespace fc

View file

@ -35,7 +35,7 @@ namespace graphene { namespace chain {
class event_object;
} }
namespace fc {
namespace fc {
void to_variant(const graphene::chain::event_object& event_obj, fc::variant& v, uint32_t max_depth = 1);
void from_variant(const fc::variant& v, graphene::chain::event_object& event_obj, uint32_t max_depth = 1);
} //end namespace fc
@ -56,7 +56,7 @@ class event_object : public graphene::db::abstract_object< event_object >
event_object& operator=(const event_object& rhs);
internationalized_string_type name;
internationalized_string_type season;
optional<time_point_sec> start_time;
@ -114,7 +114,7 @@ typedef generic_index<event_object, event_object_multi_index_type> event_object_
template<typename Stream>
inline Stream& operator<<( Stream& s, const event_object& event_obj )
{
{
fc_elog(fc::logger::get("event"), "In event_obj to_raw");
// pack all fields exposed in the header in the usual way
// instead of calling the derived pack, just serialize the one field in the base class
@ -137,7 +137,7 @@ typedef generic_index<event_object, event_object_multi_index_type> event_object_
}
template<typename Stream>
inline Stream& operator>>( Stream& s, event_object& event_obj )
{
{
fc_elog(fc::logger::get("event"), "In event_obj from_raw");
// unpack all fields exposed in the header in the usual way
//fc::raw::unpack<Stream, graphene::db::abstract_object<event_object> >(s, event_obj);
@ -154,10 +154,57 @@ typedef generic_index<event_object, event_object_multi_index_type> event_object_
fc::raw::unpack(s, stringified_stream);
std::istringstream stream(stringified_stream);
event_obj.unpack_impl(stream);
return s;
}
} } // graphene::chain
FC_REFLECT(graphene::chain::event_object, (name)(season)(start_time)(event_group_id)(at_least_one_betting_market_group_settled)(scores))
namespace fc {
template<>
template<>
inline void if_enum<fc::false_type>::from_variant(const variant &vo, graphene::chain::event_object &v, uint32_t max_depth) {
from_variant(vo, v, max_depth);
}
template<>
template<>
inline void if_enum<fc::false_type>::to_variant(const graphene::chain::event_object &v, variant &vo, uint32_t max_depth) {
to_variant(v, vo, max_depth);
}
namespace raw { namespace detail {
template<>
template<>
inline void if_enum<fc::false_type>::pack(fc::datastream<size_t> &s, const graphene::chain::event_object &v, uint32_t) {
s << v;
}
template<>
template<>
inline void if_enum<fc::false_type>::pack(fc::datastream<char*> &s, const graphene::chain::event_object &v, uint32_t) {
s << v;
}
template<>
template<>
inline void if_enum<fc::false_type>::unpack(fc::datastream<const char*> &s, graphene::chain::event_object &v, uint32_t) {
s >> v;
}
} } // namespace fc::raw::detail
template <>
struct get_typename<graphene::chain::event_object> {
static const char *name() {
return "graphene::chain::event_object";
}
};
template <>
struct reflector<graphene::chain::event_object> {
typedef graphene::chain::event_object type;
typedef fc::true_type is_defined;
typedef fc::false_type is_enum;
};
} // namespace fc

View file

@ -23,10 +23,8 @@
*/
#pragma once
#include <graphene/chain/match_object.hpp>
#include <graphene/chain/rock_paper_scissors.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <graphene/db/flat_index.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
#include <fc/crypto/hex.hpp>
#include <sstream>
@ -35,7 +33,7 @@ namespace graphene { namespace chain {
class game_object;
} }
namespace fc {
namespace fc {
void to_variant(const graphene::chain::game_object& game_obj, fc::variant& v, uint32_t max_depth = 1);
void from_variant(const fc::variant& v, graphene::chain::game_object& game_obj, uint32_t max_depth = 1);
} //end namespace fc
@ -82,7 +80,7 @@ namespace graphene { namespace chain {
void on_move(database& db, const game_move_operation& op);
void on_timeout(database& db);
void start_game(database& db, const std::vector<account_id_type>& players);
// serialization functions:
// for serializing to raw, go through a temporary sstream object to avoid
// having to implement serialization in the header file
@ -116,7 +114,7 @@ namespace graphene { namespace chain {
template<typename Stream>
inline Stream& operator<<( Stream& s, const game_object& game_obj )
{
{
// pack all fields exposed in the header in the usual way
// instead of calling the derived pack, just serialize the one field in the base class
// fc::raw::pack<Stream, const graphene::db::abstract_object<game_object> >(s, game_obj);
@ -138,7 +136,7 @@ namespace graphene { namespace chain {
template<typename Stream>
inline Stream& operator>>( Stream& s, game_object& game_obj )
{
{
// unpack all fields exposed in the header in the usual way
//fc::raw::unpack<Stream, graphene::db::abstract_object<game_object> >(s, game_obj);
fc::raw::unpack(s, game_obj.id);
@ -153,10 +151,9 @@ namespace graphene { namespace chain {
fc::raw::unpack(s, stringified_stream);
std::istringstream stream(stringified_stream);
game_obj.unpack_impl(stream);
return s;
}
} }
FC_REFLECT_ENUM(graphene::chain::game_state,
@ -165,7 +162,52 @@ FC_REFLECT_ENUM(graphene::chain::game_state,
(expecting_reveal_moves)
(game_complete))
//FC_REFLECT_TYPENAME(graphene::chain::game_object) // manually serialized
FC_REFLECT(graphene::chain::game_object, (players))
namespace fc {
template<>
template<>
inline void if_enum<fc::false_type>::from_variant(const variant &vo, graphene::chain::game_object &v, uint32_t max_depth) {
from_variant(vo, v, max_depth);
}
template<>
template<>
inline void if_enum<fc::false_type>::to_variant(const graphene::chain::game_object &v, variant &vo, uint32_t max_depth) {
to_variant(v, vo, max_depth);
}
namespace raw { namespace detail {
template<>
template<>
inline void if_enum<fc::false_type>::pack(fc::datastream<size_t> &s, const graphene::chain::game_object &v, uint32_t) {
s << v;
}
template<>
template<>
inline void if_enum<fc::false_type>::pack(fc::datastream<char*> &s, const graphene::chain::game_object &v, uint32_t) {
s << v;
}
template<>
template<>
inline void if_enum<fc::false_type>::unpack(fc::datastream<const char*> &s, graphene::chain::game_object &v, uint32_t) {
s >> v;
}
} } // namespace fc::raw::detail
template <>
struct get_typename<graphene::chain::game_object> {
static const char *name() {
return "graphene::chain::game_object";
}
};
template <>
struct reflector<graphene::chain::game_object> {
typedef graphene::chain::game_object type;
typedef fc::true_type is_defined;
typedef fc::false_type is_enum;
};
} // namespace fc

View file

@ -1,8 +1,5 @@
#pragma once
#include <graphene/chain/protocol/tournament.hpp>
#include <graphene/chain/rock_paper_scissors.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <graphene/db/flat_index.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
#include <fc/crypto/hex.hpp>
#include <sstream>
@ -11,11 +8,12 @@ namespace graphene { namespace chain {
class match_object;
} }
namespace fc {
namespace fc {
void to_variant(const graphene::chain::match_object& match_obj, fc::variant& v, uint32_t max_depth = 1);
void from_variant(const fc::variant& v, graphene::chain::match_object& match_obj, uint32_t max_depth = 1);
} //end namespace fc
namespace graphene { namespace chain {
class database;
using namespace graphene::db;
@ -89,6 +87,7 @@ namespace graphene { namespace chain {
void pack_impl(std::ostream& stream) const;
void unpack_impl(std::istream& stream);
void on_initiate_match(database& db);
void on_game_complete(database& db, const game_object& game);
game_id_type start_next_game(database& db, match_id_type match_id);
@ -106,7 +105,7 @@ namespace graphene { namespace chain {
template<typename Stream>
inline Stream& operator<<( Stream& s, const match_object& match_obj )
{
{
// pack all fields exposed in the header in the usual way
// instead of calling the derived pack, just serialize the one field in the base class
// fc::raw::pack<Stream, const graphene::db::abstract_object<match_object> >(s, match_obj);
@ -132,7 +131,7 @@ namespace graphene { namespace chain {
template<typename Stream>
inline Stream& operator>>( Stream& s, match_object& match_obj )
{
{
// unpack all fields exposed in the header in the usual way
//fc::raw::unpack<Stream, graphene::db::abstract_object<match_object> >(s, match_obj);
fc::raw::unpack(s, match_obj.id);
@ -151,10 +150,9 @@ namespace graphene { namespace chain {
fc::raw::unpack(s, stringified_stream);
std::istringstream stream(stringified_stream);
match_obj.unpack_impl(stream);
return s;
}
} }
FC_REFLECT_ENUM(graphene::chain::match_state,
@ -162,6 +160,52 @@ FC_REFLECT_ENUM(graphene::chain::match_state,
(match_in_progress)
(match_complete))
//FC_REFLECT_TYPENAME(graphene::chain::match_object) // manually serialized
FC_REFLECT(graphene::chain::match_object, (players))
namespace fc {
template<>
template<>
inline void if_enum<fc::false_type>::from_variant(const variant &vo, graphene::chain::match_object &v, uint32_t max_depth) {
from_variant(vo, v, max_depth);
}
template<>
template<>
inline void if_enum<fc::false_type>::to_variant(const graphene::chain::match_object &v, variant &vo, uint32_t max_depth) {
to_variant(v, vo, max_depth);
}
namespace raw { namespace detail {
template<>
template<>
inline void if_enum<fc::false_type>::pack(fc::datastream<size_t> &s, const graphene::chain::match_object &v, uint32_t) {
s << v;
}
template<>
template<>
inline void if_enum<fc::false_type>::pack(fc::datastream<char*> &s, const graphene::chain::match_object &v, uint32_t) {
s << v;
}
template<>
template<>
inline void if_enum<fc::false_type>::unpack(fc::datastream<const char*> &s, graphene::chain::match_object &v, uint32_t) {
s >> v;
}
} } // namespace fc::raw::detail
template <>
struct get_typename<graphene::chain::match_object> {
static const char *name() {
return "graphene::chain::match_object";
}
};
template <>
struct reflector<graphene::chain::match_object> {
typedef graphene::chain::match_object type;
typedef fc::true_type is_defined;
typedef fc::false_type is_enum;
};
} // namespace fc

View file

@ -577,6 +577,8 @@ FC_REFLECT_TYPENAME( graphene::chain::fba_accumulator_id_type )
FC_REFLECT_TYPENAME( graphene::chain::betting_market_position_id_type )
FC_REFLECT_TYPENAME( graphene::chain::global_betting_statistics_id_type )
FC_REFLECT_TYPENAME( graphene::chain::tournament_details_id_type )
FC_REFLECT_TYPENAME( graphene::chain::game_id_type )
FC_REFLECT_TYPENAME( graphene::chain::match_id_type )
FC_REFLECT_TYPENAME( graphene::chain::custom_permission_id_type )
FC_REFLECT_TYPENAME( graphene::chain::custom_account_authority_id_type )
FC_REFLECT_TYPENAME( graphene::chain::offer_history_id_type )

View file

@ -1,8 +1,7 @@
#pragma once
#include <graphene/chain/protocol/tournament.hpp>
#include <graphene/chain/rock_paper_scissors.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <graphene/db/flat_index.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
#include <fc/crypto/hex.hpp>
#include <sstream>
@ -11,7 +10,7 @@ namespace graphene { namespace chain {
class tournament_object;
} }
namespace fc {
namespace fc {
void to_variant(const graphene::chain::tournament_object& tournament_obj, fc::variant& v, uint32_t max_depth = 1);
void from_variant(const fc::variant& v, graphene::chain::tournament_object& tournament_obj, uint32_t max_depth = 1);
} //end namespace fc
@ -154,10 +153,9 @@ namespace graphene { namespace chain {
> tournament_details_object_multi_index_type;
typedef generic_index<tournament_details_object, tournament_details_object_multi_index_type> tournament_details_index;
template<typename Stream>
inline Stream& operator<<( Stream& s, const tournament_object& tournament_obj )
{
{
fc_elog(fc::logger::get("tournament"), "In tournament_obj to_raw");
// pack all fields exposed in the header in the usual way
// instead of calling the derived pack, just serialize the one field in the base class
@ -175,15 +173,16 @@ namespace graphene { namespace chain {
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}",
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;
}
template<typename Stream>
inline Stream& operator>>( Stream& s, tournament_object& tournament_obj )
{
{
fc_elog(fc::logger::get("tournament"), "In tournament_obj from_raw");
// unpack all fields exposed in the header in the usual way
//fc::raw::unpack<Stream, graphene::db::abstract_object<tournament_object> >(s, tournament_obj);
@ -201,9 +200,9 @@ 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}",
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;
}
@ -230,8 +229,6 @@ namespace graphene { namespace chain {
flat_set<account_id_type> before_account_ids;
};
} }
FC_REFLECT_DERIVED(graphene::chain::tournament_details_object, (graphene::db::object),
@ -240,8 +237,7 @@ FC_REFLECT_DERIVED(graphene::chain::tournament_details_object, (graphene::db::ob
(payers)
(players_payers)
(matches))
//FC_REFLECT_TYPENAME(graphene::chain::tournament_object) // manually serialized
FC_REFLECT(graphene::chain::tournament_object, (creator))
FC_REFLECT_ENUM(graphene::chain::tournament_state,
(accepting_registrations)
(awaiting_start)
@ -249,3 +245,52 @@ FC_REFLECT_ENUM(graphene::chain::tournament_state,
(registration_period_expired)
(concluded))
namespace fc {
template<>
template<>
inline void if_enum<fc::false_type>::from_variant(const variant &vo, graphene::chain::tournament_object &v, uint32_t max_depth) {
from_variant(vo, v, max_depth);
}
template<>
template<>
inline void if_enum<fc::false_type>::to_variant(const graphene::chain::tournament_object &v, variant &vo, uint32_t max_depth) {
to_variant(v, vo, max_depth);
}
namespace raw { namespace detail {
template<>
template<>
inline void if_enum<fc::false_type>::pack(fc::datastream<size_t> &s, const graphene::chain::tournament_object &v, uint32_t) {
s << v;
}
template<>
template<>
inline void if_enum<fc::false_type>::pack(fc::datastream<char*> &s, const graphene::chain::tournament_object &v, uint32_t) {
s << v;
}
template<>
template<>
inline void if_enum<fc::false_type>::unpack(fc::datastream<const char*> &s, graphene::chain::tournament_object &v, uint32_t) {
s >> v;
}
} } // namespace fc::raw::detail
template <>
struct get_typename<graphene::chain::tournament_object> {
static const char *name() {
return "graphene::chain::tournament_object";
}
};
template <>
struct reflector<graphene::chain::tournament_object> {
typedef graphene::chain::tournament_object type;
typedef fc::true_type is_defined;
typedef fc::false_type is_enum;
};
} // namespace fc

View file

@ -362,7 +362,7 @@ namespace graphene { namespace chain {
} } // graphene::chain
namespace fc {
namespace fc {
// Manually reflect match_object to variant to properly reflect "state"
void to_variant(const graphene::chain::match_object& match_obj, fc::variant& v, uint32_t max_depth)
{ try {

View file

@ -721,7 +721,7 @@ namespace graphene { namespace chain {
}
} } // graphene::chain
namespace fc {
namespace fc {
// Manually reflect tournament_object to variant to properly reflect "state"
void to_variant(const graphene::chain::tournament_object& tournament_obj, fc::variant& v, uint32_t max_depth)
{

View file

@ -29,7 +29,6 @@
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/protocol/asset.hpp>
#include <graphene/chain/event_object.hpp>
#include <graphene/chain/operation_history_object.hpp>
#include <graphene/affiliate_stats/affiliate_stats_objects.hpp>

View file

@ -157,37 +157,45 @@ fc::variants bookie_api_impl::get_objects(const vector<object_id_type>& ids) con
{
case event_id_type::type_id:
{
auto& persistent_events_by_event_id = db->get_index_type<detail::persistent_event_index>().indices().get<by_event_id>();
auto iter = persistent_events_by_event_id.find(id.as<event_id_type>());
if (iter != persistent_events_by_event_id.end())
return iter->ephemeral_event_object.to_variant();
const auto &idx = db->get_index_type<event_object_index>();
const auto &aidx = dynamic_cast<const base_primary_index &>(idx);
const auto &refs = aidx.get_secondary_index<detail::persistent_event_index>();
auto iter = refs.ephemeral_event_object.find(id.as<event_id_type>());
if (iter != refs.ephemeral_event_object.end())
return iter->second.to_variant();
else
return {};
}
case bet_id_type::type_id:
{
auto& persistent_bets_by_bet_id = db->get_index_type<detail::persistent_bet_index>().indices().get<by_bet_id>();
auto iter = persistent_bets_by_bet_id.find(id.as<bet_id_type>());
if (iter != persistent_bets_by_bet_id.end())
return iter->ephemeral_bet_object.to_variant();
const auto &idx = db->get_index_type<bet_object_index>();
const auto &aidx = dynamic_cast<const base_primary_index &>(idx);
const auto &refs = aidx.get_secondary_index<detail::persistent_bet_index>();
auto iter = refs.internal.find(id.as<bet_id_type>());
if (iter != refs.internal.end())
return iter->second.ephemeral_bet_object.to_variant();
else
return {};
}
case betting_market_object::type_id:
{
auto& persistent_betting_markets_by_betting_market_id = db->get_index_type<detail::persistent_betting_market_index>().indices().get<by_betting_market_id>();
auto iter = persistent_betting_markets_by_betting_market_id.find(id.as<betting_market_id_type>());
if (iter != persistent_betting_markets_by_betting_market_id.end())
return iter->ephemeral_betting_market_object.to_variant();
{
const auto &idx = db->get_index_type<betting_market_object_index>();
const auto &aidx = dynamic_cast<const base_primary_index &>(idx);
const auto &refs = aidx.get_secondary_index<detail::persistent_betting_market_index>();
auto iter = refs.ephemeral_betting_market_object.find(id.as<betting_market_id_type>());
if (iter != refs.ephemeral_betting_market_object.end())
return iter->second.to_variant();
else
return {};
}
case betting_market_group_object::type_id:
{
auto& persistent_betting_market_groups_by_betting_market_group_id = db->get_index_type<detail::persistent_betting_market_group_index>().indices().get<by_betting_market_group_id>();
auto iter = persistent_betting_market_groups_by_betting_market_group_id.find(id.as<betting_market_group_id_type>());
if (iter != persistent_betting_market_groups_by_betting_market_group_id.end())
return iter->ephemeral_betting_market_group_object.to_variant();
{
const auto &idx = db->get_index_type<betting_market_group_object_index>();
const auto &aidx = dynamic_cast<const base_primary_index &>(idx);
const auto &refs = aidx.get_secondary_index<detail::persistent_betting_market_group_index>();
auto iter = refs.internal.find(id.as<betting_market_group_id_type>());
if (iter != refs.internal.end())
return iter->second.ephemeral_betting_market_group_object.to_variant();
else
return {};
}
@ -203,25 +211,28 @@ std::vector<matched_bet_object> bookie_api_impl::get_matched_bets_for_bettor(acc
{
std::vector<matched_bet_object> result;
std::shared_ptr<graphene::chain::database> db = app.chain_database();
auto& persistent_bets_by_bettor_id = db->get_index_type<detail::persistent_bet_index>().indices().get<by_bettor_id>();
auto iter = persistent_bets_by_bettor_id.lower_bound(std::make_tuple(bettor_id, true));
while (iter != persistent_bets_by_bettor_id.end() &&
iter->get_bettor_id() == bettor_id &&
iter->is_matched())
{
matched_bet_object match;
match.id = iter->ephemeral_bet_object.id;
match.bettor_id = iter->ephemeral_bet_object.bettor_id;
match.betting_market_id = iter->ephemeral_bet_object.betting_market_id;
match.amount_to_bet = iter->ephemeral_bet_object.amount_to_bet;
match.back_or_lay = iter->ephemeral_bet_object.back_or_lay;
match.end_of_delay = iter->ephemeral_bet_object.end_of_delay;
match.amount_matched = iter->amount_matched;
match.associated_operations = iter->associated_operations;
result.emplace_back(std::move(match));
const auto &idx = db->get_index_type<bet_object_index>();
const auto &aidx = dynamic_cast<const base_primary_index &>(idx);
const auto &refs = aidx.get_secondary_index<detail::persistent_bet_index>();
++iter;
for( const auto& bet_pair : refs.internal )
{
const auto& bet = bet_pair.second;
if( bet.get_bettor_id() == bettor_id && bet.is_matched() )
{
matched_bet_object match;
match.id = bet.ephemeral_bet_object.id;
match.bettor_id = bet.ephemeral_bet_object.bettor_id;
match.betting_market_id = bet.ephemeral_bet_object.betting_market_id;
match.amount_to_bet = bet.ephemeral_bet_object.amount_to_bet;
match.back_or_lay = bet.ephemeral_bet_object.back_or_lay;
match.end_of_delay = bet.ephemeral_bet_object.end_of_delay;
match.amount_matched = bet.amount_matched;
match.associated_operations = bet.associated_operations;
result.emplace_back(std::move(match));
}
}
return result;
}
@ -231,29 +242,32 @@ std::vector<matched_bet_object> bookie_api_impl::get_all_matched_bets_for_bettor
std::vector<matched_bet_object> result;
std::shared_ptr<graphene::chain::database> db = app.chain_database();
auto& persistent_bets_by_bettor_id = db->get_index_type<detail::persistent_bet_index>().indices().get<by_bettor_id>();
persistent_bet_multi_index_type::index<by_bettor_id>::type::iterator iter;
if (start == bet_id_type())
iter = persistent_bets_by_bettor_id.lower_bound(std::make_tuple(bettor_id, true));
else
iter = persistent_bets_by_bettor_id.lower_bound(std::make_tuple(bettor_id, true, start));
while (iter != persistent_bets_by_bettor_id.end() &&
iter->get_bettor_id() == bettor_id &&
iter->is_matched() &&
result.size() < limit)
{
matched_bet_object match;
match.id = iter->ephemeral_bet_object.id;
match.bettor_id = iter->ephemeral_bet_object.bettor_id;
match.betting_market_id = iter->ephemeral_bet_object.betting_market_id;
match.amount_to_bet = iter->ephemeral_bet_object.amount_to_bet;
match.back_or_lay = iter->ephemeral_bet_object.back_or_lay;
match.end_of_delay = iter->ephemeral_bet_object.end_of_delay;
match.amount_matched = iter->amount_matched;
result.emplace_back(std::move(match));
const auto &idx = db->get_index_type<bet_object_index>();
const auto &aidx = dynamic_cast<const base_primary_index &>(idx);
const auto &refs = aidx.get_secondary_index<detail::persistent_bet_index>();
++iter;
for( const auto& bet_pair : refs.internal )
{
const auto& bet_id = bet_pair.first;
const auto& bet = bet_pair.second;
if( bet.get_bettor_id() == bettor_id &&
bet.is_matched() &&
bet_id > start &&
result.size() < limit )
{
matched_bet_object match;
match.id = bet.ephemeral_bet_object.id;
match.bettor_id = bet.ephemeral_bet_object.bettor_id;
match.betting_market_id = bet.ephemeral_bet_object.betting_market_id;
match.amount_to_bet = bet.ephemeral_bet_object.amount_to_bet;
match.back_or_lay = bet.ephemeral_bet_object.back_or_lay;
match.end_of_delay = bet.ephemeral_bet_object.end_of_delay;
match.amount_matched = bet.amount_matched;
match.associated_operations = bet.associated_operations;
result.emplace_back(std::move(match));
}
}
return result;
}

View file

@ -59,143 +59,80 @@ namespace detail
* We do this by creating a secondary index on bet_object. We don't actually use it
* to index any property of the bet, we just use it to register for callbacks.
*/
class persistent_bet_object_helper : public secondary_index
{
public:
virtual ~persistent_bet_object_helper() {}
virtual void object_inserted(const object& obj) override;
//virtual void object_removed( const object& obj ) override;
//virtual void about_to_modify( const object& before ) override;
virtual void object_modified(const object& after) override;
void set_plugin_instance(bookie_plugin* instance) { _bookie_plugin = instance; }
private:
bookie_plugin* _bookie_plugin;
};
void persistent_bet_object_helper::object_inserted(const object& obj)
void persistent_bet_index::object_inserted(const object& obj)
{
const bet_object& bet_obj = *boost::polymorphic_downcast<const bet_object*>(&obj);
_bookie_plugin->database().create<persistent_bet_object>([&](persistent_bet_object& saved_bet_obj) {
saved_bet_obj.ephemeral_bet_object = bet_obj;
});
if(0 == internal.count(bet_obj.id))
internal.insert( {bet_obj.id, bet_obj} );
else
internal[bet_obj.id] = bet_obj;
}
void persistent_bet_object_helper::object_modified(const object& after)
void persistent_bet_index::object_modified(const object& after)
{
database& db = _bookie_plugin->database();
auto& persistent_bets_by_bet_id = db.get_index_type<persistent_bet_index>().indices().get<by_bet_id>();
const bet_object& bet_obj = *boost::polymorphic_downcast<const bet_object*>(&after);
auto iter = persistent_bets_by_bet_id.find(bet_obj.id);
assert (iter != persistent_bets_by_bet_id.end());
if (iter != persistent_bets_by_bet_id.end())
db.modify(*iter, [&](persistent_bet_object& saved_bet_obj) {
saved_bet_obj.ephemeral_bet_object = bet_obj;
});
auto iter = internal.find(bet_obj.id);
assert (iter != internal.end());
if (iter != internal.end())
iter->second = bet_obj;
}
//////////// end bet_object ///////////////////
class persistent_betting_market_object_helper : public secondary_index
{
public:
virtual ~persistent_betting_market_object_helper() {}
virtual void object_inserted(const object& obj) override;
//virtual void object_removed( const object& obj ) override;
//virtual void about_to_modify( const object& before ) override;
virtual void object_modified(const object& after) override;
void set_plugin_instance(bookie_plugin* instance) { _bookie_plugin = instance; }
private:
bookie_plugin* _bookie_plugin;
};
void persistent_betting_market_object_helper::object_inserted(const object& obj)
void persistent_betting_market_index::object_inserted(const object& obj)
{
const betting_market_object& betting_market_obj = *boost::polymorphic_downcast<const betting_market_object*>(&obj);
_bookie_plugin->database().create<persistent_betting_market_object>([&](persistent_betting_market_object& saved_betting_market_obj) {
saved_betting_market_obj.ephemeral_betting_market_object = betting_market_obj;
});
if(0 == ephemeral_betting_market_object.count(betting_market_obj.id))
ephemeral_betting_market_object.insert( {betting_market_obj.id, betting_market_obj} );
else
ephemeral_betting_market_object[betting_market_obj.id] = betting_market_obj;
}
void persistent_betting_market_object_helper::object_modified(const object& after)
void persistent_betting_market_index::object_modified(const object& after)
{
database& db = _bookie_plugin->database();
auto& persistent_betting_markets_by_betting_market_id = db.get_index_type<persistent_betting_market_index>().indices().get<by_betting_market_id>();
const betting_market_object& betting_market_obj = *boost::polymorphic_downcast<const betting_market_object*>(&after);
auto iter = persistent_betting_markets_by_betting_market_id.find(betting_market_obj.id);
assert (iter != persistent_betting_markets_by_betting_market_id.end());
if (iter != persistent_betting_markets_by_betting_market_id.end())
db.modify(*iter, [&](persistent_betting_market_object& saved_betting_market_obj) {
saved_betting_market_obj.ephemeral_betting_market_object = betting_market_obj;
});
auto iter = ephemeral_betting_market_object.find(betting_market_obj.id);
assert (iter != ephemeral_betting_market_object.end());
if (iter != ephemeral_betting_market_object.end())
iter->second = betting_market_obj;
}
//////////// end betting_market_object ///////////////////
class persistent_betting_market_group_object_helper : public secondary_index
{
public:
virtual ~persistent_betting_market_group_object_helper() {}
virtual void object_inserted(const object& obj) override;
//virtual void object_removed( const object& obj ) override;
//virtual void about_to_modify( const object& before ) override;
virtual void object_modified(const object& after) override;
void set_plugin_instance(bookie_plugin* instance) { _bookie_plugin = instance; }
private:
bookie_plugin* _bookie_plugin;
};
void persistent_betting_market_group_object_helper::object_inserted(const object& obj)
void persistent_betting_market_group_index::object_inserted(const object& obj)
{
const betting_market_group_object& betting_market_group_obj = *boost::polymorphic_downcast<const betting_market_group_object*>(&obj);
_bookie_plugin->database().create<persistent_betting_market_group_object>([&](persistent_betting_market_group_object& saved_betting_market_group_obj) {
saved_betting_market_group_obj.ephemeral_betting_market_group_object = betting_market_group_obj;
});
if(0 == internal.count(betting_market_group_obj.id))
internal.insert( {betting_market_group_obj.id, betting_market_group_obj} );
else
internal[betting_market_group_obj.id] = betting_market_group_obj;
}
void persistent_betting_market_group_object_helper::object_modified(const object& after)
void persistent_betting_market_group_index::object_modified(const object& after)
{
database& db = _bookie_plugin->database();
auto& persistent_betting_market_groups_by_betting_market_group_id = db.get_index_type<persistent_betting_market_group_index>().indices().get<by_betting_market_group_id>();
const betting_market_group_object& betting_market_group_obj = *boost::polymorphic_downcast<const betting_market_group_object*>(&after);
auto iter = persistent_betting_market_groups_by_betting_market_group_id.find(betting_market_group_obj.id);
assert (iter != persistent_betting_market_groups_by_betting_market_group_id.end());
if (iter != persistent_betting_market_groups_by_betting_market_group_id.end())
db.modify(*iter, [&](persistent_betting_market_group_object& saved_betting_market_group_obj) {
saved_betting_market_group_obj.ephemeral_betting_market_group_object = betting_market_group_obj;
});
auto iter = internal.find(betting_market_group_obj.id);
assert (iter != internal.end());
if (iter != internal.end())
iter->second = betting_market_group_obj;
}
//////////// end betting_market_group_object ///////////////////
class persistent_event_object_helper : public secondary_index
{
public:
virtual ~persistent_event_object_helper() {}
virtual void object_inserted(const object& obj) override;
//virtual void object_removed( const object& obj ) override;
//virtual void about_to_modify( const object& before ) override;
virtual void object_modified(const object& after) override;
void set_plugin_instance(bookie_plugin* instance) { _bookie_plugin = instance; }
private:
bookie_plugin* _bookie_plugin;
};
void persistent_event_object_helper::object_inserted(const object& obj)
void persistent_event_index::object_inserted(const object& obj)
{
const event_object& event_obj = *boost::polymorphic_downcast<const event_object*>(&obj);
_bookie_plugin->database().create<persistent_event_object>([&](persistent_event_object& saved_event_obj) {
saved_event_obj.ephemeral_event_object = event_obj;
});
if(0 == ephemeral_event_object.count(event_obj.id))
ephemeral_event_object.insert( {event_obj.id, event_obj} );
else
ephemeral_event_object[event_obj.id] = event_obj;
}
void persistent_event_object_helper::object_modified(const object& after)
void persistent_event_index::object_modified(const object& after)
{
database& db = _bookie_plugin->database();
auto& persistent_events_by_event_id = db.get_index_type<persistent_event_index>().indices().get<by_event_id>();
const event_object& event_obj = *boost::polymorphic_downcast<const event_object*>(&after);
auto iter = persistent_events_by_event_id.find(event_obj.id);
assert (iter != persistent_events_by_event_id.end());
if (iter != persistent_events_by_event_id.end())
db.modify(*iter, [&](persistent_event_object& saved_event_obj) {
saved_event_obj.ephemeral_event_object = event_obj;
});
auto iter = ephemeral_event_object.find(event_obj.id);
assert (iter != ephemeral_event_object.end());
if (iter != ephemeral_event_object.end())
iter->second = event_obj;
}
//////////// end event_object ///////////////////
@ -207,7 +144,6 @@ class bookie_plugin_impl
{ }
virtual ~bookie_plugin_impl();
/**
* Called After a block has been applied and committed. The callback
* should not yield and should execute quickly.
@ -299,27 +235,35 @@ void bookie_plugin_impl::on_block_applied( const signed_block& )
const asset& amount_bet = bet_matched_op.amount_bet;
// object may no longer exist
//const bet_object& bet = bet_matched_op.bet_id(db);
auto& persistent_bets_by_bet_id = db.get_index_type<persistent_bet_index>().indices().get<by_bet_id>();
auto bet_iter = persistent_bets_by_bet_id.find(bet_matched_op.bet_id);
assert(bet_iter != persistent_bets_by_bet_id.end());
if (bet_iter != persistent_bets_by_bet_id.end())
const auto &idx_bet_object = db.get_index_type<bet_object_index>();
const auto &aidx_bet_object = dynamic_cast<const base_primary_index &>(idx_bet_object);
const auto &refs_bet_object = aidx_bet_object.get_secondary_index<detail::persistent_bet_index>();
auto& nonconst_refs_bet_object = const_cast<persistent_bet_index&>(refs_bet_object);
auto bet_iter = nonconst_refs_bet_object.internal.find(bet_matched_op.bet_id);
assert(bet_iter != nonconst_refs_bet_object.internal.end());
if (bet_iter != nonconst_refs_bet_object.internal.end())
{
db.modify(*bet_iter, [&]( persistent_bet_object& obj ) {
obj.amount_matched += amount_bet.amount;
if (is_operation_history_object_stored(op.id))
obj.associated_operations.emplace_back(op.id);
});
const bet_object& bet_obj = bet_iter->ephemeral_bet_object;
bet_iter->second.amount_matched += amount_bet.amount;
if (is_operation_history_object_stored(op.id))
bet_iter->second.associated_operations.emplace_back(op.id);
auto& persistent_betting_market_idx = db.get_index_type<persistent_betting_market_index>().indices().get<by_betting_market_id>();
auto persistent_betting_market_object_iter = persistent_betting_market_idx.find(bet_obj.betting_market_id);
FC_ASSERT(persistent_betting_market_object_iter != persistent_betting_market_idx.end());
const betting_market_object& betting_market = persistent_betting_market_object_iter->ephemeral_betting_market_object;
const bet_object& bet_obj = bet_iter->second.ephemeral_bet_object;
auto& persistent_betting_market_group_idx = db.get_index_type<persistent_betting_market_group_index>().indices().get<by_betting_market_group_id>();
auto persistent_betting_market_group_object_iter = persistent_betting_market_group_idx.find(betting_market.group_id);
FC_ASSERT(persistent_betting_market_group_object_iter != persistent_betting_market_group_idx.end());
const betting_market_group_object& betting_market_group = persistent_betting_market_group_object_iter->ephemeral_betting_market_group_object;
const auto &idx_betting_market = db.get_index_type<betting_market_object_index>();
const auto &aidx_betting_market = dynamic_cast<const base_primary_index &>(idx_betting_market);
const auto &refs_betting_market = aidx_betting_market.get_secondary_index<detail::persistent_betting_market_index>();
auto persistent_betting_market_object_iter = refs_betting_market.ephemeral_betting_market_object.find(bet_obj.betting_market_id);
FC_ASSERT(persistent_betting_market_object_iter != refs_betting_market.ephemeral_betting_market_object.end());
const betting_market_object& betting_market = persistent_betting_market_object_iter->second;
const auto &idx_betting_market_group = db.get_index_type<betting_market_group_object_index>();
const auto &aidx_betting_market_group = dynamic_cast<const base_primary_index &>(idx_betting_market_group);
const auto &refs_betting_market_group = aidx_betting_market_group.get_secondary_index<detail::persistent_betting_market_group_index>();
auto& nonconst_refs_betting_market_group = const_cast<persistent_betting_market_group_index&>(refs_betting_market_group);
auto persistent_betting_market_group_object_iter = nonconst_refs_betting_market_group.internal.find(betting_market.group_id);
FC_ASSERT(persistent_betting_market_group_object_iter != nonconst_refs_betting_market_group.internal.end());
const betting_market_group_object& betting_market_group = persistent_betting_market_group_object_iter->second.ephemeral_betting_market_group_object;
// if the object is still in the main database, keep the running total there
// otherwise, add it directly to the persistent version
@ -330,9 +274,7 @@ void bookie_plugin_impl::on_block_applied( const signed_block& )
obj.total_matched_bets_amount += amount_bet.amount;
});
else
db.modify( *persistent_betting_market_group_object_iter, [&]( persistent_betting_market_group_object& obj ){
obj.ephemeral_betting_market_group_object.total_matched_bets_amount += amount_bet.amount;
});
persistent_betting_market_group_object_iter->second.total_matched_bets_amount += amount_bet.amount;
}
}
else if( op.op.which() == operation::tag<event_create_operation>::value )
@ -364,33 +306,35 @@ void bookie_plugin_impl::on_block_applied( const signed_block& )
else if ( op.op.which() == operation::tag<bet_canceled_operation>::value )
{
const bet_canceled_operation& bet_canceled_op = op.op.get<bet_canceled_operation>();
auto& persistent_bets_by_bet_id = db.get_index_type<persistent_bet_index>().indices().get<by_bet_id>();
auto bet_iter = persistent_bets_by_bet_id.find(bet_canceled_op.bet_id);
assert(bet_iter != persistent_bets_by_bet_id.end());
if (bet_iter != persistent_bets_by_bet_id.end())
const auto &idx_bet_object = db.get_index_type<bet_object_index>();
const auto &aidx_bet_object = dynamic_cast<const base_primary_index &>(idx_bet_object);
const auto &refs_bet_object = aidx_bet_object.get_secondary_index<detail::persistent_bet_index>();
auto& nonconst_refs_bet_object = const_cast<persistent_bet_index&>(refs_bet_object);
auto bet_iter = nonconst_refs_bet_object.internal.find(bet_canceled_op.bet_id);
assert(bet_iter != nonconst_refs_bet_object.internal.end());
if (bet_iter != nonconst_refs_bet_object.internal.end())
{
// ilog("Adding bet_canceled_operation ${canceled_id} to bet ${bet_id}'s associated operations",
// ("canceled_id", op.id)("bet_id", bet_canceled_op.bet_id));
if (is_operation_history_object_stored(op.id))
db.modify(*bet_iter, [&]( persistent_bet_object& obj ) {
obj.associated_operations.emplace_back(op.id);
});
bet_iter->second.associated_operations.emplace_back(op.id);
}
}
else if ( op.op.which() == operation::tag<bet_adjusted_operation>::value )
{
const bet_adjusted_operation& bet_adjusted_op = op.op.get<bet_adjusted_operation>();
auto& persistent_bets_by_bet_id = db.get_index_type<persistent_bet_index>().indices().get<by_bet_id>();
auto bet_iter = persistent_bets_by_bet_id.find(bet_adjusted_op.bet_id);
assert(bet_iter != persistent_bets_by_bet_id.end());
if (bet_iter != persistent_bets_by_bet_id.end())
const auto &idx_bet_object = db.get_index_type<bet_object_index>();
const auto &aidx_bet_object = dynamic_cast<const base_primary_index &>(idx_bet_object);
const auto &refs_bet_object = aidx_bet_object.get_secondary_index<detail::persistent_bet_index>();
auto& nonconst_refs_bet_object = const_cast<persistent_bet_index&>(refs_bet_object);
auto bet_iter = nonconst_refs_bet_object.internal.find(bet_adjusted_op.bet_id);
assert(bet_iter != nonconst_refs_bet_object.internal.end());
if (bet_iter != nonconst_refs_bet_object.internal.end())
{
// ilog("Adding bet_adjusted_operation ${adjusted_id} to bet ${bet_id}'s associated operations",
// ("adjusted_id", op.id)("bet_id", bet_adjusted_op.bet_id));
if (is_operation_history_object_stored(op.id))
db.modify(*bet_iter, [&]( persistent_bet_object& obj ) {
obj.associated_operations.emplace_back(op.id);
});
bet_iter->second.associated_operations.emplace_back(op.id);
}
}
@ -472,31 +416,21 @@ void bookie_plugin::plugin_initialize(const boost::program_options::variables_ma
database().new_objects.connect([this](const vector<object_id_type>& ids, const flat_set<account_id_type>& impacted_accounts) { my->on_objects_new(ids); });
database().removed_objects.connect([this](const vector<object_id_type>& ids, const vector<const object*>& objs, const flat_set<account_id_type>& impacted_accounts) { my->on_objects_removed(ids); });
//auto event_index =
database().add_index<primary_index<detail::persistent_event_index> >();
database().add_index<primary_index<detail::persistent_betting_market_group_index> >();
database().add_index<primary_index<detail::persistent_betting_market_index> >();
database().add_index<primary_index<detail::persistent_bet_index> >();
const primary_index<bet_object_index>& bet_object_idx = database().get_index_type<primary_index<bet_object_index> >();
primary_index<bet_object_index>& nonconst_bet_object_idx = const_cast<primary_index<bet_object_index>&>(bet_object_idx);
detail::persistent_bet_object_helper* persistent_bet_object_helper_index = nonconst_bet_object_idx.add_secondary_index<detail::persistent_bet_object_helper>();
persistent_bet_object_helper_index->set_plugin_instance(this);
nonconst_bet_object_idx.add_secondary_index<detail::persistent_bet_index>();
const primary_index<betting_market_object_index>& betting_market_object_idx = database().get_index_type<primary_index<betting_market_object_index> >();
primary_index<betting_market_object_index>& nonconst_betting_market_object_idx = const_cast<primary_index<betting_market_object_index>&>(betting_market_object_idx);
detail::persistent_betting_market_object_helper* persistent_betting_market_object_helper_index = nonconst_betting_market_object_idx.add_secondary_index<detail::persistent_betting_market_object_helper>();
persistent_betting_market_object_helper_index->set_plugin_instance(this);
nonconst_betting_market_object_idx.add_secondary_index<detail::persistent_betting_market_index>();
const primary_index<betting_market_group_object_index>& betting_market_group_object_idx = database().get_index_type<primary_index<betting_market_group_object_index> >();
primary_index<betting_market_group_object_index>& nonconst_betting_market_group_object_idx = const_cast<primary_index<betting_market_group_object_index>&>(betting_market_group_object_idx);
detail::persistent_betting_market_group_object_helper* persistent_betting_market_group_object_helper_index = nonconst_betting_market_group_object_idx.add_secondary_index<detail::persistent_betting_market_group_object_helper>();
persistent_betting_market_group_object_helper_index->set_plugin_instance(this);
nonconst_betting_market_group_object_idx.add_secondary_index<detail::persistent_betting_market_group_index>();
const primary_index<event_object_index>& event_object_idx = database().get_index_type<primary_index<event_object_index> >();
primary_index<event_object_index>& nonconst_event_object_idx = const_cast<primary_index<event_object_index>&>(event_object_idx);
detail::persistent_event_object_helper* persistent_event_object_helper_index = nonconst_event_object_idx.add_secondary_index<detail::persistent_event_object_helper>();
persistent_event_object_helper_index->set_plugin_instance(this);
nonconst_event_object_idx.add_secondary_index<detail::persistent_event_index>();
ilog("bookie plugin: plugin_startup() end");
}

View file

@ -29,39 +29,21 @@
namespace graphene { namespace bookie {
using namespace chain;
enum bookie_object_type
{
persistent_event_object_type,
persistent_betting_market_group_object_type,
persistent_betting_market_object_type,
persistent_bet_object_type,
BOOKIE_OBJECT_TYPE_COUNT ///< Sentry value which contains the number of different object types
};
namespace detail
{
class persistent_event_object : public graphene::db::abstract_object<persistent_event_object>
/**
* @brief This secondary index will allow a reverse lookup of all events that happened
*/
class persistent_event_index : public secondary_index
{
public:
static const uint8_t space_id = bookie_objects;
static const uint8_t type_id = persistent_event_object_type;
public:
virtual void object_inserted( const object& obj ) override;
virtual void object_modified( const object& after ) override;
event_object ephemeral_event_object;
event_id_type get_event_id() const { return ephemeral_event_object.id; }
map< event_id_type, event_object > ephemeral_event_object;
};
typedef object_id<bookie_objects, persistent_event_object_type, persistent_event_object> persistent_event_id_type;
struct by_event_id;
typedef multi_index_container<
persistent_event_object,
indexed_by<
ordered_unique<tag<by_id>, member<object, object_id_type, &object::id> >,
ordered_unique<tag<by_event_id>, const_mem_fun<persistent_event_object, event_id_type, &persistent_event_object::get_event_id> > > > persistent_event_multi_index_type;
typedef generic_index<persistent_event_object, persistent_event_multi_index_type> persistent_event_index;
#if 0 // we no longer have competitors, just leaving this here as an example of how to do a secondary index
class events_by_competitor_index : public secondary_index
{
@ -101,95 +83,122 @@ void events_by_competitor_index::object_modified( const object& after )
}
#endif
//////////// betting_market_group_object //////////////////
class persistent_betting_market_group_object : public graphene::db::abstract_object<persistent_betting_market_group_object>
/**
* @brief This secondary index will allow a reverse lookup of all betting_market_group that happened
*/
class persistent_betting_market_group_index : public secondary_index
{
public:
static const uint8_t space_id = bookie_objects;
static const uint8_t type_id = persistent_betting_market_group_object_type;
public:
struct internal_type
{
internal_type() = default;
internal_type(const betting_market_group_object& other)
: ephemeral_betting_market_group_object{other}
{}
internal_type& operator=(const betting_market_group_object& other)
{
ephemeral_betting_market_group_object = other;
return *this;
}
friend bool operator==(const internal_type& lhs, const internal_type& rhs);
friend bool operator<(const internal_type& lhs, const internal_type& rhs);
friend bool operator>(const internal_type& lhs, const internal_type& rhs);
betting_market_group_object ephemeral_betting_market_group_object;
share_type total_matched_bets_amount;
};
betting_market_group_id_type get_betting_market_group_id() const { return ephemeral_betting_market_group_object.id; }
public:
virtual void object_inserted( const object& obj ) override;
virtual void object_modified( const object& after ) override;
map< betting_market_group_id_type, internal_type > internal;
};
struct by_betting_market_group_id;
typedef multi_index_container<
persistent_betting_market_group_object,
indexed_by<
ordered_unique<tag<by_id>, member<object, object_id_type, &object::id> >,
ordered_unique<tag<by_betting_market_group_id>, const_mem_fun<persistent_betting_market_group_object, betting_market_group_id_type, &persistent_betting_market_group_object::get_betting_market_group_id> > > > persistent_betting_market_group_multi_index_type;
typedef generic_index<persistent_betting_market_group_object, persistent_betting_market_group_multi_index_type> persistent_betting_market_group_index;
//////////// betting_market_object //////////////////
class persistent_betting_market_object : public graphene::db::abstract_object<persistent_betting_market_object>
inline bool operator==(const persistent_betting_market_group_index::internal_type& lhs, const persistent_betting_market_group_index::internal_type& rhs)
{
public:
static const uint8_t space_id = bookie_objects;
static const uint8_t type_id = persistent_betting_market_object_type;
return lhs.ephemeral_betting_market_group_object == rhs.ephemeral_betting_market_group_object;
}
betting_market_object ephemeral_betting_market_object;
inline bool operator<(const persistent_betting_market_group_index::internal_type& lhs, const persistent_betting_market_group_index::internal_type& rhs)
{
return lhs.ephemeral_betting_market_group_object < rhs.ephemeral_betting_market_group_object;
}
share_type total_matched_bets_amount;
inline bool operator>(const persistent_betting_market_group_index::internal_type& lhs, const persistent_betting_market_group_index::internal_type& rhs)
{
return !operator<(lhs, rhs);
}
betting_market_id_type get_betting_market_id() const { return ephemeral_betting_market_object.id; }
/**
* @brief This secondary index will allow a reverse lookup of all betting_market_object that happened
*/
class persistent_betting_market_index : public secondary_index
{
public:
virtual void object_inserted( const object& obj ) override;
virtual void object_modified( const object& after ) override;
map< betting_market_id_type, betting_market_object > ephemeral_betting_market_object;
};
struct by_betting_market_id;
typedef multi_index_container<
persistent_betting_market_object,
indexed_by<
ordered_unique<tag<by_id>, member<object, object_id_type, &object::id> >,
ordered_unique<tag<by_betting_market_id>, const_mem_fun<persistent_betting_market_object, betting_market_id_type, &persistent_betting_market_object::get_betting_market_id> > > > persistent_betting_market_multi_index_type;
typedef generic_index<persistent_betting_market_object, persistent_betting_market_multi_index_type> persistent_betting_market_index;
//////////// bet_object //////////////////
class persistent_bet_object : public graphene::db::abstract_object<persistent_bet_object>
/**
* @brief This secondary index will allow a reverse lookup of all bet_object that happened
*/
class persistent_bet_index : public secondary_index
{
public:
static const uint8_t space_id = bookie_objects;
static const uint8_t type_id = persistent_bet_object_type;
public:
struct internal_type
{
internal_type() = default;
bet_object ephemeral_bet_object;
internal_type(const bet_object& other)
: ephemeral_bet_object{other}
{}
// total amount of the bet that matched
share_type amount_matched;
internal_type& operator=(const bet_object& other)
{
ephemeral_bet_object = other;
return *this;
}
std::vector<operation_history_id_type> associated_operations;
bet_id_type get_bet_id() const { return ephemeral_bet_object.id; }
account_id_type get_bettor_id() const { return ephemeral_bet_object.bettor_id; }
bool is_matched() const { return amount_matched != share_type(); }
friend bool operator==(const internal_type& lhs, const internal_type& rhs);
friend bool operator<(const internal_type& lhs, const internal_type& rhs);
friend bool operator>(const internal_type& lhs, const internal_type& rhs);
bet_object ephemeral_bet_object;
// total amount of the bet that matched
share_type amount_matched;
std::vector<operation_history_id_type> associated_operations;
};
public:
virtual void object_inserted( const object& obj ) override;
virtual void object_modified( const object& after ) override;
map< bet_id_type, internal_type > internal;
};
struct by_bet_id;
struct by_bettor_id;
typedef multi_index_container<
persistent_bet_object,
indexed_by<
ordered_unique<tag<by_id>, member<object, object_id_type, &object::id> >,
ordered_unique<tag<by_bet_id>, const_mem_fun<persistent_bet_object, bet_id_type, &persistent_bet_object::get_bet_id> >,
ordered_unique<tag<by_bettor_id>,
composite_key<
persistent_bet_object,
const_mem_fun<persistent_bet_object, account_id_type, &persistent_bet_object::get_bettor_id>,
const_mem_fun<persistent_bet_object, bool, &persistent_bet_object::is_matched>,
const_mem_fun<persistent_bet_object, bet_id_type, &persistent_bet_object::get_bet_id> >,
composite_key_compare<
std::less<account_id_type>,
std::less<bool>,
std::greater<bet_id_type> > > > > persistent_bet_multi_index_type;
inline bool operator==(const persistent_bet_index::internal_type& lhs, const persistent_bet_index::internal_type& rhs)
{
return lhs.ephemeral_bet_object == rhs.ephemeral_bet_object;
}
typedef generic_index<persistent_bet_object, persistent_bet_multi_index_type> persistent_bet_index;
inline bool operator<(const persistent_bet_index::internal_type& lhs, const persistent_bet_index::internal_type& rhs)
{
return lhs.ephemeral_bet_object < rhs.ephemeral_bet_object;
}
inline bool operator>(const persistent_bet_index::internal_type& lhs, const persistent_bet_index::internal_type& rhs)
{
return !operator<(lhs, rhs);
}
} } } //graphene::bookie::detail
FC_REFLECT_DERIVED( graphene::bookie::detail::persistent_event_object, (graphene::db::object), (ephemeral_event_object) )
FC_REFLECT_DERIVED( graphene::bookie::detail::persistent_betting_market_group_object, (graphene::db::object), (ephemeral_betting_market_group_object)(total_matched_bets_amount) )
FC_REFLECT_DERIVED( graphene::bookie::detail::persistent_betting_market_object, (graphene::db::object), (ephemeral_betting_market_object) )
FC_REFLECT_DERIVED( graphene::bookie::detail::persistent_bet_object, (graphene::db::object), (ephemeral_bet_object)(amount_matched)(associated_operations) )