changes to allow user to vote in each sub-period

This commit is contained in:
pbattu123 2019-10-22 10:39:45 -03:00
parent d5dffa64b7
commit 0d1c41557d
6 changed files with 47 additions and 12 deletions

View file

@ -2039,6 +2039,8 @@ graphene::app::gpos_info database_api_impl::get_gpos_info(const account_id_type
{ {
gpos_info result; gpos_info result;
result.vesting_factor = _db.calculate_vesting_factor(account(_db)); result.vesting_factor = _db.calculate_vesting_factor(account(_db));
result.current_subperiod = _db.get_gpos_current_subperiod();
result.last_voted_time = account(_db).statistics(_db).last_vote_time;
const auto& dividend_data = asset_id_type()(_db).dividend_data(_db); const auto& dividend_data = asset_id_type()(_db).dividend_data(_db);
const account_object& dividend_distribution_account = dividend_data.dividend_distribution_account(_db); const account_object& dividend_distribution_account = dividend_data.dividend_distribution_account(_db);

View file

@ -118,6 +118,9 @@ struct gpos_info {
double vesting_factor; double vesting_factor;
asset award; asset award;
share_type total_amount; share_type total_amount;
uint32_t current_subperiod;
fc::time_point_sec last_voted_time;
}; };
/** /**
@ -672,7 +675,7 @@ FC_REFLECT( graphene::app::order_book, (base)(quote)(bids)(asks) );
FC_REFLECT( graphene::app::market_ticker, (base)(quote)(latest)(lowest_ask)(highest_bid)(percent_change)(base_volume)(quote_volume) ); FC_REFLECT( graphene::app::market_ticker, (base)(quote)(latest)(lowest_ask)(highest_bid)(percent_change)(base_volume)(quote_volume) );
FC_REFLECT( graphene::app::market_volume, (base)(quote)(base_volume)(quote_volume) ); FC_REFLECT( graphene::app::market_volume, (base)(quote)(base_volume)(quote_volume) );
FC_REFLECT( graphene::app::market_trade, (date)(price)(amount)(value) ); FC_REFLECT( graphene::app::market_trade, (date)(price)(amount)(value) );
FC_REFLECT( graphene::app::gpos_info, (vesting_factor)(award)(total_amount) ); FC_REFLECT( graphene::app::gpos_info, (vesting_factor)(award)(total_amount)(current_subperiod)(last_voted_time) );
FC_API(graphene::app::database_api, FC_API(graphene::app::database_api,

View file

@ -284,8 +284,8 @@ void_result account_update_evaluator::do_apply( const account_update_operation&
{ {
d.modify( acnt->statistics( d ), [&]( account_statistics_object& aso ) d.modify( acnt->statistics( d ), [&]( account_statistics_object& aso )
{ {
if((o.new_options->votes != acnt->options.votes || //if((o.new_options->votes != acnt->options.votes ||
o.new_options->voting_account != acnt->options.voting_account)) // o.new_options->voting_account != acnt->options.voting_account))
aso.last_vote_time = d.head_block_time(); aso.last_vote_time = d.head_block_time();
} ); } );
} }

View file

@ -725,13 +725,8 @@ void deprecate_annual_members( database& db )
return; return;
} }
double database::calculate_vesting_factor(const account_object& stake_account) uint32_t database::get_gpos_current_subperiod()
{ {
// get last time voted form stats
const auto &stats = stake_account.statistics(*this);
fc::time_point_sec last_date_voted = stats.last_vote_time;
// get global data related to gpos
const auto &gpo = this->get_global_properties(); const auto &gpo = this->get_global_properties();
const auto vesting_period = gpo.parameters.gpos_period(); const auto vesting_period = gpo.parameters.gpos_period();
const auto vesting_subperiod = gpo.parameters.gpos_subperiod(); const auto vesting_subperiod = gpo.parameters.gpos_subperiod();
@ -741,7 +736,6 @@ double database::calculate_vesting_factor(const account_object& stake_account)
const fc::time_point_sec period_end = period_start + vesting_period; const fc::time_point_sec period_end = period_start + vesting_period;
const auto number_of_subperiods = vesting_period / vesting_subperiod; const auto number_of_subperiods = vesting_period / vesting_subperiod;
const auto now = this->head_block_time(); const auto now = this->head_block_time();
double vesting_factor;
auto seconds_since_period_start = now.sec_since_epoch() - period_start.sec_since_epoch(); auto seconds_since_period_start = now.sec_since_epoch() - period_start.sec_since_epoch();
FC_ASSERT(period_start <= now && now <= period_end); FC_ASSERT(period_start <= now && now <= period_end);
@ -757,6 +751,28 @@ double database::calculate_vesting_factor(const account_object& stake_account)
current_subperiod = period; current_subperiod = period;
}); });
return current_subperiod;
}
double database::calculate_vesting_factor(const account_object& stake_account)
{
// get last time voted form stats
const auto &stats = stake_account.statistics(*this);
fc::time_point_sec last_date_voted = stats.last_vote_time;
// get global data related to gpos
const auto &gpo = this->get_global_properties();
const auto vesting_period = gpo.parameters.gpos_period();
const auto vesting_subperiod = gpo.parameters.gpos_subperiod();
const auto period_start = fc::time_point_sec(gpo.parameters.gpos_period_start());
// variables needed
const auto number_of_subperiods = vesting_period / vesting_subperiod;
double vesting_factor;
// get in what sub period we are
uint32_t current_subperiod = get_gpos_current_subperiod();
if(current_subperiod == 0 || current_subperiod > number_of_subperiods) return 0; if(current_subperiod == 0 || current_subperiod > number_of_subperiods) return 0;
if(last_date_voted < period_start) return 0; if(last_date_voted < period_start) return 0;
@ -1389,7 +1405,7 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
rolling_period_start(*this); rolling_period_start(*this);
process_dividend_assets(*this); process_dividend_assets(*this);
struct vote_tally_helper { struct vote_tally_helper {
database& d; database& d;
const global_property_object& props; const global_property_object& props;
@ -1558,6 +1574,12 @@ 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; 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() ) 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; 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.valid() )
p.pending_parameters->extensions.value.gpos_period = p.parameters.extensions.value.gpos_period;
if( !p.pending_parameters->extensions.value.gpos_subperiod.valid() )
p.pending_parameters->extensions.value.gpos_subperiod = p.parameters.extensions.value.gpos_subperiod;
if( !p.pending_parameters->extensions.value.gpos_vesting_lockin_period.valid() )
p.pending_parameters->extensions.value.gpos_vesting_lockin_period = p.parameters.extensions.value.gpos_vesting_lockin_period;
p.parameters = std::move(*p.pending_parameters); p.parameters = std::move(*p.pending_parameters);
p.pending_parameters.reset(); p.pending_parameters.reset();
} }

View file

@ -500,6 +500,7 @@ namespace graphene { namespace chain {
void update_worker_votes(); void update_worker_votes();
public: public:
double calculate_vesting_factor(const account_object& stake_account); double calculate_vesting_factor(const account_object& stake_account);
uint32_t get_gpos_current_subperiod();
template<class... Types> template<class... Types>

View file

@ -2125,13 +2125,20 @@ public:
account_object voting_account_object = get_account(voting_account); account_object voting_account_object = get_account(voting_account);
account_id_type witness_owner_account_id = get_account_id(witness); account_id_type witness_owner_account_id = get_account_id(witness);
fc::optional<witness_object> witness_obj = _remote_db->get_witness_by_account(witness_owner_account_id); fc::optional<witness_object> witness_obj = _remote_db->get_witness_by_account(witness_owner_account_id);
if (!witness_obj) if (!witness_obj)
FC_THROW("Account ${witness} is not registered as a witness", ("witness", witness)); FC_THROW("Account ${witness} is not registered as a witness", ("witness", witness));
if (approve) if (approve)
{ {
account_id_type stake_account = get_account_id(voting_account);
const auto gpos_info = _remote_db->get_gpos_info(stake_account);
const auto vesting_subperiod = _remote_db->get_global_properties().parameters.gpos_subperiod();
const auto gpos_start_time = fc::time_point_sec(_remote_db->get_global_properties().parameters.gpos_period_start());
const auto subperiod_start_time = gpos_start_time.sec_since_epoch() + (gpos_info.current_subperiod - 1) * vesting_subperiod;
auto insert_result = voting_account_object.options.votes.insert(witness_obj->vote_id); auto insert_result = voting_account_object.options.votes.insert(witness_obj->vote_id);
if (!insert_result.second) if (!insert_result.second && (gpos_info.last_voted_time.sec_since_epoch() >= subperiod_start_time))
FC_THROW("Account ${account} was already voting for witness ${witness}", ("account", voting_account)("witness", witness)); FC_THROW("Account ${account} was already voting for witness ${witness}", ("account", voting_account)("witness", witness));
} }
else else