Resolve #97: Add exponentially growing fees on account creation
It scales up aggressively right now; this can be adjusted later. I just wanted to demonstrate that it works.
This commit is contained in:
parent
dba009da4d
commit
baea85ea3a
6 changed files with 55 additions and 6 deletions
|
|
@ -108,6 +108,17 @@ object_id_type account_create_evaluator::do_apply( const account_create_operatio
|
||||||
obj.options.memo_key = get_relative_id(obj.options.memo_key);
|
obj.options.memo_key = get_relative_id(obj.options.memo_key);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const auto& global_properties = db().get_global_properties();
|
||||||
|
const auto& dynamic_properties = db().get_dynamic_global_properties();
|
||||||
|
db().modify(dynamic_properties, [](dynamic_global_property_object& p) {
|
||||||
|
++p.accounts_registered_this_interval;
|
||||||
|
});
|
||||||
|
if( dynamic_properties.accounts_registered_this_interval %
|
||||||
|
global_properties.parameters.accounts_per_fee_scale == 0 )
|
||||||
|
db().modify(global_properties, [&dynamic_properties](global_property_object& p) {
|
||||||
|
p.parameters.current_fees.account_create_fee <<= p.parameters.account_fee_scale_bitshifts;
|
||||||
|
});
|
||||||
|
|
||||||
return new_acnt_object.id;
|
return new_acnt_object.id;
|
||||||
} FC_CAPTURE_AND_RETHROW((o)) }
|
} FC_CAPTURE_AND_RETHROW((o)) }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -429,11 +429,18 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
|
||||||
update_active_witnesses();
|
update_active_witnesses();
|
||||||
update_active_delegates();
|
update_active_delegates();
|
||||||
|
|
||||||
if( gpo.pending_parameters )
|
modify(gpo, [this](global_property_object& p) {
|
||||||
modify(gpo, [](global_property_object& p) {
|
// Remove scaling of account registration fee
|
||||||
|
const auto& dgpo = get_dynamic_global_properties();
|
||||||
|
p.parameters.current_fees.account_create_fee >>= p.parameters.account_fee_scale_bitshifts *
|
||||||
|
(dgpo.accounts_registered_this_interval / p.parameters.accounts_per_fee_scale);
|
||||||
|
|
||||||
|
if( p.pending_parameters )
|
||||||
|
{
|
||||||
p.parameters = std::move(*p.pending_parameters);
|
p.parameters = std::move(*p.pending_parameters);
|
||||||
p.pending_parameters.reset();
|
p.pending_parameters.reset();
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
|
||||||
auto new_block_interval = global_props.parameters.block_interval;
|
auto new_block_interval = global_props.parameters.block_interval;
|
||||||
|
|
||||||
|
|
@ -445,7 +452,7 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
|
||||||
if( !r )
|
if( !r )
|
||||||
{
|
{
|
||||||
_pending_block.timestamp -= r;
|
_pending_block.timestamp -= r;
|
||||||
assert( (_pending_block.timestamp.sec_since_epoch() % new_block_interval) == 0 );
|
assert( (_pending_block.timestamp.sec_since_epoch() % new_block_interval) == 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
auto next_maintenance_time = get<dynamic_global_property_object>(dynamic_global_property_id_type()).next_maintenance_time;
|
auto next_maintenance_time = get<dynamic_global_property_object>(dynamic_global_property_id_type()).next_maintenance_time;
|
||||||
|
|
@ -465,6 +472,7 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
|
||||||
|
|
||||||
modify(get_dynamic_global_properties(), [next_maintenance_time](dynamic_global_property_object& d) {
|
modify(get_dynamic_global_properties(), [next_maintenance_time](dynamic_global_property_object& d) {
|
||||||
d.next_maintenance_time = next_maintenance_time;
|
d.next_maintenance_time = next_maintenance_time;
|
||||||
|
d.accounts_registered_this_interval = 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Reset all BitAsset force settlement volumes to zero
|
// Reset all BitAsset force settlement volumes to zero
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,8 @@
|
||||||
#define GRAPHENE_WITNESS_PAY_PERCENT_PRECISION (1000000000)
|
#define GRAPHENE_WITNESS_PAY_PERCENT_PRECISION (1000000000)
|
||||||
#define GRAPHENE_DEFAULT_MAX_ASSERT_OPCODE 1
|
#define GRAPHENE_DEFAULT_MAX_ASSERT_OPCODE 1
|
||||||
#define GRAPHENE_DEFAULT_FEE_LIQUIDATION_THRESHOLD GRAPHENE_BLOCKCHAIN_PRECISION * 100;
|
#define GRAPHENE_DEFAULT_FEE_LIQUIDATION_THRESHOLD GRAPHENE_BLOCKCHAIN_PRECISION * 100;
|
||||||
|
#define GRAPHENE_DEFAULT_ACCOUNTS_PER_FEE_SCALE 1000
|
||||||
|
#define GRAPHENE_DEFAULT_ACCOUNT_FEE_SCALE_BITSHIFTS 4
|
||||||
#define GRAPHENE_GENESIS_TIMESTAMP (1431700000) /// Should be divisible by GRAPHENE_DEFAULT_BLOCK_INTERVAL
|
#define GRAPHENE_GENESIS_TIMESTAMP (1431700000) /// Should be divisible by GRAPHENE_DEFAULT_BLOCK_INTERVAL
|
||||||
|
|
||||||
#define GRAPHENE_MAX_WORKER_NAME_LENGTH 63
|
#define GRAPHENE_MAX_WORKER_NAME_LENGTH 63
|
||||||
|
|
|
||||||
|
|
@ -76,10 +76,10 @@ namespace graphene { namespace chain {
|
||||||
time_point_sec next_maintenance_time;
|
time_point_sec next_maintenance_time;
|
||||||
time_point_sec last_budget_time;
|
time_point_sec last_budget_time;
|
||||||
share_type witness_budget;
|
share_type witness_budget;
|
||||||
|
uint32_t accounts_registered_this_interval;
|
||||||
};
|
};
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
|
||||||
FC_REFLECT_DERIVED( graphene::chain::dynamic_global_property_object, (graphene::db::object),
|
FC_REFLECT_DERIVED( graphene::chain::dynamic_global_property_object, (graphene::db::object),
|
||||||
(random)
|
(random)
|
||||||
(head_block_number)
|
(head_block_number)
|
||||||
|
|
@ -88,6 +88,7 @@ FC_REFLECT_DERIVED( graphene::chain::dynamic_global_property_object, (graphene::
|
||||||
(current_witness)
|
(current_witness)
|
||||||
(next_maintenance_time)
|
(next_maintenance_time)
|
||||||
(witness_budget)
|
(witness_budget)
|
||||||
|
(accounts_registered_this_interval)
|
||||||
)
|
)
|
||||||
|
|
||||||
FC_REFLECT_DERIVED( graphene::chain::global_property_object, (graphene::db::object),
|
FC_REFLECT_DERIVED( graphene::chain::global_property_object, (graphene::db::object),
|
||||||
|
|
|
||||||
|
|
@ -345,7 +345,7 @@ namespace graphene { namespace chain {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t key_create_fee = 270300; ///< the cost to register a public key with the blockchain
|
uint32_t key_create_fee = 270300; ///< the cost to register a public key with the blockchain
|
||||||
uint32_t account_create_fee = 666666; ///< the cost to register the cheapest non-free account
|
uint64_t account_create_fee = 666666; ///< the cost to register the cheapest non-free account
|
||||||
uint32_t account_update_fee = 150000; ///< the cost to update an existing account
|
uint32_t account_update_fee = 150000; ///< the cost to update an existing account
|
||||||
uint32_t account_transfer_fee = 300000; ///< the cost to transfer an account to a new owner
|
uint32_t account_transfer_fee = 300000; ///< the cost to transfer an account to a new owner
|
||||||
uint32_t account_whitelist_fee = 300000; ///< the fee to whitelist an account
|
uint32_t account_whitelist_fee = 300000; ///< the fee to whitelist an account
|
||||||
|
|
@ -457,6 +457,8 @@ namespace graphene { namespace chain {
|
||||||
share_type worker_budget_per_day = GRAPHENE_DEFAULT_WORKER_BUDGET_PER_DAY; ///< CORE to be allocated to workers (per day)
|
share_type worker_budget_per_day = GRAPHENE_DEFAULT_WORKER_BUDGET_PER_DAY; ///< CORE to be allocated to workers (per day)
|
||||||
uint16_t max_predicate_opcode = GRAPHENE_DEFAULT_MAX_ASSERT_OPCODE; ///< predicate_opcode must be less than this number
|
uint16_t max_predicate_opcode = GRAPHENE_DEFAULT_MAX_ASSERT_OPCODE; ///< predicate_opcode must be less than this number
|
||||||
share_type fee_liquidation_threshold = GRAPHENE_DEFAULT_FEE_LIQUIDATION_THRESHOLD; ///< value in CORE at which accumulated fees in blockchain-issued market assets should be liquidated
|
share_type fee_liquidation_threshold = GRAPHENE_DEFAULT_FEE_LIQUIDATION_THRESHOLD; ///< value in CORE at which accumulated fees in blockchain-issued market assets should be liquidated
|
||||||
|
uint16_t accounts_per_fee_scale = GRAPHENE_DEFAULT_ACCOUNTS_PER_FEE_SCALE; ///< number of accounts between fee scalings
|
||||||
|
uint8_t account_fee_scale_bitshifts = GRAPHENE_DEFAULT_ACCOUNT_FEE_SCALE_BITSHIFTS; ///< number of times to left bitshift account registration fee at each scaling
|
||||||
|
|
||||||
void validate()const
|
void validate()const
|
||||||
{
|
{
|
||||||
|
|
@ -616,6 +618,8 @@ FC_REFLECT( graphene::chain::chain_parameters,
|
||||||
(worker_budget_per_day)
|
(worker_budget_per_day)
|
||||||
(max_predicate_opcode)
|
(max_predicate_opcode)
|
||||||
(fee_liquidation_threshold)
|
(fee_liquidation_threshold)
|
||||||
|
(accounts_per_fee_scale)
|
||||||
|
(account_fee_scale_bitshifts)
|
||||||
)
|
)
|
||||||
|
|
||||||
FC_REFLECT_TYPENAME( graphene::chain::share_type )
|
FC_REFLECT_TYPENAME( graphene::chain::share_type )
|
||||||
|
|
|
||||||
|
|
@ -839,4 +839,27 @@ BOOST_FIXTURE_TEST_CASE( witness_scheduler_missed_blocks, database_fixture )
|
||||||
});
|
});
|
||||||
} FC_LOG_AND_RETHROW() }
|
} FC_LOG_AND_RETHROW() }
|
||||||
|
|
||||||
|
BOOST_FIXTURE_TEST_CASE( account_create_fee_scaling, database_fixture )
|
||||||
|
{ try {
|
||||||
|
auto accounts_per_scale = db.get_global_properties().parameters.accounts_per_fee_scale;
|
||||||
|
enable_fees(1);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(db.get_global_properties().parameters.current_fees.account_create_fee, 1);
|
||||||
|
for( int i = db.get_dynamic_global_properties().accounts_registered_this_interval; i < accounts_per_scale; ++i )
|
||||||
|
create_account("shill" + fc::to_string(i));
|
||||||
|
generate_block();
|
||||||
|
BOOST_CHECK_EQUAL(db.get_global_properties().parameters.current_fees.account_create_fee, 16);
|
||||||
|
for( int i = 0; i < accounts_per_scale; ++i )
|
||||||
|
create_account("moreshills" + fc::to_string(i));
|
||||||
|
generate_block();
|
||||||
|
BOOST_CHECK_EQUAL(db.get_global_properties().parameters.current_fees.account_create_fee, 256);
|
||||||
|
for( int i = 0; i < accounts_per_scale; ++i )
|
||||||
|
create_account("moarshills" + fc::to_string(i));
|
||||||
|
generate_block();
|
||||||
|
BOOST_CHECK_EQUAL(db.get_global_properties().parameters.current_fees.account_create_fee, 4096);
|
||||||
|
|
||||||
|
generate_blocks(db.get_dynamic_global_properties().next_maintenance_time);
|
||||||
|
BOOST_CHECK_EQUAL(db.get_global_properties().parameters.current_fees.account_create_fee, 1);
|
||||||
|
} FC_LOG_AND_RETHROW() }
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue