Skip to content

Commit

Permalink
Fix tick update
Browse files Browse the repository at this point in the history
  • Loading branch information
abitmore committed Jun 11, 2020
1 parent 1666504 commit 932bb9e
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 48 deletions.
7 changes: 6 additions & 1 deletion libraries/chain/db_update.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -602,8 +602,9 @@ void database::clear_expired_htlcs()
}
}

void database::process_tickets()
generic_operation_result database::process_tickets()
{
generic_operation_result result;
share_type total_delta_pob;
share_type total_delta_inactive;
auto& idx = get_index_type<ticket_index>().indices().get<by_next_update>();
Expand All @@ -619,6 +620,7 @@ void database::process_tickets()
aso.total_core_pol -= ticket.amount.amount;
aso.total_pol_value -= ticket.value;
});
result.removed_objects.insert( ticket.id );
remove( ticket );
}
else
Expand All @@ -628,6 +630,7 @@ void database::process_tickets()
modify( ticket, []( ticket_object& o ) {
o.auto_update();
});
result.updated_objects.insert( ticket.id );

share_type delta_inactive_amount;
share_type delta_forever_amount;
Expand Down Expand Up @@ -687,6 +690,8 @@ void database::process_tickets()
dgp.total_inactive += total_delta_inactive;
});
}

