added get_total_matched_bet_amount_for_betting_market_group to bookie_plugin

This commit is contained in:
Roman Olearski 2017-07-28 18:23:57 +02:00
parent c4470131ac
commit b96459045b
11 changed files with 141 additions and 17 deletions

View file

@ -55,6 +55,7 @@ void database::validate_betting_market_group_resolutions(const betting_market_gr
{
const betting_market_object& betting_market = *betting_market_itr;
// every betting market in the group tied with resolution
idump((betting_market.id)(resolutions));
assert(resolutions.count(betting_market.id));
++betting_market_itr;
}
@ -283,7 +284,7 @@ bool bet_was_matched(database& db, const bet_object& bet,
// generate a virtual "match" op
asset asset_amount_bet(amount_bet, bet.amount_to_bet.asset_id);
db.push_applied_operation(bet_matched_operation(bet.bettor_id, bet.id,
db.push_applied_operation(bet_matched_operation(bet.bettor_id, bet.id, bet.betting_market_id,
asset_amount_bet,
fee_paid,
actual_multiplier,

View file

@ -62,6 +62,8 @@ class betting_market_group_object : public graphene::db::abstract_object< bettin
asset_id_type asset_id;
share_type total_matched_bets_amount;
bool frozen;
};
@ -427,7 +429,7 @@ typedef generic_index<betting_market_position_object, betting_market_position_mu
} } // 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)(frozen) )
FC_REFLECT_DERIVED( graphene::chain::betting_market_group_object, (graphene::db::object), (description)(event_id)(rules_id)(asset_id)(frozen)(total_matched_bets_amount) )
FC_REFLECT_DERIVED( graphene::chain::betting_market_object, (graphene::db::object), (group_id)(description)(payout_condition) )
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

@ -290,12 +290,13 @@ struct bet_matched_operation : public base_operation
struct fee_parameters_type {};
bet_matched_operation(){}
bet_matched_operation(account_id_type bettor_id, bet_id_type bet_id,
bet_matched_operation(account_id_type bettor_id, bet_id_type bet_id, betting_market_id_type betting_market_id,
asset amount_bet, share_type fees_paid,
bet_multiplier_type backer_multiplier,
share_type guaranteed_winnings_returned) :
bettor_id(bettor_id),
bet_id(bet_id),
betting_market_id(betting_market_id),
amount_bet(amount_bet),
fees_paid(fees_paid),
backer_multiplier(backer_multiplier),
@ -304,6 +305,7 @@ struct bet_matched_operation : public base_operation
account_id_type bettor_id;
bet_id_type bet_id;
betting_market_id_type betting_market_id;
asset amount_bet;
share_type fees_paid; // same asset type as amount_bet
bet_multiplier_type backer_multiplier; // the actual odds received
@ -413,7 +415,7 @@ FC_REFLECT( graphene::chain::bet_place_operation,
(fee)(bettor_id)(betting_market_id)(amount_to_bet)(backer_multiplier)(amount_reserved_for_fees)(back_or_lay)(extensions) )
FC_REFLECT( graphene::chain::bet_matched_operation::fee_parameters_type, )
FC_REFLECT( graphene::chain::bet_matched_operation, (bettor_id)(bet_id)(amount_bet)(fees_paid)(backer_multiplier)(guaranteed_winnings_returned) )
FC_REFLECT( graphene::chain::bet_matched_operation, (bettor_id)(bet_id)(betting_market_id)(amount_bet)(fees_paid)(backer_multiplier)(guaranteed_winnings_returned) )
FC_REFLECT( graphene::chain::bet_cancel_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::bet_cancel_operation, (bettor_id) (bet_to_cancel) (extensions) )

View file

@ -27,6 +27,7 @@ class bookie_api_impl
binned_order_book get_binned_order_book(graphene::chain::betting_market_id_type betting_market_id, int32_t precision);
std::shared_ptr<graphene::bookie::bookie_plugin> get_plugin();
asset get_total_matched_bet_amount_for_betting_market_group(betting_market_group_id_type group_id);
graphene::app::application& app;
};
@ -107,6 +108,11 @@ std::shared_ptr<graphene::bookie::bookie_plugin> bookie_api_impl::get_plugin()
return app.get_plugin<graphene::bookie::bookie_plugin>("bookie");
}
asset bookie_api_impl::get_total_matched_bet_amount_for_betting_market_group(betting_market_group_id_type group_id)
{
return get_plugin()->get_total_matched_bet_amount_for_betting_market_group(group_id);
}
} // detail
bookie_api::bookie_api(graphene::app::application& app) :
@ -119,5 +125,11 @@ binned_order_book bookie_api::get_binned_order_book(graphene::chain::betting_mar
return my->get_binned_order_book(betting_market_id, precision);
}
asset bookie_api::get_total_matched_bet_amount_for_betting_market_group(betting_market_group_id_type group_id)
{
return my->get_total_matched_bet_amount_for_betting_market_group(group_id);
}
} } // graphene::bookie

