Merge branch 'feature/SONs-base' into feature/SON-307
This commit is contained in:
commit
083309d52d
12 changed files with 94 additions and 93 deletions
|
|
@ -170,8 +170,6 @@ void database::pay_sons()
|
|||
if(s.txs_signed > 0){
|
||||
auto son_params = get_global_properties().parameters;
|
||||
share_type pay = (s.txs_signed * son_budget.value)/total_txs_signed;
|
||||
// TODO: Remove me after QA
|
||||
ilog( "pay ${p} to ${s} for ${t} transactions signed", ("p", pay.value)("s", s.id)("t",s.txs_signed) );
|
||||
const auto& idx = get_index_type<son_index>().indices().get<by_id>();
|
||||
auto son_obj = idx.find( s.owner );
|
||||
modify( *son_obj, [&]( son_object& _son_obj)
|
||||
|
|
@ -339,6 +337,8 @@ void database::update_son_wallet(const vector<son_info>& new_active_sons)
|
|||
}
|
||||
}
|
||||
|
||||
should_recreate_pw = should_recreate_pw && (new_active_sons.size() >= get_chain_properties().immutable_parameters.min_son_count);
|
||||
|
||||
if (should_recreate_pw) {
|
||||
// Create new son_wallet_object, to initiate wallet recreation
|
||||
create<son_wallet_object>( [&]( son_wallet_object& obj ) {
|
||||
|
|
@ -830,7 +830,7 @@ void database::process_budget()
|
|||
pay_sons();
|
||||
rec.leftover_son_funds = dpo.son_budget;
|
||||
available_funds += rec.leftover_son_funds;
|
||||
son_budget = gpo.parameters.son_pay_daily_max();
|
||||
son_budget = gpo.parameters.son_pay_max();
|
||||
son_budget = std::min(son_budget, available_funds);
|
||||
rec.son_budget = son_budget;
|
||||
available_funds -= son_budget;
|
||||
|
|
|
|||
|
|
@ -229,14 +229,13 @@
|
|||
#define TOURNAMENT_MAX_WHITELIST_LENGTH 1000
|
||||
#define TOURNAMENT_MAX_START_TIME_IN_FUTURE (60*60*24*7*4) // 1 month
|
||||
#define TOURNAMENT_MAX_START_DELAY (60*60*24*7) // 1 week
|
||||
#define MIN_SON_MEMBER_COUNT 15
|
||||
#define SON_VESTING_AMOUNT (50*GRAPHENE_BLOCKCHAIN_PRECISION) // 50 PPY
|
||||
#define SON_VESTING_PERIOD (60*60*24*2) // 2 days
|
||||
#define SON_DEREGISTER_TIME (60*60*12) // 12 Hours in seconds
|
||||
#define SON_HEARTBEAT_FREQUENCY (60*3) // 3 minutes in seconds
|
||||
#define SON_DOWN_TIME (60*3*2) // 2 Heartbeats in seconds
|
||||
#define SON_PAY_TIME (60*60*24) // 1 day
|
||||
#define MIN_SON_PAY_DAILY_MAX (GRAPHENE_BLOCKCHAIN_PRECISION * int64_t(200))
|
||||
#define SON_PAY_MAX (GRAPHENE_BLOCKCHAIN_PRECISION * int64_t(200))
|
||||
#define SWEEPS_DEFAULT_DISTRIBUTION_PERCENTAGE (2*GRAPHENE_1_PERCENT)
|
||||
#define SWEEPS_DEFAULT_DISTRIBUTION_ASSET (graphene::chain::asset_id_type(0))
|
||||
#define SWEEPS_VESTING_BALANCE_MULTIPLIER 100000000
|
||||
|
|
|
|||
|
|
@ -50,10 +50,9 @@ namespace graphene { namespace chain {
|
|||
optional < uint32_t > gpos_period_start = HARDFORK_GPOS_TIME.sec_since_epoch();
|
||||
optional < uint32_t > gpos_vesting_lockin_period = GPOS_VESTING_LOCKIN_PERIOD;
|
||||
|
||||
optional < uint16_t > son_count;
|
||||
optional < uint32_t > son_vesting_amount;
|
||||
optional < uint32_t > son_vesting_period;
|
||||
optional < uint32_t > son_pay_daily_max;
|
||||
optional < uint32_t > son_pay_max;
|
||||
optional < uint32_t > son_pay_time;
|
||||
optional < uint32_t > son_deregister_time;
|
||||
optional < uint32_t > son_heartbeat_frequency;
|
||||
|
|
@ -140,17 +139,14 @@ namespace graphene { namespace chain {
|
|||
inline account_id_type sweeps_vesting_accumulator_account()const {
|
||||
return extensions.value.sweeps_vesting_accumulator_account.valid() ? *extensions.value.sweeps_vesting_accumulator_account : SWEEPS_ACCUMULATOR_ACCOUNT;
|
||||
}
|
||||
inline uint16_t son_count()const {
|
||||
return extensions.value.son_count.valid() ? *extensions.value.son_count : MIN_SON_MEMBER_COUNT;
|
||||
}
|
||||
inline uint32_t son_vesting_amount()const {
|
||||
return extensions.value.son_vesting_amount.valid() ? *extensions.value.son_vesting_amount : SON_VESTING_AMOUNT; /// current period start date
|
||||
}
|
||||
inline uint32_t son_vesting_period()const {
|
||||
return extensions.value.son_vesting_period.valid() ? *extensions.value.son_vesting_period : SON_VESTING_PERIOD; /// current period start date
|
||||
}
|
||||
inline uint16_t son_pay_daily_max()const {
|
||||
return extensions.value.son_pay_daily_max.valid() ? *extensions.value.son_pay_daily_max : MIN_SON_PAY_DAILY_MAX;
|
||||
inline uint16_t son_pay_max()const {
|
||||
return extensions.value.son_pay_max.valid() ? *extensions.value.son_pay_max : SON_PAY_MAX;
|
||||
}
|
||||
inline uint16_t son_pay_time()const {
|
||||
return extensions.value.son_pay_time.valid() ? *extensions.value.son_pay_time : SON_PAY_TIME;
|
||||
|
|
@ -192,7 +188,6 @@ FC_REFLECT( graphene::chain::parameter_extension,
|
|||
(betting_rake_fee_percentage)
|
||||
(permitted_betting_odds_increments)
|
||||
(live_betting_delay_time)
|
||||
(son_count)
|
||||
(sweeps_distribution_percentage)
|
||||
(sweeps_distribution_asset)
|
||||
(sweeps_vesting_accumulator_account)
|
||||
|
|
@ -202,7 +197,7 @@ FC_REFLECT( graphene::chain::parameter_extension,
|
|||
(gpos_vesting_lockin_period)
|
||||
(son_vesting_amount)
|
||||
(son_vesting_period)
|
||||
(son_pay_daily_max)
|
||||
(son_pay_max)
|
||||
(son_pay_time)
|
||||
(son_deregister_time)
|
||||
(son_heartbeat_frequency)
|
||||
|
|
|
|||
|
|
@ -141,8 +141,6 @@ object_id_type son_heartbeat_evaluator::do_apply(const son_heartbeat_operation&
|
|||
{
|
||||
sso.current_interval_downtime += op.ts.sec_since_epoch() - sso.last_down_timestamp.sec_since_epoch();
|
||||
sso.last_active_timestamp = op.ts;
|
||||
// TODO: Remove me after sidechain tx signing is finished
|
||||
sso.txs_signed = sso.txs_signed + 1;
|
||||
} );
|
||||
|
||||
db().modify(*itr, [&is_son_active](son_object &so) {
|
||||
|
|
@ -156,8 +154,6 @@ object_id_type son_heartbeat_evaluator::do_apply(const son_heartbeat_operation&
|
|||
db().modify( itr->statistics( db() ), [&]( son_statistics_object& sso )
|
||||
{
|
||||
sso.last_active_timestamp = op.ts;
|
||||
// TODO: Remove me after sidechain tx signing is finished
|
||||
sso.txs_signed = sso.txs_signed + 1;
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include <graphene/chain/son_wallet_deposit_evaluator.hpp>
|
||||
|
||||
#include <graphene/chain/database.hpp>
|
||||
#include <graphene/chain/chain_property_object.hpp>
|
||||
#include <graphene/chain/is_authorized_asset.hpp>
|
||||
#include <graphene/chain/son_object.hpp>
|
||||
#include <graphene/chain/son_wallet_deposit_object.hpp>
|
||||
|
|
@ -130,6 +131,7 @@ void_result process_son_wallet_deposit_evaluator::do_evaluate(const son_wallet_d
|
|||
{ try{
|
||||
FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK");
|
||||
FC_ASSERT( op.payer == db().get_global_properties().parameters.son_account(), "SON paying account must be set as payer." );
|
||||
FC_ASSERT(db().get_global_properties().active_sons.size() >= db().get_chain_properties().immutable_parameters.min_son_count, "Min required voted SONs not present");
|
||||
|
||||
const auto& idx = db().get_index_type<son_wallet_deposit_index>().indices().get<by_id>();
|
||||
const auto& itr = idx.find(op.son_wallet_deposit_id);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include <graphene/chain/son_wallet_withdraw_evaluator.hpp>
|
||||
|
||||
#include <graphene/chain/database.hpp>
|
||||
#include <graphene/chain/chain_property_object.hpp>
|
||||
#include <graphene/chain/is_authorized_asset.hpp>
|
||||
#include <graphene/chain/son_object.hpp>
|
||||
#include <graphene/chain/son_wallet_withdraw_object.hpp>
|
||||
|
|
@ -128,6 +129,7 @@ void_result process_son_wallet_withdraw_evaluator::do_evaluate(const son_wallet_
|
|||
{ try{
|
||||
FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK");
|
||||
FC_ASSERT( op.payer == db().get_global_properties().parameters.son_account(), "SON paying account must be set as payer." );
|
||||
FC_ASSERT(db().get_global_properties().active_sons.size() >= db().get_chain_properties().immutable_parameters.min_son_count, "Min required voted SONs not present");
|
||||
|
||||
const auto& idx = db().get_index_type<son_wallet_withdraw_index>().indices().get<by_id>();
|
||||
const auto& itr = idx.find(op.son_wallet_withdraw_id);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <fc/signals.hpp>
|
||||
#include <graphene/chain/global_property_object.hpp>
|
||||
#include <graphene/chain/chain_property_object.hpp>
|
||||
#include <graphene/chain/sidechain_address_object.hpp>
|
||||
#include <graphene/chain/sidechain_transaction_object.hpp>
|
||||
#include <graphene/chain/son_wallet_deposit_object.hpp>
|
||||
|
|
|
|||
|
|
@ -445,9 +445,6 @@ bool peerplays_sidechain_plugin_impl::is_valid_son_proposal(const chain::proposa
|
|||
}
|
||||
}
|
||||
|
||||
ilog("==================================================");
|
||||
ilog("Proposal not approved ${proposal}", ("proposal", proposal));
|
||||
ilog("==================================================");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -143,6 +143,10 @@ void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_
|
|||
}
|
||||
|
||||
void sidechain_net_handler::process_deposits() {
|
||||
if (database.get_global_properties().active_sons.size() < database.get_chain_properties().immutable_parameters.min_son_count) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto &idx = database.get_index_type<son_wallet_deposit_index>().indices().get<by_sidechain_and_confirmed_and_processed>();
|
||||
const auto &idx_range = idx.equal_range(std::make_tuple(sidechain, true, false));
|
||||
|
||||
|
|
@ -188,6 +192,10 @@ void sidechain_net_handler::process_deposits() {
|
|||
}
|
||||
|
||||
void sidechain_net_handler::process_withdrawals() {
|
||||
if (database.get_global_properties().active_sons.size() < database.get_chain_properties().immutable_parameters.min_son_count) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto &idx = database.get_index_type<son_wallet_withdraw_index>().indices().get<by_withdraw_sidechain_and_confirmed_and_processed>();
|
||||
const auto &idx_range = idx.equal_range(std::make_tuple(sidechain, true, false));
|
||||
|
||||
|
|
|
|||
|
|
@ -344,6 +344,7 @@
|
|||
"maximum_asset_feed_publishers": 10,
|
||||
"maximum_witness_count": 1001,
|
||||
"maximum_committee_count": 1001,
|
||||
"maximum_son_count": 15,
|
||||
"maximum_authority_membership": 10,
|
||||
"reserve_percent_of_fee": 2000,
|
||||
"network_percent_of_fee": 2000,
|
||||
|
|
@ -383,7 +384,7 @@
|
|||
"gpos_vesting_lockin_period": 2592000,
|
||||
"son_vesting_amount": 5000000,
|
||||
"son_vesting_period": 172800,
|
||||
"son_pay_daily_max": 20000000,
|
||||
"son_pay_max": 20000000,
|
||||
"son_pay_time": 86400,
|
||||
"son_deregister_time": 43200,
|
||||
"son_heartbeat_frequency": 180,
|
||||
|
|
|
|||
|
|
@ -136,76 +136,76 @@ BOOST_AUTO_TEST_CASE( create_dividend_uia )
|
|||
}
|
||||
}
|
||||
|
||||
//BOOST_AUTO_TEST_CASE( test_update_dividend_interval )
|
||||
//{
|
||||
// using namespace graphene;
|
||||
// try {
|
||||
// INVOKE( create_dividend_uia );
|
||||
//
|
||||
// const auto& dividend_holder_asset_object = get_asset("DIVIDEND");
|
||||
// const auto& dividend_data = dividend_holder_asset_object.dividend_data(db);
|
||||
//
|
||||
// auto advance_to_next_payout_time = [&]() {
|
||||
// // Advance to the next upcoming payout time
|
||||
// BOOST_REQUIRE(dividend_data.options.next_payout_time);
|
||||
// fc::time_point_sec next_payout_scheduled_time = *dividend_data.options.next_payout_time;
|
||||
// // generate blocks up to the next scheduled time
|
||||
// generate_blocks(next_payout_scheduled_time);
|
||||
// // if the scheduled time fell on a maintenance interval, then we should have paid out.
|
||||
// // if not, we need to advance to the next maintenance interval to trigger the payout
|
||||
// if (dividend_data.options.next_payout_time)
|
||||
// {
|
||||
// // we know there was a next_payout_time set when we entered this, so if
|
||||
// // it has been cleared, we must have already processed payouts, no need to
|
||||
// // further advance time.
|
||||
// BOOST_REQUIRE(dividend_data.options.next_payout_time);
|
||||
// if (*dividend_data.options.next_payout_time == next_payout_scheduled_time)
|
||||
// generate_blocks(db.get_dynamic_global_properties().next_maintenance_time);
|
||||
// generate_block(); // get the maintenance skip slots out of the way
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// BOOST_TEST_MESSAGE("Updating the payout interval");
|
||||
// {
|
||||
// asset_update_dividend_operation op;
|
||||
// op.issuer = dividend_holder_asset_object.issuer;
|
||||
// op.asset_to_update = dividend_holder_asset_object.id;
|
||||
// op.new_options.next_payout_time = fc::time_point::now() + fc::minutes(1);
|
||||
// op.new_options.payout_interval = 60 * 60 * 24; // 1 days
|
||||
// trx.operations.push_back(op);
|
||||
// set_expiration(db, trx);
|
||||
// PUSH_TX( db, trx, ~0 );
|
||||
// trx.operations.clear();
|
||||
// }
|
||||
// generate_block();
|
||||
//
|
||||
// BOOST_TEST_MESSAGE("Verifying the updated dividend holder asset options");
|
||||
// {
|
||||
// BOOST_REQUIRE(dividend_data.options.payout_interval);
|
||||
// BOOST_CHECK_EQUAL(*dividend_data.options.payout_interval, 60 * 60 * 24);
|
||||
// }
|
||||
//
|
||||
// BOOST_TEST_MESSAGE("Removing the payout interval");
|
||||
// {
|
||||
// asset_update_dividend_operation op;
|
||||
// op.issuer = dividend_holder_asset_object.issuer;
|
||||
// op.asset_to_update = dividend_holder_asset_object.id;
|
||||
// op.new_options.next_payout_time = dividend_data.options.next_payout_time;
|
||||
// op.new_options.payout_interval = fc::optional<uint32_t>();
|
||||
// trx.operations.push_back(op);
|
||||
// set_expiration(db, trx);
|
||||
// PUSH_TX( db, trx, ~0 );
|
||||
// trx.operations.clear();
|
||||
// }
|
||||
// generate_block();
|
||||
// BOOST_CHECK(!dividend_data.options.payout_interval);
|
||||
// advance_to_next_payout_time();
|
||||
// BOOST_REQUIRE_MESSAGE(!dividend_data.options.next_payout_time, "A new payout was scheduled, but none should have been");
|
||||
// } catch(fc::exception& e) {
|
||||
// edump((e.to_detail_string()));
|
||||
// throw;
|
||||
// }
|
||||
//}
|
||||
BOOST_AUTO_TEST_CASE( test_update_dividend_interval )
|
||||
{
|
||||
using namespace graphene;
|
||||
try {
|
||||
INVOKE( create_dividend_uia );
|
||||
|
||||
const auto& dividend_holder_asset_object = get_asset("DIVIDEND");
|
||||
const auto& dividend_data = dividend_holder_asset_object.dividend_data(db);
|
||||
|
||||
auto advance_to_next_payout_time = [&]() {
|
||||
// Advance to the next upcoming payout time
|
||||
BOOST_REQUIRE(dividend_data.options.next_payout_time);
|
||||
fc::time_point_sec next_payout_scheduled_time = *dividend_data.options.next_payout_time;
|
||||
// generate blocks up to the next scheduled time
|
||||
generate_blocks(next_payout_scheduled_time);
|
||||
// if the scheduled time fell on a maintenance interval, then we should have paid out.
|
||||
// if not, we need to advance to the next maintenance interval to trigger the payout
|
||||
if (dividend_data.options.next_payout_time)
|
||||
{
|
||||
// we know there was a next_payout_time set when we entered this, so if
|
||||
// it has been cleared, we must have already processed payouts, no need to
|
||||
// further advance time.
|
||||
BOOST_REQUIRE(dividend_data.options.next_payout_time);
|
||||
if (*dividend_data.options.next_payout_time == next_payout_scheduled_time)
|
||||
generate_blocks(db.get_dynamic_global_properties().next_maintenance_time);
|
||||
generate_block(); // get the maintenance skip slots out of the way
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_TEST_MESSAGE("Updating the payout interval");
|
||||
{
|
||||
asset_update_dividend_operation op;
|
||||
op.issuer = dividend_holder_asset_object.issuer;
|
||||
op.asset_to_update = dividend_holder_asset_object.id;
|
||||
op.new_options.next_payout_time = fc::time_point::now() + fc::minutes(1);
|
||||
op.new_options.payout_interval = 60 * 60 * 24; // 1 days
|
||||
trx.operations.push_back(op);
|
||||
set_expiration(db, trx);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
trx.operations.clear();
|
||||
}
|
||||
generate_block();
|
||||
|
||||
BOOST_TEST_MESSAGE("Verifying the updated dividend holder asset options");
|
||||
{
|
||||
BOOST_REQUIRE(dividend_data.options.payout_interval);
|
||||
BOOST_CHECK_EQUAL(*dividend_data.options.payout_interval, 60 * 60 * 24);
|
||||
}
|
||||
|
||||
BOOST_TEST_MESSAGE("Removing the payout interval");
|
||||
{
|
||||
asset_update_dividend_operation op;
|
||||
op.issuer = dividend_holder_asset_object.issuer;
|
||||
op.asset_to_update = dividend_holder_asset_object.id;
|
||||
op.new_options.next_payout_time = dividend_data.options.next_payout_time;
|
||||
op.new_options.payout_interval = fc::optional<uint32_t>();
|
||||
trx.operations.push_back(op);
|
||||
set_expiration(db, trx);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
trx.operations.clear();
|
||||
}
|
||||
generate_block();
|
||||
BOOST_CHECK(!dividend_data.options.payout_interval);
|
||||
advance_to_next_payout_time();
|
||||
BOOST_REQUIRE_MESSAGE(!dividend_data.options.next_payout_time, "A new payout was scheduled, but none should have been");
|
||||
} catch(fc::exception& e) {
|
||||
edump((e.to_detail_string()));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_basic_dividend_distribution )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -329,7 +329,7 @@ BOOST_AUTO_TEST_CASE( son_pay_test )
|
|||
// Make witness budget zero so that amount can be allocated to SON
|
||||
db.modify( db.get_global_properties(), [&]( global_property_object& _gpo )
|
||||
{
|
||||
_gpo.parameters.extensions.value.son_pay_daily_max = 200;
|
||||
_gpo.parameters.extensions.value.son_pay_max = 200;
|
||||
_gpo.parameters.witness_pay_per_block = 0;
|
||||
} );
|
||||
// Upgrades pay fee and this goes to reserve
|
||||
|
|
|
|||
Loading…
Reference in a new issue