Skip to content

Commit

Permalink
Change hard fork to occur at maintenance interval
Browse files Browse the repository at this point in the history
  • Loading branch information
abitmore committed Apr 7, 2018
1 parent c3d0acc commit ea12aa8
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 7 deletions.
41 changes: 41 additions & 0 deletions libraries/chain/db_maint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,38 @@ void database::process_bids( const asset_bitasset_data_object& bad )
_cancel_bids_and_revive_mpa( to_revive, bad );
}

void update_and_match_call_orders( database& db )
{
// Update call_price
asset_id_type current_asset;
const asset_bitasset_data_object* abd = nullptr;
// by_collateral index won't change after call_price updated, so it's safe to iterate
for( const auto& call_obj : db.get_index_type<call_order_index>().indices().get<by_collateral>() )
{
if( current_asset != call_obj.debt_type() ) // debt type won't be asset_id_type(), abd will always get initialized
{
current_asset = call_obj.debt_type();
abd = &current_asset(db).bitasset_data(db);
}
if( !abd || abd->is_prediction_market ) // nothing to do with PM's; check !abd just to be safe
continue;
db.modify( call_obj, [&]( call_order_object& call ) {
call.call_price = price::call_price( call.get_debt(), call.get_collateral(),
abd->current_feed.maintenance_collateral_ratio );
});
}
// Match call orders
const auto& asset_idx = db.get_index_type<asset_index>().indices().get<by_type>();
auto itr = asset_idx.lower_bound( true /** market issued */ );
while( itr != asset_idx.end() )
{
const asset_object& a = *itr;
++itr;
// be here, next_maintenance_time should have been updated already
db.check_call_orders( a, true, false ); // allow black swan, and call orders are taker
}
}

void database::perform_chain_maintenance(const signed_block& next_block, const global_property_object& global_props)
{
const auto& gpo = get_global_properties();
Expand Down Expand Up @@ -917,11 +949,20 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
if( (dgpo.next_maintenance_time < HARDFORK_613_TIME) && (next_maintenance_time >= HARDFORK_613_TIME) )
deprecate_annual_members(*this);

// To reset call_price of all call orders, then match by new rule
bool to_update_and_match_call_orders = false;
if( (dgpo.next_maintenance_time <= HARDFORK_CORE_343_TIME) && (next_maintenance_time > HARDFORK_CORE_343_TIME) )
to_update_and_match_call_orders = true;

modify(dgpo, [next_maintenance_time](dynamic_global_property_object& d) {
d.next_maintenance_time = next_maintenance_time;
d.accounts_registered_this_interval = 0;
});

// We need to do it after updated next_maintenance_time, to apply new rules here
if( to_update_and_match_call_orders )
update_and_match_call_orders(*this);

// Reset all BitAsset force settlement volumes to zero
for( const auto& d : get_index_type<asset_bitasset_data_index>().indices() )
{
Expand Down
14 changes: 8 additions & 6 deletions libraries/chain/db_market.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@ bool database::apply_order(const limit_order_object& new_order_object, bool allo
auto old_call_itr = call_itr;
++call_itr; // would be safe, since we'll end the loop if a call order is partially matched
// match returns 2 when only the old order was fully filled. In this case, we keep matching; otherwise, we stop.
// assume hard fork core-338 and core-625 will take place at same time, not checking HARDFORK_CORE_338_TIME here.
finished = ( match( new_order_object, *old_call_itr, call_match_price ) != 2 );
}
}
Expand Down Expand Up @@ -689,7 +690,7 @@ bool database::fill_order( const call_order_object& order, const asset& pays, co
collateral_freed = o.get_collateral();
o.collateral = 0;
}
else if( head_block_time() > HARDFORK_CORE_343_TIME )
else if( get_dynamic_global_properties().next_maintenance_time > HARDFORK_CORE_343_TIME )
o.call_price = price::call_price( o.get_debt(), o.get_collateral(),
mia.bitasset_data(*this).current_feed.maintenance_collateral_ratio );
});
Expand Down Expand Up @@ -807,6 +808,7 @@ bool database::check_call_orders(const asset_object& mia, bool enable_black_swan
bool margin_called = false;

auto head_time = head_block_time();
auto maint_time = get_dynamic_global_properties().next_maintenance_time;
while( !check_for_blackswan( mia, enable_black_swan ) && call_itr != call_end )
{
bool filled_limit_in_loop = false;
Expand All @@ -829,7 +831,7 @@ bool database::check_call_orders(const asset_object& mia, bool enable_black_swan
return margin_called;

// would be margin called, but there is no matching order
if( head_time <= HARDFORK_CORE_606_TIME && match_price > ~call_itr->call_price )
if( maint_time <= HARDFORK_CORE_606_TIME && match_price > ~call_itr->call_price )
return margin_called;

/*
Expand Down Expand Up @@ -877,24 +879,24 @@ bool database::check_call_orders(const asset_object& mia, bool enable_black_swan
order_pays = usd_to_buy;

filled_call = true;
if( filled_limit && head_time <= HARDFORK_CORE_453_TIME )
if( filled_limit && maint_time <= HARDFORK_CORE_453_TIME )
wlog( "Multiple limit match problem (issue 453) occurred at block #${block}", ("block",head_block_num()) );
}

FC_ASSERT( filled_call || filled_limit );
FC_ASSERT( filled_call || filled_limit_in_loop );

auto old_call_itr = call_itr;
if( filled_call && head_time <= HARDFORK_CORE_343_TIME )
if( filled_call && maint_time <= HARDFORK_CORE_343_TIME )
++call_itr;
// when for_new_limit_order is true, the call order is maker, otherwise the call order is taker
fill_order(*old_call_itr, call_pays, call_receives, match_price, for_new_limit_order );
if( head_time > HARDFORK_CORE_343_TIME )
if( maint_time > HARDFORK_CORE_343_TIME )
call_itr = call_price_index.lower_bound( call_min );

auto old_limit_itr = limit_itr;
auto next_limit_itr = std::next( limit_itr );
if( head_time <= HARDFORK_CORE_453_TIME )
if( maint_time <= HARDFORK_CORE_453_TIME )
{
if( filled_limit ) ++limit_itr;
}
Expand Down
2 changes: 1 addition & 1 deletion libraries/chain/market_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ object_id_type limit_order_create_evaluator::do_apply(const limit_order_create_o
});
limit_order_id_type order_id = new_order_object.id; // save this because we may remove the object by filling it
bool filled;
if( db().head_block_time() <= HARDFORK_CORE_625_TIME )
if( db().get_dynamic_global_properties().next_maintenance_time <= HARDFORK_CORE_625_TIME )
filled = db().apply_order_before_hardfork_625( new_order_object );
else
filled = db().apply_order( new_order_object );
Expand Down

0 comments on commit ea12aa8

Please sign in to comment.