View file

@ -28,6 +28,7 @@
#include <graphene/chain/account_evaluator.hpp>
#include <graphene/chain/account_object.hpp>
#include <graphene/chain/betting_market_object.hpp>
#include <graphene/chain/config.hpp>
#include <graphene/chain/database.hpp>
#include <graphene/chain/evaluator.hpp>
@ -35,6 +36,7 @@
#include <graphene/chain/operation_history_object.hpp>
#include <graphene/chain/transaction_evaluation_state.hpp>
#include <fc/smart_ref_impl.hpp>
#include <fc/thread/thread.hpp>
@ -141,6 +143,8 @@ class bookie_plugin_impl
*/
void on_block_applied( const signed_block& b );
asset get_total_matched_bet_amount_for_betting_market_group(betting_market_group_id_type group_id);
graphene::chain::database& database()
{
return _self.database();
@ -216,6 +220,35 @@ void bookie_plugin_impl::on_block_applied( const signed_block& )
{
graphene::chain::database& db = database();
const vector<optional<operation_history_object> >& hist = db.get_applied_operations();
for( const optional< operation_history_object >& o_op : hist )
{
if( !o_op.valid() )
{
continue;
}
const operation_history_object& op = *o_op;
if( op.op.which() == operation::tag< bet_matched_operation >::value )
{
const bet_matched_operation& bet_matched_op = op.op.get<bet_matched_operation>();
idump((bet_matched_op));
const asset& amount_bet = bet_matched_op.amount_bet;
// object may no longer exist
//const bet_object& bet = bet_matched_op.bet_id(db);
const betting_market_object& betting_market = bet_matched_op.betting_market_id(db);
const betting_market_group_object& betting_market_group = betting_market.group_id(db);
db.modify( betting_market_group, [&]( betting_market_group_object& obj ){
obj.total_matched_bets_amount += amount_bet.amount;
});
}
}
}
asset bookie_plugin_impl::get_total_matched_bet_amount_for_betting_market_group(betting_market_group_id_type group_id)
{
graphene::chain::database& db = database();
FC_ASSERT( db.find_object(group_id), "Invalid betting market group specified" );
const betting_market_group_object& betting_market_group = group_id(db);
return asset(betting_market_group.total_matched_bets_amount, betting_market_group.asset_id);
}
} // end namespace detail
@ -247,7 +280,7 @@ void bookie_plugin::plugin_set_program_options(
void bookie_plugin::plugin_initialize(const boost::program_options::variables_map& options)
{
ilog("bookie plugin: plugin_startup() begin");
//database().applied_block.connect( [&]( const signed_block& b){ my->on_block_applied(b); } );
database().applied_block.connect( [&]( const signed_block& b){ my->on_block_applied(b); } );
database().changed_objects.connect([&](const vector<object_id_type>& changed_object_ids, const fc::flat_set<graphene::chain::account_id_type>& impacted_accounts){ my->on_objects_changed(changed_object_ids); });
auto event_index = database().add_index<primary_index<detail::persistent_event_object_index> >();
//event_index->add_secondary_index<detail::events_by_competitor_index>();
@ -266,6 +299,12 @@ flat_set<account_id_type> bookie_plugin::tracked_accounts() const
return my->_tracked_accounts;
}
asset bookie_plugin::get_total_matched_bet_amount_for_betting_market_group(betting_market_group_id_type group_id)
{
ilog("bookie plugin: get_total_matched_bet_amount_for_betting_market_group($group_id)", ("group_d", group_id));
return my->get_total_matched_bet_amount_for_betting_market_group(group_id);
}
} }
FC_REFLECT_DERIVED( graphene::bookie::detail::persistent_event_object, (graphene::db::object), (event_object_id)(name)(season)(start_time)(event_group_id)(status)(scores) )

