add get_gpos_info database api call
This commit is contained in:
parent
0e3d87eaad
commit
a58eb6fae8
6 changed files with 201 additions and 15 deletions
|
|
@ -161,6 +161,8 @@ class database_api_impl : public std::enable_shared_from_this<database_api_impl>
|
|||
vector<tournament_object> get_tournaments_by_state(tournament_id_type stop, unsigned limit, tournament_id_type start, tournament_state state);
|
||||
vector<tournament_id_type> get_registered_tournaments(account_id_type account_filter, uint32_t limit) const;
|
||||
|
||||
// gpos
|
||||
gpos_info get_gpos_info(const account_id_type account) const;
|
||||
|
||||
//private:
|
||||
template<typename T>
|
||||
|
|
@ -2021,6 +2023,55 @@ vector<tournament_id_type> database_api_impl::get_registered_tournaments(account
|
|||
return tournament_ids;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// GPOS methods //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
graphene::app::gpos_info database_api::get_gpos_info(const account_id_type account) const
|
||||
{
|
||||
return my->get_gpos_info(account);
|
||||
|
||||
}
|
||||
graphene::app::gpos_info database_api_impl::get_gpos_info(const account_id_type account) const
|
||||
{
|
||||
gpos_info result;
|
||||
result.vesting_factor = _db.calculate_vesting_factor(account(_db));
|
||||
|
||||
const auto& dividend_data = asset_id_type()(_db).dividend_data(_db);
|
||||
const account_object& dividend_distribution_account = dividend_data.dividend_distribution_account(_db);
|
||||
result.award = _db.get_balance(dividend_distribution_account, asset_id_type()(_db));
|
||||
|
||||
share_type total_amount;
|
||||
auto balance_type = vesting_balance_type::gpos;
|
||||
#ifdef USE_VESTING_OBJECT_BY_ASSET_BALANCE_INDEX
|
||||
// get only once a collection of accounts that hold nonzero vesting balances of the dividend asset
|
||||
auto vesting_balances_begin =
|
||||
vesting_index.indices().get<by_asset_balance>().lower_bound(boost::make_tuple(asset_id_type(), balance_type));
|
||||
auto vesting_balances_end =
|
||||
vesting_index.indices().get<by_asset_balance>().upper_bound(boost::make_tuple(asset_id_type(), balance_type, share_type()));
|
||||
|
||||
for (const vesting_balance_object& vesting_balance_obj : boost::make_iterator_range(vesting_balances_begin, vesting_balances_end))
|
||||
{
|
||||
total_amount += vesting_balance_obj.balance.amount;
|
||||
}
|
||||
#else
|
||||
const vesting_balance_index& vesting_index = _db.get_index_type<vesting_balance_index>();
|
||||
const auto& vesting_balances = vesting_index.indices().get<by_id>();
|
||||
for (const vesting_balance_object& vesting_balance_obj : vesting_balances)
|
||||
{
|
||||
if (vesting_balance_obj.balance.asset_id == asset_id_type() && vesting_balance_obj.balance_type == balance_type)
|
||||
{
|
||||
total_amount += vesting_balance_obj.balance.amount;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
result.total_amount = total_amount;
|
||||
return result;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// Private methods //
|
||||
|
|
|
|||
|
|
@ -114,6 +114,12 @@ struct market_trade
|
|||
double value;
|
||||
};
|
||||
|
||||
struct gpos_info {
|
||||
double vesting_factor;
|
||||
asset award;
|
||||
share_type total_amount;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The database_api class implements the RPC API for the chain database.
|
||||
*
|
||||
|
|
@ -645,7 +651,17 @@ class database_api
|
|||
*/
|
||||
vector<tournament_id_type> get_registered_tournaments(account_id_type account_filter, uint32_t limit) const;
|
||||
|
||||
private:
|
||||
//////////
|
||||
// GPOS //
|
||||
//////////
|
||||
/**
|
||||
* @return account and network GPOS information
|
||||
*/
|
||||
gpos_info get_gpos_info(const account_id_type account) const;
|
||||
|
||||
|
||||
|
||||
private:
|
||||
std::shared_ptr< database_api_impl > my;
|
||||
};
|
||||
|
||||
|
|
@ -656,6 +672,8 @@ 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_volume, (base)(quote)(base_volume)(quote_volume) );
|
||||
FC_REFLECT( graphene::app::market_trade, (date)(price)(amount)(value) );
|
||||
FC_REFLECT( graphene::app::gpos_info, (vesting_factor)(award)(total_amount) );
|
||||
|
||||
|
||||
FC_API(graphene::app::database_api,
|
||||
// Objects
|
||||
|
|
@ -765,4 +783,7 @@ FC_API(graphene::app::database_api,
|
|||
(get_tournaments_by_state)
|
||||
(get_tournaments )
|
||||
(get_registered_tournaments)
|
||||
|
||||
// gpos
|
||||
(get_gpos_info)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -725,14 +725,14 @@ void deprecate_annual_members( database& db )
|
|||
return;
|
||||
}
|
||||
|
||||
double calculate_vesting_factor(const database& d, const account_object& stake_account)
|
||||
double database::calculate_vesting_factor(const account_object& stake_account)
|
||||
{
|
||||
// get last time voted form stats
|
||||
const auto &stats = stake_account.statistics(d);
|
||||
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 = d.get_global_properties();
|
||||
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());
|
||||
|
|
@ -740,7 +740,7 @@ double calculate_vesting_factor(const database& d, const account_object& stake_a
|
|||
// variables needed
|
||||
const fc::time_point_sec period_end = period_start + vesting_period;
|
||||
const auto number_of_subperiods = vesting_period / vesting_subperiod;
|
||||
const auto now = d.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();
|
||||
|
||||
|
|
@ -1071,7 +1071,7 @@ void schedule_pending_dividend_balances(database& db,
|
|||
vesting_balances_begin, vesting_balances_end)) {
|
||||
if (holder_balance_object.owner == dividend_data.dividend_distribution_account) continue;
|
||||
|
||||
auto vesting_factor = calculate_vesting_factor(db, holder_balance_object.owner(db));
|
||||
auto vesting_factor = db.calculate_vesting_factor(holder_balance_object.owner(db));
|
||||
|
||||
auto holder_balance = holder_balance_object.balance;
|
||||
|
||||
|
|
@ -1463,7 +1463,7 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
|
|||
if (itr == vesting_amounts.end())
|
||||
return;
|
||||
|
||||
auto vesting_factor = calculate_vesting_factor(d, stake_account);
|
||||
auto vesting_factor = d.calculate_vesting_factor(stake_account);
|
||||
voting_stake = (uint64_t)floor(voting_stake * vesting_factor);
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// GPOS HARDFORK Friday, February 15, 2019 5:08:21 PM
|
||||
// GPOS HARDFORK Friday, March 15, 2019 11:57:28 PM
|
||||
#ifndef HARDFORK_GPOS_TIME
|
||||
#define HARDFORK_GPOS_TIME (fc::time_point_sec( 1550250501 ))
|
||||
#define HARDFORK_GPOS_TIME (fc::time_point_sec( 1552694248 ))
|
||||
#endif
|
||||
|
|
@ -498,8 +498,11 @@ namespace graphene { namespace chain {
|
|||
void update_active_witnesses();
|
||||
void update_active_committee_members();
|
||||
void update_worker_votes();
|
||||
public:
|
||||
double calculate_vesting_factor(const account_object& stake_account);
|
||||
|
||||
template<class... Types>
|
||||
|
||||
template<class... Types>
|
||||
void perform_account_maintenance(std::tuple<Types...> helpers);
|
||||
///@}
|
||||
///@}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@
|
|||
|
||||
#include "../common/database_fixture.hpp"
|
||||
|
||||
#include <graphene/app/database_api.hpp>
|
||||
|
||||
using namespace graphene::chain;
|
||||
using namespace graphene::chain::test;
|
||||
|
||||
|
|
@ -340,6 +342,7 @@ BOOST_AUTO_TEST_CASE( voting )
|
|||
{
|
||||
ACTORS((alice)(bob));
|
||||
try {
|
||||
|
||||
// move to hardfork
|
||||
generate_blocks( HARDFORK_GPOS_TIME );
|
||||
generate_block();
|
||||
|
|
@ -638,16 +641,15 @@ BOOST_AUTO_TEST_CASE( worker_dividends_voting )
|
|||
BOOST_AUTO_TEST_CASE( account_multiple_vesting )
|
||||
{
|
||||
try {
|
||||
|
||||
// update default gpos global parameters to 4 days
|
||||
auto now = db.head_block_time();
|
||||
update_gpos_global(345600, 86400, now);
|
||||
|
||||
// advance to HF
|
||||
generate_blocks(HARDFORK_GPOS_TIME);
|
||||
generate_block();
|
||||
set_expiration(db, trx);
|
||||
|
||||
// update default gpos global parameters to 4 days
|
||||
auto now = db.head_block_time();
|
||||
update_gpos_global(345600, 86400, now);
|
||||
|
||||
ACTORS((sam)(patty));
|
||||
|
||||
const auto& core = asset_id_type()(db);
|
||||
|
|
@ -839,4 +841,113 @@ BOOST_AUTO_TEST_CASE( proxy_voting )
|
|||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( no_proposal )
|
||||
{
|
||||
try {
|
||||
|
||||
}
|
||||
catch (fc::exception &e) {
|
||||
edump((e.to_detail_string()));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
BOOST_AUTO_TEST_CASE( database_api )
|
||||
{
|
||||
ACTORS((alice)(bob));
|
||||
try {
|
||||
|
||||
// move to hardfork
|
||||
generate_blocks( HARDFORK_GPOS_TIME );
|
||||
generate_block();
|
||||
|
||||
// database api
|
||||
graphene::app::database_api db_api(db);
|
||||
|
||||
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();
|
||||
|
||||
// add some vesting to alice and bob
|
||||
create_vesting(alice_id, core.amount(100), vesting_balance_type::gpos);
|
||||
generate_block();
|
||||
|
||||
// total balance is 100 rest of data at 0
|
||||
auto gpos_info = db_api.get_gpos_info(alice_id);
|
||||
BOOST_CHECK_EQUAL(gpos_info.vesting_factor, 0);
|
||||
BOOST_CHECK_EQUAL(gpos_info.award.amount.value, 0);
|
||||
BOOST_CHECK_EQUAL(gpos_info.total_amount.value, 100);
|
||||
|
||||
create_vesting(bob_id, core.amount(100), vesting_balance_type::gpos);
|
||||
generate_block();
|
||||
|
||||
// total gpos balance is now 200
|
||||
gpos_info = db_api.get_gpos_info(alice_id);
|
||||
BOOST_CHECK_EQUAL(gpos_info.total_amount.value, 200);
|
||||
|
||||
// update default gpos and dividend interval to 10 days
|
||||
auto now = db.head_block_time();
|
||||
update_gpos_global(5184000, 864000, now); // 10 days subperiods
|
||||
update_payout_interval(core.symbol, fc::time_point::now() + fc::minutes(1), 60 * 60 * 24 * 10); // 10 days
|
||||
|
||||
generate_block();
|
||||
|
||||
// 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);
|
||||
|
||||
// transfering some coins to distribution account.
|
||||
const auto& dividend_holder_asset_object = get_asset(GRAPHENE_SYMBOL);
|
||||
const auto& dividend_data = dividend_holder_asset_object.dividend_data(db);
|
||||
const account_object& dividend_distribution_account = dividend_data.dividend_distribution_account(db);
|
||||
transfer( committee_account, dividend_distribution_account.id, core.amount( 100 ) );
|
||||
generate_block();
|
||||
|
||||
// award balance is now 100
|
||||
gpos_info = db_api.get_gpos_info(alice_id);
|
||||
BOOST_CHECK_EQUAL(gpos_info.vesting_factor, 0);
|
||||
BOOST_CHECK_EQUAL(gpos_info.award.amount.value, 100);
|
||||
BOOST_CHECK_EQUAL(gpos_info.total_amount.value, 200);
|
||||
|
||||
// vote for witness1
|
||||
vote_for(alice_id, witness1.vote_id, alice_private_key);
|
||||
vote_for(bob_id, witness1.vote_id, bob_private_key);
|
||||
|
||||
// go to maint
|
||||
generate_blocks(db.get_dynamic_global_properties().next_maintenance_time);
|
||||
|
||||
// payment for alice and bob is done, distribution account is back in 0
|
||||
gpos_info = db_api.get_gpos_info(alice_id);
|
||||
BOOST_CHECK_EQUAL(gpos_info.vesting_factor, 1);
|
||||
BOOST_CHECK_EQUAL(gpos_info.award.amount.value, 0);
|
||||
BOOST_CHECK_EQUAL(gpos_info.total_amount.value, 200);
|
||||
|
||||
advance_x_maint(10);
|
||||
|
||||
// alice vesting coeffcient decay
|
||||
gpos_info = db_api.get_gpos_info(alice_id);
|
||||
BOOST_CHECK_EQUAL(gpos_info.vesting_factor, 0.83333333333333337);
|
||||
BOOST_CHECK_EQUAL(gpos_info.award.amount.value, 0);
|
||||
BOOST_CHECK_EQUAL(gpos_info.total_amount.value, 200);
|
||||
|
||||
advance_x_maint(10);
|
||||
|
||||
// vesting factor for alice decaying more
|
||||
gpos_info = db_api.get_gpos_info(alice_id);
|
||||
BOOST_CHECK_EQUAL(gpos_info.vesting_factor, 0.66666666666666663);
|
||||
BOOST_CHECK_EQUAL(gpos_info.award.amount.value, 0);
|
||||
BOOST_CHECK_EQUAL(gpos_info.total_amount.value, 200);
|
||||
}
|
||||
catch (fc::exception &e) {
|
||||
edump((e.to_detail_string()));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
|
|
|||
Loading…
Reference in a new issue