Defer something-for-nothing culling for taker orders until the order is unmatched #555
This commit is contained in:
parent
b67d223d17
commit
ad339d2729
3 changed files with 43 additions and 17 deletions
|
|
@ -132,6 +132,27 @@ void database::cancel_order( const limit_order_object& order, bool create_virtua
|
|||
remove(order);
|
||||
}
|
||||
|
||||
bool maybe_cull_small_order( database& db, const limit_order_object& order )
|
||||
{
|
||||
/**
|
||||
* There are times when the AMOUNT_FOR_SALE * SALE_PRICE == 0 which means that we
|
||||
* have hit the limit where the seller is asking for nothing in return. When this
|
||||
* happens we must refund any balance back to the seller, it is too small to be
|
||||
* sold at the sale price.
|
||||
*
|
||||
* If the order is a taker order (as opposed to a maker order), so the price is
|
||||
* set by the counterparty, this check is deferred until the order becomes unmatched
|
||||
* (see #555) -- however, detecting this condition is the responsibility of the caller.
|
||||
*/
|
||||
if( order.amount_to_receive().amount == 0 )
|
||||
{
|
||||
ilog( "applied epsilon logic" );
|
||||
db.cancel_order(order);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool database::apply_order(const limit_order_object& new_order_object, bool allow_black_swan)
|
||||
{
|
||||
auto order_id = new_order_object.id;
|
||||
|
|
@ -171,7 +192,15 @@ bool database::apply_order(const limit_order_object& new_order_object, bool allo
|
|||
check_call_orders(sell_asset, allow_black_swan);
|
||||
check_call_orders(receive_asset, allow_black_swan);
|
||||
|
||||
return find_object(order_id) == nullptr;
|
||||
const limit_order_object* updated_order_object = find< limit_order_object >( order_id );
|
||||
if( updated_order_object == nullptr )
|
||||
return true;
|
||||
if( head_block_time() <= HARDFORK_555_TIME )
|
||||
return false;
|
||||
// before #555 we would have done maybe_cull_small_order() logic as a result of fill_order() being called by match() above
|
||||
// however after #555 we need to get rid of small orders -- #555 hardfork defers logic that was done too eagerly before, and
|
||||
// this is the point it's deferred to.
|
||||
return maybe_cull_small_order( *this, *updated_order_object );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -218,8 +247,8 @@ int database::match( const limit_order_object& usd, const OrderType& core, const
|
|||
core_pays == core.amount_for_sale() );
|
||||
|
||||
int result = 0;
|
||||
result |= fill_order( usd, usd_pays, usd_receives );
|
||||
result |= fill_order( core, core_pays, core_receives ) << 1;
|
||||
result |= fill_order( usd, usd_pays, usd_receives, false );
|
||||
result |= fill_order( core, core_pays, core_receives, true ) << 1;
|
||||
assert( result != 0 );
|
||||
return result;
|
||||
}
|
||||
|
|
@ -263,8 +292,10 @@ asset database::match( const call_order_object& call,
|
|||
return call_receives;
|
||||
} FC_CAPTURE_AND_RETHROW( (call)(settle)(match_price)(max_settlement) ) }
|
||||
|
||||
bool database::fill_order( const limit_order_object& order, const asset& pays, const asset& receives )
|
||||
bool database::fill_order( const limit_order_object& order, const asset& pays, const asset& receives, bool cull_if_small )
|
||||
{ try {
|
||||
cull_if_small |= (head_block_time() < HARDFORK_555_TIME);
|
||||
|
||||
FC_ASSERT( order.amount_for_sale().asset_id == pays.asset_id );
|
||||
FC_ASSERT( pays.asset_id != receives.asset_id );
|
||||
|
||||
|
|
@ -297,17 +328,8 @@ bool database::fill_order( const limit_order_object& order, const asset& pays, c
|
|||
b.for_sale -= pays.amount;
|
||||
b.deferred_fee = 0;
|
||||
});
|
||||
/**
|
||||
* There are times when the AMOUNT_FOR_SALE * SALE_PRICE == 0 which means that we
|
||||
* have hit the limit where the seller is asking for nothing in return. When this
|
||||
* happens we must refund any balance back to the seller, it is too small to be
|
||||
* sold at the sale price.
|
||||
*/
|
||||
if( order.amount_to_receive().amount == 0 )
|
||||
{
|
||||
cancel_order(order);
|
||||
return true;
|
||||
}
|
||||
if( cull_if_small )
|
||||
return maybe_cull_small_order( *this, order );
|
||||
return false;
|
||||
}
|
||||
} FC_CAPTURE_AND_RETHROW( (order)(pays)(receives) ) }
|
||||
|
|
@ -517,7 +539,7 @@ bool database::check_call_orders(const asset_object& mia, bool enable_black_swan
|
|||
fill_order(*old_call_itr, call_pays, call_receives);
|
||||
|
||||
auto old_limit_itr = filled_limit ? limit_itr++ : limit_itr;
|
||||
fill_order(*old_limit_itr, order_pays, order_receives);
|
||||
fill_order(*old_limit_itr, order_pays, order_receives, true);
|
||||
|
||||
} // whlie call_itr != call_end
|
||||
|
||||
|
|
|
|||
4
libraries/chain/hardfork.d/555.hf
Normal file
4
libraries/chain/hardfork.d/555.hf
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
// #555 Buyback accounts
|
||||
#ifndef HARDFORK_555_TIME
|
||||
#define HARDFORK_555_TIME (fc::time_point_sec( 1455127200 ))
|
||||
#endif
|
||||
|
|
@ -370,7 +370,7 @@ namespace graphene { namespace chain {
|
|||
/**
|
||||
* @return true if the order was completely filled and thus freed.
|
||||
*/
|
||||
bool fill_order( const limit_order_object& order, const asset& pays, const asset& receives );
|
||||
bool fill_order( const limit_order_object& order, const asset& pays, const asset& receives, bool cull_if_small );
|
||||
bool fill_order( const call_order_object& order, const asset& pays, const asset& receives );
|
||||
bool fill_order( const force_settlement_object& settle, const asset& pays, const asset& receives );
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue