Add blockchain parameters to limit the allowed bet odds, start data structure to

track an account's market position
This commit is contained in:
Eric Frias 2017-03-21 18:10:02 -04:00
parent ccd570874f
commit 06c56484de
10 changed files with 100 additions and 13 deletions

View file

@ -292,6 +292,20 @@ namespace graphene { namespace app {
} case balance_object_type:{
/** these are free from any accounts */
break;
}
case sport_object_type:
case competitor_object_type:
case event_group_object_type:
case event_object_type:
case betting_market_group_object_type:
case betting_market_object_type:
/** these are free from any accounts */
break;
case bet_object_type:{
const auto& aobj = dynamic_cast<const bet_object*>(obj);
assert( aobj != nullptr );
result.push_back( aobj->bettor_id );
break;
}
}
}
@ -350,6 +364,8 @@ namespace graphene { namespace app {
break;
case impl_fba_accumulator_object_type:
break;
case impl_betting_market_position_object_type:
break;
}
}
return result;

View file

@ -97,6 +97,22 @@ void_result bet_place_evaluator::do_evaluate(const bet_place_operation& op)
FC_ASSERT( db().find_object(op.bettor_id), "Invalid betting_market_group specified" );
FC_ASSERT( db().find_object(op.betting_market_id), "Invalid betting_market specified" );
const chain_parameters& current_params = db().get_global_properties().parameters;
FC_ASSERT( op.backer_multiplier >= current_params.min_bet_multiplier &&
op.backer_multiplier <= current_params.max_bet_multiplier,
"Bet odds are outside the blockchain's limits" );
if (!current_params.permitted_betting_odds_increments.empty())
{
bet_multiplier_type allowed_increment;
const auto iter = current_params.permitted_betting_odds_increments.upper_bound(op.backer_multiplier);
if (iter == current_params.permitted_betting_odds_increments.end())
allowed_increment = std::prev(current_params.permitted_betting_odds_increments.end())->second;
else
allowed_increment = iter->second;
FC_ASSERT(op.backer_multiplier % allowed_increment == 0, "Bet odds must be a multiple of ${allowed_increment}", ("allowed_increment", allowed_increment));
}
return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) }

View file

@ -159,6 +159,9 @@ const uint8_t betting_market_object::type_id;
const uint8_t bet_object::space_id;
const uint8_t bet_object::type_id;
const uint8_t betting_market_position_object::space_id;
const uint8_t betting_market_position_object::type_id;
void database::initialize_evaluators()
{
@ -263,6 +266,7 @@ void database::initialize_indexes()
add_index< primary_index< buyback_index > >();
add_index< primary_index< simple_index< fba_accumulator_object > > >();
add_index< primary_index< betting_market_position_multi_index > >();
}
void database::init_genesis(const genesis_state_type& genesis_state)

View file

@ -77,6 +77,22 @@ class bet_object : public graphene::db::abstract_object< bet_object >
bet_type back_or_lay;
};
class betting_market_position_object : public graphene::db::abstract_object< betting_market_position_object >
{
public:
static const uint8_t space_id = implementation_ids;
static const uint8_t type_id = impl_betting_market_position_object_type;
account_id_type bettor_id;
betting_market_id_type betting_market_id;
share_type pay_if_payout_condition;
share_type pay_if_not_payout_condition;
share_type pay_if_canceled;
share_type pay_if_not_canceled;
};
typedef multi_index_container<
betting_market_group_object,
indexed_by<
@ -100,8 +116,17 @@ typedef multi_index_container<
ordered_unique< tag<by_id>, member< object, object_id_type, &object::id > > > > bet_object_multi_index_type;
typedef generic_index<bet_object, bet_object_multi_index_type> bet_object_index;
typedef multi_index_container<
betting_market_position_object,
indexed_by<
ordered_unique< tag<by_id>, member< object, object_id_type, &object::id > > > > betting_market_position_multi_index_type;
typedef generic_index<betting_market_position_object, betting_market_position_multi_index_type> betting_market_position_multi_index;
} } // graphene::chain
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)(backer_multiplier)(amount_reserved_for_fees)(back_or_lay) )
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) )

View file

@ -186,3 +186,16 @@
/// the largest bet multiplier we will accept
#define GRAPHENE_BETTING_MAX_MULTIPLIER 100010000
///@}
#define GRAPHENE_DEFAULT_MIN_BET_MULTIPLIER 10100
#define GRAPHENE_DEFAULT_MAX_BET_MULTIPLIER 10000000
#define GRAPHENE_DEFAULT_PERMITTED_BETTING_ODDS_INCREMENTS { { 20000, 100}, /* <= 2: 0.01 */ \
{ 30000, 200}, /* <= 3: 0.02 */ \
{ 40000, 500}, /* <= 4: 0.05 */ \
{ 60000, 1000}, /* <= 6: 0.10 */ \
{ 100000, 2000}, /* <= 10: 0.20 */ \
{ 200000, 5000}, /* <= 20: 0.50 */ \
{ 300000, 10000}, /* <= 30: 1.00 */ \
{ 500000, 20000}, /* <= 50: 2.00 */ \
{ 1000000, 50000}, /* <= 100: 5.00 */ \
{ 10000000, 100000} } /* <= 1000: 10.00 */

View file

@ -37,15 +37,6 @@ class event_object : public graphene::db::abstract_object< event_object >
static const uint8_t space_id = protocol_ids;
static const uint8_t type_id = event_object_type;
enum status
{
upcoming,
in_progress,
completed,
canceled,
STATUS_COUNT
};
internationalized_string_type name;
internationalized_string_type season;
@ -55,6 +46,9 @@ class event_object : public graphene::db::abstract_object< event_object >
event_group_id_type event_group_id;
vector<competitor_id_type> competitors;
event_status status;
vector<string> scores;
};
typedef multi_index_container<
@ -65,5 +59,4 @@ typedef multi_index_container<
typedef generic_index<event_object, event_object_multi_index_type> event_object_index;
} } // graphene::chain
FC_REFLECT_ENUM( graphene::chain::event_object::status, (upcoming)(in_progress)(completed)(canceled)(STATUS_COUNT) )
FC_REFLECT_DERIVED( graphene::chain::event_object, (graphene::db::object), (name)(season)(start_time)(event_group_id)(competitors) )
FC_REFLECT_DERIVED( graphene::chain::event_object, (graphene::db::object), (name)(season)(start_time)(event_group_id)(status)(competitors)(scores) )

View file

@ -111,7 +111,6 @@ struct betting_market_resolve_operation : public base_operation
};
enum class bet_type { back, lay };
typedef uint32_t bet_multiplier_type;
struct bet_place_operation : public base_operation
{

View file

@ -69,6 +69,11 @@ namespace graphene { namespace chain {
uint16_t accounts_per_fee_scale = GRAPHENE_DEFAULT_ACCOUNTS_PER_FEE_SCALE; ///< number of accounts between fee scalings
uint8_t account_fee_scale_bitshifts = GRAPHENE_DEFAULT_ACCOUNT_FEE_SCALE_BITSHIFTS; ///< number of times to left bitshift account registration fee at each scaling
uint8_t max_authority_depth = GRAPHENE_MAX_SIG_CHECK_DEPTH;
bet_multiplier_type min_bet_multiplier = GRAPHENE_DEFAULT_MIN_BET_MULTIPLIER;
bet_multiplier_type max_bet_multiplier = GRAPHENE_DEFAULT_MAX_BET_MULTIPLIER;
flat_map<bet_multiplier_type, bet_multiplier_type> permitted_betting_odds_increments = GRAPHENE_DEFAULT_PERMITTED_BETTING_ODDS_INCREMENTS;
extensions_type extensions;
/** defined in fee_schedule.cpp */
@ -106,5 +111,8 @@ FC_REFLECT( graphene::chain::chain_parameters,
(accounts_per_fee_scale)
(account_fee_scale_bitshifts)
(max_authority_depth)
(min_bet_multiplier)
(max_bet_multiplier)
(permitted_betting_odds_increments)
(extensions)
)

View file

@ -162,7 +162,8 @@ namespace graphene { namespace chain {
impl_budget_record_object_type,
impl_special_authority_object_type,
impl_buyback_object_type,
impl_fba_accumulator_object_type
impl_fba_accumulator_object_type,
impl_betting_market_position_object_type
};
//typedef fc::unsigned_int object_id_type;
@ -228,6 +229,7 @@ namespace graphene { namespace chain {
class special_authority_object;
class buyback_object;
class fba_accumulator_object;
class betting_market_position_object;
typedef object_id< implementation_ids, impl_global_property_object_type, global_property_object> global_property_id_type;
typedef object_id< implementation_ids, impl_dynamic_global_property_object_type, dynamic_global_property_object> dynamic_global_property_id_type;
@ -248,6 +250,7 @@ namespace graphene { namespace chain {
typedef object_id< implementation_ids, impl_special_authority_object_type, special_authority_object > special_authority_id_type;
typedef object_id< implementation_ids, impl_buyback_object_type, buyback_object > buyback_id_type;
typedef object_id< implementation_ids, impl_fba_accumulator_object_type, fba_accumulator_object > fba_accumulator_id_type;
typedef object_id< implementation_ids, impl_betting_market_position_object_type, betting_market_position_object > betting_market_position_id_type;
typedef fc::array<char, GRAPHENE_MAX_ASSET_SYMBOL_LENGTH> symbol_type;
typedef fc::ripemd160 block_id_type;
@ -327,6 +330,8 @@ namespace graphene { namespace chain {
};
typedef flat_map<std::string, std::string> internationalized_string_type;
typedef uint32_t bet_multiplier_type;
} } // graphene::chain
namespace fc
@ -390,6 +395,7 @@ FC_REFLECT_ENUM( graphene::chain::impl_object_type,
(impl_special_authority_object_type)
(impl_buyback_object_type)
(impl_fba_accumulator_object_type)
(impl_betting_market_position_object_type)
)
FC_REFLECT_TYPENAME( graphene::chain::share_type )
@ -428,6 +434,7 @@ FC_REFLECT_TYPENAME( graphene::chain::budget_record_id_type )
FC_REFLECT_TYPENAME( graphene::chain::special_authority_id_type )
FC_REFLECT_TYPENAME( graphene::chain::buyback_id_type )
FC_REFLECT_TYPENAME( graphene::chain::fba_accumulator_id_type )
FC_REFLECT_TYPENAME( graphene::chain::betting_market_position_id_type )
FC_REFLECT( graphene::chain::void_t, )

View file

@ -188,6 +188,12 @@ namespace graphene { namespace chain {
"Maximum transaction expiration time must be greater than a block interval" );
FC_ASSERT( maximum_proposal_lifetime - committee_proposal_review_period > block_interval,
"Committee proposal review period must be less than the maximum proposal lifetime" );
FC_ASSERT( min_bet_multiplier >= GRAPHENE_BETTING_MIN_MULTIPLIER &&
min_bet_multiplier <= GRAPHENE_BETTING_MAX_MULTIPLIER );
FC_ASSERT( max_bet_multiplier >= GRAPHENE_BETTING_MIN_MULTIPLIER &&
max_bet_multiplier <= GRAPHENE_BETTING_MAX_MULTIPLIER );
FC_ASSERT( min_bet_multiplier < max_bet_multiplier );
}
} } // graphene::chain