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

Update EnodeURL to support enodes with listening disabled #1403

Merged
merged 19 commits into from
May 13, 2019

Conversation

mbaxter
Copy link
Contributor

@mbaxter mbaxter commented May 6, 2019

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() and getDiscoveryPort() now returnOptional values indicating whether listening / discovery are enabled. Previously, getDiscoveryPort() would return an empty Optional 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 as EnodeURL's rather than URI objects.

@mbaxter mbaxter force-pushed the PAN-2616/make-enode-ports-optional branch from 93d6313 to 8501ccb Compare May 8, 2019 17:59
@mbaxter mbaxter force-pushed the PAN-2616/make-enode-ports-optional branch from 7ae7dac to bfa7c3f Compare May 10, 2019 16:03
@@ -104,6 +112,7 @@ public void startNode(final PantheonNode node) {
.metricsSystem(noOpMetricsSystem)
.metricsConfiguration(node.metricsConfiguration())
.p2pEnabled(node.isP2pEnabled())
.graphQLRpcConfiguration(GraphQLRpcConfiguration.createDefault())
Copy link
Contributor Author

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 ...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Any ideas @shemnon ??

Copy link
Contributor

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.

Copy link
Contributor Author

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() {
Copy link
Contributor Author

@mbaxter mbaxter May 10, 2019

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?

Copy link
Contributor Author

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.

@mbaxter mbaxter marked this pull request as ready for review May 10, 2019 17:50
@@ -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");
Copy link
Contributor

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.

Copy link
Contributor

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");
Copy link
Contributor

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.

Copy link
Contributor

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)
Copy link
Contributor

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)

Copy link
Contributor Author

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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()),
Copy link
Contributor

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?

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 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) {
Copy link
Contributor

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()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍 updated

@mbaxter mbaxter merged commit d0279cb into PegaSysEng:master May 13, 2019
notlesh pushed a commit to notlesh/pantheon that referenced this pull request May 14, 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.

3 participants