HARDFORK Disallow publishing certain malformed price feeds, fix #357

This commit is contained in:
theoreticalbts 2015-10-08 15:00:11 -04:00
parent 9b910ee1a4
commit 3f00bd81b9
4 changed files with 114 additions and 1 deletions

View file

@ -506,7 +506,96 @@ void_result asset_publish_feeds_evaluator::do_evaluate(const asset_publish_feed_
const asset_bitasset_data_object& bitasset = base.bitasset_data(d);
FC_ASSERT( !bitasset.has_settlement(), "No further feeds may be published after a settlement event" );
FC_ASSERT(o.feed.settlement_price.quote.asset_id == bitasset.options.short_backing_asset);
#warning Remove this check when starting a new network
if( d.head_block_time() <= HARDFORK_357_TIME )
{
FC_ASSERT(o.feed.settlement_price.quote.asset_id == bitasset.options.short_backing_asset);
bool is_nop = false;
try
{
// these two changes should go in price_feed::validate() when creating new network
if( !o.feed.core_exchange_rate.is_null() )
{
o.feed.core_exchange_rate.validate();
}
if( (!o.feed.settlement_price.is_null()) && (!o.feed.core_exchange_rate.is_null()) )
{
if( o.feed.settlement_price.base.asset_id == o.feed.core_exchange_rate.base.asset_id )
{
// uncrossed feed, this is the form we expect
FC_ASSERT( o.feed.settlement_price.base.asset_id == o.feed.core_exchange_rate.base.asset_id );
FC_ASSERT( o.feed.settlement_price.quote.asset_id == o.feed.core_exchange_rate.quote.asset_id );
}
else
{
// crossed feed, your feed script needs to be fixed
FC_ASSERT( o.feed.settlement_price.base.asset_id == o.feed.core_exchange_rate.quote.asset_id );
FC_ASSERT( o.feed.settlement_price.quote.asset_id == o.feed.core_exchange_rate.base.asset_id );
/*
wlog( "${aname} feed pub with crossed prices by ${name} in block ${n}",
("aname", base.symbol)
("n", d.head_block_num()+1)
("name", o.publisher(d).name)
);
*/
}
}
if( !o.feed.is_for( o.asset_id ) )
{
wlog( "${aname} feed pub with wrong asset by ${name} in block ${n}",
("aname", base.symbol)
("n", d.head_block_num()+1)
("name", o.publisher(d).name)
);
is_nop = true;
}
}
catch( const fc::exception& e )
{
wlog( "${aname} feed pub with invalid price feed by ${name} in block ${n}",
("aname", base.symbol)
("n", d.head_block_num()+1)
("name", o.publisher(d).name)
);
wdump( (e) );
}
#warning Remove this check when starting a new network
if( d.head_block_num() > 59300 )
{
FC_ASSERT(
(base.symbol != "SEK")
&& (base.symbol != "SILVER")
&& (base.symbol != "RUB")
&& (base.symbol != "GBP")
);
}
}
else
{
//
// many of these checks should be moved to price_feed.validate()
// or the operation validator when new network is started
//
if( !o.feed.core_exchange_rate.is_null() )
{
o.feed.core_exchange_rate.validate();
}
if( (!o.feed.settlement_price.is_null()) && (!o.feed.core_exchange_rate.is_null()) )
{
FC_ASSERT( o.feed.settlement_price.base.asset_id == o.feed.core_exchange_rate.base.asset_id );
FC_ASSERT( o.feed.settlement_price.quote.asset_id == o.feed.core_exchange_rate.quote.asset_id );
}
FC_ASSERT( !o.feed.settlement_price.is_null() );
FC_ASSERT( !o.feed.core_exchange_rate.is_null() );
FC_ASSERT( o.feed.settlement_price.quote.asset_id == bitasset.options.short_backing_asset );
FC_ASSERT( o.feed.is_for( o.asset_id ) );
}
//Verify that the publisher is authoritative to publish a feed
if( (base.issuer == GRAPHENE_WITNESS_ACCOUNT) || (base.issuer == GRAPHENE_COMMITTEE_ACCOUNT) )
{
@ -522,6 +611,14 @@ void_result asset_publish_feeds_evaluator::do_evaluate(const asset_publish_feed_
void_result asset_publish_feeds_evaluator::do_apply(const asset_publish_feed_operation& o)
{ try {
#warning Remove this check when preparing for new network release
if( !o.feed.is_for( o.asset_id ) )
{
wlog( "Ignoring bad feed" );
return void_result();
}
database& d = db();
const asset_object& base = o.asset_id(d);

View file

@ -17,4 +17,5 @@
*/
#pragma once
#define HARDFORK_357_TIME (fc::time_point_sec( 1444416300 ))
#define HARDFORK_359_TIME (fc::time_point_sec( 1444416300 ))

View file

@ -200,6 +200,7 @@ namespace graphene { namespace chain {
}
void validate() const;
bool is_for( asset_id_type asset_id ) const;
};
} }

View file

@ -138,6 +138,20 @@ namespace graphene { namespace chain {
//FC_ASSERT( maintenance_collateral_ratio >= maximum_short_squeeze_ratio );
} FC_CAPTURE_AND_RETHROW( (*this) ) }
bool price_feed::is_for( asset_id_type asset_id ) const
{
try
{
if( !settlement_price.is_null() )
return (settlement_price.base.asset_id == asset_id);
if( !core_exchange_rate.is_null() )
return (core_exchange_rate.base.asset_id == asset_id);
// (null, null) is valid for any feed
return true;
}
FC_CAPTURE_AND_RETHROW( (*this) )
}
price price_feed::max_short_squeeze_price()const
{
boost::rational<uint64_t> sp( settlement_price.base.amount.value, settlement_price.quote.amount.value ); //debt.amount.value,collateral.amount.value);