-
Notifications
You must be signed in to change notification settings - Fork 130
[NC-1909] IBFT message gossiping #501
[NC-1909] IBFT message gossiping #501
Conversation
consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/IbftGossip.java
Outdated
Show resolved
Hide resolved
...sus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/statemachine/IbftController.java
Outdated
Show resolved
Hide resolved
consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/IbftGossipTest.java
Outdated
Show resolved
Hide resolved
consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/IbftGossipTest.java
Outdated
Show resolved
Hide resolved
consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/IbftGossipTest.java
Show resolved
Hide resolved
.../src/main/java/tech/pegasys/pantheon/consensus/ibft/ibftmessage/AbstractIbftMessageData.java
Show resolved
Hide resolved
...sus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/statemachine/IbftController.java
Show resolved
Hide resolved
...sus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/statemachine/IbftController.java
Outdated
Show resolved
Hide resolved
consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/IbftMessages.java
Show resolved
Hide resolved
* @return Boolean of whether the message was rebroadcast or ignored as it's already been | ||
* broadcast in recent memory | ||
*/ | ||
public boolean gossipPreparePayload( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The 'msg specific' functions could be removed, and the IbftController invoke gossipMessage directly. The "excludeAddress" would be the signer in that instance, rather than the sender.
I don't THINK there's a need to re-serialise the SignedData<?> into a messageData.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sender is available from the message object, the signer is available from the SignedData object, the signature I need to cache is in the SignedData object, dispatching a message requires it to be a MessageData. So at the end of everything all 3 (Message, MessageData, SignedData) need to be utilised at one level or another.
I've tried writing it a few ways and I've gotten to this version because it means the IbftController only needs to worry about the transport layer addresses when excluding things and the gossiper worries about the message contents. The other versions I've written didn't end up with a clean division of responsibilities.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know its not ideal - but in IbftController, can we not write:
gossiper.gossipMessage(payload.getSignature(),
messageData,
payload.getSender(),
payload.getSender(), message.getConnection().getPeer().getAddress());
Inside the handleMessage()? Or something similar in the new processMessage function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that's an improvement. This moves the concern for identifying a message from the gossiper to the controller. Ideally I'd like to pass a Message
into the gossiper but with the type information that's lost about it's contents and the requirements to re decode the message I compromised and picked the most descriptive object that contained as much of the information I required as it could.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even better:
public boolean gossipMessage(
final SignedData<?> signedMessage,
final Message message) {
final Signature msgUniqueId = signedMessage.getSignature();
if (seenMessages.contains(msgUniqueId)) {
return false;
} else {
final Address receivedFrom = message.getConnection().getPeer().getAddress();
final List<Address> excludeAddressesList =
Lists.newArrayList(receivedFrom, signedMessage.getSender());
peers.multicastToValidatorsExcept(message.getData(), excludeAddressesList);
seenMessages.add(msgUniqueId);
return true;
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't make encapsulation any better, the invoker needs to co-ordinate that the message contains that SignedData.
consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/IbftGossip.java
Outdated
Show resolved
Hide resolved
consensus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/ibftevent/IbftEvents.java
Show resolved
Hide resolved
...t/src/main/java/tech/pegasys/pantheon/consensus/ibft/ibftevent/IbftReceivedMessageEvent.java
Outdated
Show resolved
Hide resolved
...sus/ibft/src/main/java/tech/pegasys/pantheon/consensus/ibft/statemachine/IbftController.java
Outdated
Show resolved
Hide resolved
consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/TestHelpers.java
Show resolved
Hide resolved
final BiConsumer<SignedData<P>, Address> gossipMessage, | ||
final Consumer<SignedData<P>> handleMessage) { | ||
if (processMessage(signedPayload, message)) { | ||
gossipMessage.accept(signedPayload, message.getConnection().getPeer().getAddress()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is reworked as per:
private
void processMessage(
final Message message,
final SignedData
signedPayload,
final Consumer<SignedData
> handleMessage) {
if (processMessage(signedPayload, message)) {
gossiper.gossipMessage(signedPayload.getSignature(),
message.getData(),
signedPayload.getSender(),
signedPayload.getSender(), message.getConnection().getPeer().getAddress());
handleMessage.accept(signedPayload);
}
}
The gossip Biconsumer can be removed, and the msg specific handlers in Gossiper can be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is an improvement. There's nothing wrong with using a Biconsumer. The suggested version makes using the Gossiper require additional co-ordination and moves the responsibility for identifying the message and it's signer to the invoker which is worse encapsulation.
667f9cd
to
e819d1f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
PR description
Need to retransmit IBFT messages that we receive. Need to not send them back to who we received them from and not to who originally signed them