Implementing missing functionality (5)

Peerplays Blockchain pre-launch settings & modifications I II III
This commit is contained in:
Roman Olearski 2017-04-08 13:45:05 +02:00
parent 33e2f4fd14
commit 94ba6266c6
11 changed files with 88 additions and 47 deletions

View file

@ -179,6 +179,7 @@ void database::initialize_evaluators()
register_evaluator<tournament_create_evaluator>();
register_evaluator<tournament_join_evaluator>();
register_evaluator<game_move_evaluator>();
register_evaluator<tournament_leave_evaluator>();
}
void database::initialize_indexes()

View file

@ -153,7 +153,7 @@ namespace graphene { namespace chain {
asset fee;
/// The account that payed the buy-in for the tournament
/// The account that is paying the fee
account_id_type payer_account_id;
/// The account that would play in the tournament, would receive any winnings.

View file

@ -33,9 +33,6 @@ namespace graphene { namespace chain {
private:
const tournament_object* _tournament_obj = nullptr;
const tournament_details_object* _tournament_details_obj = nullptr;
//const account_object* _payer_account = nullptr;
//const account_object* _player_account = nullptr;
//const asset_object* _buy_in_back_asset_type = nullptr;
public:
typedef tournament_leave_operation operation_type;

View file

@ -38,6 +38,9 @@ namespace graphene { namespace chain {
/// List of payers who have contributed to the prize pool
flat_map<account_id_type, share_type> payers;
/// List of player payer pairs needed by torunament leave operation
flat_map<account_id_type, account_id_type> players_payers;
/// List of all matches in this tournament. When the tournament starts, all matches
/// are created. Matches in the first round will have players, matches in later
/// rounds will not be populated.

View file

@ -125,13 +125,12 @@ namespace graphene { namespace chain {
}
else
{
// $$$ III. Rock Paper Scissors Game Need to review how Ties are dealt with.
short i = std::rand() % match.players.size(); // ! event.db.get_random_bits(match.players.size()) ;
// III. Rock Paper Scissors Game Need to review how Ties are dealt with.
short i = match.number_of_ties == match.games.size() ? 0 : event.db.get_random_bits(match.players.size()) ;
match.match_winners.insert(match.players[i]);
++match.number_of_wins[i];
if (match.number_of_ties == match.games.size())
match.game_winners[match.game_winners.size()-1].insert(match.players[i]);
}
match.end_time = event.db.head_block_time();

View file

@ -59,7 +59,7 @@ share_type tournament_leave_operation::calculate_fee(const fee_parameters_type&
void tournament_leave_operation::validate()const
{
FC_ASSERT( fee.amount >= 0 );
// todo FC_ASSERT( fee.amount >= 0 );
}

View file

@ -186,23 +186,11 @@ namespace graphene { namespace chain {
_tournament_details_obj = &_tournament_obj->tournament_details_id(d);
FC_ASSERT(_tournament_details_obj->registered_players.find(op.player_account_id) != _tournament_details_obj->registered_players.end(),
"Player is not registered for this tournament");
FC_ASSERT(_tournament_details_obj->payers.find(op.payer_account_id) != _tournament_details_obj->payers.end(),
"Payer is not registered for this tournament");
#if 0
_payer_account = &op.payer_account_id(d);
_buy_in_back_asset_type = &(_tournament_obj->options.buy_in.asset_id(d));
GRAPHENE_ASSERT(!_buy_in_back_asset_type->is_transfer_restricted(),
transfer_restricted_transfer_asset,
"Asset {asset} has transfer_restricted flag enabled",
("asset", _buy_in_back_asset_type->id));
//FC_ASSERT(_tournament_details_obj->payers.find(op.payer_account_id) != _tournament_details_obj->payers.end(),
// "Payer is not registered for this tournament");
GRAPHENE_ASSERT(is_authorized_asset(d, *_payer_account, *_buy_in_back_asset_type),
transfer_from_account_not_whitelisted,
"payer account ${payer} is not whitelisted for asset ${asset}",
("payer", op.payer_account_id)
("asset", _buy_in_back_asset_type->id));
#endif
FC_ASSERT(_tournament_obj->get_state() == tournament_state::accepting_registrations);
FC_ASSERT(_tournament_obj->get_state() == tournament_state::accepting_registrations ||
_tournament_obj->get_state() == tournament_state::awaiting_start);
FC_ASSERT(d.head_block_time() <= _tournament_obj->options.registration_deadline,
"Registration deadline has already passed");
return void_result();

View file

@ -391,6 +391,7 @@ namespace graphene { namespace chain {
event.db.modify(tournament_details_obj, [&](tournament_details_object& tournament_details_obj){
tournament_details_obj.payers[event.payer_id] += tournament_obj->options.buy_in.amount;
tournament_details_obj.registered_players.insert(event.player_id);
tournament_details_obj.players_payers[event.player_id] = event.payer_id;
});
++tournament_obj->registered_players;
tournament_obj->prize_pool += tournament_obj->options.buy_in.amount;
@ -399,19 +400,21 @@ namespace graphene { namespace chain {
void unregister_player(const player_unregistered& event)
{
fc_ilog(fc::logger::get("tournament"),
"In register_player action, player_id is ${player_id}, payer_id is ${payer_id}",
("player_id", event.player_id)("payer_id", event.payer_id));
"In unregister_player action, player_id is ${player_id}",
("player_id", event.player_id));
event.db.adjust_balance(event.payer_id, tournament_obj->options.buy_in);
const tournament_details_object& tournament_details_obj = tournament_obj->tournament_details_id(event.db);
event.db.modify(tournament_details_obj, [&](tournament_details_object& tournament_details_obj){
tournament_details_obj.payers[event.payer_id] -= tournament_obj->options.buy_in.amount;
if (tournament_details_obj.payers[event.payer_id] <= 0)
tournament_details_obj.payers.erase(event.payer_id);
account_id_type payer_id = tournament_details_obj.players_payers[event.player_id];
tournament_details_obj.payers[payer_id] -= tournament_obj->options.buy_in.amount;
if (tournament_details_obj.payers[payer_id] <= 0)
tournament_details_obj.payers.erase(payer_id);
tournament_details_obj.registered_players.erase(event.player_id);
tournament_details_obj.players_payers.erase(event.player_id);
});
++tournament_obj->registered_players;
tournament_obj->prize_pool += tournament_obj->options.buy_in.amount;
--tournament_obj->registered_players;
tournament_obj->prize_pool -= tournament_obj->options.buy_in.amount;
}
// Transition table for tournament

View file

@ -1501,13 +1501,13 @@ class wallet_api
signed_transaction tournament_join( string payer_account, string player_account, tournament_id_type tournament_id, string buy_in_amount, string buy_in_asset_symbol, bool broadcast = false );
/** Leave an existing tournament
* @param payer_account the account that payed buy-in and the fee to join the tournament
* @param payer_account the account that is paying the fee
* @param player_account the account that would be playing in the tournament
* @param tournament_id the tournament the user wishes to leave
* @param broadcast true if you wish to broadcast the transaction
* @return the signed version of the transaction
*/
signed_transaction tournament_leave( string payer_account, string player_account, tournament_id_type tournament_id, bool broadcast = false);
signed_transaction tournament_leave(string payer_account, string player_account, tournament_id_type tournament_id, bool broadcast = false);
/** Get a list of upcoming tournaments
* @param limit the number of tournaments to return

View file

@ -4859,8 +4859,8 @@ signed_transaction wallet_api::tournament_leave( string payer_account,
bool broadcast)
{
FC_ASSERT( !is_locked() );
account_object payer_account_obj = get_account(payer_account);
account_object player_account_obj = get_account(player_account);
account_object payer_account_obj = get_account(payer_account);
//graphene::chain::tournament_object tournament_obj = my->get_object<graphene::chain::tournament_object>(tournament_id);
signed_transaction tx;

View file

@ -234,7 +234,34 @@ public:
players.insert(player_id);
players_keys[player_id] = sig_priv_key;
}
}
void leave_tournament(const tournament_id_type & tournament_id,
const account_id_type& player_id,
const account_id_type& payer_id,
const fc::ecc::private_key& sig_priv_key
)
{
graphene::chain::database& db = df.db;
const chain_parameters& params = db.get_global_properties().parameters;
signed_transaction tx;
tournament_leave_operation op;
op.payer_account_id = payer_id;
op.player_account_id = player_id;
op.tournament_id = tournament_id;
tx.operations = {op};
for( auto& op : tx.operations )
db.current_fee_schedule().set_fee(op);
tx.validate();
tx.set_expiration(db.head_block_time() + fc::seconds( params.block_interval * (params.maintenance_skip_slots + 1) * 3));
df.sign(tx, sig_priv_key);
PUSH_TX(db, tx);
//players.erase(player_id);
}
// stolen from cli_wallet
void rps_throw(const game_id_type& game_id,
@ -434,13 +461,14 @@ BOOST_FIXTURE_TEST_CASE( simple, database_fixture )
#define TEST2_NR_OF_PLAYERS_NUMBER 4
#endif
BOOST_TEST_MESSAGE("Hello simple tournament test");
ACTORS((nathan)(alice)(bob)(carol)(dave)(ed)(frank)(george)(harry)(ike));
ACTORS((nathan)(alice)(bob)(carol)(dave)(ed)(frank)(george)(harry)(ike)(romek));
tournaments_helper tournament_helper(*this);
fc::ecc::private_key nathan_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("nathan")));
BOOST_TEST_MESSAGE( "Giving folks some money" );
transfer(committee_account, nathan_id, asset(1000000000));
transfer(committee_account, romek_id, asset(2000000));
transfer(committee_account, alice_id, asset(2000000));
transfer(committee_account, bob_id, asset(3000000));
transfer(committee_account, carol_id, asset(4000000));
@ -486,8 +514,13 @@ BOOST_FIXTURE_TEST_CASE( simple, database_fixture )
3, 1, 3, 3600, 3, 3, true);
BOOST_REQUIRE(tournament_id == tournament_id_type(1));
tournament_helper.join_tournament(tournament_id, alice_id, alice_id, fc::ecc::private_key::regenerate(fc::sha256::hash(string("alice"))), buy_in);
// romek joins but will leave
//tournament_helper.leave_tournament(tournament_id, romek_id, romek_id, fc::ecc::private_key::regenerate(fc::sha256::hash(string("romek"))));
tournament_helper.join_tournament(tournament_id, romek_id, romek_id, fc::ecc::private_key::regenerate(fc::sha256::hash(string("romek"))), buy_in);
tournament_helper.join_tournament(tournament_id, bob_id, bob_id, fc::ecc::private_key::regenerate(fc::sha256::hash(string("bob"))), buy_in);
tournament_helper.join_tournament(tournament_id, carol_id, carol_id, fc::ecc::private_key::regenerate(fc::sha256::hash(string("carol"))), buy_in);
// romek leaves
tournament_helper.leave_tournament(tournament_id, romek_id, romek_id, fc::ecc::private_key::regenerate(fc::sha256::hash(string("romek"))));
tournament_helper.join_tournament(tournament_id, dave_id, dave_id, fc::ecc::private_key::regenerate(fc::sha256::hash(string("dave"))), buy_in);
#if TEST2_NR_OF_PLAYERS_NUMBER > 4
tournament_helper.join_tournament(tournament_id, ed_id, ed_id, fc::ecc::private_key::regenerate(fc::sha256::hash(string("ed"))), buy_in);
@ -535,12 +568,7 @@ BOOST_FIXTURE_TEST_CASE( simple, database_fixture )
#endif
};
#if 0
// trying to randomize automatic moves ?
auto n = std::rand() % 100;
for(int i = 0; i < n ; ++i)
db.get_random_bits(3);
#endif
abc("@ tournament awaiting start");
BOOST_TEST_MESSAGE( "Generating blocks, waiting for tournaments' completion");
generate_block();
@ -599,6 +627,7 @@ BOOST_FIXTURE_TEST_CASE( simple, database_fixture )
}
#endif
#if 1
// Test of handling ties, creating two tournamenst, joinig players,
// All generated moves are identical.
BOOST_FIXTURE_TEST_CASE( ties, database_fixture )
@ -711,6 +740,7 @@ BOOST_FIXTURE_TEST_CASE( ties, database_fixture )
throw;
}
}
#endif
// Test of canceled tournament
// Checking buyin refund.
@ -1074,8 +1104,8 @@ BOOST_FIXTURE_TEST_CASE( massive, database_fixture )
{
try
{
#define MIN_TOURNAMENTS_NUMBER 1
#define MAX_TOURNAMENTS_NUMBER 10
#define MIN_TOURNAMENTS_NUMBER 7
#define MAX_TOURNAMENTS_NUMBER 13
#define MIN_PLAYERS_NUMBER 2
#define MAX_PLAYERS_NUMBER 64
@ -1093,7 +1123,7 @@ BOOST_FIXTURE_TEST_CASE( massive, database_fixture )
// creating a pool of actors
std::vector<std::tuple<std::string, account_id_type, fc::ecc::private_key>> actors;
for(unsigned i = 0; i < 2 * MAX_PLAYERS_NUMBER; ++i)
for(unsigned i = 0; i < 3 * MAX_PLAYERS_NUMBER; ++i)
{
std::string name = "account" + std::to_string(i);
auto priv_key = generate_private_key(name);
@ -1114,14 +1144,34 @@ BOOST_FIXTURE_TEST_CASE( massive, database_fixture )
asset buy_in = asset(1000 * number_of_players + 100 * i);
tournament_id_type tournament_id;
tournament_id = tournament_helper.create_tournament (nathan_id, nathan_priv_key, buy_in, number_of_players, 30, 30, number_of_wins);
const tournament_object& tournament = tournament_id(db);
for (unsigned j = 0; j < actors.size() && number_of_players > 0; ++j)
for (unsigned j = 0; j < actors.size()-1 && number_of_players > 0; ++j)
{
if (number_of_players < actors.size() - j && std::rand() % 2 == 0) continue;
auto a = actors[j];
--number_of_players;
tournament_helper.join_tournament(tournament_id, std::get<1>(a), std::get<1>(a), std::get<2>(a), buy_in);
if (j == i)
{
BOOST_TEST_MESSAGE("Player " + std::get<0>(a) + " is leaving tournament " + std::to_string(i) +
", when tournament state is " + std::to_string((int)tournament.get_state()));
tournament_helper.leave_tournament(tournament_id, std::get<1>(a), std::get<1>(a), std::get<2>(a));
continue;
}
--number_of_players;
if (!number_of_players)
{
BOOST_TEST_MESSAGE("Player " + std::get<0>(a) + " is leaving tournament " + std::to_string(i) +
", when tournament state is " + std::to_string((int)tournament.get_state()));
tournament_helper.leave_tournament(tournament_id, std::get<1>(a), std::get<1>(a), std::get<2>(a));
++j;
a = actors[j];
BOOST_TEST_MESSAGE("Player " + std::get<0>(a) + " is joinig tournament " + std::to_string(i) +
", when tournament state is " + std::to_string((int)tournament.get_state()));
tournament_helper.join_tournament(tournament_id, std::get<1>(a), std::get<1>(a), std::get<2>(a), buy_in);
}
}
BOOST_TEST_MESSAGE("Tournament " + std::to_string(i) + " is in state " + std::to_string((int)tournament.get_state()));
}
uint16_t tournaments_to_complete = number_of_tournaments;