Skip to content

Commit

Permalink
Merge pull request #345 from peerplays-network/feature/beatrice_winne…
Browse files Browse the repository at this point in the history
…r_id

5050 winner id changes
  • Loading branch information
pbattu123 authored Apr 10, 2020
2 parents dc9cbe6 + 02a89dd commit 6fd2e5e
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 3 deletions.
43 changes: 43 additions & 0 deletions libraries/chain/asset_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
*/
#include <graphene/chain/asset_object.hpp>
#include <graphene/chain/database.hpp>
#include <graphene/chain/operation_history_object.hpp>
#include <graphene/chain/hardfork.hpp>

#include <fc/io/raw.hpp>
#include <fc/uint128.hpp>
Expand Down Expand Up @@ -185,6 +187,41 @@ vector<account_id_type> asset_object::get_holders( database& db ) const
return holders;
}

vector<uint64_t> asset_object::get_ticket_ids( database& db ) const
{
auto& asset_bal_idx = db.get_index_type< account_balance_index >().indices().get< by_asset_balance >();
vector<uint64_t> ids;
const auto range = asset_bal_idx.equal_range( boost::make_tuple( get_id() ) );

for( const account_balance_object& bal : boost::make_iterator_range( range.first, range.second ) )
{
const auto& stats = bal.owner(db).statistics(db);
const account_transaction_history_object* ath = static_cast<const account_transaction_history_object*>(&stats.most_recent_op(db));
for( uint64_t balance = bal.balance.value; balance > 0;)
{
if(ath != nullptr)
{
const operation_history_object& oho = db.get<operation_history_object>( ath->operation_id );
if( oho.op.which() == operation::tag<ticket_purchase_operation>::value && get_id() == oho.op.get<ticket_purchase_operation>().lottery)
{
uint64_t tickets_count = oho.op.get<ticket_purchase_operation>().tickets_to_buy;
ids.insert(ids.end(), tickets_count, oho.id.instance());
balance -= tickets_count;
assert(balance >= 0);
}

if( ath->next == account_transaction_history_id_type() )
{
ath = nullptr;
break;
}
else ath = db.find(ath->next);
}
}
}
return ids;
}

void asset_object::distribute_benefactors_part( database& db )
{
transaction_evaluation_state eval( &db );
Expand All @@ -206,6 +243,7 @@ map< account_id_type, vector< uint16_t > > asset_object::distribute_winners_part
transaction_evaluation_state eval( &db );

auto holders = get_holders( db );
vector<uint64_t> ticket_ids = get_ticket_ids(db);
FC_ASSERT( dynamic_data( db ).current_supply == holders.size() );
map<account_id_type, vector<uint16_t> > structurized_participants;
for( account_id_type holder : holders )
Expand Down Expand Up @@ -234,6 +272,11 @@ map< account_id_type, vector< uint16_t > > asset_object::distribute_winners_part
reward_op.lottery = get_id();
reward_op.is_benefactor_reward = false;
reward_op.winner = holders[winner_num];
if(db.head_block_time() > HARDFORK_5050_1_TIME && ticket_ids.size() >= winner_num)
{
const static_variant<uint64_t, void_t> tkt_id = ticket_ids[winner_num];
reward_op.winner_ticket_id = tkt_id;
}
reward_op.win_percentage = tickets[c];
reward_op.amount = asset( jackpot * tickets[c] * ( 1. - sweeps_distribution_percentage / (double)GRAPHENE_100_PERCENT ) / GRAPHENE_100_PERCENT , db.get_balance(id).asset_id );
db.apply_operation(eval, reward_op);
Expand Down
4 changes: 4 additions & 0 deletions libraries/chain/hardfork.d/5050-1.hf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// 5050_1 HARDFORK Thursday, 15 April 2020 20:00:00 GMT
#ifndef HARDFORK_5050_1_TIME
#define HARDFORK_5050_1_TIME (fc::time_point_sec( 1586980800 ))
#endif
1 change: 1 addition & 0 deletions libraries/chain/include/graphene/chain/asset_object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ namespace graphene { namespace chain {
optional<lottery_asset_options> lottery_options;
time_point_sec get_lottery_expiration() const;
vector<account_id_type> get_holders( database& db ) const;
vector<uint64_t> get_ticket_ids( database& db ) const;
void distribute_benefactors_part( database& db );
map< account_id_type, vector< uint16_t > > distribute_winners_part( database& db );
void distribute_sweeps_holders_part( database& db );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ namespace graphene { namespace chain {
share_type calculate_fee( const fee_parameters_type& k )const;
};

typedef static_variant<uint64_t, void_t> ticket_num;

/**
* @ingroup operations
*/
Expand All @@ -73,7 +75,7 @@ namespace graphene { namespace chain {
// true if recieved from benefators section of lottery; false otherwise
bool is_benefactor_reward;

extensions_type extensions;
ticket_num winner_ticket_id;

account_id_type fee_payer()const { return account_id_type(); }
void validate()const {};
Expand Down Expand Up @@ -114,15 +116,15 @@ FC_REFLECT( graphene::chain::ticket_purchase_operation,
)
FC_REFLECT( graphene::chain::ticket_purchase_operation::fee_parameters_type, (fee) )


FC_REFLECT_TYPENAME( graphene::chain::ticket_num )
FC_REFLECT( graphene::chain::lottery_reward_operation,
(fee)
(lottery)
(winner)
(amount)
(win_percentage)
(is_benefactor_reward)
(extensions)
(winner_ticket_id)
)
FC_REFLECT( graphene::chain::lottery_reward_operation::fee_parameters_type, (fee) )

Expand Down
61 changes: 61 additions & 0 deletions tests/tests/lottery_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ BOOST_AUTO_TEST_CASE( create_lottery_asset_test )
lottery_options.end_date = db.head_block_time() + fc::minutes(5);
lottery_options.ticket_price = asset(100);
lottery_options.winning_tickets = { 5 * GRAPHENE_1_PERCENT, 5 * GRAPHENE_1_PERCENT, 5 * GRAPHENE_1_PERCENT, 10 * GRAPHENE_1_PERCENT, 10 * GRAPHENE_1_PERCENT, 10 * GRAPHENE_1_PERCENT, 10 * GRAPHENE_1_PERCENT, 10 * GRAPHENE_1_PERCENT, 10 * GRAPHENE_1_PERCENT };
//lottery_options.winning_tickets = { 75 * GRAPHENE_1_PERCENT };
lottery_options.is_active = test_asset_id.instance.value % 2;
lottery_options.ending_on_soldout = true;

Expand Down Expand Up @@ -482,4 +483,64 @@ BOOST_AUTO_TEST_CASE( try_to_end_empty_lottery_test )
}
}

BOOST_AUTO_TEST_CASE( lottery_winner_ticket_id_test )
{
try {
asset_id_type test_asset_id = db.get_index<asset_object>().get_next_id();
INVOKE( create_lottery_asset_test );
auto test_asset = test_asset_id(db);
for( int i = 1; i < 4; ++i ) {
transfer(account_id_type(), account_id_type(i), asset(2000000));
}
for( int i = 1; i < 4; ++i ) {
if( i == 4 ) continue;
ticket_purchase_operation tpo;
tpo.buyer = account_id_type(i);
tpo.lottery = test_asset.id;
tpo.tickets_to_buy = 1;
tpo.amount = asset(100);
trx.operations.push_back(std::move(tpo));
graphene::chain::test::set_expiration(db, trx);
PUSH_TX( db, trx, ~0 );
trx.operations.clear();
}

for( int i = 1; i < 4; ++i ) {
if( i == 4 ) continue;
ticket_purchase_operation tpo;
tpo.buyer = account_id_type(i);
tpo.lottery = test_asset.id;
tpo.tickets_to_buy = 1;
tpo.amount = asset(100);
trx.operations.push_back(std::move(tpo));
graphene::chain::test::set_expiration(db, trx);
PUSH_TX( db, trx, ~0 );
trx.operations.clear();
}
generate_block();
test_asset = test_asset_id(db);
uint64_t creator_balance_before_end = db.get_balance( account_id_type(), asset_id_type() ).amount.value;
uint64_t jackpot = db.get_balance( test_asset.get_id() ).amount.value;
uint16_t winners_part = 0;
for( uint8_t win: test_asset.lottery_options->winning_tickets )
winners_part += win;

while( db.head_block_time() < ( test_asset.lottery_options->end_date ) )
generate_block();

auto op_history = get_operation_history( account_id_type(1) ); //Can observe operation 79 to verify winner ticket number
for( auto h: op_history ) {
idump((h));
}

BOOST_CHECK( db.get_balance( test_asset.get_id() ).amount.value == 0 );
uint64_t creator_recieved = db.get_balance( account_id_type(), asset_id_type() ).amount.value - creator_balance_before_end;
test_asset = test_asset_id(db);
BOOST_CHECK(jackpot * test_asset.lottery_options->benefactors[0].share / GRAPHENE_100_PERCENT == creator_recieved);
} catch (fc::exception& e) {
edump((e.to_detail_string()));
throw;
}
}

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit 6fd2e5e

Please sign in to comment.