Merge branch 'master' of github.com:cryptonomex/graphene
This commit is contained in:
commit
186b970689
6 changed files with 63 additions and 47 deletions
|
|
@ -97,6 +97,17 @@ void database::deposit_cashback(const account_object& acct, share_type amount, b
|
|||
if( amount == 0 )
|
||||
return;
|
||||
|
||||
if( acct.get_id() == GRAPHENE_COMMITTEE_ACCOUNT || acct.get_id() == GRAPHENE_WITNESS_ACCOUNT ||
|
||||
acct.get_id() == GRAPHENE_RELAXED_COMMITTEE_ACCOUNT || acct.get_id() == GRAPHENE_NULL_ACCOUNT ||
|
||||
acct.get_id() == GRAPHENE_TEMP_ACCOUNT )
|
||||
{
|
||||
// The blockchain's accounts do not get cashback; it simply goes to the reserve pool.
|
||||
modify(get(asset_id_type()).dynamic_asset_data_id(*this), [amount](asset_dynamic_data_object& d) {
|
||||
d.current_supply -= amount;
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t global_vesting_seconds = get_global_properties().parameters.cashback_vesting_period_seconds;
|
||||
fc::time_point_sec now = head_block_time();
|
||||
|
||||
|
|
|
|||
|
|
@ -232,6 +232,7 @@ void database::init_genesis(const genesis_state_type& genesis_state)
|
|||
});
|
||||
create<dynamic_global_property_object>( [&](dynamic_global_property_object& p) {
|
||||
p.time = fc::time_point_sec(GRAPHENE_GENESIS_TIMESTAMP);
|
||||
p.witness_budget = 0;
|
||||
});
|
||||
create<block_summary_object>([&](block_summary_object& p) {
|
||||
});
|
||||
|
|
|
|||
|
|
@ -233,6 +233,9 @@ share_type database::get_max_budget( fc::time_point_sec now )const
|
|||
// are available for the budget at this point, but not included
|
||||
// in core.burned().
|
||||
share_type reserve = core.burned(*this) + core_dd.accumulated_fees;
|
||||
// Similarly, we consider leftover witness_budget to be burned
|
||||
// at the BEGINNING of the maintenance interval.
|
||||
reserve += dpo.witness_budget;
|
||||
|
||||
fc::uint128_t budget_u128 = reserve.value;
|
||||
budget_u128 *= uint64_t(dt);
|
||||
|
|
@ -303,16 +306,24 @@ void database::process_budget()
|
|||
pay_workers(leftover_worker_funds);
|
||||
available_funds += leftover_worker_funds;
|
||||
|
||||
share_type unused_prev_witness_budget = dpo.witness_budget;
|
||||
modify(core, [&]( asset_dynamic_data_object& _core )
|
||||
{
|
||||
_core.current_supply = (_core.current_supply + witness_budget +
|
||||
worker_budget - leftover_worker_funds -
|
||||
_core.accumulated_fees);
|
||||
_core.current_supply = (_core.current_supply
|
||||
+ witness_budget
|
||||
+ worker_budget
|
||||
- leftover_worker_funds
|
||||
- _core.accumulated_fees
|
||||
- unused_prev_witness_budget
|
||||
);
|
||||
_core.accumulated_fees = 0;
|
||||
});
|
||||
modify(dpo, [&]( dynamic_global_property_object& _dpo )
|
||||
{
|
||||
_dpo.witness_budget += witness_budget;
|
||||
// Since initial witness_budget was rolled into
|
||||
// available_funds, we replace it with witness_budget
|
||||
// instead of adding it.
|
||||
_dpo.witness_budget = witness_budget;
|
||||
_dpo.last_budget_time = now;
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -78,14 +78,15 @@ database_fixture::database_fixture()
|
|||
|
||||
database_fixture::~database_fixture()
|
||||
{
|
||||
// If we're unwinding due to an exception, don't do any more checks.
|
||||
// This way, boost test's last checkpoint tells us approximately where the error was.
|
||||
if( !std::uncaught_exception() )
|
||||
{
|
||||
verify_asset_supplies();
|
||||
verify_account_history_plugin_index();
|
||||
BOOST_CHECK( db.get_node_properties().skip_flags == database::skip_nothing );
|
||||
}
|
||||
|
||||
BOOST_CHECK( db.get_node_properties().skip_flags == database::skip_nothing );
|
||||
|
||||
if( data_dir )
|
||||
db.close();
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -62,6 +62,20 @@ BOOST_AUTO_TEST_CASE( price_test )
|
|||
BOOST_CHECK( ~price::min(0,1) == price::max(1,0) );
|
||||
BOOST_CHECK( ~price::max(0,1) < ~price::min(0,1) );
|
||||
BOOST_CHECK( ~price::max(0,1) <= ~price::min(0,1) );
|
||||
price a(asset(1), asset(2,1));
|
||||
price b(asset(2), asset(2,1));
|
||||
price c(asset(1), asset(2,1));
|
||||
BOOST_CHECK(a < b);
|
||||
BOOST_CHECK(b > a);
|
||||
BOOST_CHECK(a == c);
|
||||
BOOST_CHECK(!(b == c));
|
||||
|
||||
price_feed dummy;
|
||||
dummy.maintenance_collateral_ratio = 1002;
|
||||
dummy.maximum_short_squeeze_ratio = 1234;
|
||||
dummy.settlement_price = price(asset(1000), asset(2000, 1));
|
||||
price_feed dummy2 = dummy;
|
||||
BOOST_CHECK(dummy == dummy2);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( serialization_tests )
|
||||
|
|
|
|||
|
|
@ -987,7 +987,6 @@ BOOST_AUTO_TEST_CASE( cancel_limit_order_test )
|
|||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES( delegate_feeds, 1 )
|
||||
BOOST_AUTO_TEST_CASE( delegate_feeds )
|
||||
{
|
||||
using namespace graphene::chain;
|
||||
|
|
@ -1009,44 +1008,31 @@ BOOST_AUTO_TEST_CASE( delegate_feeds )
|
|||
|
||||
asset_publish_feed_operation op({asset(), active_witnesses[0]});
|
||||
op.asset_id = bit_usd.get_id();
|
||||
op.feed.settlement_price = price(asset(GRAPHENE_BLOCKCHAIN_PRECISION),bit_usd.amount(30));
|
||||
op.feed.settlement_price = ~price(asset(GRAPHENE_BLOCKCHAIN_PRECISION),bit_usd.amount(30));
|
||||
// Accept defaults for required collateral
|
||||
trx.operations.emplace_back(op);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
{
|
||||
//Dumb sanity check of some operators. Only here to improve code coverage. :D
|
||||
price_feed dummy = op.feed;
|
||||
BOOST_CHECK(op.feed == dummy);
|
||||
price a(asset(1), bit_usd.amount(2));
|
||||
price b(asset(2), bit_usd.amount(2));
|
||||
price c(asset(1), bit_usd.amount(2));
|
||||
BOOST_CHECK(a < b);
|
||||
BOOST_CHECK(b > a);
|
||||
BOOST_CHECK(a == c);
|
||||
BOOST_CHECK(!(b == c));
|
||||
}
|
||||
|
||||
const asset_bitasset_data_object& bitasset = bit_usd.bitasset_data(db);
|
||||
BOOST_CHECK(bitasset.current_feed.settlement_price.to_real() == GRAPHENE_BLOCKCHAIN_PRECISION / 30.0);
|
||||
BOOST_CHECK(bitasset.current_feed.settlement_price.to_real() == 30.0 / GRAPHENE_BLOCKCHAIN_PRECISION);
|
||||
BOOST_CHECK(bitasset.current_feed.maintenance_collateral_ratio == GRAPHENE_DEFAULT_MAINTENANCE_COLLATERAL_RATIO);
|
||||
|
||||
op.publisher = active_witnesses[1];
|
||||
op.feed.settlement_price = price(asset(GRAPHENE_BLOCKCHAIN_PRECISION),bit_usd.amount(25));
|
||||
op.feed.settlement_price = ~price(asset(GRAPHENE_BLOCKCHAIN_PRECISION),bit_usd.amount(25));
|
||||
trx.operations.back() = op;
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
BOOST_CHECK_EQUAL(bitasset.current_feed.settlement_price.to_real(), GRAPHENE_BLOCKCHAIN_PRECISION / 25.0);
|
||||
BOOST_CHECK_EQUAL(bitasset.current_feed.settlement_price.to_real(), 30.0 / GRAPHENE_BLOCKCHAIN_PRECISION);
|
||||
BOOST_CHECK(bitasset.current_feed.maintenance_collateral_ratio == GRAPHENE_DEFAULT_MAINTENANCE_COLLATERAL_RATIO);
|
||||
|
||||
op.publisher = active_witnesses[2];
|
||||
op.feed.settlement_price = price(asset(GRAPHENE_BLOCKCHAIN_PRECISION),bit_usd.amount(40));
|
||||
op.feed.settlement_price = ~price(asset(GRAPHENE_BLOCKCHAIN_PRECISION),bit_usd.amount(40));
|
||||
// But this delegate is an idiot.
|
||||
op.feed.maintenance_collateral_ratio = 1000;
|
||||
op.feed.maintenance_collateral_ratio = 1001;
|
||||
trx.operations.back() = op;
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
BOOST_CHECK_EQUAL(bitasset.current_feed.settlement_price.to_real(), GRAPHENE_BLOCKCHAIN_PRECISION / 30.0);
|
||||
BOOST_CHECK_EQUAL(bitasset.current_feed.settlement_price.to_real(), 30.0 / GRAPHENE_BLOCKCHAIN_PRECISION);
|
||||
BOOST_CHECK(bitasset.current_feed.maintenance_collateral_ratio == GRAPHENE_DEFAULT_MAINTENANCE_COLLATERAL_RATIO);
|
||||
} catch (const fc::exception& e) {
|
||||
edump((e.to_detail_string()));
|
||||
|
|
@ -1130,11 +1116,10 @@ BOOST_AUTO_TEST_CASE( witness_withdraw_pay_test )
|
|||
// which will initialize last_budget_time
|
||||
generate_block();
|
||||
|
||||
// budget should be 25 satoshis based on 30 blocks at 5-second interval
|
||||
// with 17 / 2**32 rate per block
|
||||
const int ref_budget = 125;
|
||||
// set to a value which will exhaust ref_budget after three witnesses
|
||||
// Based on the size of the reserve fund later in the test, the witness budget will be set to this value
|
||||
const int ref_budget = 624;
|
||||
const int witness_ppb = 55;
|
||||
|
||||
db.modify( db.get_global_properties(), [&]( global_property_object& _gpo )
|
||||
{
|
||||
_gpo.parameters.witness_pay_per_block = witness_ppb;
|
||||
|
|
@ -1190,43 +1175,36 @@ 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 );
|
||||
// The 80% lifetime referral fee went to the committee account, which burned it. Check that it's here.
|
||||
BOOST_CHECK_EQUAL( core->burned(db).value, 840000000 );
|
||||
generate_block();
|
||||
BOOST_CHECK_EQUAL( core->burned(db).value, 210000000 - ref_budget );
|
||||
BOOST_CHECK_EQUAL( core->burned(db).value, 840000000 + 210000000 - ref_budget );
|
||||
BOOST_CHECK_EQUAL( db.get_dynamic_global_properties().witness_budget.value, ref_budget );
|
||||
witness = &db.fetch_block_by_number(db.head_block_num())->witness(db);
|
||||
// first witness paid from old budget (so no pay)
|
||||
BOOST_CHECK_EQUAL( witness->accumulated_income.value, 0 );
|
||||
// second witness finally gets paid!
|
||||
generate_block();
|
||||
witness = &db.fetch_block_by_number(db.head_block_num())->witness(db);
|
||||
BOOST_CHECK_EQUAL( witness->accumulated_income.value, witness_ppb );
|
||||
BOOST_CHECK_EQUAL( db.get_dynamic_global_properties().witness_budget.value, ref_budget - witness_ppb );
|
||||
const witness_object* paid_witness = witness;
|
||||
|
||||
// full payment to next witness
|
||||
generate_block();
|
||||
witness = &db.fetch_block_by_number(db.head_block_num())->witness(db);
|
||||
BOOST_CHECK_EQUAL( witness->accumulated_income.value, witness_ppb );
|
||||
BOOST_CHECK_EQUAL( db.get_dynamic_global_properties().witness_budget.value, ref_budget - 2 * witness_ppb );
|
||||
|
||||
// partial payment to last witness
|
||||
generate_block();
|
||||
witness = &db.fetch_block_by_number(db.head_block_num())->witness(db);
|
||||
BOOST_CHECK_EQUAL( witness->accumulated_income.value, ref_budget - 2 * witness_ppb );
|
||||
BOOST_CHECK_EQUAL( db.get_dynamic_global_properties().witness_budget.value, 0 );
|
||||
BOOST_CHECK_EQUAL( witness->accumulated_income.value, witness_ppb );
|
||||
BOOST_CHECK_EQUAL( db.get_dynamic_global_properties().witness_budget.value, ref_budget - 3 * witness_ppb );
|
||||
|
||||
generate_block();
|
||||
witness = &db.fetch_block_by_number(db.head_block_num())->witness(db);
|
||||
BOOST_CHECK_EQUAL( witness->accumulated_income.value, 0 );
|
||||
BOOST_CHECK_EQUAL( db.get_dynamic_global_properties().witness_budget.value, 0 );
|
||||
BOOST_CHECK_EQUAL( witness->accumulated_income.value, witness_ppb );
|
||||
BOOST_CHECK_EQUAL( db.get_dynamic_global_properties().witness_budget.value, ref_budget - 4 * witness_ppb );
|
||||
|
||||
trx.set_expiration(db.head_block_time() + GRAPHENE_DEFAULT_MAX_TIME_UNTIL_EXPIRATION);
|
||||
// last one was unpaid, so pull out a paid one for checks
|
||||
witness = paid_witness;
|
||||
//wdump((*witness));
|
||||
// Withdraw the witness's pay
|
||||
enable_fees(1);
|
||||
witness_withdraw_pay_operation wop;
|
||||
|
|
@ -1242,7 +1220,7 @@ BOOST_AUTO_TEST_CASE( witness_withdraw_pay_test )
|
|||
trx.clear();
|
||||
|
||||
BOOST_CHECK_EQUAL(get_balance(witness->witness_account(db), *core), witness_ppb - 1/*fee*/);
|
||||
BOOST_CHECK_EQUAL(core->burned(db).value, 210000000 - ref_budget );
|
||||
BOOST_CHECK_EQUAL(core->burned(db).value, 840000000 + 210000000 - ref_budget );
|
||||
BOOST_CHECK_EQUAL(witness->accumulated_income.value, 0);
|
||||
} FC_LOG_AND_RETHROW() }
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue