Updated data structures to take bets with explicit odds

This commit is contained in:
Eric Frias 2017-03-21 12:27:13 -04:00
parent 1b0b2b77d5
commit ccd570874f
6 changed files with 124 additions and 8 deletions

View file

@ -107,7 +107,7 @@ object_id_type bet_place_evaluator::do_apply(const bet_place_operation& op)
bet_obj.bettor_id = op.bettor_id;
bet_obj.betting_market_id = op.betting_market_id;
bet_obj.amount_to_bet = op.amount_to_bet;
bet_obj.amount_to_win = op.amount_to_win;
bet_obj.backer_multiplier = op.backer_multiplier;
bet_obj.amount_reserved_for_fees = op.amount_reserved_for_fees;
bet_obj.back_or_lay = op.back_or_lay;
});

View file

@ -70,7 +70,7 @@ class bet_object : public graphene::db::abstract_object< bet_object >
share_type amount_to_bet;
share_type amount_to_win;
bet_multiplier_type backer_multiplier;
share_type amount_reserved_for_fees;
@ -104,4 +104,4 @@ typedef generic_index<bet_object, bet_object_multi_index_type> bet_object_index;
FC_REFLECT_DERIVED( graphene::chain::betting_market_group_object, (graphene::db::object), (event_id)(options) )
FC_REFLECT_DERIVED( graphene::chain::betting_market_object, (graphene::db::object), (group_id)(payout_condition)(asset_id) )
FC_REFLECT_DERIVED( graphene::chain::bet_object, (graphene::db::object), (bettor_id)(betting_market_id)(amount_to_bet)(amount_to_win)(amount_reserved_for_fees)(back_or_lay) )
FC_REFLECT_DERIVED( graphene::chain::bet_object, (graphene::db::object), (bettor_id)(betting_market_id)(amount_to_bet)(backer_multiplier)(amount_reserved_for_fees)(back_or_lay) )

View file

@ -169,3 +169,20 @@
///@}
#define GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET (asset_id_type(743))
/**
* Betting-related constants.
*
* We store bet multipliers as fixed-precision uint32_t. These values are
* the maximum power-of-ten bet we can have on a "symmetric" market:
* (decimal) 1.0001 - 10001
* (fractional) 1:10000 - 10000:1
*/
///@{
/// betting odds (multipliers) are stored as fixed-precision, divide by this to get the actual multiplier
#define GRAPHENE_BETTING_ODDS_PRECISION 10000
/// the smallest bet multiplier we will accept
#define GRAPHENE_BETTING_MIN_MULTIPLIER 10001
/// the largest bet multiplier we will accept
#define GRAPHENE_BETTING_MAX_MULTIPLIER 100010000
///@}

View file

@ -29,7 +29,7 @@
namespace graphene { namespace chain {
enum betting_market_type {
enum class betting_market_type {
moneyline,
spread,
over_under,
@ -88,7 +88,31 @@ struct betting_market_create_operation : public base_operation
void validate()const;
};
enum bet_type { back_bet, lay_bet };
enum class betting_market_resolution_type {
win,
not_win,
cancel,
BETTING_MARKET_RESOLUTION_COUNT
};
struct betting_market_resolve_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };
asset fee;
betting_market_id_type betting_market_id;
betting_market_resolution_type resolution;
extensions_type extensions;
account_id_type fee_payer()const { return GRAPHENE_WITNESS_ACCOUNT; }
void validate()const;
};
enum class bet_type { back, lay };
typedef uint32_t bet_multiplier_type;
struct bet_place_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };
@ -98,10 +122,19 @@ struct bet_place_operation : public base_operation
betting_market_id_type betting_market_id;
/// the bettor's stake
share_type amount_to_bet;
share_type amount_to_win;
// decimal odds as seen by the backer, even if this is a lay bet.
// this is a fixed-precision number scaled by GRAPHENE_BETTING_ODDS_PRECISION.
//
// For example, an even 1/1 bet would be decimal odds 2.0, so backer_multiplier
// would be 2 * GRAPHENE_BETTING_ODDS_PRECISION.
bet_multiplier_type backer_multiplier;
// the amount the blockchain reserves to pay the percentage fee on matched bets.
// when this bet is (partially) matched, the blockchain will take (part of) the fee. If this bet is canceled
// the remaining amount will be returned to the bettor
share_type amount_reserved_for_fees;
bet_type back_or_lay;
@ -131,7 +164,14 @@ FC_REFLECT( graphene::chain::betting_market_create_operation::fee_parameters_typ
FC_REFLECT( graphene::chain::betting_market_create_operation,
(fee)(group_id)(payout_condition)(asset_id)(extensions) )
FC_REFLECT_ENUM( graphene::chain::bet_type, (back_bet)(lay_bet) )
FC_REFLECT_ENUM( graphene::chain::betting_market_resolution_type, (win)(not_win)(cancel)(BETTING_MARKET_RESOLUTION_COUNT) )
FC_REFLECT( graphene::chain::betting_market_resolve_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::betting_market_resolve_operation,
(fee)(betting_market_id)(resolution)(extensions) )
FC_REFLECT_ENUM( graphene::chain::bet_type, (back)(lay) )
FC_REFLECT( graphene::chain::bet_place_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::bet_place_operation,
(fee)(bettor_id)(betting_market_id)(amount_to_bet)(amount_to_win)(amount_reserved_for_fees)(back_or_lay)(extensions) )
(fee)(bettor_id)(betting_market_id)(amount_to_bet)(backer_multiplier)(amount_reserved_for_fees)(back_or_lay)(extensions) )

View file

@ -60,8 +60,62 @@ struct event_create_operation : public base_operation
void validate()const;
};
/**
* The status of an event; this is only used for display, the blockchain does
* not care about the event's status
*/
enum class event_status
{
upcoming,
in_progress,
completed,
canceled,
STATUS_COUNT
};
/**
* The current (or final) score of an event.
* This is only used for display to the user, witnesses must resolve each
* betting market explicitly.
* These are free-form strings that we assume will make sense to the user.
* For a game like football, this may be a score like "3". For races,
* it could be a time like "1:53.4".
*/
typedef map<competitor_id_type, string> scores_map_type;
struct event_update_status_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };
asset fee;
/// the id of the event to update
event_id_type event_id;
/**
* the new status of the event (if the status hasn't changed, the creator
* of this operation must still set `status` to the event's current status)
*/
event_status status;
/*
* the new scores to be merged with the existing scores (if this operation
* does not provide scores for all competitors, they will keep their
* previous score
*/
scores_map_type scores;
extensions_type extensions;
account_id_type fee_payer()const { return GRAPHENE_WITNESS_ACCOUNT; }
void validate()const;
};
} }
FC_REFLECT( graphene::chain::event_create_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::event_create_operation,
(fee)(name)(season)(start_time)(event_group_id)(competitors)(extensions) )
FC_REFLECT_ENUM( graphene::chain::event_status, (upcoming)(in_progress)(completed)(canceled)(STATUS_COUNT) )
FC_REFLECT( graphene::chain::event_update_status_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::event_update_status_operation,
(fee)(event_id)(status)(scores)(extensions) )

View file

@ -35,6 +35,11 @@ void betting_market_create_operation::validate() const
FC_ASSERT( fee.amount >= 0 );
}
void betting_market_resolve_operation::validate() const
{
FC_ASSERT( fee.amount >= 0 );
}
void bet_place_operation::validate() const
{
FC_ASSERT( fee.amount >= 0 );