return result;
}

} }
6 changes: 4 additions & 2 deletions libraries/chain/include/graphene/chain/database.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ namespace graphene { namespace chain {

//////////////////// db_block.cpp ////////////////////

public:
public:
// these were formerly private, but they have a fairly well-defined API, so let's make them public
void apply_block( const signed_block& next_block, uint32_t skip = skip_nothing );
processed_transaction apply_transaction( const signed_transaction& trx, uint32_t skip = skip_nothing );
Expand All @@ -581,6 +581,9 @@ namespace graphene { namespace chain {
uint32_t update_witness_missed_blocks( const signed_block& b );

//////////////////// db_update.cpp ////////////////////
public:
generic_operation_result process_tickets();
private:
void update_global_dynamic_data( const signed_block& b, const uint32_t missed_blocks );
void update_signing_witness(const witness_object& signing_witness, const signed_block& new_block);
void update_last_irreversible_block();
Expand All @@ -591,7 +594,6 @@ namespace graphene { namespace chain {
void update_core_exchange_rates();
void update_maintenance_flag( bool new_maintenance_flag );
void update_withdraw_permissions();
void process_tickets();
bool check_for_blackswan( const asset_object& mia, bool enable_black_swan = true,
const asset_bitasset_data_object* bitasset_ptr = nullptr );
void clear_expired_htlcs();
Expand Down
13 changes: 12 additions & 1 deletion libraries/chain/ticket_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,20 @@ generic_operation_result ticket_update_evaluator::do_apply(const ticket_update_o
d.modify( stat, [delta_value](account_statistics_object& aso) {
aso.total_pol_value += delta_value;
});
result.updated_objects.insert( stat.id );
}

// Do auto-update now.
// Note: calling process_tickets() here won't affect other tickets,
// since head_block_time is not updated after last call,
// even when called via a proposal this time or last time
generic_operation_result process_result = d.process_tickets();
result.removed_objects.insert( process_result.removed_objects.begin(), process_result.removed_objects.end() );
result.updated_objects.insert( process_result.updated_objects.begin(), process_result.updated_objects.end() );
for( const auto id : result.new_objects )
result.updated_objects.erase( id );
for( const auto id : result.removed_objects )
result.updated_objects.erase( id );

return result;
} FC_CAPTURE_AND_RETHROW( (op) ) }

Expand Down
145 changes: 101 additions & 44 deletions tests/tests/pob_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2644,20 +2644,7 @@ BOOST_AUTO_TEST_CASE( update_from_withdrawing_to_charging_then_withdraw_again )
// downgrade again
result = update_ticket( tick_1_id(db), lock_180_days, {} );
BOOST_CHECK_EQUAL( result.new_objects.size(), 0u );

// current type should not change
BOOST_CHECK( tick_1_id(db).target_type == lock_180_days );
BOOST_CHECK( tick_1_id(db).current_type == lock_360_days );
BOOST_CHECK( tick_1_id(db).status == withdrawing );
BOOST_CHECK( tick_1_id(db).amount == asset(100) );
BOOST_CHECK_EQUAL( tick_1_id(db).value.value, 100 * 4 );
BOOST_CHECK_EQUAL( db.get_balance( sam_id, asset_id_type() ).amount.value, sam_balance );

BOOST_CHECK( tick_1_id(db).next_type_downgrade_time == down_time );
BOOST_CHECK( tick_1_id(db).next_auto_update_time == down_time );

// generate a block
generate_block();
BOOST_CHECK_EQUAL( result.updated_objects.size(), 1u );

// the ticket should have downgraded
BOOST_CHECK( tick_1_id(db).target_type == lock_180_days );
Expand Down Expand Up @@ -2703,15 +2690,32 @@ BOOST_AUTO_TEST_CASE( update_from_withdrawing_to_charging_then_withdraw_again )
// should have downgraded if not changed to upgrade
BOOST_CHECK( tick_1_id(db).next_type_downgrade_time < db.head_block_time() );

// cancel charging
result = update_ticket( tick_1_id(db), lock_180_days, {} );
BOOST_CHECK_EQUAL( result.new_objects.size(), 0u );
// partially cancel charging
result = update_ticket( tick_1_id(db), lock_180_days, asset(10) );
BOOST_REQUIRE_EQUAL( result.new_objects.size(), 1u );
BOOST_REQUIRE_EQUAL( result.updated_objects.size(), 1u );
BOOST_CHECK_EQUAL( result.removed_objects.size(), 0u );
BOOST_CHECK( *result.updated_objects.begin() == tick_1_id );

BOOST_CHECK( tick_1_id(db).target_type == lock_180_days );
// the new ticket is stable
ticket_id_type tick_2_id = *result.new_objects.begin();

BOOST_REQUIRE( db.find( tick_2_id ) );
BOOST_CHECK( tick_2_id(db).target_type == lock_180_days );
BOOST_CHECK( tick_2_id(db).current_type == lock_180_days );
BOOST_CHECK( tick_2_id(db).status == stable );
BOOST_CHECK( tick_2_id(db).next_auto_update_time == time_point_sec::maximum() );
BOOST_CHECK( tick_2_id(db).next_type_downgrade_time == time_point_sec::maximum() );
BOOST_CHECK( tick_2_id(db).amount == asset(10) );
BOOST_CHECK_EQUAL( tick_2_id(db).value.value, 10 * 2 );
BOOST_CHECK_EQUAL( db.get_balance( sam_id, asset_id_type() ).amount.value, sam_balance );

// check the remainder
BOOST_CHECK( tick_1_id(db).target_type == lock_720_days );
BOOST_CHECK( tick_1_id(db).current_type == lock_180_days );
BOOST_CHECK( tick_1_id(db).status == withdrawing );
BOOST_CHECK( tick_1_id(db).amount == asset(100) );
BOOST_CHECK_EQUAL( tick_1_id(db).value.value, 100 * 2 );
BOOST_CHECK( tick_1_id(db).status == charging );
BOOST_CHECK( tick_1_id(db).amount == asset(90) );
BOOST_CHECK_EQUAL( tick_1_id(db).value.value, 90 * 2 );
BOOST_CHECK_EQUAL( db.get_balance( sam_id, asset_id_type() ).amount.value, sam_balance );

BOOST_CHECK( tick_1_id(db).next_type_downgrade_time == down_time + 180*86400 );
Expand All @@ -2721,14 +2725,31 @@ BOOST_AUTO_TEST_CASE( update_from_withdrawing_to_charging_then_withdraw_again )
// generate a block
generate_block();

// no change
BOOST_CHECK( tick_1_id(db).target_type == lock_720_days );
BOOST_CHECK( tick_1_id(db).current_type == lock_180_days );
BOOST_CHECK( tick_1_id(db).status == charging );
BOOST_CHECK( tick_1_id(db).amount == asset(90) );
BOOST_CHECK_EQUAL( tick_1_id(db).value.value, 90 * 2 );
BOOST_CHECK_EQUAL( db.get_balance( sam_id, asset_id_type() ).amount.value, sam_balance );

BOOST_CHECK( tick_1_id(db).next_type_downgrade_time == down_time + 180*86400 );
// should have downgraded if not changed to upgrade
BOOST_CHECK( tick_1_id(db).next_type_downgrade_time < db.head_block_time() );

// cancel charging
result = update_ticket( tick_1_id(db), lock_180_days, {} );
BOOST_CHECK_EQUAL( result.new_objects.size(), 0u );
BOOST_CHECK_EQUAL( result.updated_objects.size(), 1u );

// the ticket is now stable
BOOST_CHECK( tick_1_id(db).target_type == lock_180_days );
BOOST_CHECK( tick_1_id(db).current_type == lock_180_days );
BOOST_CHECK( tick_1_id(db).status == stable );
BOOST_CHECK( tick_1_id(db).next_auto_update_time == time_point_sec::maximum() );
BOOST_CHECK( tick_1_id(db).next_type_downgrade_time == time_point_sec::maximum() );
BOOST_CHECK( tick_1_id(db).amount == asset(100) );
BOOST_CHECK_EQUAL( tick_1_id(db).value.value, 100 * 2 );
BOOST_CHECK( tick_1_id(db).amount == asset(90) );
BOOST_CHECK_EQUAL( tick_1_id(db).value.value, 90 * 2 );
BOOST_CHECK_EQUAL( db.get_balance( sam_id, asset_id_type() ).amount.value, sam_balance );

// downgrade again
Expand All @@ -2738,14 +2759,14 @@ BOOST_AUTO_TEST_CASE( update_from_withdrawing_to_charging_then_withdraw_again )
BOOST_CHECK( tick_1_id(db).target_type == liquid );
BOOST_CHECK( tick_1_id(db).current_type == liquid );
BOOST_CHECK( tick_1_id(db).status == withdrawing );
BOOST_CHECK( tick_1_id(db).amount == asset(100) );
BOOST_CHECK_EQUAL( tick_1_id(db).value.value, 100 );
BOOST_CHECK( tick_1_id(db).amount == asset(90) );
BOOST_CHECK_EQUAL( tick_1_id(db).value.value, 90 );
BOOST_CHECK_EQUAL( db.get_balance( sam_id, asset_id_type() ).amount.value, sam_balance );

BOOST_CHECK( tick_1_id(db).next_type_downgrade_time != time_point_sec::maximum() );
down_time = tick_1_id(db).next_type_downgrade_time;

// 30 days passed
// X days passed, 30 days to downgrade
generate_blocks( down_time - fc::days(30) );
set_expiration( db, trx );

Expand All @@ -2756,8 +2777,8 @@ BOOST_AUTO_TEST_CASE( update_from_withdrawing_to_charging_then_withdraw_again )
BOOST_CHECK( tick_1_id(db).target_type == lock_720_days );
BOOST_CHECK( tick_1_id(db).current_type == liquid );
BOOST_CHECK( tick_1_id(db).status == charging );
BOOST_CHECK( tick_1_id(db).amount == asset(100) );
BOOST_CHECK_EQUAL( tick_1_id(db).value.value, 100 );
BOOST_CHECK( tick_1_id(db).amount == asset(90) );
BOOST_CHECK_EQUAL( tick_1_id(db).value.value, 90 );
BOOST_CHECK_EQUAL( db.get_balance( sam_id, asset_id_type() ).amount.value, sam_balance );

BOOST_CHECK( tick_1_id(db).next_type_downgrade_time == down_time );
Expand All @@ -2769,8 +2790,8 @@ BOOST_AUTO_TEST_CASE( update_from_withdrawing_to_charging_then_withdraw_again )
BOOST_CHECK( tick_1_id(db).target_type == liquid );
BOOST_CHECK( tick_1_id(db).current_type == liquid );
BOOST_CHECK( tick_1_id(db).status == withdrawing );
BOOST_CHECK( tick_1_id(db).amount == asset(100) );
BOOST_CHECK_EQUAL( tick_1_id(db).value.value, 100 );
BOOST_CHECK( tick_1_id(db).amount == asset(90) );
BOOST_CHECK_EQUAL( tick_1_id(db).value.value, 90 );
BOOST_CHECK_EQUAL( db.get_balance( sam_id, asset_id_type() ).amount.value, sam_balance );

BOOST_CHECK( tick_1_id(db).next_type_downgrade_time == down_time );
Expand All @@ -2786,8 +2807,8 @@ BOOST_AUTO_TEST_CASE( update_from_withdrawing_to_charging_then_withdraw_again )
BOOST_CHECK( tick_1_id(db).target_type == lock_720_days );
BOOST_CHECK( tick_1_id(db).current_type == liquid );
BOOST_CHECK( tick_1_id(db).status == charging );
BOOST_CHECK( tick_1_id(db).amount == asset(100) );
BOOST_CHECK_EQUAL( tick_1_id(db).value.value, 100 );
BOOST_CHECK( tick_1_id(db).amount == asset(90) );
BOOST_CHECK_EQUAL( tick_1_id(db).value.value, 90 );
BOOST_CHECK_EQUAL( db.get_balance( sam_id, asset_id_type() ).amount.value, sam_balance );

BOOST_CHECK( tick_1_id(db).next_type_downgrade_time == down_time );
Expand All @@ -2800,24 +2821,33 @@ BOOST_AUTO_TEST_CASE( update_from_withdrawing_to_charging_then_withdraw_again )
BOOST_CHECK( tick_1_id(db).target_type == lock_720_days );
BOOST_CHECK( tick_1_id(db).current_type == liquid );
BOOST_CHECK( tick_1_id(db).status == charging );
BOOST_CHECK( tick_1_id(db).amount == asset(100) );
BOOST_CHECK_EQUAL( tick_1_id(db).value.value, 100 );
BOOST_CHECK( tick_1_id(db).amount == asset(90) );
BOOST_CHECK_EQUAL( tick_1_id(db).value.value, 90 );
BOOST_CHECK_EQUAL( db.get_balance( sam_id, asset_id_type() ).amount.value, sam_balance );

BOOST_CHECK( tick_1_id(db).next_type_downgrade_time == down_time );
// should have freed if not changed to upgrade
BOOST_CHECK( tick_1_id(db).next_type_downgrade_time < db.head_block_time() );

// cancel charging
result = update_ticket( tick_1_id(db), liquid, {} );
BOOST_CHECK_EQUAL( result.new_objects.size(), 0u );
// partially cancel charging
result = update_ticket( tick_1_id(db), liquid, asset(15) );
BOOST_REQUIRE_EQUAL( result.new_objects.size(), 1u );
BOOST_REQUIRE_EQUAL( result.updated_objects.size(), 1u );
BOOST_REQUIRE_EQUAL( result.removed_objects.size(), 1u );
BOOST_CHECK( *result.updated_objects.begin() == tick_1_id );

BOOST_CHECK( tick_1_id(db).target_type == liquid );
// the new created ticket is freed already
ticket_id_type tick_3_id = *result.new_objects.begin();
BOOST_CHECK( *result.removed_objects.begin() == tick_3_id );
BOOST_CHECK( !db.find( tick_3_id ) );

// check the remainder
BOOST_CHECK( tick_1_id(db).target_type == lock_720_days );
BOOST_CHECK( tick_1_id(db).current_type == liquid );
BOOST_CHECK( tick_1_id(db).status == withdrawing );
BOOST_CHECK( tick_1_id(db).amount == asset(100) );
BOOST_CHECK_EQUAL( tick_1_id(db).value.value, 100 );
BOOST_CHECK_EQUAL( db.get_balance( sam_id, asset_id_type() ).amount.value, sam_balance );
BOOST_CHECK( tick_1_id(db).status == charging );
BOOST_CHECK( tick_1_id(db).amount == asset(75) );
BOOST_CHECK_EQUAL( tick_1_id(db).value.value, 75 );
BOOST_CHECK_EQUAL( db.get_balance( sam_id, asset_id_type() ).amount.value, sam_balance + 15 );

BOOST_CHECK( tick_1_id(db).next_type_downgrade_time == down_time );
// should have freed if not changed to upgrade
Expand All @@ -2826,10 +2856,37 @@ BOOST_AUTO_TEST_CASE( update_from_withdrawing_to_charging_then_withdraw_again )
// generate a block
generate_block();

// the ticket is now freed
// no change
BOOST_CHECK( tick_1_id(db).target_type == lock_720_days );
BOOST_CHECK( tick_1_id(db).current_type == liquid );
BOOST_CHECK( tick_1_id(db).status == charging );
BOOST_CHECK( tick_1_id(db).amount == asset(75) );
BOOST_CHECK_EQUAL( tick_1_id(db).value.value, 75 );
BOOST_CHECK_EQUAL( db.get_balance( sam_id, asset_id_type() ).amount.value, sam_balance + 15 );

BOOST_CHECK( tick_1_id(db).next_type_downgrade_time == down_time );
// should have freed if not changed to upgrade
BOOST_CHECK( tick_1_id(db).next_type_downgrade_time < db.head_block_time() );

// cancel charging
result = update_ticket( tick_1_id(db), liquid, {} );
BOOST_CHECK_EQUAL( result.new_objects.size(), 0u );
BOOST_CHECK_EQUAL( result.updated_objects.size(), 0u );
BOOST_REQUIRE_EQUAL( result.removed_objects.size(), 1u );
BOOST_CHECK( *result.removed_objects.begin() == tick_1_id );

// the ticket is freed
BOOST_CHECK( !db.find( tick_1_id ) );

BOOST_CHECK_EQUAL( db.get_balance( sam_id, asset_id_type() ).amount.value, sam_balance + 100 );
BOOST_CHECK_EQUAL( db.get_balance( sam_id, asset_id_type() ).amount.value, sam_balance + 90 );

// generate a block
generate_block();

// the ticket is freed
BOOST_CHECK( !db.find( tick_1_id ) );

BOOST_CHECK_EQUAL( db.get_balance( sam_id, asset_id_type() ).amount.value, sam_balance + 90 );

} FC_LOG_AND_RETHROW()
}
Expand Down

0 comments on commit 932bb9e

Please sign in to comment.