Skip to content
This repository has been archived by the owner on Sep 26, 2019. It is now read-only.

Prevent duplicate ibft messages being processed by state machine #811

Merged
merged 11 commits into from
Feb 8, 2019

Conversation

jframe
Copy link
Contributor

@jframe jframe commented Feb 7, 2019

PR description

Prevent duplicate IBFT messages from being processed by the state machine.

Fixed Issue(s)

@jframe jframe requested review from CjHare and rain-on February 7, 2019 22:19

import java.util.Set;

public class MessageTracker {
Copy link
Contributor

Choose a reason for hiding this comment

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

This could probably do with an interface of "previouslySeen"? Such that the IbftController can only query if a message has been sent, where as the UniqueMulticaster can actually add new messages.

private final Set<Hash> seenMessages;

public MessageTracker(final int gossipHistoryLimit) {
this.seenMessages = newSetFromMap(new SizeLimitedMap<>(gossipHistoryLimit));
Copy link
Contributor

Choose a reason for hiding this comment

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

Wouldn't it be 'safer' to use a descendant of WeakHashMap instead of HashMap here? GC & all?

Copy link
Contributor

Choose a reason for hiding this comment

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

WeakHashMap will drop messages surprisingly often even if the JVM hasn't hit its full memory allocation yet. Anytime it might have to expand the memory currently in use it will drop weak references first, so you can never count on anything being kept. So it's only ever suitable for a cache where values can be recreated on demand and even then I'd avoid it if possible because it makes GC more expensive.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As AJS said, I want a stronger guarantee. And to ensure memory usage doesn't explode the size of the Map is limited.

}

public void start() {
startNewHeightManager(blockchain.getChainHeadHeader());
}

public void handleMessageEvent(final IbftReceivedMessageEvent msg) {
handleMessage(msg.getMessage());
if (!messageTracker.hasSeenMessage(msg.getMessage().getData())) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe this should be reconsidered - i.e. it should say "If we have SEEN this message before, do not handle it" - whereas it currently says "If I have SENT/GOSSIPED this message before, do not handle it" ... I believe our requirement/concept should be the first of these.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thinking about it more your right. I'm preventing sent messages from being processed but it's previously received messages that we need to filter out.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added seperate buffer for seen messages in the IbftController

@jframe jframe merged commit bc20d50 into PegaSysEng:master Feb 8, 2019
@jframe jframe deleted the msg_duplicates branch February 8, 2019 04:42
rain-on pushed a commit to rain-on/pantheon that referenced this pull request Feb 8, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants