Resolve #31: Wrap it up and fix the failing tests
This commit is contained in:
parent
4df4e8014a
commit
876e9a125d
10 changed files with 60 additions and 42 deletions
|
|
@ -226,6 +226,7 @@ void_result account_upgrade_evaluator::do_apply(const account_upgrade_evaluator:
|
|||
// Upgrade to lifetime member. I don't care what the account was before.
|
||||
a.membership_expiration_date = time_point_sec::maximum();
|
||||
a.referrer = a.registrar = a.lifetime_referrer = a.get_id();
|
||||
a.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT - a.network_fee_percentage;
|
||||
} else if( a.is_annual_member(d.head_block_time()) ) {
|
||||
// Renew an annual subscription that's still in effect.
|
||||
FC_ASSERT(a.membership_expiration_date - d.head_block_time() < fc::days(3650),
|
||||
|
|
|
|||
|
|
@ -155,6 +155,8 @@ void database::init_genesis(const genesis_allocation& initial_allocation)
|
|||
const account_object& genesis_account =
|
||||
create<account_object>( [&](account_object& n) {
|
||||
n.membership_expiration_date = time_point_sec::maximum();
|
||||
n.network_fee_percentage = GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
|
||||
n.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT - GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
|
||||
n.name = "genesis";
|
||||
n.owner.add_authority(genesis_key.get_id(), 1);
|
||||
n.owner.weight_threshold = 1;
|
||||
|
|
@ -179,6 +181,8 @@ void database::init_genesis(const genesis_allocation& initial_allocation)
|
|||
a.referrer = account_id_type(i);
|
||||
a.registrar = account_id_type(i);
|
||||
a.lifetime_referrer = account_id_type(i);
|
||||
a.network_fee_percentage = GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
|
||||
a.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT - GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
|
||||
a.membership_expiration_date = fc::time_point_sec::maximum();
|
||||
a.name = string("init") + fc::to_string(i);
|
||||
a.statistics = stats_obj.id;
|
||||
|
|
|
|||
|
|
@ -242,10 +242,10 @@ void database::process_budget()
|
|||
// blocks_to_maint > 0 because time_to_maint > 0,
|
||||
// which means numerator is at least equal to block_interval
|
||||
|
||||
share_type available_funds = get_max_budget( now );
|
||||
share_type available_funds = get_max_budget(now);
|
||||
|
||||
share_type witness_budget = gpo.parameters.witness_pay_per_block.value * blocks_to_maint;
|
||||
witness_budget = std::min( witness_budget, available_funds );
|
||||
witness_budget = std::min(witness_budget, available_funds);
|
||||
available_funds -= witness_budget;
|
||||
|
||||
fc::uint128_t worker_budget_u128 = gpo.parameters.worker_budget_per_day.value;
|
||||
|
|
@ -260,21 +260,22 @@ void database::process_budget()
|
|||
available_funds -= worker_budget;
|
||||
|
||||
share_type leftover_worker_funds = worker_budget;
|
||||
pay_workers( leftover_worker_funds );
|
||||
pay_workers(leftover_worker_funds);
|
||||
available_funds += leftover_worker_funds;
|
||||
|
||||
modify( core, [&]( asset_dynamic_data_object& _core )
|
||||
modify(core, [&]( asset_dynamic_data_object& _core )
|
||||
{
|
||||
_core.current_supply = (_core.current_supply + witness_budget +
|
||||
worker_budget - leftover_worker_funds -
|
||||
_core.accumulated_fees);
|
||||
_core.accumulated_fees = 0;
|
||||
} );
|
||||
modify( dpo, [&]( dynamic_global_property_object& _dpo )
|
||||
});
|
||||
modify(dpo, [&]( dynamic_global_property_object& _dpo )
|
||||
{
|
||||
// Should this be +=?
|
||||
_dpo.witness_budget = witness_budget;
|
||||
_dpo.last_budget_time = now;
|
||||
} );
|
||||
});
|
||||
|
||||
// available_funds is money we could spend, but don't want to.
|
||||
// we simply let it evaporate back into the reserve.
|
||||
|
|
@ -361,6 +362,11 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
|
|||
|
||||
auto cut_fee = [](share_type a, uint16_t p) -> share_type
|
||||
{
|
||||
if( a == 0 || p == 0 )
|
||||
return 0;
|
||||
if( p == GRAPHENE_100_PERCENT )
|
||||
return a;
|
||||
|
||||
fc::uint128 r(a.value);
|
||||
r *= p;
|
||||
r /= GRAPHENE_100_PERCENT;
|
||||
|
|
@ -400,10 +406,11 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
|
|||
share_type burned = cut_fee(network_cut, props.parameters.burn_percent_of_fee);
|
||||
share_type accumulated = network_cut - burned;
|
||||
assert( accumulated + burned == network_cut );
|
||||
share_type referral = core_fee_total - network_cut;
|
||||
share_type lifetime_cut = cut_fee(core_fee_total, a.lifetime_referrer_fee_percentage);
|
||||
share_type referral = core_fee_total - network_cut - lifetime_cut;
|
||||
|
||||
d.modify(dynamic_asset_data_id_type()(d), [burned,accumulated](asset_dynamic_data_object& d) {
|
||||
d.accumulated_fees += accumulated + burned;
|
||||
d.modify(dynamic_asset_data_id_type()(d), [network_cut](asset_dynamic_data_object& d) {
|
||||
d.accumulated_fees += network_cut;
|
||||
});
|
||||
|
||||
d.modify(a.statistics(d), [core_fee_total](account_statistics_object& s) {
|
||||
|
|
@ -413,20 +420,18 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
|
|||
|
||||
d.deposit_cashback( a, bulk_cashback );
|
||||
|
||||
assert( referral + bulk_cashback + accumulated + burned == core_fee_subtotal );
|
||||
|
||||
// Potential optimization: Skip some of this math and object lookups by special casing on the account type.
|
||||
// For example, if the account is a lifetime member, we can skip all this and just deposit the referral to
|
||||
// it directly.
|
||||
share_type lifetime_cut = cut_fee(referral, a.lifetime_referrer_fee_percentage);
|
||||
share_type referrer_cut = cut_fee(referral, a.referrer_rewards_percentage);
|
||||
share_type registrar_cut = referral - lifetime_cut = referrer_cut;
|
||||
share_type registrar_cut = referral - referrer_cut;
|
||||
|
||||
d.deposit_cashback(d.get(a.lifetime_referrer), lifetime_cut);
|
||||
d.deposit_cashback(d.get(a.referrer), referrer_cut);
|
||||
d.deposit_cashback(d.get(a.registrar), registrar_cut);
|
||||
|
||||
assert( lifetime_cut + referrer_cut + registrar_cut == referral );
|
||||
idump((referrer_cut)(registrar_cut)(bulk_cashback)(accumulated)(burned)(lifetime_cut)(core_fee_subtotal));
|
||||
assert( referrer_cut + registrar_cut + bulk_cashback + accumulated + burned + lifetime_cut == core_fee_subtotal );
|
||||
}
|
||||
}
|
||||
} fees_helper(*this, gpo);
|
||||
|
|
|
|||
|
|
@ -81,7 +81,6 @@
|
|||
#define GRAPHENE_DEFAULT_CASHBACK_VESTING_PERIOD_SEC (60*60*24*365) ///< 1 year
|
||||
#define GRAPHENE_DEFAULT_CASHBACK_VESTING_THRESHOLD (GRAPHENE_BLOCKCHAIN_PRECISION*int64_t(100))
|
||||
#define GRAPHENE_DEFAULT_BURN_PERCENT_OF_FEE (20*GRAPHENE_1_PERCENT)
|
||||
#define GRAPHENE_DEFAULT_WITNESS_PAY_PERCENT_OF_ACCUMULATED ( 1728000) /// gives a half life of 1 year assuming 1 second blocks
|
||||
#define GRAPHENE_WITNESS_PAY_PERCENT_PRECISION (1000000000)
|
||||
#define GRAPHENE_GENESIS_TIMESTAMP (1431700000) /// Should be divisible by GRAPHENE_DEFAULT_BLOCK_INTERVAL
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@
|
|||
#include <graphene/chain/types.hpp>
|
||||
#include <graphene/chain/operations.hpp>
|
||||
|
||||
#include <numeric>
|
||||
|
||||
// this is for htonl() and ntohl() functions
|
||||
// TODO: write and use FC wrappers for these functions
|
||||
#ifndef WIN32
|
||||
|
|
|
|||
|
|
@ -416,8 +416,7 @@ namespace graphene { namespace chain {
|
|||
|
||||
struct chain_parameters
|
||||
{
|
||||
fee_schedule_type current_fees; ///< current schedule of fees, indexed by @ref fee_type
|
||||
uint32_t witness_pay_percent_of_accumulated = GRAPHENE_DEFAULT_WITNESS_PAY_PERCENT_OF_ACCUMULATED; ///< percentage of accumulated fees in core asset to pay to witnesses for block production
|
||||
fee_schedule_type current_fees; ///< current schedule of fees
|
||||
uint8_t block_interval = GRAPHENE_DEFAULT_BLOCK_INTERVAL; ///< interval in seconds between blocks
|
||||
uint32_t maintenance_interval = GRAPHENE_DEFAULT_MAINTENANCE_INTERVAL; ///< interval in sections between blockchain maintenance events
|
||||
uint32_t maximum_transaction_size = GRAPHENE_DEFAULT_MAX_TRANSACTION_SIZE; ///< maximum allowable size in bytes for a transaction
|
||||
|
|
@ -454,7 +453,6 @@ namespace graphene { namespace chain {
|
|||
FC_ASSERT( bulk_discount_threshold_min <= bulk_discount_threshold_max );
|
||||
FC_ASSERT( bulk_discount_threshold_min > 0 );
|
||||
|
||||
FC_ASSERT( witness_pay_percent_of_accumulated < GRAPHENE_WITNESS_PAY_PERCENT_PRECISION );
|
||||
FC_ASSERT( block_interval <= GRAPHENE_MAX_BLOCK_INTERVAL );
|
||||
FC_ASSERT( block_interval > 0 );
|
||||
FC_ASSERT( maintenance_interval > block_interval,
|
||||
|
|
@ -575,7 +573,6 @@ FC_REFLECT( graphene::chain::fee_schedule_type,
|
|||
|
||||
FC_REFLECT( graphene::chain::chain_parameters,
|
||||
(current_fees)
|
||||
(witness_pay_percent_of_accumulated)
|
||||
(block_interval)
|
||||
(maintenance_interval)
|
||||
(maximum_transaction_size)
|
||||
|
|
|
|||
|
|
@ -763,9 +763,11 @@ public:
|
|||
account_object account_obj = get_account(name);
|
||||
FC_ASSERT( !account_obj.is_lifetime_member() );
|
||||
|
||||
// TODO
|
||||
|
||||
signed_transaction tx;
|
||||
account_upgrade_operation op;
|
||||
op.account_to_upgrade = account_obj.get_id();
|
||||
op.upgrade_to_lifetime_member = true;
|
||||
tx.operations = {op};
|
||||
tx.visit( operation_set_fee( _remote_db->get_global_properties().parameters.current_fees ) );
|
||||
tx.validate();
|
||||
|
||||
|
|
|
|||
|
|
@ -119,6 +119,7 @@ void database_fixture::verify_asset_supplies( )const
|
|||
for( const account_statistics_object& a : statistics_index )
|
||||
{
|
||||
reported_core_in_orders += a.total_core_in_orders;
|
||||
total_balances[asset_id_type()] += a.pending_fees;
|
||||
}
|
||||
for( const limit_order_object& o : db.get_index_type<limit_order_index>().indices() )
|
||||
{
|
||||
|
|
@ -672,7 +673,8 @@ void database_fixture::enable_fees(
|
|||
{
|
||||
fc::reflector<fee_schedule_type>::visit(fee_schedule_type::fee_set_visitor{gpo.parameters.current_fees,
|
||||
uint32_t(fee.value)});
|
||||
gpo.parameters.current_fees.membership_annual_fee = 10*fee.value;
|
||||
gpo.parameters.current_fees.membership_annual_fee = 3*fee.value;
|
||||
gpo.parameters.current_fees.membership_lifetime_fee = 10*fee.value;
|
||||
} );
|
||||
}
|
||||
|
||||
|
|
@ -685,9 +687,12 @@ void database_fixture::upgrade_to_lifetime_member( const account_object& account
|
|||
{
|
||||
try
|
||||
{
|
||||
// TODO
|
||||
account_upgrade_operation op;
|
||||
op.account_to_upgrade = account.get_id();
|
||||
op.upgrade_to_lifetime_member = true;
|
||||
trx.operations = {op};
|
||||
db.push_transaction( trx, ~0 );
|
||||
FC_ASSERT( account.is_lifetime_member() );
|
||||
FC_ASSERT( op.account_to_upgrade(db).is_lifetime_member() );
|
||||
trx.clear();
|
||||
}
|
||||
FC_CAPTURE_AND_RETHROW((account))
|
||||
|
|
|
|||
|
|
@ -816,6 +816,7 @@ BOOST_FIXTURE_TEST_CASE( max_authority_membership, database_fixture )
|
|||
private_key_type sam_key = generate_private_key("sam");
|
||||
|
||||
account_object sam_account_object = create_account( "sam", sam_key );
|
||||
upgrade_to_lifetime_member(sam_account_object);
|
||||
account_object genesis_account_object = genesis_account(db);
|
||||
|
||||
const asset_object& core = asset_id_type()(db);
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ BOOST_AUTO_TEST_CASE( child_account )
|
|||
const auto& nathan_key = register_key(nathan_private_key.get_public_key());
|
||||
const account_object& nathan = get_account("nathan");
|
||||
const account_object& root = create_account("root");
|
||||
upgrade_to_lifetime_member(root);
|
||||
|
||||
skip_key_index_test = true;
|
||||
db.modify(nathan, [nathan_key](account_object& a) {
|
||||
|
|
@ -128,7 +129,7 @@ BOOST_AUTO_TEST_CASE( child_account )
|
|||
BOOST_REQUIRE_THROW(db.push_transaction(trx), fc::exception);
|
||||
trx.signatures.clear();
|
||||
op.owner = authority(1, account_id_type(nathan.id), 1);
|
||||
trx.operations.back() = op;
|
||||
trx.operations = {op};
|
||||
sign(trx, key_id_type(), fc::ecc::private_key::regenerate(fc::sha256::hash(string("genesis"))));
|
||||
sign(trx, nathan_key.id, nathan_private_key);
|
||||
db.push_transaction(trx);
|
||||
|
|
@ -186,13 +187,16 @@ BOOST_AUTO_TEST_CASE( update_account )
|
|||
transfer(account_id_type()(db), nathan, asset(3000000));
|
||||
|
||||
enable_fees();
|
||||
// TODO: op.upgrade_to_prime = true;
|
||||
op.fee = op.calculate_fee( db.get_global_properties().parameters.current_fees );
|
||||
trx.operations.push_back(op);
|
||||
db.push_transaction(trx, ~0);
|
||||
{
|
||||
account_upgrade_operation op;
|
||||
op.account_to_upgrade = nathan.id;
|
||||
op.upgrade_to_lifetime_member = true;
|
||||
op.fee = op.calculate_fee(db.get_global_properties().parameters.current_fees);
|
||||
trx.operations = {op};
|
||||
db.push_transaction(trx, ~0);
|
||||
}
|
||||
|
||||
BOOST_CHECK( nathan.referrer == nathan.id );
|
||||
BOOST_CHECK( nathan.referrer_rewards_percentage == 100 );
|
||||
BOOST_CHECK( nathan.is_lifetime_member() );
|
||||
} catch (fc::exception& e) {
|
||||
edump((e.to_detail_string()));
|
||||
throw;
|
||||
|
|
@ -1866,13 +1870,13 @@ BOOST_AUTO_TEST_CASE( witness_withdraw_pay_test )
|
|||
|
||||
const asset_object* core = &asset_id_type()(db);
|
||||
const account_object* nathan = &get_account("nathan");
|
||||
enable_fees(100000000);
|
||||
enable_fees(105000000);
|
||||
BOOST_CHECK_GT(db.current_fee_schedule().membership_lifetime_fee, 0);
|
||||
|
||||
BOOST_CHECK_EQUAL(core->dynamic_asset_data_id(db).accumulated_fees.value, 0);
|
||||
account_update_operation uop;
|
||||
uop.account = nathan->get_id();
|
||||
// TODO: uop.upgrade_to_prime = true;
|
||||
account_upgrade_operation uop;
|
||||
uop.account_to_upgrade = nathan->get_id();
|
||||
uop.upgrade_to_lifetime_member = true;
|
||||
trx.set_expiration(db.head_block_id());
|
||||
trx.operations.push_back(uop);
|
||||
trx.visit(operation_set_fee(db.current_fee_schedule()));
|
||||
|
|
@ -1880,17 +1884,13 @@ BOOST_AUTO_TEST_CASE( witness_withdraw_pay_test )
|
|||
trx.sign(key_id_type(),generate_private_key("genesis"));
|
||||
db.push_transaction(trx);
|
||||
trx.clear();
|
||||
BOOST_CHECK_EQUAL(get_balance(*nathan, *core), 9000000000);
|
||||
BOOST_CHECK_EQUAL(core->dynamic_asset_data_id(db).accumulated_fees.value, 210000000);
|
||||
// TODO: Replace this with another check
|
||||
//BOOST_CHECK_EQUAL(account_id_type()(db).statistics(db).cashback_rewards.value, 1000000000-210000000);
|
||||
BOOST_CHECK_EQUAL(get_balance(*nathan, *core), 8950000000);
|
||||
|
||||
generate_block();
|
||||
nathan = &get_account("nathan");
|
||||
core = &asset_id_type()(db);
|
||||
const witness_object* witness = &db.fetch_block_by_number(db.head_block_num())->witness(db);
|
||||
|
||||
BOOST_CHECK_GT(core->dynamic_asset_data_id(db).accumulated_fees.value, 0);
|
||||
BOOST_CHECK_EQUAL(witness->accumulated_income.value, 0);
|
||||
|
||||
auto schedule_maint = [&]()
|
||||
|
|
@ -1900,7 +1900,7 @@ BOOST_AUTO_TEST_CASE( witness_withdraw_pay_test )
|
|||
{
|
||||
_dpo.next_maintenance_time = db.head_block_time() + 1;
|
||||
} );
|
||||
} ;
|
||||
};
|
||||
|
||||
// generate some blocks
|
||||
while( db.head_block_num() < 30 )
|
||||
|
|
@ -1913,6 +1913,8 @@ BOOST_AUTO_TEST_CASE( witness_withdraw_pay_test )
|
|||
// maintenance will be in block 31. time of block 31 - time of block 1 = 30 * 5 seconds.
|
||||
|
||||
schedule_maint();
|
||||
// TODO: Replace this with another check
|
||||
//BOOST_CHECK_EQUAL(account_id_type()(db).statistics(db).cashback_rewards.value, 1000000000-200000000);
|
||||
// first witness paid from old budget (so no pay)
|
||||
BOOST_CHECK_EQUAL( core->burned(db).value, 0 );
|
||||
generate_block();
|
||||
|
|
|
|||
Loading…
Reference in a new issue