HARDFORK Disallow publishing certain malformed price feeds, fix #357
This commit is contained in:
parent
9b910ee1a4
commit
3f00bd81b9
4 changed files with 114 additions and 1 deletions
|
|
@ -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);
|
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( !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
|
//Verify that the publisher is authoritative to publish a feed
|
||||||
if( (base.issuer == GRAPHENE_WITNESS_ACCOUNT) || (base.issuer == GRAPHENE_COMMITTEE_ACCOUNT) )
|
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)
|
void_result asset_publish_feeds_evaluator::do_apply(const asset_publish_feed_operation& o)
|
||||||
{ try {
|
{ 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();
|
database& d = db();
|
||||||
|
|
||||||
const asset_object& base = o.asset_id(d);
|
const asset_object& base = o.asset_id(d);
|
||||||
|
|
|
||||||
|
|
@ -17,4 +17,5 @@
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#define HARDFORK_357_TIME (fc::time_point_sec( 1444416300 ))
|
||||||
#define HARDFORK_359_TIME (fc::time_point_sec( 1444416300 ))
|
#define HARDFORK_359_TIME (fc::time_point_sec( 1444416300 ))
|
||||||
|
|
|
||||||
|
|
@ -200,6 +200,7 @@ namespace graphene { namespace chain {
|
||||||
}
|
}
|
||||||
|
|
||||||
void validate() const;
|
void validate() const;
|
||||||
|
bool is_for( asset_id_type asset_id ) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} }
|
} }
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,20 @@ namespace graphene { namespace chain {
|
||||||
//FC_ASSERT( maintenance_collateral_ratio >= maximum_short_squeeze_ratio );
|
//FC_ASSERT( maintenance_collateral_ratio >= maximum_short_squeeze_ratio );
|
||||||
} FC_CAPTURE_AND_RETHROW( (*this) ) }
|
} 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
|
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);
|
boost::rational<uint64_t> sp( settlement_price.base.amount.value, settlement_price.quote.amount.value ); //debt.amount.value,collateral.amount.value);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue