Test affiliate payout in RPS tournament

This commit is contained in:
Peter Conrad 2018-04-15 10:18:41 +02:00 committed by Fabian Schuh
parent d25604e467
commit 55fb6c4ce2
No known key found for this signature in database
GPG key ID: F2538A4B282D6238
3 changed files with 182 additions and 22 deletions

View file

@ -131,7 +131,7 @@ optional<account_id_type> tournaments_helper::get_asset_dividend_account(const a
{
graphene::chain::database& db = df.db;
optional<account_id_type> result;
const asset_object& asset_obj = asset_id(db);
const asset_object& asset_obj = asset_id_type()(db);
if (asset_obj.dividend_data_id.valid())
{
@ -270,7 +270,7 @@ void tournaments_helper::rps_throw(const game_id_type& game_id,
match_object match_obj = game_obj.match_id(db);
tournament_object tournament_obj = match_obj.tournament_id(db);
rock_paper_scissors_game_options game_options = tournament_obj.options.game_options.get<rock_paper_scissors_game_options>();
assert((int)gesture < game_options.number_of_gestures);
FC_ASSERT( (int)gesture < game_options.number_of_gestures );
account_object player_account_obj = player_id(db);
@ -291,6 +291,7 @@ void tournaments_helper::rps_throw(const game_id_type& game_id,
// store off the reveal for applying after both players commit
committed_game_moves[commit_throw] = reveal_throw;
latest_committs[player_account_obj.id] = commit_throw;
signed_transaction tx;
game_move_operation move_operation;
@ -310,6 +311,33 @@ void tournaments_helper::rps_throw(const game_id_type& game_id,
PUSH_TX(db, tx);
}
void tournaments_helper::rps_reveal( const game_id_type& game_id,
const account_id_type& player_id,
rock_paper_scissors_gesture gesture,
const fc::ecc::private_key& sig_priv_key )
{
graphene::chain::database& db = df.db;
FC_ASSERT( latest_committs.find(player_id) != latest_committs.end() );
const auto& reveal = committed_game_moves.find( latest_committs[player_id] );
FC_ASSERT( reveal != committed_game_moves.end() );
FC_ASSERT( reveal->second.gesture == gesture );
game_move_operation move_operation;
move_operation.game_id = game_id;
move_operation.player_account_id = player_id;
move_operation.move = reveal->second;
signed_transaction tx;
tx.operations.push_back( move_operation );
const asset f = db.current_fee_schedule().set_fee( tx.operations[0] );
players_fees[player_id][f.asset_id] -= f.amount;
tx.validate();
test::set_expiration( db, tx );
df.sign( tx, sig_priv_key );
PUSH_TX(db, tx);
}
// spaghetti programming
// walking through all tournaments, matches and games and throwing random moves
// optionaly skip generting randomly selected moves

View file

@ -51,9 +51,9 @@ public:
dividend_asset_options new_options,
const fc::ecc::private_key& sig_priv_key);
optional<account_id_type> get_asset_dividend_account(const asset_id_type& asset_id)const;
optional<account_id_type> get_asset_dividend_account( const asset_id_type& asset_id = asset_id_type() )const;
const tournament_id_type create_tournament (const account_id_type& creator,
const tournament_id_type create_tournament( const account_id_type& creator,
const fc::ecc::private_key& sig_priv_key,
asset buy_in,
uint32_t number_of_players = 2,
@ -89,6 +89,11 @@ public:
const fc::ecc::private_key& sig_priv_key
);
void rps_reveal( const game_id_type& game_id,
const account_id_type& player_id,
rock_paper_scissors_gesture gesture,
const fc::ecc::private_key& sig_priv_key );
// spaghetti programming
// walking through all tournaments, matches and games and throwing random moves
// optionaly skip generting randomly selected moves
@ -113,4 +118,6 @@ private:
std::map<account_id_type, std::map<asset_id_type, share_type>> players_fees;
// store of commits and reveals
std::map<rock_paper_scissors_throw_commit, rock_paper_scissors_throw_reveal> committed_game_moves;
// store of latest commits, for use by rps_reveal
std::map<account_id_type, rock_paper_scissors_throw_commit> latest_committs;
};

View file

@ -24,26 +24,13 @@
#include <boost/test/unit_test.hpp>
#include <graphene/chain/database.hpp>
#include <graphene/chain/protocol/account.hpp>
#include <graphene/chain/protocol/protocol.hpp>
#include <graphene/chain/hardfork.hpp>
#include "../common/tournament_helper.hpp"
#include <graphene/chain/account_object.hpp>
#include <graphene/chain/asset_object.hpp>
#include <graphene/chain/witness_scheduler_rng.hpp>
#include <graphene/chain/exceptions.hpp>
#include <graphene/chain/affiliate_payout.hpp>
#include <graphene/db/simple_index.hpp>
#include <fc/crypto/digest.hpp>
#include <fc/crypto/hex.hpp>
#include <fc/crypto/hash_ctr_rng.hpp>
#include "../common/database_fixture.hpp"
#include <algorithm>
#include <random>
#include <graphene/chain/game_object.hpp>
#include <graphene/chain/hardfork.hpp>
#include <graphene/chain/match_object.hpp>
#include <graphene/chain/tournament_object.hpp>
using namespace graphene::chain;
using namespace graphene::db;
@ -328,4 +315,142 @@ BOOST_AUTO_TEST_CASE( affiliate_payout_helper_test )
}
}
BOOST_AUTO_TEST_CASE( rps_tournament_payout_test )
{ try {
ACTORS( (alice)(ann)(audrey)(martha) );
generate_blocks( HARDFORK_999_TIME );
generate_block();
test::set_expiration( db, trx );
trx.clear();
// Paula: 100% to Alice for Bookie / nothing for RPS
const fc::ecc::private_key paula_private_key = generate_private_key( "paula" );
account_create_operation aco = make_account( "paula", paula_private_key.get_public_key() );
aco.extensions.value.affiliate_distributions = affiliate_reward_distributions();
aco.extensions.value.affiliate_distributions->_dists[bookie]._dist[alice_id] = GRAPHENE_100_PERCENT;
trx.operations.push_back( aco );
// Penny: For Bookie 60% to Alice + 40% to Ann / For RPS 20% to Alice, 30% to Ann, 50% to Audrey
const fc::ecc::private_key penny_private_key = generate_private_key( "penny" );
aco = make_account( "penny", penny_private_key.get_public_key() );
aco.extensions.value.affiliate_distributions = affiliate_reward_distributions();
aco.extensions.value.affiliate_distributions->_dists[bookie]._dist[alice_id] = GRAPHENE_100_PERCENT * 3 / 5;
aco.extensions.value.affiliate_distributions->_dists[bookie]._dist[ann_id] = GRAPHENE_100_PERCENT
- aco.extensions.value.affiliate_distributions->_dists[bookie]._dist[alice_id];
aco.extensions.value.affiliate_distributions->_dists[rps]._dist[alice_id] = GRAPHENE_100_PERCENT / 5;
aco.extensions.value.affiliate_distributions->_dists[rps]._dist[audrey_id] = GRAPHENE_100_PERCENT / 2;
aco.extensions.value.affiliate_distributions->_dists[rps]._dist[ann_id] = GRAPHENE_100_PERCENT
- aco.extensions.value.affiliate_distributions->_dists[rps]._dist[alice_id]
- aco.extensions.value.affiliate_distributions->_dists[rps]._dist[audrey_id];
trx.operations.push_back( aco );
// Petra: nothing for Bookie / For RPS 10% to Ann, 90% to Audrey
const fc::ecc::private_key petra_private_key = generate_private_key( "petra" );
aco = make_account( "petra", petra_private_key.get_public_key() );
aco.extensions.value.affiliate_distributions = affiliate_reward_distributions();
aco.extensions.value.affiliate_distributions->_dists[rps]._dist[ann_id] = GRAPHENE_100_PERCENT / 10;
aco.extensions.value.affiliate_distributions->_dists[rps]._dist[audrey_id] = GRAPHENE_100_PERCENT
- aco.extensions.value.affiliate_distributions->_dists[rps]._dist[ann_id];
trx.operations.push_back( aco );
processed_transaction result = db.push_transaction(trx, ~0);
trx.clear();
account_id_type paula_id = result.operation_results[0].get<object_id_type>();
account_id_type penny_id = result.operation_results[1].get<object_id_type>();
account_id_type petra_id = result.operation_results[2].get<object_id_type>();
fund( martha_id(db), asset(1000000000) );
fund( paula_id(db), asset(20000000) );
fund( penny_id(db), asset(30000000) );
fund( petra_id(db), asset(40000000) );
upgrade_to_lifetime_member( martha );
tournaments_helper helper(*this);
account_id_type dividend_id = *helper.get_asset_dividend_account();
int64_t div_ppy = get_balance( dividend_id, asset_id_type() );
const asset buy_in = asset(12000);
tournament_id_type tournament_id = helper.create_tournament( martha_id, martha_private_key, buy_in, 3, 3, 1, 1 );
BOOST_REQUIRE(tournament_id == tournament_id_type());
helper.join_tournament( tournament_id, paula_id, paula_id, paula_private_key, buy_in);
helper.join_tournament( tournament_id, penny_id, penny_id, penny_private_key, buy_in);
helper.join_tournament( tournament_id, petra_id, petra_id, petra_private_key, buy_in);
generate_block();
const tournament_object& tournament = db.get<tournament_object>( tournament_id );
BOOST_CHECK_EQUAL( 19988000, get_balance( paula_id, asset_id_type() ) );
BOOST_CHECK_EQUAL( 29988000, get_balance( penny_id, asset_id_type() ) );
BOOST_CHECK_EQUAL( 39988000, get_balance( petra_id, asset_id_type() ) );
const tournament_details_object& tournament_details = tournament.tournament_details_id(db);
BOOST_CHECK_EQUAL( 3, tournament_details.matches.size() );
{ // 3 players, match 1 is a bye for penny
const match_object& match = tournament_details.matches[0](db);
BOOST_CHECK_EQUAL( int64_t(match_state::match_complete), int64_t(match.get_state()) );
BOOST_CHECK_EQUAL( 1, match.players.size() );
BOOST_CHECK_EQUAL( object_id_type(penny_id).instance(), object_id_type(match.players[0]).instance() );
}
{ // match 2 is paula vs. petra: paula wins
const match_object& match = tournament_details.matches[1](db);
BOOST_CHECK_EQUAL( int64_t(match_state::match_in_progress), int64_t(match.get_state()) );
BOOST_CHECK_EQUAL( 2, match.players.size() );
BOOST_CHECK_EQUAL( object_id_type(paula_id).instance(), object_id_type(match.players[0]).instance() );
BOOST_CHECK_EQUAL( object_id_type(petra_id).instance(), object_id_type(match.players[1]).instance() );
BOOST_CHECK_EQUAL( 1, match.games.size() );
const game_object& game = match.games[0](db);
BOOST_CHECK_EQUAL( int64_t(game_state::expecting_commit_moves), int64_t(game.get_state()) );
helper.rps_throw( game.id, paula_id, rock_paper_scissors_gesture::paper, paula_private_key );
helper.rps_throw( game.id, petra_id, rock_paper_scissors_gesture::rock, petra_private_key );
BOOST_CHECK_EQUAL( int64_t(game_state::expecting_reveal_moves), int64_t(game.get_state()) );
helper.rps_reveal( game.id, paula_id, rock_paper_scissors_gesture::paper, paula_private_key );
helper.rps_reveal( game.id, petra_id, rock_paper_scissors_gesture::rock, petra_private_key );
BOOST_CHECK_EQUAL( int64_t(game_state::game_complete), int64_t(game.get_state()) );
BOOST_CHECK_EQUAL( 1, match.games.size() );
BOOST_CHECK_EQUAL( int64_t(match_state::match_complete), int64_t(match.get_state()) );
}
{ // match 3 is penny vs. paula: penny wins
const match_object& match = tournament_details.matches[2](db);
BOOST_CHECK_EQUAL( int64_t(match_state::match_in_progress), int64_t(match.get_state()) );
BOOST_CHECK_EQUAL( 2, match.players.size() );
BOOST_CHECK_EQUAL( object_id_type(penny_id).instance(), object_id_type(match.players[0]).instance() );
BOOST_CHECK_EQUAL( object_id_type(paula_id).instance(), object_id_type(match.players[1]).instance() );
BOOST_CHECK_EQUAL( 1, match.games.size() );
const game_object& game = match.games[0](db);
BOOST_CHECK_EQUAL( int64_t(game_state::expecting_commit_moves), int64_t(game.get_state()) );
helper.rps_throw( game.id, paula_id, rock_paper_scissors_gesture::paper, paula_private_key );
helper.rps_throw( game.id, penny_id, rock_paper_scissors_gesture::scissors, penny_private_key );
BOOST_CHECK_EQUAL( int64_t(game_state::expecting_reveal_moves), int64_t(game.get_state()) );
helper.rps_reveal( game.id, paula_id, rock_paper_scissors_gesture::paper, paula_private_key );
helper.rps_reveal( game.id, penny_id, rock_paper_scissors_gesture::scissors, penny_private_key );
BOOST_CHECK_EQUAL( int64_t(game_state::game_complete), int64_t(game.get_state()) );
BOOST_CHECK_EQUAL( int64_t(match_state::match_complete), int64_t(match.get_state()) );
}
BOOST_CHECK_EQUAL( 3*GRAPHENE_1_PERCENT, db.get_global_properties().parameters.rake_fee_percentage );
// Penny wins net 3*buy_in minus rake = 36000 - 1080 = 34920
BOOST_CHECK_EQUAL( 19988000, get_balance( paula_id, asset_id_type() ) );
BOOST_CHECK_EQUAL( 29988000 + 34920, get_balance( penny_id, asset_id_type() ) );
BOOST_CHECK_EQUAL( 39988000, get_balance( petra_id, asset_id_type() ) );
// Dividend account receives 80% of rake = 864
BOOST_CHECK_EQUAL( div_ppy + 864, get_balance( dividend_id, asset_id_type() ) );
// 20% of rake = 216 is paid to Penny's affiliates: 43 to Alice, 64 to Ann, 109 to Audrey
BOOST_CHECK_EQUAL( 43, get_balance( alice_id, asset_id_type() ) );
BOOST_CHECK_EQUAL( 64, get_balance( ann_id, asset_id_type() ) );
BOOST_CHECK_EQUAL( 109, get_balance( audrey_id, asset_id_type() ) );
} FC_LOG_AND_RETHROW() }
BOOST_AUTO_TEST_SUITE_END()