View file

@ -7,6 +7,9 @@
#include <fc/variant_object.hpp>
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/protocol/asset.hpp>
using namespace graphene::chain;
namespace graphene { namespace app {
class application;
@ -39,6 +42,7 @@ class bookie_api
* precision = 2 would bin on (1 - 1.01], (1.01 - 1.02]
*/
binned_order_book get_binned_order_book(graphene::chain::betting_market_id_type betting_market_id, int32_t precision);
asset get_total_matched_bet_amount_for_betting_market_group(betting_market_group_id_type group_id);
std::shared_ptr<detail::bookie_api_impl> my;
};
@ -50,5 +54,6 @@ FC_REFLECT(graphene::bookie::binned_order_book, (aggregated_back_bets)(aggregate
FC_API(graphene::bookie::bookie_api,
(get_binned_order_book)
(get_total_matched_bet_amount_for_betting_market_group)
)

View file

@ -70,6 +70,7 @@ class bookie_plugin : public graphene::app::plugin
virtual void plugin_startup() override;
flat_set<account_id_type> tracked_accounts()const;
asset get_total_matched_bet_amount_for_betting_market_group(betting_market_group_id_type group_id);
friend class detail::bookie_plugin_impl;
std::unique_ptr<detail::bookie_plugin_impl> my;

View file

@ -1570,6 +1570,8 @@ class wallet_api
order_book get_order_book( const string& base, const string& quote, unsigned limit = 50);
asset get_total_matched_bet_amount_for_betting_market_group(betting_market_group_id_type group_id);
vector<sport_object> list_sports() const;
vector<event_group_object> list_event_groups(sport_id_type sport_id) const;
vector<betting_market_group_object> list_betting_market_groups(event_id_type event_id) const;
@ -1980,4 +1982,5 @@ FC_API( graphene::wallet::wallet_api,
(get_tournaments_by_state)
(get_tournament)
(get_order_book)
(get_total_matched_bet_amount_for_betting_market_group)
)

View file

@ -5628,6 +5628,11 @@ order_book wallet_api::get_order_book( const string& base, const string& quote,
return( my->_remote_db->get_order_book( base, quote, limit ) );
}
asset wallet_api::get_total_matched_bet_amount_for_betting_market_group(betting_market_group_id_type group_id)
{
return asset();
}
// default ctor necessary for FC_REFLECT
signed_block_with_info::signed_block_with_info( const signed_block& block )
: signed_block( block )

View file

@ -775,7 +775,13 @@ BOOST_FIXTURE_TEST_SUITE( tennis_bet_tests, database_fixture )
const betting_market_object& berdych_wins_market = create_betting_market(moneyline_berdych_vs_federer.id, {{"en", "T. Berdych defeats R. Federer"}}); \
const betting_market_object& federer_wins_market = create_betting_market(moneyline_berdych_vs_federer.id, {{"en", "R. Federer defeats T. Berdych"}}); \
const betting_market_object& cilic_wins_market = create_betting_market(moneyline_cilic_vs_querrey.id, {{"en", "M. Cilic defeats S. Querrey"}}); \
const betting_market_object& querrey_wins_market = create_betting_market(moneyline_cilic_vs_querrey.id, {{"en", "S. Querrey defeats M. Cilic"}});
const betting_market_object& querrey_wins_market = create_betting_market(moneyline_cilic_vs_querrey.id, {{"en", "S. Querrey defeats M. Cilic"}});\
\
const event_object& cilic_vs_federer = create_event({{"en", "R. Federer/M. Cilic"}}, {{"en", "2017"}}, wimbledon.id); \
const betting_market_group_object& moneyline_cilic_vs_federer = create_betting_market_group({{"en", "Moneyline final"}}, cilic_vs_federer.id, tennis_rules.id, asset_id_type()); \
const betting_market_object& federer_wins_final_market = create_betting_market(moneyline_cilic_vs_federer.id, {{"en", "R. Federer defeats M. Cilic"}}); \
const betting_market_object& cilic_wins_final_market = create_betting_market(moneyline_cilic_vs_federer.id, {{"en", "M. Cilic defeats R. Federer"}});
BOOST_AUTO_TEST_CASE( wimbledon_2017_gentelmen_singles_sf_test )
{
@ -789,13 +795,13 @@ BOOST_AUTO_TEST_CASE( wimbledon_2017_gentelmen_singles_sf_test )
transfer(account_id_type(), alice_id, asset(10000000));
transfer(account_id_type(), bob_id, asset(10000000));
BOOST_TEST_MESSAGE("moneyline_berdych_vs_federer event " << fc::variant(moneyline_berdych_vs_federer.event_id).as<std::string>());
BOOST_TEST_MESSAGE("moneyline_cilic_vs_querrey event " << fc::variant(moneyline_cilic_vs_querrey.event_id).as<std::string>());
BOOST_TEST_MESSAGE("moneyline_berdych_vs_federer " << fc::variant(moneyline_berdych_vs_federer.id).as<std::string>());
BOOST_TEST_MESSAGE("moneyline_cilic_vs_querrey " << fc::variant(moneyline_cilic_vs_querrey.id).as<std::string>());
BOOST_TEST_MESSAGE("berdych_wins_market group " << fc::variant(berdych_wins_market.group_id).as<std::string>());
BOOST_TEST_MESSAGE("federer_wins_market group " << fc::variant(federer_wins_market.group_id).as<std::string>());
BOOST_TEST_MESSAGE("cilic_wins_market group " << fc::variant(cilic_wins_market.group_id).as<std::string>());
BOOST_TEST_MESSAGE("querrey_wins_market group " << fc::variant(querrey_wins_market.group_id).as<std::string>());
BOOST_TEST_MESSAGE("berdych_wins_market " << fc::variant(berdych_wins_market.id).as<std::string>());
BOOST_TEST_MESSAGE("federer_wins_market " << fc::variant(federer_wins_market.id).as<std::string>());
BOOST_TEST_MESSAGE("cilic_wins_market " << fc::variant(cilic_wins_market.id).as<std::string>());
BOOST_TEST_MESSAGE("querrey_wins_market " << fc::variant(querrey_wins_market.id).as<std::string>());
place_bet(alice_id, berdych_wins_market.id, bet_type::back, asset(1000000, asset_id_type()), 2 * GRAPHENE_BETTING_ODDS_PRECISION, 1000000 / 50 /* chain defaults to 2% fees */);
place_bet(bob_id, berdych_wins_market.id, bet_type::lay, asset(1000000, asset_id_type()), 2 * GRAPHENE_BETTING_ODDS_PRECISION, 1000000 / 50 /* chain defaults to 2% fees */);
@ -834,9 +840,56 @@ BOOST_AUTO_TEST_CASE( wimbledon_2017_gentelmen_singles_sf_test )
} FC_LOG_AND_RETHROW()
}
BOOST_AUTO_TEST_CASE( wimbledon_2017_gentelmen_singles_final_test )
{
try
{
ACTORS( (alice)(bob) );
CREATE_TENNIS_BETTING_MARKET();
uint16_t rake_fee_percentage = db.get_global_properties().parameters.betting_rake_fee_percentage;
transfer(account_id_type(), alice_id, asset(10000000));
transfer(account_id_type(), bob_id, asset(10000000));
BOOST_TEST_MESSAGE("moneyline_cilic_vs_federer " << fc::variant(moneyline_cilic_vs_federer.id).as<std::string>());
BOOST_TEST_MESSAGE("federer_wins_final_market " << fc::variant(federer_wins_final_market.id).as<std::string>());
BOOST_TEST_MESSAGE("cilic_wins_final_market " << fc::variant(cilic_wins_final_market.id).as<std::string>());
place_bet(alice_id, cilic_wins_final_market.id, bet_type::back, asset(1000000, asset_id_type()), 2 * GRAPHENE_BETTING_ODDS_PRECISION, 1000000 / 50 /* chain defaults to 2% fees */);
place_bet(bob_id, cilic_wins_final_market.id, bet_type::lay, asset(1000000, asset_id_type()), 2 * GRAPHENE_BETTING_ODDS_PRECISION, 1000000 / 50 /* chain defaults to 2% fees */);
betting_market_group_id_type moneyline_cilic_vs_federer_id = moneyline_cilic_vs_federer.id;
auto cilic_wins_final_market_id = cilic_wins_final_market.id;
auto federer_wins_final_market_id = federer_wins_final_market.id;
generate_blocks(13);
const betting_market_group_object& betting_market_group = moneyline_cilic_vs_federer_id(db);
BOOST_CHECK_EQUAL(betting_market_group.total_matched_bets_amount.value, 2000000);
BOOST_CHECK_EQUAL(get_balance(alice_id, asset_id_type()), 10000000 - 1000000 - 20000);
BOOST_CHECK_EQUAL(get_balance(bob_id, asset_id_type()), 10000000 - 1000000 - 20000);
// federer wins
resolve_betting_market_group(moneyline_cilic_vs_federer_id,
{{cilic_wins_final_market_id, betting_market_resolution_type::/*don't use cancel - there are bets for berdych*/not_win},
{federer_wins_final_market_id, betting_market_resolution_type::win}});
uint32_t bob_rake_value = (-1000000 + 2000000) * rake_fee_percentage / GRAPHENE_1_PERCENT / 100;
BOOST_TEST_MESSAGE("Bob's rake value " + std::to_string(bob_rake_value));
BOOST_CHECK_EQUAL(get_balance(alice_id, asset_id_type()), 10000000 - 1000000 - 20000);
BOOST_CHECK_EQUAL(get_balance(bob_id, asset_id_type()), 10000000 - 1000000 - 20000 + 2000000 - bob_rake_value);
} FC_LOG_AND_RETHROW()
}
BOOST_AUTO_TEST_SUITE_END()
//#define BOOST_TEST_MODULE "C++ Unit Tests for Graphene Blockchain Database"
#include <cstdlib>
#include <iostream>

View file

@ -26,7 +26,8 @@
#include <graphene/account_history/account_history_plugin.hpp>
#include <graphene/market_history/market_history_plugin.hpp>
//#include <graphene/bookie/bookie_plugin.hpp>
#include <graphene/bookie/bookie_plugin.hpp>
#include <graphene/bookie/bookie_api.hpp>
#include <graphene/db/simple_index.hpp>
@ -81,7 +82,7 @@ database_fixture::database_fixture()
auto ahplugin = app.register_plugin<graphene::account_history::account_history_plugin>();
auto mhplugin = app.register_plugin<graphene::market_history::market_history_plugin>();
//auto bookieplugin = app.register_plugin<graphene::bookie::bookie_plugin>();
auto bookieplugin = app.register_plugin<graphene::bookie::bookie_plugin>();
init_account_pub_key = init_account_priv_key.get_public_key();
boost::program_options::variables_map options;
@ -111,12 +112,12 @@ database_fixture::database_fixture()
ahplugin->plugin_initialize(options);
mhplugin->plugin_set_app(&app);
mhplugin->plugin_initialize(options);
//bookieplugin->plugin_set_app(&app);
//bookieplugin->plugin_initialize(options);
bookieplugin->plugin_set_app(&app);
bookieplugin->plugin_initialize(options);
ahplugin->plugin_startup();
mhplugin->plugin_startup();
//bookieplugin->plugin_startup();
bookieplugin->plugin_startup();
generate_block();