-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
consensus: disconnect from bad peers #2871
Comments
@ebuchman I'd love trying myself on removal of Anyway, when I start working on it (be it with just removing the signing in the first step) should such a thing be done in a separate issue or just a banch referencing this issue here? |
I've done https://github.com/srmo/tendermint/tree/2871-remove-proposal-hearbeat |
It was never introduced for any purpose other than the thought that "maybe it will be useful for debugging some time". While it might be true, so far in debugging issues with this feature we've always been able to resort to the logs of each instance, so the extra message wasn't useful. In a case where you don't have access to the proposer's logs or otherwise lose them, we'd be losing that information. Note that this message isn't gossipped, only sent to directly connected peers, so, in deployments where you want to hide the validator, eg. behind sentries, only the sentries would receive this message. If there's a strong desire to keep this message, we would have to think securing it, and it's not clear it's worth it. |
OK. Understood. |
Possibly relevant: I'd like to revisit #1557- I would like a way to remove bad peers from the ABCI layer. I think app-level validation should matter (in some cases, and for some applications) when deciding who to devote network resources to. For example, if a peer misbehaves in a very specific way (more than simply than x number of messages failing CheckTX, but perhaps for certain types of important messages), I would like to be able to remove that peer. |
This is tricky. Right now there is a way for the app to filter peers when they are first connected to, but it's not clear how the app would tell tendermint to disconnect peers in other cases. Since I believe this is quite distinct from the current issue, can you open a new issue describing how you think this might work? I can imagine how it would work for CheckTx - ie. certain responses would cause the sending peer to be disconnected, but it's hard for other cases because the app doesn't otherwise really get information about particular peers ... |
Went through #2871, there are several issues, this PR tries to tackle the `HasVoteMessage` with an invalid validator index sent by a bad peer and it prevents the bad vote goes to the peerMsgQueue. Future work, check other bad message cases and plumbing the reactor errors with the peer manager and then can disconnect the peer sending the bad messages.
The consensus reactor only disconnects from peers in three cases:
While we log other kinds of errors in processing (invalid blocks, proposals, votes), we never disconnect from peers due to them, which open us up to being spammed with bad consensus messages.
We also don't enforce that our peers ever send us anything useful. While we mark them as good if they send us 10,000 unique block parts or votes, we never mark them bad if they just fail to send us anything. This could result in us being connected to lots of useless peers.
We need to address both of these things:
Bad Messages
Let's enumerate all messages and see when they indicate a bad peer (beyond failing their ValidateBasic() check).
In general we could probably add some more rules around all of these to prevent eg. receiving the same information multiple times from the same peer, but we'd need to ensure on the sending side that it never happens too.
NewRoundStepMessage, NewValidBlockMessage, HasVoteMessage
These are just informational so we know what to send the peer.
HasVote may contain an index beyond the size of the validator set for the given height, which should be a sign of malice, but currently we just ignore it.
VoteSetMaj23Message
We already stop peers for errors here.
ProposalHeartbeatMessage
Comes with a signature, and could be checked, but not actually helpful and should probably be eliminated outright (#2626).
ProposalMessage
Handled in the receiveRoutine - calls setProposal.
Any error here should result in disconnect from peers (as noted in #2158 (comment))
ProposalPOLMessage
Don't think there's much we can do here
BlockPartMessage
Handled in the receiveRoutine - calls addProposalBlockPart.
Some errors here (eg. in AddPart) should cause us to disconnect from the peer, but others (eg. error in unmarshaling) are not the particular peers fault, but the original proposer, and we don't know which peer corresponds to the actual proposer, so there's nothing we can do here (ultimately, we'd like to publish evidence about this so the app can punish the proposer).
VoteMessage
Handled in the receiveRoutine - calls tryAddVote. This can result in many kinds of errors - some resulting in disconnecting, and others not, hence we should use sentinels (#1327)
tryAddVote calls addVote, which may return
ErrVoteHeightMismatch
, for which we shouldn't disconnect.We then call cs.LastCommit.AddVote. Some errors here could come from honest peers, so we shouldn't disconnect:
The rest are from bad peers, and we should disconnect:
VoteSetBitsMessage
Don't think there's much we can do here
Useless Peers
A peer could just never send us any consensus messages and we wouldn't disconnect from it.
We need to enforce some cadence on our peers. While this is partially mitigated by preferentially connecting to at least some peers marked good via the PEX, we would probably benefit from having additional protections within the reactor, though we can leave that to a separate issue.
Summary
For now we should do the following, as described above:
This subsumes #2158, #1327, #2626
The text was updated successfully, but these errors were encountered: