From 6bc2d06833b26493b57bb646cf2c32cc046c4894 Mon Sep 17 00:00:00 2001 From: Nathan Hourt Date: Fri, 19 Jun 2015 13:31:47 -0400 Subject: [PATCH 1/5] Cashback to blockchain accounts is put in reserve pool --- libraries/chain/db_balance.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libraries/chain/db_balance.cpp b/libraries/chain/db_balance.cpp index 791d8488..7873cbfb 100644 --- a/libraries/chain/db_balance.cpp +++ b/libraries/chain/db_balance.cpp @@ -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(); From a90e3f0155da7d8b5ad3802d181a95fd31c76fdb Mon Sep 17 00:00:00 2001 From: Nathan Hourt Date: Fri, 19 Jun 2015 13:43:39 -0400 Subject: [PATCH 2/5] Fix broken delegate_feeds test --- tests/common/database_fixture.cpp | 5 +++-- tests/tests/basic_tests.cpp | 14 ++++++++++++++ tests/tests/operation_tests.cpp | 28 +++++++--------------------- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/tests/common/database_fixture.cpp b/tests/common/database_fixture.cpp index 44bb134d..c19d9f11 100644 --- a/tests/common/database_fixture.cpp +++ b/tests/common/database_fixture.cpp @@ -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; diff --git a/tests/tests/basic_tests.cpp b/tests/tests/basic_tests.cpp index 65ce489a..efe1ae5b 100644 --- a/tests/tests/basic_tests.cpp +++ b/tests/tests/basic_tests.cpp @@ -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 ) diff --git a/tests/tests/operation_tests.cpp b/tests/tests/operation_tests.cpp index 8196c263..759124b0 100644 --- a/tests/tests/operation_tests.cpp +++ b/tests/tests/operation_tests.cpp @@ -933,7 +933,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; @@ -955,44 +954,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())); From 5e475e0c15c66cd980471318b75bc9c6c487b03b Mon Sep 17 00:00:00 2001 From: Nathan Hourt Date: Fri, 19 Jun 2015 13:46:27 -0400 Subject: [PATCH 3/5] Mark expected failures while I track them down --- tests/tests/operation_tests.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/tests/operation_tests.cpp b/tests/tests/operation_tests.cpp index 759124b0..6fe13076 100644 --- a/tests/tests/operation_tests.cpp +++ b/tests/tests/operation_tests.cpp @@ -1056,6 +1056,7 @@ BOOST_AUTO_TEST_CASE( fill_order ) o.calculate_fee(db.current_fee_schedule()); } FC_LOG_AND_RETHROW() } +BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES( witness_withdraw_pay_test, 10 ) BOOST_AUTO_TEST_CASE( witness_withdraw_pay_test ) { try { // there is an immediate maintenance interval in the first block From 5e28a79e6fe23a733cbb8a80498e8df76433dc60 Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Thu, 18 Jun 2015 16:06:42 -0400 Subject: [PATCH 4/5] db_maint.cpp: Roll over leftover witness pay, see 8f739ac7678ba0a06bedf6f7f9c989e521aff346 for description --- libraries/chain/db_init.cpp | 1 + libraries/chain/db_maint.cpp | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/libraries/chain/db_init.cpp b/libraries/chain/db_init.cpp index 1d75f601..0f95fd1d 100644 --- a/libraries/chain/db_init.cpp +++ b/libraries/chain/db_init.cpp @@ -232,6 +232,7 @@ void database::init_genesis(const genesis_state_type& genesis_state) }); create( [&](dynamic_global_property_object& p) { p.time = fc::time_point_sec(GRAPHENE_GENESIS_TIMESTAMP); + p.witness_budget = 0; }); create([&](block_summary_object& p) { }); diff --git a/libraries/chain/db_maint.cpp b/libraries/chain/db_maint.cpp index 5c019c4d..92a2e6a1 100644 --- a/libraries/chain/db_maint.cpp +++ b/libraries/chain/db_maint.cpp @@ -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; }); From 9742bf511d5f03ea86e055bced929b9b1bad3f71 Mon Sep 17 00:00:00 2001 From: Nathan Hourt Date: Fri, 19 Jun 2015 14:18:43 -0400 Subject: [PATCH 5/5] Fix witness_withdraw_pay_test --- tests/tests/operation_tests.cpp | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/tests/tests/operation_tests.cpp b/tests/tests/operation_tests.cpp index 6fe13076..b89caca6 100644 --- a/tests/tests/operation_tests.cpp +++ b/tests/tests/operation_tests.cpp @@ -1056,18 +1056,16 @@ BOOST_AUTO_TEST_CASE( fill_order ) o.calculate_fee(db.current_fee_schedule()); } FC_LOG_AND_RETHROW() } -BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES( witness_withdraw_pay_test, 10 ) BOOST_AUTO_TEST_CASE( witness_withdraw_pay_test ) { try { // there is an immediate maintenance interval in the first block // 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; @@ -1123,43 +1121,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; @@ -1175,7 +1166,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() }