Core exchange rate is now redundantly stored in price feed for
bitassets, and updated when the median feed changes. This allows feed
producers to update the core exchange rate. Redundant storage is
necessary, because the core exchange rate is needed for user-issued
assets as well as market issued assets.
This commit is contained in:
Nathan Hourt 2015-06-26 10:42:40 -04:00
parent 0936f9b5f2
commit 5b55ab71ea
4 changed files with 33 additions and 15 deletions

View file

@ -58,7 +58,7 @@ void_result asset_create_evaluator::do_evaluate( const asset_create_operation& o
FC_ASSERT( op.bitasset_options->feed_lifetime_sec > chain_parameters.block_interval &&
op.bitasset_options->force_settlement_delay_sec > chain_parameters.block_interval );
}
if( op.is_prediction_market )
if( op.is_prediction_market )
{
FC_ASSERT( op.bitasset_options );
FC_ASSERT( op.precision == op.bitasset_options->short_backing_asset(d).precision );
@ -313,6 +313,9 @@ void_result asset_update_feed_producers_evaluator::do_apply(const asset_update_f
a.feeds[*itr];
a.update_median_feeds(db().head_block_time());
});
db().modify(o.asset_to_update(db()), [this](asset_object& a) {
a.options.core_exchange_rate = bitasset_to_update->current_feed.core_exchange_rate;
});
db().check_call_orders( o.asset_to_update(db()) );
return void_result();
@ -429,9 +432,12 @@ void_result asset_publish_feeds_evaluator::do_apply(const asset_publish_feed_ope
a.feeds[o.publisher] = make_pair(d.head_block_time(), o.feed);
a.update_median_feeds(d.head_block_time());
});
d.modify(base, [&d](asset_object& a) {
a.options.core_exchange_rate = a.bitasset_data(d).current_feed.core_exchange_rate;
});
/// TODO: optimization: only do this if the median feed actually changed, otherwise there is no point
db().check_call_orders( base );
db().check_call_orders(base);
return void_result();
} FC_CAPTURE_AND_RETHROW((o)) }

View file

@ -219,16 +219,24 @@ void database::clear_expired_orders()
void database::update_expired_feeds()
{
auto& asset_idx = get_index_type<asset_bitasset_data_index>();
for( const asset_bitasset_data_object* b : asset_idx )
if( b->feed_is_expired(head_block_time()) )
auto& asset_idx = get_index_type<asset_index>().indices();
for( const asset_object& a : asset_idx )
{
if( !a.is_market_issued() )
continue;
const asset_bitasset_data_object& b = a.bitasset_data(*this);
if( b.feed_is_expired(head_block_time()) )
{
modify(*b, [this](asset_bitasset_data_object& a) {
modify(b, [this](asset_bitasset_data_object& a) {
a.update_median_feeds(head_block_time());
});
check_call_orders( b->current_feed.settlement_price.base.asset_id(*this) );
modify(a, [&b](asset_object& a) {
a.options.core_exchange_rate = b.current_feed.core_exchange_rate;
});
check_call_orders(b.current_feed.settlement_price.base.asset_id(*this));
}
}
}
void database::update_withdraw_permissions()

View file

@ -141,10 +141,13 @@ namespace graphene { namespace chain {
*/
///@{
/**
* Forced settlements will evaluate using this price, defined as BITASSET / COLLATERAL
* Forced settlements will evaluate using this price, defined as BITASSET / COLLATERAL
*/
price settlement_price;
/// Price at which automatically exchanging this asset for CORE from fee pool occurs (used for paying fees)
price core_exchange_rate;
/** Fixed point between 1.000 and 10.000, implied fixed point denominator is GRAPHENE_COLLATERAL_RATIO_DENOM */
uint16_t maintenance_collateral_ratio = GRAPHENE_DEFAULT_MAINTENANCE_COLLATERAL_RATIO;
@ -154,14 +157,14 @@ namespace graphene { namespace chain {
/**
* When updating a call order the following condition must be maintained:
*
* debt * maintenance_price() < collateral
* debt * maintenance_price() < collateral
* debt * settlement_price < debt * maintenance
* debt * maintenance_price() < debt * max_short_squeeze_price()
* debt * maintenance_price() < debt * max_short_squeeze_price()
price maintenance_price()const;
*/
/** When selling collateral to pay off debt, the least amount of debt to receive should be
* min_usd = max_short_squeeze_price() * collateral
/** When selling collateral to pay off debt, the least amount of debt to receive should be
* min_usd = max_short_squeeze_price() * collateral
*
* This is provided to ensure that a black swan cannot be trigged due to poor liquidity alone, it
* must be confirmed by having the max_short_squeeze_price() move below the black swan price.
@ -183,7 +186,8 @@ namespace graphene { namespace chain {
FC_REFLECT( graphene::chain::asset, (amount)(asset_id) )
FC_REFLECT( graphene::chain::price, (base)(quote) )
#define GRAPHENE_PRICE_FEED_FIELDS (settlement_price)(maintenance_collateral_ratio)(maximum_short_squeeze_ratio)
#define GRAPHENE_PRICE_FEED_FIELDS (settlement_price)(maintenance_collateral_ratio)(maximum_short_squeeze_ratio) \
(core_exchange_rate)
FC_REFLECT( graphene::chain::price_feed, GRAPHENE_PRICE_FEED_FIELDS )

View file

@ -400,7 +400,7 @@ const asset_object& database_fixture::create_bitasset(
creator.fee = asset();
creator.symbol = name;
creator.common_options.max_supply = GRAPHENE_MAX_SHARE_SUPPLY;
creator.precision = 2;
creator.precision = GRAPHENE_BLOCKCHAIN_PRECISION_DIGITS;
creator.common_options.market_fee_percent = market_fee_percent;
creator.common_options.issuer_permissions = flags;
creator.common_options.flags = flags & ~global_settle;