-
Notifications
You must be signed in to change notification settings - Fork 647
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BSIP 36 Candidate #832
BSIP 36 Candidate #832
Conversation
IMHO using |
using still, if the operation is never called feed will stay forever, the after HF fix will delete not needed and expired feeds in this case. added test case |
libraries/chain/db_maint.cpp
Outdated
for( auto itr = o.feeds.begin(); itr != o.feeds.end();) | ||
{ | ||
auto feed_time = itr[0].second.first; | ||
if( feed_time + (o.options.feed_lifetime_sec) < head_block_time() && o.feeds.size() > o.options.minimum_feeds) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Why leave minimum_feeds in? They will be ignored anyway.
- No need to cycle through the rest when the minimum has been reached.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why leave minimum_feeds in? They will be ignored anyway.
are you sure this is safe? i guess the only thing that matters if all feeds are expired is current_feed
.
just confirming before making the change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assets start out with no feeds at all and go through a time with less than minimum. I don't see why it shouldn't be safe.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@oxarbitrage please remove && o.feeds.size() > o.options.minimum_feeds
check. It's not relevant here.
No need to cycle through the rest when the minimum has been reached.
@pmconrad what did this mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once o.feeds.size() > o.options.minimum_feeds becomes false it will remain false, so once we reach that point we can as well break out of the loop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anyway I think this doesn't belong to here, since we want to remove ALL expired price feed entries.
i had the intention initially to remove expired non needed feeds from MPAs that are fed by witnesses or by feed producers as well. However, it seems that this will only be possible on witness fed MPAs(aka smartcoins). the problem is in non smartcoins the feed producers are actually entries in the the related code is here: as you can see witness feed producer are validated different and it doesn't matter if they are already in the feed fields or not while in the last case the feed producer need to be inside the @pmconrad @abitmore please let me know what do you think because i think we need to change code to only go after smartcoins and leave the other mpas untouched. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned in last comment, please only remove feeds for assets enabled witness_fed_asset
or committee_fed_asset
.
libraries/chain/db_maint.cpp
Outdated
// Remove all expired feeds | ||
for( auto itr = o.feeds.begin(); itr != o.feeds.end();) | ||
{ | ||
auto feed_time = itr[0].second.first; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
itr[0]
here looks strange. Why not use itr->
?
libraries/chain/db_maint.cpp
Outdated
for( auto itr = o.feeds.begin(); itr != o.feeds.end();) | ||
{ | ||
auto feed_time = itr[0].second.first; | ||
if( feed_time + (o.options.feed_lifetime_sec) < head_block_time() && o.feeds.size() > o.options.minimum_feeds) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@oxarbitrage please remove && o.feeds.size() > o.options.minimum_feeds
check. It's not relevant here.
No need to cycle through the rest when the minimum has been reached.
@pmconrad what did this mean?
libraries/chain/db_maint.cpp
Outdated
modify( d, [this](asset_bitasset_data_object& o) { | ||
o.force_settled_volume = 0; | ||
// Remove all expired feeds | ||
for( auto itr = o.feeds.begin(); itr != o.feeds.end();) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use a reverse iterator for better performance while erasing multiple entries.
In the last commit(101a02c) the bsip code is changed to only affect smartcoins. A few considerations:
thanks. |
Instead of this, you can find the original asset_id from o.feeds.begin()->settlement_price.base.asset_id . (If o.feeds is empty there's nothing to do anyway.) |
thanks, i had this idea in a telegram chat and then i forgot about it. implemented now in 63199d0 |
@oxarbitrage you're removing elements from a |
libraries/chain/db_maint.cpp
Outdated
o.force_settled_volume = 0; | ||
|
||
// Check if asset is smartcoin | ||
const auto& settlement_price = o.feeds.begin()->second.second.settlement_price; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not safe. Before dereferencing begin()
, please check whether feeds
is empty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
silly me, fixed here f60a953 thank you.
libraries/chain/db_maint.cpp
Outdated
@@ -925,7 +925,29 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g | |||
// Reset all BitAsset force settlement volumes to zero | |||
for( const auto& d : get_index_type<asset_bitasset_data_index>().indices() ) | |||
{ | |||
modify( d, [](asset_bitasset_data_object& o) { o.force_settled_volume = 0; }); | |||
if(head_block_time() < HARDFORK_CORE_518_TIME) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For better performance, please move this check out of the for
loop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
libraries/chain/db_maint.cpp
Outdated
|
||
// Check if asset is smartcoin | ||
const auto& settlement_price = o.feeds.begin()->second.second.settlement_price; | ||
if(!settlement_price.is_null()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check is incorrect. The first feed is null doesn't mean all feeds are null.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#832 (comment)
you think that is wrong ? makes sense to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
waiting for more comments from @pmconrad maybe.
libraries/chain/db_maint.cpp
Outdated
if ((flags & witness_fed_asset) || (flags & committee_fed_asset)) { // if smartcoin | ||
for (auto itr = o.feeds.begin(); itr != o.feeds.end();) { // loop feeds | ||
auto feed_time = itr->second.first; | ||
if (feed_time + (o.options.feed_lifetime_sec) < head_block_time()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For better performance, please calculate head_block_time()-feed_lifetime_sec
out of the for
loop (and be careful about Integer overflow or underflow) and only check feed_time
while looping.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done this one, checked for overflow only as we are dealing with all unsigned ints so underflow will not be possible. overflow could occur with a feed_lifetime_sec is too big. hard to happen in practice as when we are here we are in a smartcoin but check was added anyways.
libraries/chain/db_maint.cpp
Outdated
// Reset all BitAsset force settlement volumes to zero | ||
for( const auto& d : get_index_type<asset_bitasset_data_index>().indices() ) | ||
{ | ||
modify( d, [](asset_bitasset_data_object& o) { o.force_settled_volume = 0; }); | ||
if(!hf518) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer this structure:
if ( hf )
for
else
for
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed to it.
libraries/chain/db_maint.cpp
Outdated
} | ||
}); | ||
if (d.has_settlement()) | ||
process_bids(d); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, this is a bit ugly (duplicate code). But I guess it's better to live with it at this moment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather avoid the duplicate code. Why not pull the HF check into the lambda?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pmconrad it's a side-effect of one of my earlier requests, since hard fork time check is independent, for slightly better performance, moved it to out of for
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I think it's better to move the whole code to a new function since it's getting a bit too long.
libraries/chain/db_maint.cpp
Outdated
} | ||
else { | ||
for( const auto& d : get_index_type<asset_bitasset_data_index>().indices() ) { | ||
modify(d, [](asset_bitasset_data_object &o) { o.force_settled_volume = 0; }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better leave the "Reset all BitAsset force settlement volumes to zero" comment here.
moved code to new function. |
as discussed in telegram i now added will need replay of course as this is added on object creation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Looks good to me, except the coding style (most code elsewhere has {
in a new line). Approving anyway.
@pmconrad what's your opinion?
libraries/chain/db_maint.cpp
Outdated
} | ||
}); | ||
if (d.has_settlement()) | ||
process_bids(d); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather avoid the duplicate code. Why not pull the HF check into the lambda?
libraries/chain/db_maint.cpp
Outdated
if ((flags & witness_fed_asset) || (flags & committee_fed_asset)) // if smartcoin | ||
{ | ||
// check overflow | ||
if (std::numeric_limits<uint32_t>::max() - o.options.feed_lifetime_sec > head_block_time().sec_since_epoch()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is wrong. Two lines below you calculate (head_block_time - feed_lifetime), so what you want to avoid is feed_lifetime > head_block_time.
Also, please move this check into the if two lines above.
(Good thinking to put in the check though.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// bitshares-core issue #518 Clean up bitasset_data during maintenance | ||
#ifndef HARDFORK_CORE_518_TIME | ||
#define HARDFORK_CORE_518_TIME (fc::time_point_sec( 1600000000 )) | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a newline.
tests/tests/smartcoin_tests.cpp
Outdated
{ | ||
try | ||
{ | ||
/* Bug affects only smartcoions(market pegged assets feeded by active witnesses or committee members). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not a bug, it's an issue. :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW smartcoions
is typo.
libraries/chain/db_maint.cpp
Outdated
@@ -778,20 +778,19 @@ void database::process_bitassets() | |||
|
|||
const auto &asset = get(o.asset_id); | |||
auto flags = asset.options.flags; | |||
if ((flags & witness_fed_asset) || (flags & committee_fed_asset)) // if smartcoin | |||
if ( (flags & witness_fed_asset || flags & committee_fed_asset) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To make sure &
will be done before ||
, it's not harm to leave the ()
s.
BTW as @jmjatlanta mentioned, perhaps better to use ( flag & ( witness_fed_asset | committee_fed_asset ) )
Please resolve conflicts. |
Resolved conflicts and merged into a new |
The fix in
db_maint
was already introduced in #598 but needed hardfork protection, also there was a small bug on it to delete the correct feeds that now is fixed.Test cases reproduce the problem before and after hardfork. I created the test in a new file as i was not sure where it could fit. This can be changed.
Problem is present only with smartcoins(mpas that are feeded by the witnesses)
Had to add a bunch of witnesses in the testcases to be able to remove default and control them, there is probably a simpler way to do this(by modifying the genesis?)
Open to all kind of feedback and test cases suggestions.
Issue: #518
BSIP: https://github.com/bitshares/bsips/blob/master/bsip-0036.md
Replaces: #598