it builds

This commit is contained in:
Daniel Larimer 2015-06-16 10:14:10 -04:00
parent 4ca3bb9f06
commit 663036f2aa
13 changed files with 35 additions and 230 deletions

View file

@ -16,7 +16,7 @@ add_library( graphene_chain
asset_evaluator.cpp
transfer_evaluator.cpp
proposal_evaluator.cpp
short_order_evaluator.cpp
call_order_evaluator.cpp
limit_order_evaluator.cpp
vesting_balance_evaluator.cpp
withdraw_permission_evaluator.cpp

View file

@ -122,18 +122,11 @@ namespace graphene { namespace chain {
{ try {
if( !call_limit.is_null() )
call_limit.validate();
if( !short_limit.is_null() )
short_limit.validate();
if( !settlement_price.is_null() )
settlement_price.validate();
FC_ASSERT( call_limit.is_null() == short_limit.is_null() );
FC_ASSERT( call_limit.base.asset_id == short_limit.quote.asset_id );
FC_ASSERT( call_limit.quote.asset_id == short_limit.base.asset_id );
FC_ASSERT( max_margin_period_sec > 0 );
FC_ASSERT( required_maintenance_collateral < required_initial_collateral );
FC_ASSERT( required_maintenance_collateral >= 1000 );
FC_ASSERT( call_limit.is_null() || call_limit < ~short_limit );
} FC_CAPTURE_AND_RETHROW( (call_limit.is_null())(short_limit.is_null())(call_limit)(short_limit)
(max_margin_period_sec)(required_maintenance_collateral)(required_initial_collateral) ) }
} FC_CAPTURE_AND_RETHROW( (call_limit.is_null())(call_limit)
(max_margin_period_sec)(required_maintenance_collateral) ) }
} } // graphene::chain

View file

@ -18,7 +18,7 @@
#include <graphene/chain/asset_evaluator.hpp>
#include <graphene/chain/asset_object.hpp>
#include <graphene/chain/account_object.hpp>
#include <graphene/chain/short_order_object.hpp>
#include <graphene/chain/call_order_object.hpp>
#include <graphene/chain/database.hpp>
#include <functional>

View file

@ -16,9 +16,9 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <graphene/chain/database.hpp>
#include <graphene/chain/short_order_evaluator.hpp>
#include <graphene/chain/call_order_evaluator.hpp>
#include <graphene/chain/account_object.hpp>
#include <graphene/chain/short_order_object.hpp>
#include <graphene/chain/call_order_object.hpp>
#include <graphene/chain/limit_order_object.hpp>
#include <fc/uint128.hpp>
@ -47,17 +47,17 @@ asset call_order_update_evaluator::do_evaluate(const call_order_update_operation
o.maintenance_collateral_ratio > _bitasset_data->current_feed.required_maintenance_collateral );
}
if( o.amount_to_cover > 0 )
if( o.amount_to_cover.amount > 0 )
{
FC_ASSERT( d.get_balance(*_paying_account, *_debt_asset) >= o.amount_to_cover,
"Cannot cover by ${c} when payer only has ${b}",
("c", o.amount_to_cover.amount)("b", d.get_balance(*_paying_account, *_debt_asset).amount) );
}
if( o.collateral_to_add > 0 )
if( o.collateral_to_add.amount > 0 )
{
FC_ASSERT( d.get_balance(*_paying_account, bitasset_data.options.short_backing_asset(d)) >= o.collateral_to_add,
FC_ASSERT( d.get_balance(*_paying_account, _bitasset_data->options.short_backing_asset(d)) >= o.collateral_to_add,
"Cannot increase collateral by ${c} when payer only has ${b}", ("c", o.amount_to_cover.amount)
("b", d.get_balance(*_paying_account, bitasset_data.options.short_backing_asset(d)).amount) );
("b", d.get_balance(*_paying_account, _bitasset_data->options.short_backing_asset(d)).amount) );
}
return asset();
@ -73,7 +73,7 @@ asset call_order_update_evaluator::do_apply(const call_order_update_operation& o
d.adjust_balance( o.funding_account, -o.collateral_to_add);
// Deduct the debt paid from the total supply of the debt asset.
if( o.amount_to_cover != 0 )
if( o.amount_to_cover.amount != 0 )
{
d.modify(_debt_asset->dynamic_asset_data_id(d), [&](asset_dynamic_data_object& dynamic_asset) {
dynamic_asset.current_supply -= o.amount_to_cover.amount;
@ -88,7 +88,7 @@ asset call_order_update_evaluator::do_apply(const call_order_update_operation& o
FC_ASSERT( o.collateral_to_add.amount > 0 );
FC_ASSERT( o.amount_to_cover.amount < 0 );
d.create<call_order_object>( [&](call_order_object& call ){
call.owner = o.funding_account;
call.borrower = o.funding_account;
call.collateral = o.collateral_to_add.amount;
call.debt = -o.amount_to_cover.amount;
call.maintenance_collateral_ratio = o.maintenance_collateral_ratio;
@ -99,11 +99,11 @@ asset call_order_update_evaluator::do_apply(const call_order_update_operation& o
}
else
{
if( itr->debt - o.amount_to_cover == 0 )
if( itr->debt - o.amount_to_cover.amount == 0 )
{
FC_ASSERT( o.collateral_to_add == 0 );
FC_ASSERT( o.collateral_to_add.amount == 0 );
collateral_returned = itr->get_collateral();
d.adjust_balance( o.funding_account, call.
d.adjust_balance( o.funding_account, collateral_returned );
d.remove( *itr );
}
else

View file

@ -21,7 +21,7 @@
#include <graphene/chain/account_object.hpp>
#include <graphene/chain/asset_object.hpp>
#include <graphene/chain/limit_order_object.hpp>
#include <graphene/chain/short_order_object.hpp>
#include <graphene/chain/call_order_object.hpp>
#include <graphene/chain/vesting_balance_object.hpp>
#include <graphene/chain/witness_object.hpp>
@ -60,13 +60,6 @@ void database::debug_dump()
if( for_sale.asset_id == asset_id_type() ) core_in_orders += for_sale.amount;
total_balances[for_sale.asset_id] += for_sale.amount;
}
for( const short_order_object& o : db.get_index_type<short_order_index>().indices() )
{
idump(("short_order")(o));
auto col = o.get_collateral();
if( col.asset_id == asset_id_type() ) core_in_orders += col.amount;
total_balances[col.asset_id] += col.amount;
}
for( const call_order_object& o : db.get_index_type<call_order_index>().indices() )
{
idump(("call_order")(o));

View file

@ -26,7 +26,7 @@
#include <graphene/chain/key_object.hpp>
#include <graphene/chain/limit_order_object.hpp>
#include <graphene/chain/proposal_object.hpp>
#include <graphene/chain/short_order_object.hpp>
#include <graphene/chain/call_order_object.hpp>
#include <graphene/chain/transaction_object.hpp>
#include <graphene/chain/vesting_balance_object.hpp>
#include <graphene/chain/withdraw_permission_object.hpp>
@ -42,7 +42,7 @@
#include <graphene/chain/key_evaluator.hpp>
#include <graphene/chain/limit_order_evaluator.hpp>
#include <graphene/chain/proposal_evaluator.hpp>
#include <graphene/chain/short_order_evaluator.hpp>
#include <graphene/chain/call_order_evaluator.hpp>
#include <graphene/chain/transfer_evaluator.hpp>
#include <graphene/chain/vesting_balance_evaluator.hpp>
#include <graphene/chain/withdraw_permission_evaluator.hpp>
@ -75,8 +75,6 @@ void database::initialize_evaluators()
register_evaluator<asset_global_settle_evaluator>();
register_evaluator<limit_order_create_evaluator>();
register_evaluator<limit_order_cancel_evaluator>();
register_evaluator<short_order_create_evaluator>();
register_evaluator<short_order_cancel_evaluator>();
register_evaluator<call_order_update_evaluator>();
register_evaluator<transfer_evaluator>();
register_evaluator<asset_fund_fee_pool_evaluator>();
@ -108,7 +106,6 @@ void database::initialize_indexes()
add_index< primary_index<simple_index<delegate_object>> >();
add_index< primary_index<simple_index<witness_object>> >();
add_index< primary_index<limit_order_index > >();
add_index< primary_index<short_order_index > >();
add_index< primary_index<call_order_index > >();
add_index< primary_index<proposal_index > >();
add_index< primary_index<withdraw_permission_index > >();

View file

@ -21,7 +21,7 @@
#include <graphene/chain/account_object.hpp>
#include <graphene/chain/asset_object.hpp>
#include <graphene/chain/limit_order_object.hpp>
#include <graphene/chain/short_order_object.hpp>
#include <graphene/chain/call_order_object.hpp>
#include <fc/uint128.hpp>
@ -225,10 +225,6 @@ int database::match( const limit_order_object& bid, const limit_order_object& as
return match<limit_order_object>( bid, ask, match_price );
}
int database::match( const limit_order_object& bid, const short_order_object& ask, const price& match_price )
{
return match<short_order_object>( bid, ask, match_price );
}
asset database::match( const call_order_object& call, const force_settlement_object& settle, const price& match_price,
asset max_settlement )
@ -290,107 +286,6 @@ bool database::fill_order( const limit_order_object& order, const asset& pays, c
}
}
bool database::fill_order( const short_order_object& order, const asset& pays, const asset& receives )
{ try {
assert( order.amount_for_sale().asset_id == pays.asset_id );
assert( pays.asset_id != receives.asset_id );
const call_order_index& call_index = get_index_type<call_order_index>();
const account_object& seller = order.seller(*this);
const asset_object& recv_asset = receives.asset_id(*this);
const asset_object& pays_asset = pays.asset_id(*this);
assert( pays_asset.is_market_issued() );
auto issuer_fees = pay_market_fees( recv_asset, receives );
bool filled = pays == order.amount_for_sale();
asset seller_to_collateral;
if( (*pays_asset.bitasset_data_id)(*this).is_prediction_market )
{
assert( pays.amount >= receives.amount );
seller_to_collateral = pays.amount - receives.amount;
}
else
{
seller_to_collateral = filled ? order.get_collateral() : pays * order.sell_price;
}
auto buyer_to_collateral = receives - issuer_fees;
if( receives.asset_id == asset_id_type() )
{
const auto& statistics = seller.statistics(*this);
modify( statistics, [&]( account_statistics_object& b ){
b.total_core_in_orders += buyer_to_collateral.amount;
});
}
modify( pays_asset.dynamic_asset_data_id(*this), [&]( asset_dynamic_data_object& obj ){
obj.current_supply += pays.amount;
});
const auto& call_account_index = call_index.indices().get<by_account>();
auto call_itr = call_account_index.find( boost::make_tuple(order.seller, pays.asset_id) );
if( call_itr == call_account_index.end() )
{
create<call_order_object>( [&]( call_order_object& c ){
c.borrower = seller.id;
c.collateral = seller_to_collateral.amount + buyer_to_collateral.amount;
c.debt = pays.amount;
c.maintenance_collateral_ratio = order.maintenance_collateral_ratio;
c.call_price = price::max(seller_to_collateral.asset_id, pays.asset_id);
c.update_call_price();
});
}
else
{
modify( *call_itr, [&]( call_order_object& c ){
c.debt += pays.amount;
c.collateral += seller_to_collateral.amount + buyer_to_collateral.amount;
c.maintenance_collateral_ratio = order.maintenance_collateral_ratio;
c.update_call_price();
});
}
if( filled )
{
remove( order );
}
else
{
modify( order, [&]( short_order_object& b ) {
b.for_sale -= pays.amount;
b.available_collateral -= seller_to_collateral.amount;
assert( b.available_collateral > 0 );
assert( b.for_sale > 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 )
{
adjust_balance(seller.get_id(), order.get_collateral());
if( order.get_collateral().asset_id == asset_id_type() )
{
const auto& statistics = seller.statistics(*this);
modify( statistics, [&]( account_statistics_object& b ){
b.total_core_in_orders -= order.available_collateral;
});
}
remove( order );
filled = true;
}
}
push_applied_operation( fill_order_operation{ order.id, order.seller, pays, receives, issuer_fees } );
return filled;
} FC_CAPTURE_AND_RETHROW( (order)(pays)(receives) ) }
bool database::fill_order( const call_order_object& order, const asset& pays, const asset& receives )
{ try {
@ -483,11 +378,6 @@ bool database::check_call_orders( const asset_object& mia )
const limit_order_index& limit_index = get_index_type<limit_order_index>();
const auto& limit_price_index = limit_index.indices().get<by_price>();
const short_order_index& short_index = get_index_type<short_order_index>();
const auto& short_price_index = short_index.indices().get<by_price>();
auto short_itr = short_price_index.lower_bound( price::max( mia.id, bitasset.options.short_backing_asset ) );
auto short_end = short_price_index.upper_bound( ~bitasset.current_feed.call_limit );
auto limit_itr = limit_price_index.lower_bound( price::max( mia.id, bitasset.options.short_backing_asset ) );
auto limit_end = limit_price_index.upper_bound( ~bitasset.current_feed.call_limit );
@ -499,33 +389,14 @@ bool database::check_call_orders( const asset_object& mia )
while( call_itr != call_end )
{
bool current_is_limit = true;
bool filled_call = false;
price match_price;
asset usd_for_sale;
if( limit_itr != limit_end )
{
assert( limit_itr != limit_price_index.end() );
if( short_itr != short_end && limit_itr->sell_price < short_itr->sell_price )
{
assert( short_itr != short_price_index.end() );
current_is_limit = false;
match_price = short_itr->sell_price;
usd_for_sale = short_itr->amount_for_sale();
}
else
{
current_is_limit = true;
match_price = limit_itr->sell_price;
usd_for_sale = limit_itr->amount_for_sale();
}
}
else if( short_itr != short_end )
{
assert( short_itr != short_price_index.end() );
current_is_limit = false;
match_price = short_itr->sell_price;
usd_for_sale = short_itr->amount_for_sale();
match_price = limit_itr->sell_price;
usd_for_sale = limit_itr->amount_for_sale();
}
else return filled_short_or_limit;
@ -569,16 +440,9 @@ bool database::check_call_orders( const asset_object& mia )
auto old_call_itr = call_itr;
if( filled_call ) ++call_itr;
fill_order( *old_call_itr, call_pays, call_receives );
if( current_is_limit )
{
auto old_limit_itr = !filled_call ? limit_itr++ : limit_itr;
fill_order( *old_limit_itr, order_pays, order_receives );
}
else
{
auto old_short_itr = !filled_call ? short_itr++ : short_itr;
fill_order( *old_short_itr, order_pays, order_receives );
}
auto old_limit_itr = !filled_call ? limit_itr++ : limit_itr;
fill_order( *old_limit_itr, order_pays, order_receives );
} // whlie call_itr != call_end
return filled_short_or_limit;

View file

@ -22,7 +22,7 @@
#include <graphene/chain/global_property_object.hpp>
#include <graphene/chain/limit_order_object.hpp>
#include <graphene/chain/proposal_object.hpp>
#include <graphene/chain/short_order_object.hpp>
#include <graphene/chain/call_order_object.hpp>
#include <graphene/chain/transaction_object.hpp>
#include <graphene/chain/withdraw_permission_object.hpp>
#include <graphene/chain/witness_object.hpp>
@ -131,16 +131,6 @@ void database::clear_expired_orders()
apply_operation(cancel_context, canceler);
}
//Cancel expired short orders
auto& short_index = get_index_type<short_order_index>().indices().get<by_expiration>();
while( !short_index.empty() && short_index.begin()->expiration <= head_block_time() )
{
const short_order_object& order = *short_index.begin();
short_order_cancel_operation canceler;
canceler.fee_paying_account = order.seller;
canceler.order = order.id;
apply_operation(cancel_context, canceler);
}
//Process expired force settlement orders
auto& settlement_index = get_index_type<force_settlement_index>().indices().get<by_expiration>();

View file

@ -23,7 +23,7 @@
#include <graphene/chain/account_object.hpp>
#include <graphene/chain/delegate_object.hpp>
#include <graphene/chain/limit_order_object.hpp>
#include <graphene/chain/short_order_object.hpp>
#include <graphene/chain/call_order_object.hpp>
#include <fc/uint128.hpp>

View file

@ -34,7 +34,7 @@ namespace graphene { namespace chain {
const asset_object* _debt_asset = nullptr;
const account_object* _paying_account = nullptr;
const call_order_object* _order = nullptr;
const bitasset_data_object* _bitasset_data = nullptr;
const asset_bitasset_data_object* _bitasset_data = nullptr;
};
} } // graphene::chain

View file

@ -74,6 +74,9 @@ namespace graphene { namespace chain {
{ return balance.asset_id; }
};
struct by_collateral;
struct by_account;
struct by_price;
typedef multi_index_container<
call_order_object,
indexed_by<
@ -101,7 +104,6 @@ namespace graphene { namespace chain {
>
> call_order_multi_index_type;
struct by_account;
struct by_expiration;
typedef multi_index_container<
force_settlement_object,

View file

@ -281,7 +281,6 @@ namespace graphene { namespace chain {
template<typename OrderType>
int match( const limit_order_object& bid, const OrderType& ask, const price& match_price );
int match( const limit_order_object& bid, const limit_order_object& ask, const price& trade_price );
int match( const limit_order_object& bid, const short_order_object& ask, const price& trade_price );
/// @return the amount of asset settled
asset match(const call_order_object& call,
const force_settlement_object& settle,
@ -293,7 +292,6 @@ 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 short_order_object& order, const asset& pays, const asset& receives );
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 );

View file

@ -18,7 +18,6 @@
#include <graphene/chain/limit_order_evaluator.hpp>
#include <graphene/chain/account_object.hpp>
#include <graphene/chain/limit_order_object.hpp>
#include <graphene/chain/short_order_object.hpp>
#include <fc/uint128.hpp>
namespace graphene { namespace chain {
@ -104,44 +103,13 @@ object_id_type limit_order_create_evaluator::do_apply( const limit_order_create_
if( converted_some && !db().find(result) ) // then we were filled by call order
return result;
}
const auto& short_order_idx = db().get_index_type<short_order_index>();
const auto& sell_price_idx = short_order_idx.indices().get<by_price>();
FC_ASSERT( max_price.max() >= max_price );
auto short_itr = sell_price_idx.lower_bound( max_price.max() );
auto short_end = sell_price_idx.upper_bound( max_price );
while( !filled )
{
if( limit_itr != limit_end )
{
if( short_itr != short_end && limit_itr->sell_price < short_itr->sell_price )
{
auto old_short_itr = short_itr;
++short_itr;
filled = (db().match( new_order_object, *old_short_itr, old_short_itr->sell_price ) != 2 );
}
else
{
auto old_limit_itr = limit_itr;
++limit_itr;
filled = (db().match( new_order_object, *old_limit_itr, old_limit_itr->sell_price ) != 2 );
}
}
else if( short_itr != short_end )
{
auto old_short_itr = short_itr;
++short_itr;
filled = (db().match( new_order_object, *old_short_itr, old_short_itr->sell_price ) != 2 );
}
else break;
}
}
else while( !filled && limit_itr != limit_end )
while( !filled && limit_itr != limit_end )
{
auto old_itr = limit_itr;
++limit_itr;
filled = (db().match( new_order_object, *old_itr, old_itr->sell_price ) != 2);
auto old_limit_itr = limit_itr;
++limit_itr;
filled = (db().match( new_order_object, *old_limit_itr, old_limit_itr->sell_price ) != 2 );
}
//Possible optimization: only check calls if the new order completely filled some old order