[Bug] Steem blockchain freezes if the SBD supply is 0
Project Information
- Repository: https://github.com/steemit/steem
- Project Name: Steem
This issue is related with the function update_median_feed()
in database.cpp
Expected behavior
If the SBD supply is 0 the blockchain takes the median feed price from witnesses.
Actual behavior
When the SBD supply is 0 everyone stop producing blocks.
How to reproduce
- Start a testnet with 21 witnesses (the current version is 0.20.9).
- Set a feed price on at least 7 witnesses.
- Wait 1 hour for the update of the median feed price.
- All witnesses stop producing blocks with this error:
Failed to push new block:
10 assert_exception: Assert Exception
base.amount > share_type(0):
{}
asset.cpp:377 validate
{"base":{"amount":"0","precision":3,"nai":"@@000000013"},"quote":{"amount":"250037129","precision":3,"nai":"@@000000021"}}
asset.cpp:380 validate
Got exception while generating block:
10 assert_exception: Assert Exception
base.amount > share_type(0):
{}
asset.cpp:377 validate
{"base":{"amount":"0","precision":3,"nai":"@@000000013"},"quote":{"amount":"250037129","precision":3,"nai":"@@000000021"}}
asset.cpp:380 validate
{}
database.cpp:3128 update_median_feed
Reason
First, a little background about the variable type price
. The prices in steem are not defined with floating point numbers but with fractional numbers, that is, using two numbers: numerator and denominator. In this sense, if the price is 0.3333333... SBD/STEEM, it can be very well defined as 1 SBD/3 STEEM, and we don't need to use floating point numbers and address their accuracy problems.
Then, the conversion of assets needs a multiplication and a division:
- 30 STEEM is equal to: 30 STEEM * 1 SBD / 3 STEEM = 10 SBD
- and, 10 SBD is equal to: 10 SBD * 3 STEEM / 1 SBD = 30 STEEM
As you can see, both numbers can be in the denominator depending the conversion. And, to prevent division by 0, both numbers are required to be greater than zero (validation)
Coming back to update_median_feed()
. This function updates the feed price taking into account two things:
- The median price given by the witnesses, and
- The haircut price to force SBD to remain below 10%.
However, if the SBD supply is zero, the haircut price throws an exception because both quote and base have to be greater than zero (to prevent division by 0). No witness can create this new block and therefore the blockchain freezes.
price min_price( asset( 9 * gpo.current_sbd_supply.amount, SBD_SYMBOL ), gpo.current_supply );
Low vulnerability
The unique way to reach 0 SBD in the mainnet is by stopping printing SBD and converting all of them into STEEM, which is very unlikely. However, it becomes more relevant on testnets or private blockchains.
Solution
Only calculate the haircut price if the SBD supply is greater than zero, because in this case there is no risk of debt, the ratio is 0%.
GitHub Account
GitHub account: https://github.com/joticajulian
GitHub issue: https://github.com/steemit/steem/issues/3258
Pull request proposed: https://github.com/steemit/steem/pull/3263
Hi @jga, thanks for making this contribution
I am sorry the review is coming this late. It is a valuable contribution and though I am unable to conduct a test to reproduce the behavior you have described, I have it on a good note from other moderators that the contribution is good and indeed valid.
I love that you broke every detail to the barest minimum. It is enough to give any reader an idea as to what is at play. And for curious readers who are new to the blockchain, this should pique their interest towards the inner workings of the steem blockchain.
Thanks again for the contribution. I look forward to more of your reports :)
Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.
To view those questions and the relevant answers related to your post, click here.
Need help? Chat with us on Discord.
[utopian-moderator]
Hi @fego. Thank you very much for your review! 👍
Thank you for your review, @fego! Keep up the good work!
Hi @jga!
Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your UA account score is currently 4.553 which ranks you at #1917 across all Steem accounts.
Your rank has not changed in the last three days.
In our last Algorithmic Curation Round, consisting of 226 contributions, your post is ranked at #175.
Evaluation of your UA score:
Feel free to join our @steem-ua Discord server
Hey, @jga!
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!
Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).
Want to chat? Join us on Discord https://discord.gg/h52nFrV.
Vote for Utopian Witness!
Congratulations @jga! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :
You can view your badges on your Steem Board and compare to others on the Steem Ranking
If you no longer want to receive notifications, reply to this comment with the word
STOP
Vote for @Steemitboard as a witness to get one more award and increased upvotes!
Congratulations @jga! You received a personal award!
You can view your badges on your Steem Board and compare to others on the Steem Ranking
Vote for @Steemitboard as a witness to get one more award and increased upvotes!
Dear jga:
We are SteemBet, the next generation STEEM based gaming platform. We are honored to invite you to join our first fantastic dice game, which is just the beginning of SteemBet game series. Our dividend system has now launched. The prize pool has already accumulated 2,000 STEEM and more than 60 players have participated in staking mining token SBT. A huge reward of 40,000 STEEM is awaiting! Join us NOW with other 500 STEEM users to loot HUGE dividend reward!!
SteemBet Team
Official Website
https://steem-bet.com
Discord Server
https://discord.gg/95cBN3W
Telegram Group
https://t.me/steembet