Moving NodeWhitelistController to permissioning package (#855)

* Moving NodeWhitelistController to permissioning package

* Refactoring unit tests

* Fix string.format

Signed-off-by: Adrian Sutton <adrian.sutton@consensys.net>
pull/2/head
Lucas Saldanha 6 years ago committed by GitHub
parent 1dfe3e8eb7
commit d3b9211b82
  1. 7
      acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java
  2. 21
      ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermAddNodesToWhitelist.java
  3. 6
      ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermGetNodesWhitelist.java
  4. 2
      ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermReloadPermissionsFromFile.java
  5. 21
      ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermRemoveNodesFromWhitelist.java
  6. 20
      ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermAddNodesToWhitelistTest.java
  7. 10
      ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermGetNodesWhitelistTest.java
  8. 2
      ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermReloadPermissionsFromFileTest.java
  9. 14
      ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermRemoveNodesFromWhitelistTest.java
  10. 2
      ethereum/mock-p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/testing/MockNetwork.java
  11. 2
      ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/NoopP2PNetwork.java
  12. 2
      ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/api/P2PNetwork.java
  13. 2
      ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryAgent.java
  14. 2
      ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/VertxPeerDiscoveryAgent.java
  15. 4
      ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/internal/PeerDiscoveryController.java
  16. 6
      ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/internal/RecursivePeerRefreshState.java
  17. 11
      ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/netty/NettyP2PNetwork.java
  18. 18
      ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/NettyP2PNetworkTest.java
  19. 2
      ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryTestHelper.java
  20. 2
      ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/internal/MockPeerDiscoveryAgent.java
  21. 6
      ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/internal/PeerDiscoveryControllerTest.java
  22. 5
      ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/internal/RecursivePeerRefreshStateTest.java
  23. 116
      ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/NodeWhitelistController.java
  24. 147
      ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/NodeWhitelistControllerTest.java
  25. 2
      pantheon/src/main/java/tech/pegasys/pantheon/RunnerBuilder.java
  26. 21
      util/src/main/java/tech/pegasys/pantheon/util/enode/EnodeURL.java

@ -138,7 +138,12 @@ public class PantheonNode implements Node, NodeConfiguration, RunnableNode, Auto
@Override
public String enodeUrl() {
return "enode://" + keyPair.getPublicKey().toString() + "@" + LOCALHOST + ":" + p2pPort;
return "enode://"
+ keyPair.getPublicKey().toString().substring(2)
+ "@"
+ LOCALHOST
+ ":"
+ p2pPort;
}
private Optional<String> jsonRpcBaseUrl() {

@ -22,12 +22,9 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcResponse;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcSuccessResponse;
import tech.pegasys.pantheon.ethereum.p2p.P2pDisabledException;
import tech.pegasys.pantheon.ethereum.p2p.api.P2PNetwork;
import tech.pegasys.pantheon.ethereum.p2p.peers.DefaultPeer;
import tech.pegasys.pantheon.ethereum.p2p.peers.Peer;
import tech.pegasys.pantheon.ethereum.p2p.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController;
import java.util.List;
import java.util.stream.Collectors;
public class PermAddNodesToWhitelist implements JsonRpcMethod {
@ -52,15 +49,9 @@ public class PermAddNodesToWhitelist implements JsonRpcMethod {
try {
if (p2pNetwork.getNodeWhitelistController().isPresent()) {
try {
List<Peer> peers =
enodeListParam
.getStringList()
.parallelStream()
.map(this::parsePeer)
.collect(Collectors.toList());
NodeWhitelistController.NodesWhitelistResult nodesWhitelistResult =
p2pNetwork.getNodeWhitelistController().get().addNodes(peers);
final List<String> enodeURLs = enodeListParam.getStringList();
final NodeWhitelistController.NodesWhitelistResult nodesWhitelistResult =
p2pNetwork.getNodeWhitelistController().get().addNodes(enodeURLs);
switch (nodesWhitelistResult.result()) {
case SUCCESS:
@ -92,8 +83,4 @@ public class PermAddNodesToWhitelist implements JsonRpcMethod {
return new JsonRpcErrorResponse(req.getId(), JsonRpcError.P2P_DISABLED);
}
}
private DefaultPeer parsePeer(final String enodeURI) {
return DefaultPeer.fromURI(enodeURI);
}
}

@ -20,10 +20,8 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcResponse;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcSuccessResponse;
import tech.pegasys.pantheon.ethereum.p2p.P2pDisabledException;
import tech.pegasys.pantheon.ethereum.p2p.api.P2PNetwork;
import tech.pegasys.pantheon.ethereum.p2p.peers.Peer;
import java.util.List;
import java.util.stream.Collectors;
public class PermGetNodesWhitelist implements JsonRpcMethod {
@ -42,10 +40,8 @@ public class PermGetNodesWhitelist implements JsonRpcMethod {
public JsonRpcResponse response(final JsonRpcRequest req) {
try {
if (p2pNetwork.getNodeWhitelistController().isPresent()) {
List<Peer> nodesWhitelist =
final List<String> enodeList =
p2pNetwork.getNodeWhitelistController().get().getNodesWhitelist();
List<String> enodeList =
nodesWhitelist.parallelStream().map(Peer::getEnodeURI).collect(Collectors.toList());
return new JsonRpcSuccessResponse(req.getId(), enodeList);
} else {

@ -18,8 +18,8 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcError;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcErrorResponse;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcResponse;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcSuccessResponse;
import tech.pegasys.pantheon.ethereum.p2p.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.ethereum.permissioning.AccountWhitelistController;
import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController;
import java.util.Optional;

@ -22,12 +22,9 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcResponse;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcSuccessResponse;
import tech.pegasys.pantheon.ethereum.p2p.P2pDisabledException;
import tech.pegasys.pantheon.ethereum.p2p.api.P2PNetwork;
import tech.pegasys.pantheon.ethereum.p2p.peers.DefaultPeer;
import tech.pegasys.pantheon.ethereum.p2p.peers.Peer;
import tech.pegasys.pantheon.ethereum.p2p.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController;
import java.util.List;
import java.util.stream.Collectors;
public class PermRemoveNodesFromWhitelist implements JsonRpcMethod {
@ -52,15 +49,9 @@ public class PermRemoveNodesFromWhitelist implements JsonRpcMethod {
try {
if (p2pNetwork.getNodeWhitelistController().isPresent()) {
try {
List<Peer> peers =
enodeListParam
.getStringList()
.parallelStream()
.map(this::parsePeer)
.collect(Collectors.toList());
NodeWhitelistController.NodesWhitelistResult nodesWhitelistResult =
p2pNetwork.getNodeWhitelistController().get().removeNodes(peers);
final List<String> enodeURLs = enodeListParam.getStringList();
final NodeWhitelistController.NodesWhitelistResult nodesWhitelistResult =
p2pNetwork.getNodeWhitelistController().get().removeNodes(enodeURLs);
switch (nodesWhitelistResult.result()) {
case SUCCESS:
@ -92,8 +83,4 @@ public class PermRemoveNodesFromWhitelist implements JsonRpcMethod {
return new JsonRpcErrorResponse(req.getId(), JsonRpcError.P2P_DISABLED);
}
}
private DefaultPeer parsePeer(final String enodeURI) {
return DefaultPeer.fromURI(enodeURI);
}
}

@ -19,7 +19,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import static tech.pegasys.pantheon.ethereum.p2p.permissioning.NodeWhitelistController.NodesWhitelistResult;
import static tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController.NodesWhitelistResult;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.JsonRpcRequest;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.parameters.JsonRpcParameter;
@ -29,7 +29,7 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcResponse;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcSuccessResponse;
import tech.pegasys.pantheon.ethereum.p2p.P2pDisabledException;
import tech.pegasys.pantheon.ethereum.p2p.api.P2PNetwork;
import tech.pegasys.pantheon.ethereum.p2p.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.ethereum.permissioning.WhitelistOperationResult;
import java.util.ArrayList;
@ -74,11 +74,13 @@ public class PermAddNodesToWhitelistTest {
@Test
public void shouldThrowInvalidJsonRpcParametersExceptionWhenOnlyBadEnode() {
final JsonRpcRequest request = buildRequest(Lists.newArrayList(badEnode));
final ArrayList<String> enodeList = Lists.newArrayList(badEnode);
final JsonRpcRequest request = buildRequest(enodeList);
final JsonRpcResponse expected =
new JsonRpcErrorResponse(request.getId(), JsonRpcError.NODE_WHITELIST_INVALID_ENTRY);
when(p2pNetwork.getNodeWhitelistController()).thenReturn(Optional.of(nodeWhitelistController));
when(nodeWhitelistController.addNodes(eq(enodeList))).thenThrow(IllegalArgumentException.class);
final JsonRpcResponse actual = method.response(request);
@ -87,11 +89,13 @@ public class PermAddNodesToWhitelistTest {
@Test
public void shouldThrowInvalidJsonRpcParametersExceptionWhenBadEnodeInList() {
final JsonRpcRequest request = buildRequest(Lists.newArrayList(enode2, badEnode, enode1));
final ArrayList<String> enodeList = Lists.newArrayList(enode2, badEnode, enode1);
final JsonRpcRequest request = buildRequest(enodeList);
final JsonRpcResponse expected =
new JsonRpcErrorResponse(request.getId(), JsonRpcError.NODE_WHITELIST_INVALID_ENTRY);
when(p2pNetwork.getNodeWhitelistController()).thenReturn(Optional.of(nodeWhitelistController));
when(nodeWhitelistController.addNodes(eq(enodeList))).thenThrow(IllegalArgumentException.class);
final JsonRpcResponse actual = method.response(request);
@ -99,12 +103,14 @@ public class PermAddNodesToWhitelistTest {
}
@Test
public void shouldThrowInvalidJsonRpcParametersExceptionWhenNoEnode() {
final JsonRpcRequest request = buildRequest(Lists.newArrayList(""));
public void shouldThrowInvalidJsonRpcParametersExceptionWhenEmptyEnode() {
final JsonRpcRequest request = buildRequest(Lists.emptyList());
final JsonRpcResponse expected =
new JsonRpcErrorResponse(request.getId(), JsonRpcError.NODE_WHITELIST_INVALID_ENTRY);
new JsonRpcErrorResponse(request.getId(), JsonRpcError.NODE_WHITELIST_EMPTY_ENTRY);
when(p2pNetwork.getNodeWhitelistController()).thenReturn(Optional.of(nodeWhitelistController));
when(nodeWhitelistController.addNodes(eq(Lists.emptyList())))
.thenReturn(new NodesWhitelistResult(WhitelistOperationResult.ERROR_EMPTY_ENTRY));
final JsonRpcResponse actual = method.response(request);

@ -25,14 +25,10 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcResponse;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcSuccessResponse;
import tech.pegasys.pantheon.ethereum.p2p.P2pDisabledException;
import tech.pegasys.pantheon.ethereum.p2p.api.P2PNetwork;
import tech.pegasys.pantheon.ethereum.p2p.peers.DefaultPeer;
import tech.pegasys.pantheon.ethereum.p2p.peers.Peer;
import tech.pegasys.pantheon.ethereum.p2p.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.assertj.core.util.Lists;
import org.junit.Before;
@ -118,7 +114,7 @@ public class PermGetNodesWhitelistTest {
return new JsonRpcRequest("2.0", METHOD_NAME, new Object[] {});
}
private List<Peer> buildNodesList(final String... enodes) {
return Arrays.stream(enodes).parallel().map(DefaultPeer::fromURI).collect(Collectors.toList());
private List<String> buildNodesList(final String... enodes) {
return Lists.newArrayList(enodes);
}
}

@ -21,8 +21,8 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcError;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcErrorResponse;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcResponse;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcSuccessResponse;
import tech.pegasys.pantheon.ethereum.p2p.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.ethereum.permissioning.AccountWhitelistController;
import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController;
import java.util.Optional;

@ -19,7 +19,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import static tech.pegasys.pantheon.ethereum.p2p.permissioning.NodeWhitelistController.NodesWhitelistResult;
import static tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController.NodesWhitelistResult;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.JsonRpcRequest;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.parameters.JsonRpcParameter;
@ -29,7 +29,7 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcResponse;
import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcSuccessResponse;
import tech.pegasys.pantheon.ethereum.p2p.P2pDisabledException;
import tech.pegasys.pantheon.ethereum.p2p.api.P2PNetwork;
import tech.pegasys.pantheon.ethereum.p2p.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.ethereum.permissioning.WhitelistOperationResult;
import java.util.ArrayList;
@ -79,6 +79,8 @@ public class PermRemoveNodesFromWhitelistTest {
new JsonRpcErrorResponse(request.getId(), JsonRpcError.NODE_WHITELIST_INVALID_ENTRY);
when(p2pNetwork.getNodeWhitelistController()).thenReturn(Optional.of(nodeWhitelistController));
when(nodeWhitelistController.removeNodes(eq(Lists.newArrayList(badEnode))))
.thenThrow(IllegalArgumentException.class);
final JsonRpcResponse actual = method.response(request);
@ -86,12 +88,14 @@ public class PermRemoveNodesFromWhitelistTest {
}
@Test
public void shouldThrowInvalidJsonRpcParametersExceptionWhenNoEnode() {
final JsonRpcRequest request = buildRequest(Lists.newArrayList(""));
public void shouldThrowInvalidJsonRpcParametersExceptionWhenEmptyList() {
final JsonRpcRequest request = buildRequest(Lists.emptyList());
final JsonRpcResponse expected =
new JsonRpcErrorResponse(request.getId(), JsonRpcError.NODE_WHITELIST_INVALID_ENTRY);
new JsonRpcErrorResponse(request.getId(), JsonRpcError.NODE_WHITELIST_EMPTY_ENTRY);
when(p2pNetwork.getNodeWhitelistController()).thenReturn(Optional.of(nodeWhitelistController));
when(nodeWhitelistController.removeNodes(eq(Lists.emptyList())))
.thenReturn(new NodesWhitelistResult(WhitelistOperationResult.ERROR_EMPTY_ENTRY));
final JsonRpcResponse actual = method.response(request);

@ -18,11 +18,11 @@ import tech.pegasys.pantheon.ethereum.p2p.api.MessageData;
import tech.pegasys.pantheon.ethereum.p2p.api.P2PNetwork;
import tech.pegasys.pantheon.ethereum.p2p.api.PeerConnection;
import tech.pegasys.pantheon.ethereum.p2p.peers.Peer;
import tech.pegasys.pantheon.ethereum.p2p.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.ethereum.p2p.wire.Capability;
import tech.pegasys.pantheon.ethereum.p2p.wire.DefaultMessage;
import tech.pegasys.pantheon.ethereum.p2p.wire.PeerInfo;
import tech.pegasys.pantheon.ethereum.p2p.wire.messages.DisconnectMessage.DisconnectReason;
import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.util.Subscribers;
import java.net.InetSocketAddress;

@ -17,9 +17,9 @@ import tech.pegasys.pantheon.ethereum.p2p.api.Message;
import tech.pegasys.pantheon.ethereum.p2p.api.P2PNetwork;
import tech.pegasys.pantheon.ethereum.p2p.api.PeerConnection;
import tech.pegasys.pantheon.ethereum.p2p.peers.Peer;
import tech.pegasys.pantheon.ethereum.p2p.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.ethereum.p2p.wire.Capability;
import tech.pegasys.pantheon.ethereum.p2p.wire.PeerInfo;
import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController;
import java.io.IOException;
import java.net.InetSocketAddress;

@ -13,9 +13,9 @@
package tech.pegasys.pantheon.ethereum.p2p.api;
import tech.pegasys.pantheon.ethereum.p2p.peers.Peer;
import tech.pegasys.pantheon.ethereum.p2p.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.ethereum.p2p.wire.Capability;
import tech.pegasys.pantheon.ethereum.p2p.wire.PeerInfo;
import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController;
import java.io.Closeable;
import java.net.InetSocketAddress;

@ -32,8 +32,8 @@ import tech.pegasys.pantheon.ethereum.p2p.discovery.internal.TimerUtil;
import tech.pegasys.pantheon.ethereum.p2p.peers.DefaultPeerId;
import tech.pegasys.pantheon.ethereum.p2p.peers.Endpoint;
import tech.pegasys.pantheon.ethereum.p2p.peers.PeerBlacklist;
import tech.pegasys.pantheon.ethereum.p2p.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.ethereum.p2p.wire.messages.DisconnectMessage;
import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.util.NetworkUtility;
import tech.pegasys.pantheon.util.Subscribers;
import tech.pegasys.pantheon.util.bytes.BytesValue;

@ -23,7 +23,7 @@ import tech.pegasys.pantheon.ethereum.p2p.discovery.internal.TimerUtil;
import tech.pegasys.pantheon.ethereum.p2p.discovery.internal.VertxTimerUtil;
import tech.pegasys.pantheon.ethereum.p2p.peers.Endpoint;
import tech.pegasys.pantheon.ethereum.p2p.peers.PeerBlacklist;
import tech.pegasys.pantheon.ethereum.p2p.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.util.NetworkUtility;
import tech.pegasys.pantheon.util.Preconditions;

@ -24,7 +24,7 @@ import tech.pegasys.pantheon.ethereum.p2p.discovery.PeerDiscoveryEvent.PeerBonde
import tech.pegasys.pantheon.ethereum.p2p.discovery.PeerDiscoveryStatus;
import tech.pegasys.pantheon.ethereum.p2p.peers.Peer;
import tech.pegasys.pantheon.ethereum.p2p.peers.PeerBlacklist;
import tech.pegasys.pantheon.ethereum.p2p.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.util.Subscribers;
import tech.pegasys.pantheon.util.bytes.BytesValue;
@ -201,7 +201,7 @@ public class PeerDiscoveryController {
private boolean whitelistIfPresentIsNodePermitted(final DiscoveryPeer sender) {
return nodeWhitelistController
.map(nodeWhitelistController -> nodeWhitelistController.isPermitted(sender))
.map(nodeWhitelistController -> nodeWhitelistController.isPermitted(sender.getEnodeURI()))
.orElse(true);
}

@ -17,7 +17,7 @@ import static tech.pegasys.pantheon.ethereum.p2p.discovery.internal.PeerDistance
import tech.pegasys.pantheon.ethereum.p2p.discovery.DiscoveryPeer;
import tech.pegasys.pantheon.ethereum.p2p.discovery.PeerDiscoveryStatus;
import tech.pegasys.pantheon.ethereum.p2p.peers.PeerBlacklist;
import tech.pegasys.pantheon.ethereum.p2p.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.util.bytes.BytesValue;
import java.util.List;
@ -183,7 +183,9 @@ public class RecursivePeerRefreshState {
private boolean satisfiesMapAdditionCriteria(final DiscoveryPeer discoPeer) {
return !oneTrueMap.containsKey(discoPeer.getId())
&& !peerBlacklist.contains(discoPeer)
&& peerWhitelist.map(whitelist -> whitelist.isPermitted(discoPeer)).orElse(true)
&& peerWhitelist
.map(whitelist -> whitelist.isPermitted(discoPeer.getEnodeURI()))
.orElse(true)
&& (initialPeers.contains(discoPeer) || !peerTable.get(discoPeer).isPresent())
&& !discoPeer.getId().equals(localPeerId);
}

@ -28,11 +28,11 @@ import tech.pegasys.pantheon.ethereum.p2p.peers.DefaultPeer;
import tech.pegasys.pantheon.ethereum.p2p.peers.Endpoint;
import tech.pegasys.pantheon.ethereum.p2p.peers.Peer;
import tech.pegasys.pantheon.ethereum.p2p.peers.PeerBlacklist;
import tech.pegasys.pantheon.ethereum.p2p.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.ethereum.p2p.wire.Capability;
import tech.pegasys.pantheon.ethereum.p2p.wire.PeerInfo;
import tech.pegasys.pantheon.ethereum.p2p.wire.SubProtocol;
import tech.pegasys.pantheon.ethereum.p2p.wire.messages.DisconnectMessage.DisconnectReason;
import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.metrics.Counter;
import tech.pegasys.pantheon.metrics.LabelledMetric;
import tech.pegasys.pantheon.metrics.MetricCategory;
@ -304,10 +304,11 @@ public class NettyP2PNetwork implements P2PNetwork {
nwc ->
nwc.isPermitted(
new DefaultPeer(
connection.getPeer().getNodeId(),
ch.remoteAddress().getAddress().getHostAddress(),
connection.getPeer().getPort(),
connection.getPeer().getPort())))
connection.getPeer().getNodeId(),
ch.remoteAddress().getAddress().getHostAddress(),
connection.getPeer().getPort(),
connection.getPeer().getPort())
.getEnodeURI()))
.orElse(true);
}

@ -35,17 +35,18 @@ import tech.pegasys.pantheon.ethereum.p2p.peers.DefaultPeer;
import tech.pegasys.pantheon.ethereum.p2p.peers.Endpoint;
import tech.pegasys.pantheon.ethereum.p2p.peers.Peer;
import tech.pegasys.pantheon.ethereum.p2p.peers.PeerBlacklist;
import tech.pegasys.pantheon.ethereum.p2p.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.ethereum.p2p.wire.Capability;
import tech.pegasys.pantheon.ethereum.p2p.wire.PeerInfo;
import tech.pegasys.pantheon.ethereum.p2p.wire.SubProtocol;
import tech.pegasys.pantheon.ethereum.p2p.wire.messages.DisconnectMessage.DisconnectReason;
import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration;
import tech.pegasys.pantheon.metrics.noop.NoOpMetricsSystem;
import tech.pegasys.pantheon.util.bytes.BytesValue;
import java.net.InetAddress;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.OptionalInt;
@ -416,7 +417,7 @@ public final class NettyP2PNetworkTest {
Files.createTempFile("test", "test").toAbsolutePath().toString());
final NodeWhitelistController localWhitelistController = new NodeWhitelistController(config);
// turn on whitelisting by adding a different node NOT remote node
localWhitelistController.addNode(mockPeer());
localWhitelistController.addNodes(Arrays.asList(mockPeer().getEnodeURI()));
final SubProtocol subprotocol = subProtocol();
final Capability cap = Capability.create(subprotocol.getName(), 63);
@ -646,8 +647,19 @@ public final class NettyP2PNetworkTest {
private Peer mockPeer() {
final Peer peer = mock(Peer.class);
final BytesValue id = SECP256K1.KeyPair.generate().getPublicKey().getEncodedBytes();
final Endpoint endpoint = new Endpoint("127.0.0.1", 30303, OptionalInt.of(30303));
final String enodeURL =
String.format(
"enode://%s@%s:%d?discport=%d",
id.toString().substring(2),
endpoint.getHost(),
endpoint.getUdpPort(),
endpoint.getTcpPort().getAsInt());
when(peer.getId()).thenReturn(id);
when(peer.getEndpoint()).thenReturn(new Endpoint("127.0.0.1", 30303, OptionalInt.of(30303)));
when(peer.getEndpoint()).thenReturn(endpoint);
when(peer.getEnodeURI()).thenReturn(enodeURL);
return peer;
}
}

@ -20,7 +20,7 @@ import tech.pegasys.pantheon.ethereum.p2p.discovery.internal.Packet;
import tech.pegasys.pantheon.ethereum.p2p.discovery.internal.PacketType;
import tech.pegasys.pantheon.ethereum.p2p.discovery.internal.PingPacketData;
import tech.pegasys.pantheon.ethereum.p2p.peers.PeerBlacklist;
import tech.pegasys.pantheon.ethereum.p2p.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.util.bytes.BytesValue;
import java.util.Arrays;

@ -17,7 +17,7 @@ import tech.pegasys.pantheon.ethereum.p2p.config.DiscoveryConfiguration;
import tech.pegasys.pantheon.ethereum.p2p.discovery.DiscoveryPeer;
import tech.pegasys.pantheon.ethereum.p2p.discovery.PeerDiscoveryAgent;
import tech.pegasys.pantheon.ethereum.p2p.peers.PeerBlacklist;
import tech.pegasys.pantheon.ethereum.p2p.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.util.bytes.BytesValue;
import java.net.InetSocketAddress;

@ -35,7 +35,7 @@ import tech.pegasys.pantheon.ethereum.p2p.discovery.PeerDiscoveryTestHelper;
import tech.pegasys.pantheon.ethereum.p2p.peers.Endpoint;
import tech.pegasys.pantheon.ethereum.p2p.peers.Peer;
import tech.pegasys.pantheon.ethereum.p2p.peers.PeerBlacklist;
import tech.pegasys.pantheon.ethereum.p2p.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration;
import tech.pegasys.pantheon.util.Subscribers;
import tech.pegasys.pantheon.util.bytes.Bytes32;
@ -947,8 +947,8 @@ public class PeerDiscoveryControllerTest {
final NodeWhitelistController nodeWhitelistController = new NodeWhitelistController(config);
// Whitelist peers
nodeWhitelistController.addNode(discoPeer);
nodeWhitelistController.addNode(otherPeer2);
nodeWhitelistController.addNodes(Arrays.asList(discoPeer.getEnodeURI()));
nodeWhitelistController.addNodes(Arrays.asList(otherPeer2.getEnodeURI()));
final OutboundMessageHandler outboundMessageHandler = mock(OutboundMessageHandler.class);
controller =

@ -27,11 +27,12 @@ import tech.pegasys.pantheon.ethereum.p2p.discovery.PeerDiscoveryStatus;
import tech.pegasys.pantheon.ethereum.p2p.discovery.internal.RecursivePeerRefreshState.BondingAgent;
import tech.pegasys.pantheon.ethereum.p2p.discovery.internal.RecursivePeerRefreshState.FindNeighbourDispatcher;
import tech.pegasys.pantheon.ethereum.p2p.peers.PeerBlacklist;
import tech.pegasys.pantheon.ethereum.p2p.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration;
import tech.pegasys.pantheon.util.bytes.BytesValue;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
@ -486,7 +487,7 @@ public class RecursivePeerRefreshStateTest {
final NodeWhitelistController peerWhitelist =
new NodeWhitelistController(permissioningConfiguration);
peerWhitelist.addNode(peerA);
peerWhitelist.addNodes(Arrays.asList(peerA.getEnodeURI()));
recursivePeerRefreshState =
new RecursivePeerRefreshState(

@ -10,15 +10,9 @@
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package tech.pegasys.pantheon.ethereum.p2p.permissioning;
package tech.pegasys.pantheon.ethereum.permissioning;
import tech.pegasys.pantheon.ethereum.p2p.peers.DefaultPeer;
import tech.pegasys.pantheon.ethereum.p2p.peers.Peer;
import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration;
import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfigurationBuilder;
import tech.pegasys.pantheon.ethereum.permissioning.WhitelistFileSyncException;
import tech.pegasys.pantheon.ethereum.permissioning.WhitelistOperationResult;
import tech.pegasys.pantheon.ethereum.permissioning.WhitelistPersistor;
import tech.pegasys.pantheon.util.enode.EnodeURL;
import java.io.IOException;
import java.net.URI;
@ -38,7 +32,7 @@ public class NodeWhitelistController {
private static final Logger LOG = LogManager.getLogger();
private PermissioningConfiguration configuration;
private List<Peer> nodesWhitelist = new ArrayList<>();
private List<EnodeURL> nodesWhitelist = new ArrayList<>();
private final WhitelistPersistor whitelistPersistor;
public NodeWhitelistController(final PermissioningConfiguration permissioningConfiguration) {
@ -57,70 +51,72 @@ public class NodeWhitelistController {
private void readNodesFromConfig(final PermissioningConfiguration configuration) {
if (configuration.isNodeWhitelistEnabled() && configuration.getNodeWhitelist() != null) {
for (URI uri : configuration.getNodeWhitelist()) {
nodesWhitelist.add(DefaultPeer.fromURI(uri));
nodesWhitelist.add(new EnodeURL(uri.toString()));
}
}
}
public boolean addNode(final Peer node) {
return nodesWhitelist.add(node);
}
private boolean removeNode(final Peer node) {
return nodesWhitelist.remove(node);
}
public NodesWhitelistResult addNodes(final List<Peer> peers) {
final NodesWhitelistResult inputValidationResult = validInput(peers);
public NodesWhitelistResult addNodes(final List<String> enodeURLs) {
final NodesWhitelistResult inputValidationResult = validInput(enodeURLs);
if (inputValidationResult.result() != WhitelistOperationResult.SUCCESS) {
return inputValidationResult;
}
final List<EnodeURL> peers = enodeURLs.stream().map(EnodeURL::new).collect(Collectors.toList());
for (Peer peer : peers) {
for (EnodeURL peer : peers) {
if (nodesWhitelist.contains(peer)) {
return new NodesWhitelistResult(
WhitelistOperationResult.ERROR_EXISTING_ENTRY,
String.format("Specified peer: %s already exists in whitelist.", peer.getId()));
String.format("Specified peer: %s already exists in whitelist.", peer.getNodeId()));
}
}
final List<Peer> oldWhitelist = new ArrayList<>(this.nodesWhitelist);
final List<EnodeURL> oldWhitelist = new ArrayList<>(this.nodesWhitelist);
peers.forEach(this::addNode);
try {
verifyConfigurationFileState(peerToEnodeURI(oldWhitelist));
updateConfigurationFile(peerToEnodeURI(nodesWhitelist));
verifyConfigurationFileState(peerToEnodeURI(nodesWhitelist));
} catch (IOException e) {
revertState(oldWhitelist);
return new NodesWhitelistResult(WhitelistOperationResult.ERROR_WHITELIST_PERSIST_FAIL);
} catch (WhitelistFileSyncException e) {
return new NodesWhitelistResult(WhitelistOperationResult.ERROR_WHITELIST_FILE_SYNC);
final NodesWhitelistResult updateConfigFileResult = updateWhitelistInConfigFile(oldWhitelist);
if (updateConfigFileResult.result() != WhitelistOperationResult.SUCCESS) {
return updateConfigFileResult;
}
return new NodesWhitelistResult(WhitelistOperationResult.SUCCESS);
}
private boolean peerListHasDuplicates(final List<Peer> peers) {
return !peers.stream().allMatch(new HashSet<>()::add);
private boolean addNode(final EnodeURL enodeURL) {
return nodesWhitelist.add(enodeURL);
}
public NodesWhitelistResult removeNodes(final List<Peer> peers) {
final NodesWhitelistResult inputValidationResult = validInput(peers);
public NodesWhitelistResult removeNodes(final List<String> enodeURLs) {
final NodesWhitelistResult inputValidationResult = validInput(enodeURLs);
if (inputValidationResult.result() != WhitelistOperationResult.SUCCESS) {
return inputValidationResult;
}
final List<EnodeURL> peers = enodeURLs.stream().map(EnodeURL::new).collect(Collectors.toList());
for (Peer peer : peers) {
for (EnodeURL peer : peers) {
if (!(nodesWhitelist.contains(peer))) {
return new NodesWhitelistResult(
WhitelistOperationResult.ERROR_ABSENT_ENTRY,
String.format("Specified peer: %s does not exist in whitelist.", peer.getId()));
String.format("Specified peer: %s does not exist in whitelist.", peer.getNodeId()));
}
}
final List<Peer> oldWhitelist = new ArrayList<>(this.nodesWhitelist);
final List<EnodeURL> oldWhitelist = new ArrayList<>(this.nodesWhitelist);
peers.forEach(this::removeNode);
final NodesWhitelistResult updateConfigFileResult = updateWhitelistInConfigFile(oldWhitelist);
if (updateConfigFileResult.result() != WhitelistOperationResult.SUCCESS) {
return updateConfigFileResult;
}
return new NodesWhitelistResult(WhitelistOperationResult.SUCCESS);
}
private boolean removeNode(final EnodeURL enodeURL) {
return nodesWhitelist.remove(enodeURL);
}
private NodesWhitelistResult updateWhitelistInConfigFile(final List<EnodeURL> oldWhitelist) {
try {
verifyConfigurationFileState(peerToEnodeURI(oldWhitelist));
updateConfigurationFile(peerToEnodeURI(nodesWhitelist));
@ -131,10 +127,11 @@ public class NodeWhitelistController {
} catch (WhitelistFileSyncException e) {
return new NodesWhitelistResult(WhitelistOperationResult.ERROR_WHITELIST_FILE_SYNC);
}
return new NodesWhitelistResult(WhitelistOperationResult.SUCCESS);
}
private NodesWhitelistResult validInput(final List<Peer> peers) {
private NodesWhitelistResult validInput(final List<String> peers) {
if (peers == null || peers.isEmpty()) {
return new NodesWhitelistResult(
WhitelistOperationResult.ERROR_EMPTY_ENTRY, String.format("Null/empty peers list"));
@ -149,6 +146,10 @@ public class NodeWhitelistController {
return new NodesWhitelistResult(WhitelistOperationResult.SUCCESS);
}
private boolean peerListHasDuplicates(final List<String> peers) {
return !peers.stream().allMatch(new HashSet<>()::add);
}
private void verifyConfigurationFileState(final Collection<String> oldNodes)
throws IOException, WhitelistFileSyncException {
whitelistPersistor.verifyConfigFileMatchesState(
@ -159,40 +160,41 @@ public class NodeWhitelistController {
whitelistPersistor.updateConfig(WhitelistPersistor.WHITELIST_TYPE.NODES, nodes);
}
private void revertState(final List<Peer> nodesWhitelist) {
private void revertState(final List<EnodeURL> nodesWhitelist) {
this.nodesWhitelist = nodesWhitelist;
}
private Collection<String> peerToEnodeURI(final Collection<Peer> peers) {
return peers.parallelStream().map(Peer::getEnodeURI).collect(Collectors.toList());
private Collection<String> peerToEnodeURI(final Collection<EnodeURL> peers) {
return peers.parallelStream().map(EnodeURL::toString).collect(Collectors.toList());
}
public boolean isPermitted(final String enodeURL) {
return isPermitted(new EnodeURL(enodeURL));
}
public boolean isPermitted(final Peer node) {
private boolean isPermitted(final EnodeURL node) {
return nodesWhitelist.stream()
.anyMatch(
p -> {
boolean idsMatch = node.getId().equals(p.getId());
boolean hostsMatch = node.getEndpoint().getHost().equals(p.getEndpoint().getHost());
boolean udpPortsMatch =
node.getEndpoint().getUdpPort() == p.getEndpoint().getUdpPort();
boolean idsMatch = node.getNodeId().equals(p.getNodeId());
boolean hostsMatch = node.getIp().equals(p.getIp());
boolean udpPortsMatch = node.getListeningPort().equals(p.getListeningPort());
boolean tcpPortsMatchIfPresent = true;
if (node.getEndpoint().getTcpPort().isPresent()
&& p.getEndpoint().getTcpPort().isPresent()) {
if (node.getDiscoveryPort().isPresent() && p.getDiscoveryPort().isPresent()) {
tcpPortsMatchIfPresent =
node.getEndpoint().getTcpPort().getAsInt()
== p.getEndpoint().getTcpPort().getAsInt();
node.getDiscoveryPort().getAsInt() == p.getDiscoveryPort().getAsInt();
}
return idsMatch && hostsMatch && udpPortsMatch && tcpPortsMatchIfPresent;
});
}
public List<Peer> getNodesWhitelist() {
return nodesWhitelist;
public List<String> getNodesWhitelist() {
return nodesWhitelist.stream().map(Object::toString).collect(Collectors.toList());
}
public synchronized void reload() throws RuntimeException {
final List<Peer> currentAccountsList = new ArrayList<>(nodesWhitelist);
final List<EnodeURL> currentAccountsList = new ArrayList<>(nodesWhitelist);
nodesWhitelist.clear();
try {

@ -10,7 +10,7 @@
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package tech.pegasys.pantheon.ethereum.p2p.permissioning;
package tech.pegasys.pantheon.ethereum.permissioning;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
@ -22,15 +22,9 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import static tech.pegasys.pantheon.ethereum.p2p.permissioning.NodeWhitelistController.NodesWhitelistResult;
import static tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController.NodesWhitelistResult;
import tech.pegasys.pantheon.ethereum.p2p.peers.DefaultPeer;
import tech.pegasys.pantheon.ethereum.p2p.peers.Peer;
import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration;
import tech.pegasys.pantheon.ethereum.permissioning.WhitelistFileSyncException;
import tech.pegasys.pantheon.ethereum.permissioning.WhitelistOperationResult;
import tech.pegasys.pantheon.ethereum.permissioning.WhitelistPersistor;
import tech.pegasys.pantheon.util.bytes.BytesValue;
import tech.pegasys.pantheon.util.enode.EnodeURL;
import java.io.IOException;
import java.net.URI;
@ -67,13 +61,11 @@ public class NodeWhitelistControllerTest {
@Test
public void whenAddNodesInputHasExistingNodeShouldReturnAddErrorExistingEntry() {
controller.addNode(DefaultPeer.fromURI(enode1));
controller.addNodes(Arrays.asList(enode1));
NodesWhitelistResult expected =
new NodesWhitelistResult(WhitelistOperationResult.ERROR_EXISTING_ENTRY);
NodesWhitelistResult actualResult =
controller.addNodes(
Lists.newArrayList(DefaultPeer.fromURI(enode1), DefaultPeer.fromURI(enode2)));
NodesWhitelistResult actualResult = controller.addNodes(Lists.newArrayList(enode1, enode2));
assertThat(actualResult).isEqualToComparingOnlyGivenFields(expected, "result");
}
@ -83,9 +75,7 @@ public class NodeWhitelistControllerTest {
NodesWhitelistResult expected =
new NodesWhitelistResult(WhitelistOperationResult.ERROR_DUPLICATED_ENTRY);
NodesWhitelistResult actualResult =
controller.addNodes(
Arrays.asList(DefaultPeer.fromURI(enode1), DefaultPeer.fromURI(enode1)));
NodesWhitelistResult actualResult = controller.addNodes(Arrays.asList(enode1, enode1));
assertThat(actualResult).isEqualToComparingOnlyGivenFields(expected, "result");
}
@ -112,9 +102,7 @@ public class NodeWhitelistControllerTest {
public void whenRemoveNodesInputHasAbsentNodeShouldReturnRemoveErrorAbsentEntry() {
NodesWhitelistResult expected =
new NodesWhitelistResult(WhitelistOperationResult.ERROR_ABSENT_ENTRY);
NodesWhitelistResult actualResult =
controller.removeNodes(
Lists.newArrayList(DefaultPeer.fromURI(enode1), DefaultPeer.fromURI(enode2)));
NodesWhitelistResult actualResult = controller.removeNodes(Lists.newArrayList(enode1, enode2));
assertThat(actualResult).isEqualToComparingOnlyGivenFields(expected, "result");
}
@ -123,9 +111,7 @@ public class NodeWhitelistControllerTest {
public void whenRemoveNodesInputHasDuplicateNodesShouldReturnErrorDuplicatedEntry() {
NodesWhitelistResult expected =
new NodesWhitelistResult(WhitelistOperationResult.ERROR_DUPLICATED_ENTRY);
NodesWhitelistResult actualResult =
controller.removeNodes(
Lists.newArrayList(DefaultPeer.fromURI(enode1), DefaultPeer.fromURI(enode1)));
NodesWhitelistResult actualResult = controller.removeNodes(Lists.newArrayList(enode1, enode1));
assertThat(actualResult).isEqualToComparingOnlyGivenFields(expected, "result");
}
@ -150,103 +136,60 @@ public class NodeWhitelistControllerTest {
@Test
public void whenNodeIdsAreDifferentItShouldNotBePermitted() {
Peer peer1 =
new DefaultPeer(
BytesValue.fromHexString(
"0xaaaa80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0"),
"127.0.0.1",
30303);
Peer peer2 =
new DefaultPeer(
BytesValue.fromHexString(
"0xbbba80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0"),
"127.0.0.1",
30303);
controller.addNode(peer1);
String peer1 =
"enode://aaaa80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@127.0.0.1:30303";
String peer2 =
"enode://bbbb80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@127.0.0.1:30303";
controller.addNodes(Arrays.asList(peer1));
assertThat(controller.isPermitted(peer2)).isFalse();
}
@Test
public void whenNodesHostsAreDifferentItShouldNotBePermitted() {
Peer peer1 =
new DefaultPeer(
BytesValue.fromHexString(
"0xaaaa80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0"),
"127.0.0.1",
30303);
Peer peer2 =
new DefaultPeer(
BytesValue.fromHexString(
"0xaaaa80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0"),
"127.0.0.2",
30303);
controller.addNode(peer1);
String peer1 =
"enode://aaaa80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@127.0.0.1:30303";
String peer2 =
"enode://aaaa80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@127.0.0.2:30303";
controller.addNodes(Arrays.asList(peer1));
assertThat(controller.isPermitted(peer2)).isFalse();
}
@Test
public void whenNodesUdpPortsAreDifferentItShouldNotBePermitted() {
Peer peer1 =
new DefaultPeer(
BytesValue.fromHexString(
"0xaaaa80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0"),
"127.0.0.1",
30301);
Peer peer2 =
new DefaultPeer(
BytesValue.fromHexString(
"0xaaaa80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0"),
"127.0.0.1",
30302);
controller.addNode(peer1);
String peer1 =
"enode://aaaa80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@127.0.0.1:30301";
String peer2 =
"enode://aaaa80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@127.0.0.1:30302";
controller.addNodes(Arrays.asList(peer1));
assertThat(controller.isPermitted(peer2)).isFalse();
}
@Test
public void whenCheckingIfNodeIsPermittedTcpPortShouldNotBeConsideredIfAbsent() {
Peer peerWithTcpPortSet =
new DefaultPeer(
BytesValue.fromHexString(
"0x6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0"),
"127.0.0.1",
30303,
10001);
Peer peerWithoutTcpPortSet =
new DefaultPeer(
BytesValue.fromHexString(
"0x6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0"),
"127.0.0.1",
30303);
controller.addNode(peerWithoutTcpPortSet);
assertThat(controller.isPermitted(peerWithTcpPortSet)).isTrue();
String peerWithTcpPortSet =
"enode://aaaa80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@127.0.0.1:30303?discport=10001";
String peerWithoutTcpPortSet =
"enode://aaaa80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@127.0.0.1:30303";
controller.addNodes(Arrays.asList(peerWithTcpPortSet));
assertThat(controller.isPermitted(peerWithoutTcpPortSet)).isTrue();
}
@Test
public void whenCheckingIfNodeIsPermittedTcpPortShouldBeConsideredIfPresent() {
Peer peerWithTcpPortSet =
new DefaultPeer(
BytesValue.fromHexString(
"0x6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0"),
"127.0.0.1",
30303,
10001);
Peer peerWithDifferentTcpPortSet =
new DefaultPeer(
BytesValue.fromHexString(
"0x6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0"),
"127.0.0.1",
30303,
10002);
controller.addNode(peerWithDifferentTcpPortSet);
String peerWithTcpPortSet =
"enode://aaaa80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@127.0.0.1:30303?discport=10001";
String peerWithDifferentTcpPortSet =
"enode://aaaa80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@127.0.0.1:30303?discport=10002";
controller.addNodes(Arrays.asList(peerWithDifferentTcpPortSet));
assertThat(controller.isPermitted(peerWithTcpPortSet)).isFalse();
}
@ -254,8 +197,8 @@ public class NodeWhitelistControllerTest {
@Test
public void stateShouldRevertIfWhitelistPersistFails()
throws IOException, WhitelistFileSyncException {
List<Peer> newNode1 = singletonList(DefaultPeer.fromURI(enode1));
List<Peer> newNode2 = singletonList(DefaultPeer.fromURI(enode2));
List<String> newNode1 = singletonList(new EnodeURL(enode1).toString());
List<String> newNode2 = singletonList(new EnodeURL(enode2).toString());
assertThat(controller.getNodesWhitelist().size()).isEqualTo(0);
@ -289,8 +232,7 @@ public class NodeWhitelistControllerTest {
controller.reload();
assertThat(controller.getNodesWhitelist())
.containsExactly(DefaultPeer.fromURI(expectedEnodeURL));
assertThat(controller.getNodesWhitelist()).containsExactly(expectedEnodeURL);
}
@Test
@ -311,8 +253,7 @@ public class NodeWhitelistControllerTest {
.isInstanceOf(RuntimeException.class)
.hasMessageContaining("Unable to read permissions TOML config file");
assertThat(controller.getNodesWhitelist())
.containsExactly(DefaultPeer.fromURI(expectedEnodeURI));
assertThat(controller.getNodesWhitelist()).containsExactly(expectedEnodeURI);
}
private Path createPermissionsFileWithNode(final String node) throws IOException {

@ -49,10 +49,10 @@ import tech.pegasys.pantheon.ethereum.p2p.config.RlpxConfiguration;
import tech.pegasys.pantheon.ethereum.p2p.config.SubProtocolConfiguration;
import tech.pegasys.pantheon.ethereum.p2p.netty.NettyP2PNetwork;
import tech.pegasys.pantheon.ethereum.p2p.peers.PeerBlacklist;
import tech.pegasys.pantheon.ethereum.p2p.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.ethereum.p2p.wire.Capability;
import tech.pegasys.pantheon.ethereum.p2p.wire.SubProtocol;
import tech.pegasys.pantheon.ethereum.permissioning.AccountWhitelistController;
import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController;
import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration;
import tech.pegasys.pantheon.ethereum.privacy.PrivateTransactionHandler;
import tech.pegasys.pantheon.ethereum.worldstate.WorldStateArchive;

@ -143,6 +143,22 @@ public class EnodeURL {
return value.contains("discport");
}
public String getNodeId() {
return nodeId;
}
public String getIp() {
return ip;
}
public Integer getListeningPort() {
return listeningPort;
}
public OptionalInt getDiscoveryPort() {
return discoveryPort;
}
@Override
public boolean equals(final Object o) {
if (this == o) {
@ -162,4 +178,9 @@ public class EnodeURL {
public int hashCode() {
return Objects.hashCode(nodeId, ip, listeningPort, discoveryPort);
}
@Override
public String toString() {
return this.toURI().toString();
}
}

Loading…
Cancel
Save