From 067fcd13f78d86979050038a144c55e187f61ed9 Mon Sep 17 00:00:00 2001 From: pbattu123 Date: Fri, 6 Dec 2019 11:26:49 -0400 Subject: [PATCH] Votes consideration on GPOS activation --- libraries/chain/account_evaluator.cpp | 2 - libraries/chain/db_maint.cpp | 12 +++- tests/tests/gpos_tests.cpp | 87 +++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 3 deletions(-) diff --git a/libraries/chain/account_evaluator.cpp b/libraries/chain/account_evaluator.cpp index 0d389d7c..ad6ac5dc 100644 --- a/libraries/chain/account_evaluator.cpp +++ b/libraries/chain/account_evaluator.cpp @@ -261,8 +261,6 @@ void_result account_update_evaluator::do_evaluate( const account_update_operatio FC_ASSERT( !o.extensions.value.owner_special_authority.valid() ); FC_ASSERT( !o.extensions.value.active_special_authority.valid() ); } - if( d.head_block_time() < HARDFORK_GPOS_TIME ) - FC_ASSERT( !o.extensions.value.update_last_voting_time.valid() ); try { diff --git a/libraries/chain/db_maint.cpp b/libraries/chain/db_maint.cpp index af609833..11a2b426 100644 --- a/libraries/chain/db_maint.cpp +++ b/libraries/chain/db_maint.cpp @@ -1560,11 +1560,19 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g if(d.head_block_time() >= HARDFORK_GPOS_TIME) { - if (itr == vesting_amounts.end()) + if (itr == vesting_amounts.end() && d.head_block_time() >= (HARDFORK_GPOS_TIME + props.parameters.gpos_subperiod()/2)) return; auto vesting_factor = d.calculate_vesting_factor(stake_account); voting_stake = (uint64_t)floor(voting_stake * vesting_factor); + + //Include votes(based on stake) for the period of gpos_subperiod()/2 as system has zero votes on GPOS activation + if(d.head_block_time() < (HARDFORK_GPOS_TIME + props.parameters.gpos_subperiod()/2)) + { + voting_stake += stats.total_core_in_orders.value + + (stake_account.cashback_vb.valid() ? (*stake_account.cashback_vb)(d).balance.amount.value : 0) + + d.get_balance(stake_account.get_id(), asset_id_type()).amount.value; + } } else { @@ -1644,6 +1652,8 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g p.pending_parameters->extensions.value.permitted_betting_odds_increments = p.parameters.extensions.value.permitted_betting_odds_increments; if( !p.pending_parameters->extensions.value.live_betting_delay_time.valid() ) p.pending_parameters->extensions.value.live_betting_delay_time = p.parameters.extensions.value.live_betting_delay_time; + if( !p.pending_parameters->extensions.value.gpos_period_start.valid() ) + p.pending_parameters->extensions.value.gpos_period_start = p.parameters.extensions.value.gpos_period_start; if( !p.pending_parameters->extensions.value.gpos_period.valid() ) p.pending_parameters->extensions.value.gpos_period = p.parameters.extensions.value.gpos_period; if( !p.pending_parameters->extensions.value.gpos_subperiod.valid() ) diff --git a/tests/tests/gpos_tests.cpp b/tests/tests/gpos_tests.cpp index 196fe7ee..1e6415e0 100644 --- a/tests/tests/gpos_tests.cpp +++ b/tests/tests/gpos_tests.cpp @@ -514,6 +514,93 @@ BOOST_AUTO_TEST_CASE( gpos_basic_dividend_distribution_to_core_asset ) } } +BOOST_AUTO_TEST_CASE( votes_on_gpos_activation ) +{ + ACTORS((alice)(bob)); + try { + const auto& core = asset_id_type()(db); + + // send some asset to alice and bob + transfer( committee_account, alice_id, core.amount( 1000 ) ); + transfer( committee_account, bob_id, core.amount( 1000 ) ); + generate_block(); + + // update default gpos + auto now = db.head_block_time(); + // 5184000 = 60x60x24x6 = 6 days + // 864000 = 60x60x24x1 = 1 days + update_gpos_global(518400, 86400, now); + + BOOST_CHECK_EQUAL(db.get_global_properties().parameters.gpos_period(), 518400); + BOOST_CHECK_EQUAL(db.get_global_properties().parameters.gpos_subperiod(), 86400); + BOOST_CHECK_EQUAL(db.get_global_properties().parameters.gpos_period_start(), now.sec_since_epoch()); + // no votes for witness 1 + auto witness1 = witness_id_type(1)(db); + BOOST_CHECK_EQUAL(witness1.total_votes, 0); + + // no votes for witness 2 + auto witness2 = witness_id_type(2)(db); + BOOST_CHECK_EQUAL(witness2.total_votes, 0); + + // vote for witness1 and witness2 - this before GPOS period starts + vote_for(alice_id, witness1.vote_id, alice_private_key); + vote_for(bob_id, witness2.vote_id, bob_private_key); + + // go to maint + generate_blocks(db.get_dynamic_global_properties().next_maintenance_time); + + // vote is the same as amount in the first subperiod since voting + witness1 = witness_id_type(1)(db); + witness2 = witness_id_type(2)(db); + BOOST_CHECK_EQUAL(witness1.total_votes, 1000); + BOOST_CHECK_EQUAL(witness2.total_votes, 1000); + + // move to hardfork + generate_blocks( HARDFORK_GPOS_TIME ); + generate_block(); + + update_maintenance_interval(3600); //update maintenance interval to 1hr to evaluate sub-periods + BOOST_CHECK_EQUAL(db.get_global_properties().parameters.maintenance_interval, 3600); + + witness1 = witness_id_type(1)(db); + witness2 = witness_id_type(2)(db); + BOOST_CHECK_EQUAL(witness1.total_votes, 1000); + BOOST_CHECK_EQUAL(witness2.total_votes, 1000); + + // add some vesting to alice and don't add anything for Bob + create_vesting(alice_id, core.amount(99), vesting_balance_type::gpos); + generate_block(); + vote_for(alice_id, witness1.vote_id, alice_private_key); + generate_block(); + + advance_x_maint(1); + witness1 = witness_id_type(1)(db); + witness2 = witness_id_type(2)(db); + //System needs to consider votes based on both regular balance + GPOS balance for 1/2 sub-period on GPOS activation + BOOST_CHECK_EQUAL(witness1.total_votes, 1000); + BOOST_CHECK_EQUAL(witness2.total_votes, 1000); + + advance_x_maint(2); + witness1 = witness_id_type(1)(db); + witness2 = witness_id_type(2)(db); + BOOST_CHECK_EQUAL(witness1.total_votes, 1000); + BOOST_CHECK_EQUAL(witness2.total_votes, 1000); + + advance_x_maint(3); + witness1 = witness_id_type(1)(db); + witness2 = witness_id_type(2)(db); + //Since Alice has votes, votes should be based on GPOS balance i.e 99 + //Since Bob not voted after GPOS activation, witness2 votes should be 0 after crossing 1/2 sub-period(6 maintanence intervals in this case) + BOOST_CHECK_EQUAL(witness1.total_votes, 99); + BOOST_CHECK_EQUAL(witness2.total_votes, 0); + + } + catch (fc::exception &e) { + edump((e.to_detail_string())); + throw; + } +} + BOOST_AUTO_TEST_CASE( voting ) { ACTORS((alice)(bob));