-
Notifications
You must be signed in to change notification settings - Fork 649
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
Follow up EOS issue 2204: check block before pushing to fork db #831
Comments
EOSIO/eos#2718 is related. |
And here I thought I was taking on an easy fix. It seems that PR #884 opened a discussion with many moving pieces. I am hoping to move that discussion here, to help all find the best solution. I am generalizing here, and must admit I only have a cursory understanding of the issues involved. EOS 2204 adds a check to make sure that the witness is an active witness before adding its block to the chain. EOS 2718 adds a little more data to the header to help get the 2/3+1 majority back, in the case of forks that have diverged and contain subsets of witness approvals that would otherwise require manual intervention to merge. (1) Can we implement 2204 without 2718? And if so, (1b) does that open the door to an easier DOS than what we have now? (2) Can a comprehensive fix (i.e. DPoS 3.0) be completed in a short enough time frame to improve security and network stability, or would incremental fixes be the better option? @abitmore @pmconrad I will pause on PR #884 unless it is deemed worthwhile to continue. Relevant: #884 (comment) |
AFAICS EOS 2204 adds that check, except for the first block in a round. That means that as a DOS protection measure the fix is useless (the DOS can still be executed at the start of each round). EOS 2718 is a protection against a witness signing blocks on two sides of a fork simultaneously, which could lead to multiple forks having a 2/3+1 majority. I think the solution is incomplete (insofar as it does not take timing effects into account), and it also doesn't solve the problem that the list of active witnesses can be different in each side of the fork. I agree about pausing this, because I don't see an effective short-term solution. |
There is an interesting discussion in Steem which is related to this issue: steemit/steem#2471 |
Perhaps it's mentioned elsewhere: there is a DoS factor that an old block will be pushed to fork db without being validated as long as
|
There is a scenario described in steemit/steem#2911. When there is a long reversible fork, node performance got heavily hit when tries to push another fork which is even longer. |
Fix #831 - check witness signature before adding block to fork db
Fixed by #1987 |
IMO a better idea would be to limit fork_db to one block per witness per block height. That would automatically limit the blocks per height to the number of witnesses, without the potential for a DOS attack. |
With #1987, one attack vector is a legit active witness signing lots of blocks, which can be a) on the same height, or b) on different heights but with the same timestamp so they would still pass the Another attack vector is when there is a minor fork created by a legit witness, since the first block would pass To mitigate influence of the 2nd attack vector,
|
The problem here is that this would open up a different way for a DOS: if a witness spams the network with different blocks for the same timestamp, the nodes who receive the "wrong" blocks first will be unable to switch to the majority chain. I think the only thing we can do about a malicious witness is detect and log different blocks with the same timestamp (more precisely: with the same slot time). For the other attack vector, the height of a fork is not that much of a problem. Once the fake fork outgrows the majority fork the node will try to switch to it. At that point, the legitimate block will have its So in order to bloat a node's fork db an attacker will have to push many blocks on top of a minority fork in breadth-first fashion. The only real protection against that is to evaluate the legitimate block, as you suggest, so the fake blocks will be recognized. Any absolute limit on the number of blocks in fork_database creates a DOS attack vector, see above. Since switching to a minority fork is expensive, we can use an absolute number > 1 of unverified blocks as a threshold for temporarily switching to a minority fork, just so the |
Good catch. There are 2 scenarios here.
I agree, although we can also look for better solutions in the meanwhile.
This is an interesting idea, although I guess it's not easy to do for our use case. One concern is popping blocks from the major fork would update quite some memory segments, which would need a copy in the child process. It means we need more RAM to run the node. |
Keeping this issue open for future improvement. See discussions above. |
EOSIO/eos#2204:
The text was updated successfully, but these errors were encountered: