Skip to content

Commit 0e86ff5

Browse files
authored
Merge pull request #1306 from bitshares/call-order-refactory
Call order and bitAsset related code refactory
2 parents 5008359 + 2aa175c commit 0e86ff5

File tree

6 files changed

+161
-143
lines changed

6 files changed

+161
-143
lines changed

libraries/chain/asset_evaluator.cpp

+58-32
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,8 @@ void_result asset_update_bitasset_evaluator::do_apply(const asset_update_bitasse
730730
});
731731

732732
if( to_check_call_orders )
733-
db_conn.check_call_orders( asset_being_updated );
733+
// Process margin calls, allow black swan, not for a new limit order
734+
db_conn.check_call_orders( asset_being_updated, true, false, bitasset_to_update );
734735

735736
return void_result();
736737

@@ -741,28 +742,42 @@ void_result asset_update_feed_producers_evaluator::do_evaluate(const asset_updat
741742
{ try {
742743
database& d = db();
743744

744-
FC_ASSERT( o.new_feed_producers.size() <= d.get_global_properties().parameters.maximum_asset_feed_publishers );
745-
for( auto id : o.new_feed_producers )
746-
d.get_object(id);
745+
FC_ASSERT( o.new_feed_producers.size() <= d.get_global_properties().parameters.maximum_asset_feed_publishers,
746+
"Cannot specify more feed producers than maximum allowed" );
747747

748748
const asset_object& a = o.asset_to_update(d);
749749

750750
FC_ASSERT(a.is_market_issued(), "Cannot update feed producers on a non-BitAsset.");
751751
FC_ASSERT(!(a.options.flags & committee_fed_asset), "Cannot set feed producers on a committee-fed asset.");
752752
FC_ASSERT(!(a.options.flags & witness_fed_asset), "Cannot set feed producers on a witness-fed asset.");
753753

754-
const asset_bitasset_data_object& b = a.bitasset_data(d);
755-
bitasset_to_update = &b;
756-
FC_ASSERT( a.issuer == o.issuer );
754+
FC_ASSERT( a.issuer == o.issuer, "Only asset issuer can update feed producers of an asset" );
755+
756+
asset_to_update = &a;
757+
758+
// Make sure all producers exist. Check these after asset because account lookup is more expensive
759+
for( auto id : o.new_feed_producers )
760+
d.get_object(id);
761+
757762
return void_result();
758763
} FC_CAPTURE_AND_RETHROW( (o) ) }
759764

760765
void_result asset_update_feed_producers_evaluator::do_apply(const asset_update_feed_producers_evaluator::operation_type& o)
761766
{ try {
762-
db().modify(*bitasset_to_update, [&](asset_bitasset_data_object& a) {
767+
database& d = db();
768+
const auto head_time = d.head_block_time();
769+
const asset_bitasset_data_object& bitasset_to_update = asset_to_update->bitasset_data(d);
770+
d.modify( bitasset_to_update, [&o,head_time](asset_bitasset_data_object& a) {
763771
//This is tricky because I have a set of publishers coming in, but a map of publisher to feed is stored.
764772
//I need to update the map such that the keys match the new publishers, but not munge the old price feeds from
765773
//publishers who are being kept.
774+
775+
// TODO possible performance optimization:
776+
// Since both the map and the set are ordered by account already, we can iterate through them only once
777+
// and avoid lookups while iterating by maintaining two iterators at same time.
778+
// However, this operation is not used much, and both the set and the map are small,
779+
// so likely we won't gain much with the optimization.
780+
766781
//First, remove any old publishers who are no longer publishers
767782
for( auto itr = a.feeds.begin(); itr != a.feeds.end(); )
768783
{
@@ -772,12 +787,14 @@ void_result asset_update_feed_producers_evaluator::do_apply(const asset_update_f
772787
++itr;
773788
}
774789
//Now, add any new publishers
775-
for( auto itr = o.new_feed_producers.begin(); itr != o.new_feed_producers.end(); ++itr )
776-
if( !a.feeds.count(*itr) )
777-
a.feeds[*itr];
778-
a.update_median_feeds(db().head_block_time());
790+
for( const account_id_type acc : o.new_feed_producers )
791+
{
792+
a.feeds[acc];
793+
}
794+
a.update_median_feeds( head_time );
779795
});
780-
db().check_call_orders( o.asset_to_update(db()) );
796+
// Process margin calls, allow black swan, not for a new limit order
797+
d.check_call_orders( *asset_to_update, true, false, &bitasset_to_update );
781798

782799
return void_result();
783800
} FC_CAPTURE_AND_RETHROW( (o) ) }
@@ -786,20 +803,19 @@ void_result asset_global_settle_evaluator::do_evaluate(const asset_global_settle
786803
{ try {
787804
const database& d = db();
788805
asset_to_settle = &op.asset_to_settle(d);
789-
FC_ASSERT(asset_to_settle->is_market_issued());
790-
FC_ASSERT(asset_to_settle->can_global_settle());
791-
FC_ASSERT(asset_to_settle->issuer == op.issuer );
792-
FC_ASSERT(asset_to_settle->dynamic_data(d).current_supply > 0);
806+
FC_ASSERT( asset_to_settle->is_market_issued(), "Can only globally settle market-issued assets" );
807+
FC_ASSERT( asset_to_settle->can_global_settle(), "The global_settle permission of this asset is disabled" );
808+
FC_ASSERT( asset_to_settle->issuer == op.issuer, "Only asset issuer can globally settle an asset" );
809+
FC_ASSERT( asset_to_settle->dynamic_data(d).current_supply > 0, "Can not globally settle an asset with zero supply" );
793810

794811
const asset_bitasset_data_object& _bitasset_data = asset_to_settle->bitasset_data(d);
795812
// if there is a settlement for this asset, then no further global settle may be taken
796813
FC_ASSERT( !_bitasset_data.has_settlement(), "This asset has settlement, cannot global settle again" );
797814

798815
const auto& idx = d.get_index_type<call_order_index>().indices().get<by_collateral>();
799-
assert( !idx.empty() );
800-
auto itr = idx.lower_bound(boost::make_tuple(price::min(asset_to_settle->bitasset_data(d).options.short_backing_asset,
801-
op.asset_to_settle)));
802-
assert( itr != idx.end() && itr->debt_type() == op.asset_to_settle );
816+
FC_ASSERT( !idx.empty(), "Internal error: no debt position found" );
817+
auto itr = idx.lower_bound( price::min( _bitasset_data.options.short_backing_asset, op.asset_to_settle ) );
818+
FC_ASSERT( itr != idx.end() && itr->debt_type() == op.asset_to_settle, "Internal error: no debt position found" );
803819
const call_order_object& least_collateralized_short = *itr;
804820
FC_ASSERT(least_collateralized_short.get_debt() * op.settle_price <= least_collateralized_short.get_collateral(),
805821
"Cannot force settle at supplied price: least collateralized short lacks sufficient collateral to settle.");
@@ -810,7 +826,7 @@ void_result asset_global_settle_evaluator::do_evaluate(const asset_global_settle
810826
void_result asset_global_settle_evaluator::do_apply(const asset_global_settle_evaluator::operation_type& op)
811827
{ try {
812828
database& d = db();
813-
d.globally_settle_asset( op.asset_to_settle(db()), op.settle_price );
829+
d.globally_settle_asset( *asset_to_settle, op.settle_price );
814830
return void_result();
815831
} FC_CAPTURE_AND_RETHROW( (op) ) }
816832

@@ -897,7 +913,7 @@ void_result asset_publish_feeds_evaluator::do_evaluate(const asset_publish_feed_
897913

898914
const asset_object& base = o.asset_id(d);
899915
//Verify that this feed is for a market-issued asset and that asset is backed by the base
900-
FC_ASSERT(base.is_market_issued());
916+
FC_ASSERT( base.is_market_issued(), "Can only publish price feeds for market-issued assets" );
901917

902918
const asset_bitasset_data_object& bitasset = base.bitasset_data(d);
903919
if( bitasset.is_prediction_market || d.head_block_time() <= HARDFORK_CORE_216_TIME )
@@ -906,37 +922,46 @@ void_result asset_publish_feeds_evaluator::do_evaluate(const asset_publish_feed_
906922
}
907923

908924
// the settlement price must be quoted in terms of the backing asset
909-
FC_ASSERT( o.feed.settlement_price.quote.asset_id == bitasset.options.short_backing_asset );
925+
FC_ASSERT( o.feed.settlement_price.quote.asset_id == bitasset.options.short_backing_asset,
926+
"Quote asset type in settlement price should be same as backing asset of this asset" );
910927

911928
if( d.head_block_time() > HARDFORK_480_TIME )
912929
{
913930
if( !o.feed.core_exchange_rate.is_null() )
914931
{
915-
FC_ASSERT( o.feed.core_exchange_rate.quote.asset_id == asset_id_type() );
932+
FC_ASSERT( o.feed.core_exchange_rate.quote.asset_id == asset_id_type(),
933+
"Quote asset in core exchange rate should be CORE asset" );
916934
}
917935
}
918936
else
919937
{
920938
if( (!o.feed.settlement_price.is_null()) && (!o.feed.core_exchange_rate.is_null()) )
921939
{
922-
FC_ASSERT( o.feed.settlement_price.quote.asset_id == o.feed.core_exchange_rate.quote.asset_id );
940+
// Old buggy code, but we have to live with it
941+
FC_ASSERT( o.feed.settlement_price.quote.asset_id == o.feed.core_exchange_rate.quote.asset_id, "Bad feed" );
923942
}
924943
}
925944

926945
//Verify that the publisher is authoritative to publish a feed
927946
if( base.options.flags & witness_fed_asset )
928947
{
929-
FC_ASSERT( d.get(GRAPHENE_WITNESS_ACCOUNT).active.account_auths.count(o.publisher) );
948+
FC_ASSERT( d.get(GRAPHENE_WITNESS_ACCOUNT).active.account_auths.count(o.publisher),
949+
"Only active witnesses are allowed to publish price feeds for this asset" );
930950
}
931951
else if( base.options.flags & committee_fed_asset )
932952
{
933-
FC_ASSERT( d.get(GRAPHENE_COMMITTEE_ACCOUNT).active.account_auths.count(o.publisher) );
953+
FC_ASSERT( d.get(GRAPHENE_COMMITTEE_ACCOUNT).active.account_auths.count(o.publisher),
954+
"Only active committee members are allowed to publish price feeds for this asset" );
934955
}
935956
else
936957
{
937-
FC_ASSERT(bitasset.feeds.count(o.publisher));
958+
FC_ASSERT( bitasset.feeds.count(o.publisher),
959+
"The account is not in the set of allowed price feed producers of this asset" );
938960
}
939961

962+
asset_ptr = &base;
963+
bitasset_ptr = &bitasset;
964+
940965
return void_result();
941966
} FC_CAPTURE_AND_RETHROW((o)) }
942967

@@ -945,8 +970,8 @@ void_result asset_publish_feeds_evaluator::do_apply(const asset_publish_feed_ope
945970

946971
database& d = db();
947972

948-
const asset_object& base = o.asset_id(d);
949-
const asset_bitasset_data_object& bad = base.bitasset_data(d);
973+
const asset_object& base = *asset_ptr;
974+
const asset_bitasset_data_object& bad = *bitasset_ptr;
950975

951976
auto old_feed = bad.current_feed;
952977
// Store medians for this asset
@@ -967,7 +992,8 @@ void_result asset_publish_feeds_evaluator::do_apply(const asset_publish_feed_ope
967992
bad.current_feed.maintenance_collateral_ratio ) < bad.current_feed.settlement_price ) )
968993
d.revive_bitasset(base);
969994
}
970-
db().check_call_orders(base);
995+
// Process margin calls, allow black swan, not for a new limit order
996+
d.check_call_orders( base, true, false, bitasset_ptr );
971997
}
972998

973999
return void_result();

0 commit comments

Comments
 (0)