Skip to content
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

Message Pool Rudimentary Spam Protection Measures #3313

Merged
merged 22 commits into from
Aug 28, 2020

Conversation

vyzo
Copy link
Contributor

@vyzo vyzo commented Aug 26, 2020

This adds tracking of required funds for pending messages so that we can stop spam attacks.
This also allows us to finally enable some score contribution from the messages topic.

@vyzo vyzo changed the title Message Pool Balance tracking Message Pool Required Funds tracking Aug 26, 2020
@vyzo
Copy link
Contributor Author

vyzo commented Aug 26, 2020

Follow up: we also want to rate limit messages per actor to some reasonable number.

@vyzo vyzo force-pushed the feat/mpool-balance-tracking branch from 2b858dc to 038e83b Compare August 26, 2020 19:55
@vyzo vyzo changed the title Message Pool Required Funds tracking Message Pool Rudimentary Spam Protection Measures Aug 26, 2020
Copy link
Contributor

@schomatis schomatis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a very solid step in the right direction, the general idea makes sense to me but still I'd need someone more familiarized with mpool internals to review this. There may be many corner cases we may not be anticipating with this "balance simulator" (illustrative but probably not useful example: what if I transfer funds to the actor in the same round that it wants to submit the message?).

On the implementation side (but again with very little insight here), I'm not totally sold on the way this new requiredFunds state is maintained across calls, there seem to be many callers that now need to be aware of it and maintain it (which sounds a bit error prone to me).

@vyzo
Copy link
Contributor Author

vyzo commented Aug 27, 2020

thanks for the review @schomatis!

On the implementation side (but again with very little insight here), I'm not totally sold on the way this new requiredFunds state is maintained across calls, there seem to be many callers that now need to be aware of it and maintain it (which sounds a bit error prone to me).

Well, the state is maintained in the add/rm methods of the msgSet struct, and accessed with the getRequiredFunds method, so it should be safe.

@vyzo
Copy link
Contributor Author

vyzo commented Aug 27, 2020

One potential follow up, probably for another pr because I want to think about it, is to turn the Ignores into Rejections if a peer is sending us too much stuff that gets Ignored.
Some kind of rate-limiting for resources we can consume from one peer -- but as I said, that's for another pr.

Comment on lines -434 to -437
if m.Message.GasLimit > build.BlockGasLimit {
return xerrors.Errorf("given message has too high of a gas limit")
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is checked by ValidForBlockInclusion, so it was redundant here and I removed it.

@@ -319,7 +348,7 @@ func (mp *MessagePool) checkMessage(m *types.SignedMessage) error {
return xerrors.Errorf("mpool message too large (%dB): %w", m.Size(), ErrMessageTooBig)
}

// Perform syntaxtic validation, minGas=0 as we check if correctly in select messages
// Perform syntactic validation, minGas=0 as we check the actual mingas before we add it
if err := m.Message.ValidForBlockInclusion(0); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

were do we do that check now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we do it in both add and push.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and we check with the actual gas in the add logic, so it happens in all paths.

func (ms *msgSet) rm(nonce uint64) {
m, has := ms.msgs[nonce]
if has {
ms.requiredFunds.Sub(ms.requiredFunds, m.Message.RequiredFunds().Int)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be Add no?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh wait, we're tracking funds required for this message chain here, so this means we're removing the message from the chain, which lowers the required funds for that chain. SGTM

essential for correctness in the revert case
@vyzo
Copy link
Contributor Author

vyzo commented Aug 27, 2020

I fixed a correctness issue by adding a flag in msgSet.add/addLocked to specify whether to check the limit or not.
This is to allow us to revert blocks safely even in the presence of a large number of pending messages (near or at the limit).

Copy link
Contributor

@arajasek arajasek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@magik6k magik6k merged commit 84a6327 into master Aug 28, 2020
@magik6k magik6k deleted the feat/mpool-balance-tracking branch August 28, 2020 20:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants