-
Notifications
You must be signed in to change notification settings - Fork 130
Update EnodeURL to support enodes with listening disabled #1403
Update EnodeURL to support enodes with listening disabled #1403
Conversation
93d6313
to
8501ccb
Compare
Add bootnode validation to CLI command.
7ae7dac
to
bfa7c3f
Compare
@@ -104,6 +112,7 @@ public void startNode(final PantheonNode node) { | |||
.metricsSystem(noOpMetricsSystem) | |||
.metricsConfiguration(node.metricsConfiguration()) | |||
.p2pEnabled(node.isP2pEnabled()) | |||
.graphQLRpcConfiguration(GraphQLRpcConfiguration.createDefault()) |
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.
Not sure why this was failing on my branch and not master - was getting a null pointer exception because this dependency wasn't set ...
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.
Any ideas @shemnon ??
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.
Looks like this was missed.
The big issue I see is that the threaded acceptance runner is only ever run by developers, the process runner is run on the jenkins boxes instead and would have broke there.
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.
Ah, so maybe it was just a flaky test and when I ran it locally I got the null pointer?
@@ -194,19 +194,21 @@ public void whenNodesListeningPortsAreDifferentItShouldNotBePermitted() { | |||
} | |||
|
|||
@Test | |||
public void whenCheckingIfNodeIsPermittedDiscoveryPortShouldNotBeConsideredIfAbsent() { | |||
public void | |||
whenCheckingIfNodeIsPermittedDiscoveryPortShouldBeConsidered_implicitDiscPortMismatch() { |
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.
@lucassaldanha - How do you think these permissions should work wrt discovery? I've changed EnodeURL
so that it can represent the case where discovery is actually disabled. So now the discoveryPort
is only empty if discovery is disabled which meant I had to rework these checks a bit.
I think the code would be simpler if we just ignore the discovery port and use EnodeURL.sameListeningEndpoint
to check enodes against the whitelist. Alternatively, we could check that the discovery port values are the same (so if one peer has discovery enabled and the other doesn't, they don't match).
What do you think?
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 actually just went ahead and updated NodeLocalConfigPermissioningController
to ignore the discovery port. Let me know if you disagree.
@@ -401,10 +401,10 @@ private void notifyPeerDropped(final DiscoveryPeer peer, final long now) { | |||
private void refreshTableIfRequired() { | |||
final long now = System.currentTimeMillis(); | |||
if (lastRefreshTime + tableRefreshIntervalMs <= now) { | |||
LOG.info("Peer table refresh triggered by timer expiry"); | |||
LOG.trace("Peer table refresh triggered by timer expiry"); |
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.
would debug be more appropriate? Either way.
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.
+1 for debug. This seems to be quite an atomic log message and not something that we are interested in different steps for tracing. But I'm ok with either.
refreshTable(); | ||
} else if (!peerRequirement.hasSufficientPeers()) { | ||
LOG.info("Peer table refresh triggered by insufficient peers"); | ||
LOG.trace("Peer table refresh triggered by insufficient peers"); |
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.
Would debug be more appropriate? Either way.
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.
Same as above. +1 for Debug.
return false; | ||
} | ||
|
||
return Objects.equal(enodeA.nodeId, enodeB.nodeId) |
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.
Google's Objects.equal says not to use it after Java 7. Can these change to java.util.Object.equals? (the replacement Guava recommends)
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.
yikes - we have a lot of these (Objects.hashCode too), wonder if we can we add an error-prone check for this. I'll open a ticket to clean this up globally.
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've got a PR ready to roll that conflicts with some of this code. If you want to submit it as is that's fine, I can get the PR out today.
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.
final OptionalInt discoveryPort) { | ||
checkArgument( | ||
nodeId.size() == NODE_ID_SIZE, "Invalid node id. Expected id of length: 64 bytes."); | ||
checkArgument( | ||
NetworkUtility.isValidPort(listeningPort), | ||
!listeningPort.isPresent() || NetworkUtility.isValidPort(listeningPort.getAsInt()), |
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.
Question: Why do we need to check if the port is available for this representation of an EnodeURL? For example, what will happen if port 1234 is not available but we are only trying to instantiate a representation of another node's EnodeURL that is listening on 1234?
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 just checks that the port is a valid port number, not that the port is available.
@@ -246,18 +286,92 @@ public Builder ipAddress(final String ip) { | |||
return this; | |||
} | |||
|
|||
public Builder listeningPort(final Integer listeningPort) { | |||
this.listeningPort = listeningPort; | |||
public Builder ports(final int listeningAndDiscoveryPorts) { |
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 think this method name doesn't clearly communicate the outcome of using it. Either we remove it (and force the user to use listeningPort()
and discoveryPort()
or we rename it to something a bit clearer.
e.g. discoveryAndListeningPorts()
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.
👍 updated
PR description
Update
EnodeURL
to handle representations that indicate a node is not listening for incoming connections, is not running discovery, or both. When parsing string enode url's, a port of "0" is interpreted as "not listening".Both
getListeningPort()
andgetDiscoveryPort()
now returnOptional
values indicating whether listening / discovery are enabled. Previously,getDiscoveryPort()
would return an emptyOptional
if the discovery port was not distinct from the listening port. Since an empty value now indicates "not listening",getDiscoveryPort()
now returns a non-empty value if discovery is enabled implicitly or explicitly.Bootnode validation has been added to ensure that bootnodes have discovery enabled. If bootnodes with discovery disabled are supplied via the CLI, an error is returned. In order to facilitate this change,
DiscoveryConfiguration
bootnodes
are now set asEnodeURL
's rather thanURI
objects.