diff --git a/libraries/chain/db_maint.cpp b/libraries/chain/db_maint.cpp index f330e746..b8044259 100644 --- a/libraries/chain/db_maint.cpp +++ b/libraries/chain/db_maint.cpp @@ -780,6 +780,16 @@ double database::calculate_vesting_factor(const account_object& stake_account) uint32_t current_subperiod = get_gpos_current_subperiod(); if(current_subperiod == 0 || current_subperiod > number_of_subperiods) return 0; + + // On starting new vesting period, all votes become zero until someone votes, To avoid a situation of zero votes, + // changes were done to roll in GPOS rules, the vesting factor will be 1 for whoever votes in 6th sub-period of last vesting period + // BLOCKBACK-174 fix + if(current_subperiod == 1 && this->head_block_time() >= HARDFORK_GPOS_TIME + vesting_period) //Applicable only from 2nd vesting period + { + if(last_date_voted > period_start - vesting_subperiod) + return 1; + } + if(last_date_voted < period_start) return 0; double numerator = number_of_subperiods; diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 8d2ae75f..449000bc 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -2193,9 +2193,6 @@ public: FC_THROW("Account ${account} was already voting for witness ${witness} in the current GPOS sub-period", ("account", voting_account)("witness", witness)); else update_vote_time = true; //Allow user to vote in each sub-period(Update voting time, which is reference in calculating VF) - - if (!insert_result.second) - FC_THROW("Account ${account} has already voted for witness ${witness}", ("account", voting_account)("witness", witness)); } else { diff --git a/tests/tests/gpos_tests.cpp b/tests/tests/gpos_tests.cpp index fb3f6987..eb0c1d09 100644 --- a/tests/tests/gpos_tests.cpp +++ b/tests/tests/gpos_tests.cpp @@ -562,7 +562,7 @@ BOOST_AUTO_TEST_CASE( voting ) auto witness2 = witness_id_type(2)(db); BOOST_CHECK_EQUAL(witness2.total_votes, 0); - // vote for witness1 + // vote for witness1 and witness2 - sub-period 1 vote_for(alice_id, witness1.vote_id, alice_private_key); vote_for(bob_id, witness2.vote_id, bob_private_key); @@ -577,7 +577,7 @@ BOOST_AUTO_TEST_CASE( voting ) advance_x_maint(10); - //vote bob tot witness2 in each subperiod and verify votes + //Bob votes for witness2 - sub-period 2 vote_for(bob_id, witness2.vote_id, bob_private_key); // go to maint generate_blocks(db.get_dynamic_global_properties().next_maintenance_time); @@ -589,6 +589,7 @@ BOOST_AUTO_TEST_CASE( voting ) BOOST_CHECK_EQUAL(witness2.total_votes, 100); advance_x_maint(10); + //Bob votes for witness2 - sub-period 3 vote_for(bob_id, witness2.vote_id, bob_private_key); generate_blocks(db.get_dynamic_global_properties().next_maintenance_time); // decay more @@ -599,7 +600,7 @@ BOOST_AUTO_TEST_CASE( voting ) advance_x_maint(10); - // more + // Bob votes for witness2 - sub-period 4 vote_for(bob_id, witness2.vote_id, bob_private_key); generate_blocks(db.get_dynamic_global_properties().next_maintenance_time); // decay more @@ -610,7 +611,7 @@ BOOST_AUTO_TEST_CASE( voting ) advance_x_maint(10); - // more + // Bob votes for witness2 - sub-period 5 vote_for(bob_id, witness2.vote_id, bob_private_key); generate_blocks(db.get_dynamic_global_properties().next_maintenance_time); // decay more @@ -622,7 +623,7 @@ BOOST_AUTO_TEST_CASE( voting ) advance_x_maint(10); - // more + // Bob votes for witness2 - sub-period 6 vote_for(bob_id, witness2.vote_id, bob_private_key); generate_blocks(db.get_dynamic_global_properties().next_maintenance_time); // decay more @@ -635,18 +636,23 @@ BOOST_AUTO_TEST_CASE( voting ) BOOST_CHECK_EQUAL(db.get_global_properties().parameters.gpos_period_start(), now.sec_since_epoch()); advance_x_maint(5); - // a new GPOS period is in but vote from user is before the start so his voting power is 0 + // a new GPOS period is in but vote from user is before the start. Whoever votes in 6th sub-period, votes will carry now = db.head_block_time(); BOOST_CHECK_EQUAL(db.get_global_properties().parameters.gpos_period_start(), now.sec_since_epoch()); generate_block(); + // we are in the second GPOS period, at subperiod 1, witness1 = witness_id_type(1)(db); witness2 = witness_id_type(2)(db); BOOST_CHECK_EQUAL(witness1.total_votes, 0); - BOOST_CHECK_EQUAL(witness2.total_votes, 0); + //It's critical here, since bob votes in 6th sub-period of last vesting period, witness2 should retain his votes + BOOST_CHECK_EQUAL(witness2.total_votes, 100); - // we are in the second GPOS period, at subperiod 2, lets vote here + + // lets vote here from alice to generate votes for witness 1 + //vote from bob to reatin VF 1 + vote_for(alice_id, witness1.vote_id, alice_private_key); vote_for(bob_id, witness2.vote_id, bob_private_key); generate_block(); @@ -656,7 +662,7 @@ BOOST_AUTO_TEST_CASE( voting ) witness1 = witness_id_type(1)(db); witness2 = witness_id_type(2)(db); - BOOST_CHECK_EQUAL(witness1.total_votes, 0); + BOOST_CHECK_EQUAL(witness1.total_votes, 100); BOOST_CHECK_EQUAL(witness2.total_votes, 100); advance_x_maint(10); @@ -664,7 +670,7 @@ BOOST_AUTO_TEST_CASE( voting ) witness1 = witness_id_type(1)(db); witness2 = witness_id_type(2)(db); - BOOST_CHECK_EQUAL(witness1.total_votes, 0); + BOOST_CHECK_EQUAL(witness1.total_votes, 83); BOOST_CHECK_EQUAL(witness2.total_votes, 83); vote_for(bob_id, witness2.vote_id, bob_private_key); @@ -675,7 +681,7 @@ BOOST_AUTO_TEST_CASE( voting ) witness1 = witness_id_type(1)(db); witness2 = witness_id_type(2)(db); - BOOST_CHECK_EQUAL(witness1.total_votes, 0); + BOOST_CHECK_EQUAL(witness1.total_votes, 66); BOOST_CHECK_EQUAL(witness2.total_votes, 83); // alice votes again, now for witness 2, her vote worth 100 now