diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java index 1a1df67164..8ceba60b15 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/PantheonNode.java @@ -23,7 +23,7 @@ import tech.pegasys.pantheon.ethereum.core.Util; import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration; -import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration; +import tech.pegasys.pantheon.ethereum.permissioning.LocalPermissioningConfiguration; import tech.pegasys.pantheon.metrics.prometheus.MetricsConfiguration; import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition; import tech.pegasys.pantheon.tests.acceptance.dsl.httptransaction.HttpRequestFactory; @@ -83,7 +83,7 @@ public class PantheonNode implements NodeConfiguration, RunnableNode, AutoClosea private final JsonRpcConfiguration jsonRpcConfiguration; private final WebSocketConfiguration webSocketConfiguration; private final MetricsConfiguration metricsConfiguration; - private final Optional permissioningConfiguration; + private final Optional permissioningConfiguration; private final GenesisConfigProvider genesisConfigProvider; private final boolean devMode; private final boolean discoveryEnabled; @@ -103,7 +103,7 @@ public PantheonNode( final JsonRpcConfiguration jsonRpcConfiguration, final WebSocketConfiguration webSocketConfiguration, final MetricsConfiguration metricsConfiguration, - final Optional permissioningConfiguration, + final Optional permissioningConfiguration, final boolean devMode, final GenesisConfigProvider genesisConfigProvider, final boolean p2pEnabled, @@ -472,7 +472,7 @@ public boolean isDiscoveryEnabled() { return discoveryEnabled; } - Optional getPermissioningConfiguration() { + Optional getPermissioningConfiguration() { return permissioningConfiguration; } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonFactoryConfiguration.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonFactoryConfiguration.java index 0bd5366bb2..0c693e8983 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonFactoryConfiguration.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonFactoryConfiguration.java @@ -16,7 +16,7 @@ import tech.pegasys.pantheon.ethereum.core.PrivacyParameters; import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration; -import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration; +import tech.pegasys.pantheon.ethereum.permissioning.LocalPermissioningConfiguration; import tech.pegasys.pantheon.metrics.prometheus.MetricsConfiguration; import tech.pegasys.pantheon.tests.acceptance.dsl.node.GenesisConfigProvider; @@ -30,7 +30,7 @@ class PantheonFactoryConfiguration { private final JsonRpcConfiguration jsonRpcConfiguration; private final WebSocketConfiguration webSocketConfiguration; private final MetricsConfiguration metricsConfiguration; - private final Optional permissioningConfiguration; + private final Optional permissioningConfiguration; private final boolean devMode; private final GenesisConfigProvider genesisConfigProvider; private final boolean p2pEnabled; @@ -44,7 +44,7 @@ class PantheonFactoryConfiguration { final JsonRpcConfiguration jsonRpcConfiguration, final WebSocketConfiguration webSocketConfiguration, final MetricsConfiguration metricsConfiguration, - final Optional permissioningConfiguration, + final Optional permissioningConfiguration, final boolean devMode, final GenesisConfigProvider genesisConfigProvider, final boolean p2pEnabled, @@ -88,7 +88,7 @@ public MetricsConfiguration getMetricsConfiguration() { return metricsConfiguration; } - public Optional getPermissioningConfiguration() { + public Optional getPermissioningConfiguration() { return permissioningConfiguration; } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonFactoryConfigurationBuilder.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonFactoryConfigurationBuilder.java index 2955af4126..4ce1c83bfd 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonFactoryConfigurationBuilder.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonFactoryConfigurationBuilder.java @@ -20,7 +20,7 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration; import tech.pegasys.pantheon.ethereum.jsonrpc.RpcApis; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration; -import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration; +import tech.pegasys.pantheon.ethereum.permissioning.LocalPermissioningConfiguration; import tech.pegasys.pantheon.metrics.prometheus.MetricsConfiguration; import tech.pegasys.pantheon.tests.acceptance.dsl.node.GenesisConfigProvider; @@ -38,7 +38,7 @@ public class PantheonFactoryConfigurationBuilder { private JsonRpcConfiguration jsonRpcConfiguration = JsonRpcConfiguration.createDefault(); private WebSocketConfiguration webSocketConfiguration = WebSocketConfiguration.createDefault(); private MetricsConfiguration metricsConfiguration = MetricsConfiguration.createDefault(); - private Optional permissioningConfiguration = Optional.empty(); + private Optional permissioningConfiguration = Optional.empty(); private boolean devMode = true; private GenesisConfigProvider genesisConfigProvider = ignore -> Optional.empty(); private Boolean p2pEnabled = true; @@ -137,7 +137,7 @@ public PantheonFactoryConfigurationBuilder webSocketAuthenticationEnabled() } public PantheonFactoryConfigurationBuilder setPermissioningConfiguration( - final PermissioningConfiguration permissioningConfiguration) { + final LocalPermissioningConfiguration permissioningConfiguration) { this.permissioningConfiguration = Optional.of(permissioningConfiguration); return this; } diff --git a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonNodeFactory.java b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonNodeFactory.java index 1615c50f20..a3f50f93d4 100644 --- a/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonNodeFactory.java +++ b/acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/factory/PantheonNodeFactory.java @@ -26,7 +26,7 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.RpcApi; import tech.pegasys.pantheon.ethereum.jsonrpc.RpcApis; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration; -import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration; +import tech.pegasys.pantheon.ethereum.permissioning.LocalPermissioningConfiguration; import tech.pegasys.pantheon.ethereum.permissioning.WhitelistPersistor; import tech.pegasys.pantheon.ethereum.permissioning.WhitelistPersistor.WHITELIST_TYPE; import tech.pegasys.pantheon.tests.acceptance.dsl.node.GenesisConfigProvider; @@ -183,8 +183,8 @@ public PantheonNode createNodeWithWhitelistsEnabled( final List accountsWhitelist, final String tempFilePath) throws IOException { - final PermissioningConfiguration permissioningConfiguration = - PermissioningConfiguration.createDefault(); + final LocalPermissioningConfiguration permissioningConfiguration = + LocalPermissioningConfiguration.createDefault(); permissioningConfiguration.setNodeWhitelist(nodesWhitelist); permissioningConfiguration.setAccountWhitelist(accountsWhitelist); permissioningConfiguration.setConfigurationFilePath(tempFilePath); @@ -204,8 +204,8 @@ public PantheonNode createNodeWithNodesWhitelist( public PantheonNode createNodeWithNodesWhitelist( final String name, final List nodesWhitelist) throws IOException { - final PermissioningConfiguration permissioningConfiguration = - PermissioningConfiguration.createDefault(); + final LocalPermissioningConfiguration permissioningConfiguration = + LocalPermissioningConfiguration.createDefault(); permissioningConfiguration.setNodeWhitelist(nodesWhitelist); final List whitelistAsStrings = @@ -241,8 +241,8 @@ private void initPermissioningConfigurationFile( public PantheonNode createNodeWithAccountsWhitelist( final String name, final List accountsWhitelist) throws IOException { - final PermissioningConfiguration permissioningConfiguration = - PermissioningConfiguration.createDefault(); + final LocalPermissioningConfiguration permissioningConfiguration = + LocalPermissioningConfiguration.createDefault(); permissioningConfiguration.setAccountWhitelist(accountsWhitelist); permissioningConfiguration.setConfigurationFilePath( createTempPermissioningConfigurationFile().getPath()); diff --git a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermAddNodesToWhitelist.java b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermAddNodesToWhitelist.java index 51a21043fd..651e6491a1 100644 --- a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermAddNodesToWhitelist.java +++ b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermAddNodesToWhitelist.java @@ -22,7 +22,7 @@ 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.permissioning.NodeWhitelistController; +import tech.pegasys.pantheon.ethereum.permissioning.NodeLocalConfigPermissioningController; import java.util.List; @@ -50,7 +50,7 @@ public JsonRpcResponse response(final JsonRpcRequest req) { if (p2pNetwork.getNodeWhitelistController().isPresent()) { try { final List enodeURLs = enodeListParam.getStringList(); - final NodeWhitelistController.NodesWhitelistResult nodesWhitelistResult = + final NodeLocalConfigPermissioningController.NodesWhitelistResult nodesWhitelistResult = p2pNetwork.getNodeWhitelistController().get().addNodes(enodeURLs); switch (nodesWhitelistResult.result()) { diff --git a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermReloadPermissionsFromFile.java b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermReloadPermissionsFromFile.java index 3026d75dfd..be7618cc33 100644 --- a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermReloadPermissionsFromFile.java +++ b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermReloadPermissionsFromFile.java @@ -19,18 +19,18 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcResponse; import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcSuccessResponse; import tech.pegasys.pantheon.ethereum.permissioning.AccountWhitelistController; -import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController; +import tech.pegasys.pantheon.ethereum.permissioning.NodeLocalConfigPermissioningController; import java.util.Optional; public class PermReloadPermissionsFromFile implements JsonRpcMethod { private final Optional accountWhitelistController; - private final Optional nodesWhitelistController; + private final Optional nodesWhitelistController; public PermReloadPermissionsFromFile( final Optional accountWhitelistController, - final Optional nodesWhitelistController) { + final Optional nodesWhitelistController) { this.accountWhitelistController = accountWhitelistController; this.nodesWhitelistController = nodesWhitelistController; } @@ -48,7 +48,7 @@ public JsonRpcResponse response(final JsonRpcRequest request) { try { accountWhitelistController.ifPresent(AccountWhitelistController::reload); - nodesWhitelistController.ifPresent(NodeWhitelistController::reload); + nodesWhitelistController.ifPresent(NodeLocalConfigPermissioningController::reload); return new JsonRpcSuccessResponse(request.getId()); } catch (Exception e) { return new JsonRpcErrorResponse(request.getId(), JsonRpcError.WHITELIST_RELOAD_ERROR); diff --git a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermRemoveNodesFromWhitelist.java b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermRemoveNodesFromWhitelist.java index 6985e9fc6e..b2eada6223 100644 --- a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermRemoveNodesFromWhitelist.java +++ b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermRemoveNodesFromWhitelist.java @@ -22,7 +22,7 @@ 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.permissioning.NodeWhitelistController; +import tech.pegasys.pantheon.ethereum.permissioning.NodeLocalConfigPermissioningController; import java.util.List; @@ -50,7 +50,7 @@ public JsonRpcResponse response(final JsonRpcRequest req) { if (p2pNetwork.getNodeWhitelistController().isPresent()) { try { final List enodeURLs = enodeListParam.getStringList(); - final NodeWhitelistController.NodesWhitelistResult nodesWhitelistResult = + final NodeLocalConfigPermissioningController.NodesWhitelistResult nodesWhitelistResult = p2pNetwork.getNodeWhitelistController().get().removeNodes(enodeURLs); switch (nodesWhitelistResult.result()) { diff --git a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermAddNodesToWhitelistTest.java b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermAddNodesToWhitelistTest.java index 57fa202a3f..315dc14e54 100644 --- a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermAddNodesToWhitelistTest.java +++ b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermAddNodesToWhitelistTest.java @@ -19,7 +19,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; -import static tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController.NodesWhitelistResult; +import static tech.pegasys.pantheon.ethereum.permissioning.NodeLocalConfigPermissioningController.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.JsonRpcSuccessResponse; import tech.pegasys.pantheon.ethereum.p2p.P2pDisabledException; import tech.pegasys.pantheon.ethereum.p2p.api.P2PNetwork; -import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController; +import tech.pegasys.pantheon.ethereum.permissioning.NodeLocalConfigPermissioningController; import tech.pegasys.pantheon.ethereum.permissioning.WhitelistOperationResult; import java.util.ArrayList; @@ -58,7 +58,7 @@ public class PermAddNodesToWhitelistTest { private final String badEnode = "enod://dog@cat:fish"; @Mock private P2PNetwork p2pNetwork; - @Mock private NodeWhitelistController nodeWhitelistController; + @Mock private NodeLocalConfigPermissioningController nodeLocalConfigPermissioningController; private JsonRpcParameter params = new JsonRpcParameter(); @@ -79,8 +79,10 @@ public void shouldThrowInvalidJsonRpcParametersExceptionWhenOnlyBadEnode() { 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); + when(p2pNetwork.getNodeWhitelistController()) + .thenReturn(Optional.of(nodeLocalConfigPermissioningController)); + when(nodeLocalConfigPermissioningController.addNodes(eq(enodeList))) + .thenThrow(IllegalArgumentException.class); final JsonRpcResponse actual = method.response(request); @@ -94,8 +96,10 @@ public void shouldThrowInvalidJsonRpcParametersExceptionWhenBadEnodeInList() { 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); + when(p2pNetwork.getNodeWhitelistController()) + .thenReturn(Optional.of(nodeLocalConfigPermissioningController)); + when(nodeLocalConfigPermissioningController.addNodes(eq(enodeList))) + .thenThrow(IllegalArgumentException.class); final JsonRpcResponse actual = method.response(request); @@ -108,8 +112,9 @@ public void shouldThrowInvalidJsonRpcParametersExceptionWhenEmptyEnode() { final JsonRpcResponse expected = new JsonRpcErrorResponse(request.getId(), JsonRpcError.NODE_WHITELIST_EMPTY_ENTRY); - when(p2pNetwork.getNodeWhitelistController()).thenReturn(Optional.of(nodeWhitelistController)); - when(nodeWhitelistController.addNodes(eq(Lists.emptyList()))) + when(p2pNetwork.getNodeWhitelistController()) + .thenReturn(Optional.of(nodeLocalConfigPermissioningController)); + when(nodeLocalConfigPermissioningController.addNodes(eq(Lists.emptyList()))) .thenReturn(new NodesWhitelistResult(WhitelistOperationResult.ERROR_EMPTY_ENTRY)); final JsonRpcResponse actual = method.response(request); @@ -123,8 +128,9 @@ public void whenRequestContainsDuplicatedNodesShouldReturnDuplicatedEntryError() final JsonRpcResponse expected = new JsonRpcErrorResponse(request.getId(), JsonRpcError.NODE_WHITELIST_DUPLICATED_ENTRY); - when(p2pNetwork.getNodeWhitelistController()).thenReturn(Optional.of(nodeWhitelistController)); - when(nodeWhitelistController.addNodes(any())) + when(p2pNetwork.getNodeWhitelistController()) + .thenReturn(Optional.of(nodeLocalConfigPermissioningController)); + when(nodeLocalConfigPermissioningController.addNodes(any())) .thenReturn(new NodesWhitelistResult(WhitelistOperationResult.ERROR_DUPLICATED_ENTRY)); final JsonRpcResponse actual = method.response(request); @@ -138,8 +144,9 @@ public void whenRequestContainsEmptyListOfNodesShouldReturnEmptyEntryError() { final JsonRpcResponse expected = new JsonRpcErrorResponse(request.getId(), JsonRpcError.NODE_WHITELIST_EMPTY_ENTRY); - when(p2pNetwork.getNodeWhitelistController()).thenReturn(Optional.of(nodeWhitelistController)); - when(nodeWhitelistController.addNodes(eq(new ArrayList<>()))) + when(p2pNetwork.getNodeWhitelistController()) + .thenReturn(Optional.of(nodeLocalConfigPermissioningController)); + when(nodeLocalConfigPermissioningController.addNodes(eq(new ArrayList<>()))) .thenReturn(new NodesWhitelistResult(WhitelistOperationResult.ERROR_EMPTY_ENTRY)); final JsonRpcResponse actual = method.response(request); @@ -152,16 +159,17 @@ public void shouldAddSingleValidNode() { final JsonRpcRequest request = buildRequest(Lists.newArrayList(enode1)); final JsonRpcResponse expected = new JsonRpcSuccessResponse(request.getId()); - when(p2pNetwork.getNodeWhitelistController()).thenReturn(Optional.of(nodeWhitelistController)); - when(nodeWhitelistController.addNodes(any())) + when(p2pNetwork.getNodeWhitelistController()) + .thenReturn(Optional.of(nodeLocalConfigPermissioningController)); + when(nodeLocalConfigPermissioningController.addNodes(any())) .thenReturn(new NodesWhitelistResult(WhitelistOperationResult.SUCCESS)); final JsonRpcResponse actual = method.response(request); assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected); - verify(nodeWhitelistController, times(1)).addNodes(any()); - verifyNoMoreInteractions(nodeWhitelistController); + verify(nodeLocalConfigPermissioningController, times(1)).addNodes(any()); + verifyNoMoreInteractions(nodeLocalConfigPermissioningController); } @Test @@ -169,16 +177,17 @@ public void shouldAddMultipleValidNodes() { final JsonRpcRequest request = buildRequest(Lists.newArrayList(enode1, enode2, enode3)); final JsonRpcResponse expected = new JsonRpcSuccessResponse(request.getId()); - when(p2pNetwork.getNodeWhitelistController()).thenReturn(Optional.of(nodeWhitelistController)); - when(nodeWhitelistController.addNodes(any())) + when(p2pNetwork.getNodeWhitelistController()) + .thenReturn(Optional.of(nodeLocalConfigPermissioningController)); + when(nodeLocalConfigPermissioningController.addNodes(any())) .thenReturn(new NodesWhitelistResult(WhitelistOperationResult.SUCCESS)); final JsonRpcResponse actual = method.response(request); assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected); - verify(nodeWhitelistController, times(1)).addNodes(any()); - verifyNoMoreInteractions(nodeWhitelistController); + verify(nodeLocalConfigPermissioningController, times(1)).addNodes(any()); + verifyNoMoreInteractions(nodeLocalConfigPermissioningController); } @Test diff --git a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermGetNodesWhitelistTest.java b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermGetNodesWhitelistTest.java index a6f57bcff6..ac649c854f 100644 --- a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermGetNodesWhitelistTest.java +++ b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermGetNodesWhitelistTest.java @@ -25,7 +25,7 @@ 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.permissioning.NodeWhitelistController; +import tech.pegasys.pantheon.ethereum.permissioning.NodeLocalConfigPermissioningController; import java.util.List; import java.util.Optional; @@ -51,7 +51,7 @@ public class PermGetNodesWhitelistTest { "enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.12:4567"; @Mock private P2PNetwork p2pNetwork; - @Mock private NodeWhitelistController nodeWhitelistController; + @Mock private NodeLocalConfigPermissioningController nodeLocalConfigPermissioningController; @Before public void setUp() { @@ -69,16 +69,17 @@ public void shouldReturnSuccessResponseWhenListPopulated() { final JsonRpcResponse expected = new JsonRpcSuccessResponse(request.getId(), Lists.newArrayList(enode1, enode2, enode3)); - when(p2pNetwork.getNodeWhitelistController()).thenReturn(Optional.of(nodeWhitelistController)); - when(nodeWhitelistController.getNodesWhitelist()) + when(p2pNetwork.getNodeWhitelistController()) + .thenReturn(Optional.of(nodeLocalConfigPermissioningController)); + when(nodeLocalConfigPermissioningController.getNodesWhitelist()) .thenReturn(buildNodesList(enode1, enode2, enode3)); final JsonRpcResponse actual = method.response(request); assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected); - verify(nodeWhitelistController, times(1)).getNodesWhitelist(); - verifyNoMoreInteractions(nodeWhitelistController); + verify(nodeLocalConfigPermissioningController, times(1)).getNodesWhitelist(); + verifyNoMoreInteractions(nodeLocalConfigPermissioningController); } @Test @@ -87,15 +88,15 @@ public void shouldReturnSuccessResponseWhenListSetAndEmpty() { final JsonRpcResponse expected = new JsonRpcSuccessResponse(request.getId(), Lists.emptyList()); when(p2pNetwork.getNodeWhitelistController()) - .thenReturn(java.util.Optional.of(nodeWhitelistController)); - when(nodeWhitelistController.getNodesWhitelist()).thenReturn(buildNodesList()); + .thenReturn(java.util.Optional.of(nodeLocalConfigPermissioningController)); + when(nodeLocalConfigPermissioningController.getNodesWhitelist()).thenReturn(buildNodesList()); final JsonRpcResponse actual = method.response(request); assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected); - verify(nodeWhitelistController, times(1)).getNodesWhitelist(); - verifyNoMoreInteractions(nodeWhitelistController); + verify(nodeLocalConfigPermissioningController, times(1)).getNodesWhitelist(); + verifyNoMoreInteractions(nodeLocalConfigPermissioningController); } @Test diff --git a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermReloadPermissionsFromFileTest.java b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermReloadPermissionsFromFileTest.java index 4f5aeadcfb..b6868569a5 100644 --- a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermReloadPermissionsFromFileTest.java +++ b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermReloadPermissionsFromFileTest.java @@ -22,7 +22,7 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcResponse; import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcSuccessResponse; import tech.pegasys.pantheon.ethereum.permissioning.AccountWhitelistController; -import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController; +import tech.pegasys.pantheon.ethereum.permissioning.NodeLocalConfigPermissioningController; import java.util.Optional; @@ -36,14 +36,15 @@ public class PermReloadPermissionsFromFileTest { @Mock private AccountWhitelistController accountWhitelistController; - @Mock private NodeWhitelistController nodeWhitelistController; + @Mock private NodeLocalConfigPermissioningController nodeLocalConfigPermissioningController; private PermReloadPermissionsFromFile method; @Before public void before() { method = new PermReloadPermissionsFromFile( - Optional.of(accountWhitelistController), Optional.of(nodeWhitelistController)); + Optional.of(accountWhitelistController), + Optional.of(nodeLocalConfigPermissioningController)); } @Test @@ -68,7 +69,7 @@ public void whenControllersReloadSucceedsMethodShouldReturnSuccess() { JsonRpcResponse response = method.response(reloadRequest()); verify(accountWhitelistController).reload(); - verify(nodeWhitelistController).reload(); + verify(nodeLocalConfigPermissioningController).reload(); assertThat(response).isEqualToComparingFieldByField(successResponse()); } diff --git a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermRemoveNodesFromWhitelistTest.java b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermRemoveNodesFromWhitelistTest.java index 632727f89d..61c5dd9b28 100644 --- a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermRemoveNodesFromWhitelistTest.java +++ b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/permissioning/PermRemoveNodesFromWhitelistTest.java @@ -19,7 +19,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; -import static tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController.NodesWhitelistResult; +import static tech.pegasys.pantheon.ethereum.permissioning.NodeLocalConfigPermissioningController.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.JsonRpcSuccessResponse; import tech.pegasys.pantheon.ethereum.p2p.P2pDisabledException; import tech.pegasys.pantheon.ethereum.p2p.api.P2PNetwork; -import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController; +import tech.pegasys.pantheon.ethereum.permissioning.NodeLocalConfigPermissioningController; import tech.pegasys.pantheon.ethereum.permissioning.WhitelistOperationResult; import java.util.ArrayList; @@ -58,13 +58,14 @@ public class PermRemoveNodesFromWhitelistTest { private final String badEnode = "enod://dog@cat:fish"; @Mock private P2PNetwork p2pNetwork; - @Mock NodeWhitelistController nodeWhitelistController; + @Mock NodeLocalConfigPermissioningController nodeLocalConfigPermissioningController; private JsonRpcParameter params = new JsonRpcParameter(); @Before public void setUp() { - when(p2pNetwork.getNodeWhitelistController()).thenReturn(Optional.of(nodeWhitelistController)); + when(p2pNetwork.getNodeWhitelistController()) + .thenReturn(Optional.of(nodeLocalConfigPermissioningController)); method = new PermRemoveNodesFromWhitelist(p2pNetwork, params); } @@ -79,7 +80,7 @@ public void shouldThrowInvalidJsonRpcParametersExceptionWhenBadEnode() { final JsonRpcResponse expected = new JsonRpcErrorResponse(request.getId(), JsonRpcError.NODE_WHITELIST_INVALID_ENTRY); - when(nodeWhitelistController.removeNodes(eq(Lists.newArrayList(badEnode)))) + when(nodeLocalConfigPermissioningController.removeNodes(eq(Lists.newArrayList(badEnode)))) .thenThrow(IllegalArgumentException.class); final JsonRpcResponse actual = method.response(request); @@ -93,7 +94,7 @@ public void shouldThrowInvalidJsonRpcParametersExceptionWhenEmptyList() { final JsonRpcResponse expected = new JsonRpcErrorResponse(request.getId(), JsonRpcError.NODE_WHITELIST_EMPTY_ENTRY); - when(nodeWhitelistController.removeNodes(eq(Lists.emptyList()))) + when(nodeLocalConfigPermissioningController.removeNodes(eq(Lists.emptyList()))) .thenReturn(new NodesWhitelistResult(WhitelistOperationResult.ERROR_EMPTY_ENTRY)); final JsonRpcResponse actual = method.response(request); @@ -106,15 +107,15 @@ public void shouldRemoveSingleValidNode() { final JsonRpcRequest request = buildRequest(Lists.newArrayList(enode1)); final JsonRpcResponse expected = new JsonRpcSuccessResponse(request.getId()); - when(nodeWhitelistController.removeNodes(any())) + when(nodeLocalConfigPermissioningController.removeNodes(any())) .thenReturn(new NodesWhitelistResult(WhitelistOperationResult.SUCCESS)); final JsonRpcResponse actual = method.response(request); assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected); - verify(nodeWhitelistController, times(1)).removeNodes(any()); - verifyNoMoreInteractions(nodeWhitelistController); + verify(nodeLocalConfigPermissioningController, times(1)).removeNodes(any()); + verifyNoMoreInteractions(nodeLocalConfigPermissioningController); } @Test @@ -122,15 +123,15 @@ public void shouldRemoveMultipleValidNodes() { final JsonRpcRequest request = buildRequest(Lists.newArrayList(enode1, enode2, enode3)); final JsonRpcResponse expected = new JsonRpcSuccessResponse(request.getId()); - when(nodeWhitelistController.removeNodes(any())) + when(nodeLocalConfigPermissioningController.removeNodes(any())) .thenReturn(new NodesWhitelistResult(WhitelistOperationResult.SUCCESS)); final JsonRpcResponse actual = method.response(request); assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected); - verify(nodeWhitelistController, times(1)).removeNodes(any()); - verifyNoMoreInteractions(nodeWhitelistController); + verify(nodeLocalConfigPermissioningController, times(1)).removeNodes(any()); + verifyNoMoreInteractions(nodeLocalConfigPermissioningController); } @Test @@ -151,7 +152,7 @@ public void whenRequestContainsDuplicatedNodesShouldReturnDuplicatedEntryError() final JsonRpcResponse expected = new JsonRpcErrorResponse(request.getId(), JsonRpcError.NODE_WHITELIST_DUPLICATED_ENTRY); - when(nodeWhitelistController.removeNodes(any())) + when(nodeLocalConfigPermissioningController.removeNodes(any())) .thenReturn(new NodesWhitelistResult(WhitelistOperationResult.ERROR_DUPLICATED_ENTRY)); final JsonRpcResponse actual = method.response(request); @@ -165,7 +166,7 @@ public void whenRequestContainsEmptyListOfNodesShouldReturnEmptyEntryError() { final JsonRpcResponse expected = new JsonRpcErrorResponse(request.getId(), JsonRpcError.NODE_WHITELIST_EMPTY_ENTRY); - when(nodeWhitelistController.removeNodes(eq(new ArrayList<>()))) + when(nodeLocalConfigPermissioningController.removeNodes(eq(new ArrayList<>()))) .thenReturn(new NodesWhitelistResult(WhitelistOperationResult.ERROR_EMPTY_ENTRY)); final JsonRpcResponse actual = method.response(request); @@ -180,7 +181,7 @@ public void shouldReturnCantRemoveBootnodeWhenRemovingBootnode() { new JsonRpcErrorResponse( request.getId(), JsonRpcError.NODE_WHITELIST_BOOTNODE_CANNOT_BE_REMOVED); - when(nodeWhitelistController.removeNodes(any())) + when(nodeLocalConfigPermissioningController.removeNodes(any())) .thenReturn( new NodesWhitelistResult(WhitelistOperationResult.ERROR_BOOTNODE_CANNOT_BE_REMOVED)); diff --git a/ethereum/mock-p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/testing/MockNetwork.java b/ethereum/mock-p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/testing/MockNetwork.java index b271f006cc..ebbfe6a030 100644 --- a/ethereum/mock-p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/testing/MockNetwork.java +++ b/ethereum/mock-p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/testing/MockNetwork.java @@ -23,7 +23,7 @@ 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.ethereum.permissioning.NodeLocalConfigPermissioningController; import tech.pegasys.pantheon.util.Subscribers; import java.net.SocketAddress; @@ -204,7 +204,7 @@ public boolean isP2pEnabled() { } @Override - public Optional getNodeWhitelistController() { + public Optional getNodeWhitelistController() { return Optional.empty(); } } diff --git a/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/NoopP2PNetwork.java b/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/NoopP2PNetwork.java index 5c183806a7..ba234f46c5 100644 --- a/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/NoopP2PNetwork.java +++ b/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/NoopP2PNetwork.java @@ -19,7 +19,7 @@ import tech.pegasys.pantheon.ethereum.p2p.peers.Peer; import tech.pegasys.pantheon.ethereum.p2p.wire.Capability; import tech.pegasys.pantheon.ethereum.p2p.wire.PeerInfo; -import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController; +import tech.pegasys.pantheon.ethereum.permissioning.NodeLocalConfigPermissioningController; import java.io.IOException; import java.util.Collection; @@ -82,7 +82,7 @@ public boolean isP2pEnabled() { } @Override - public Optional getNodeWhitelistController() { + public Optional getNodeWhitelistController() { return Optional.empty(); } diff --git a/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/api/P2PNetwork.java b/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/api/P2PNetwork.java index ab02c38113..b40b5c822f 100644 --- a/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/api/P2PNetwork.java +++ b/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/api/P2PNetwork.java @@ -15,7 +15,7 @@ import tech.pegasys.pantheon.ethereum.p2p.peers.Peer; import tech.pegasys.pantheon.ethereum.p2p.wire.Capability; import tech.pegasys.pantheon.ethereum.p2p.wire.PeerInfo; -import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController; +import tech.pegasys.pantheon.ethereum.permissioning.NodeLocalConfigPermissioningController; import java.io.Closeable; import java.util.Collection; @@ -114,7 +114,7 @@ public interface P2PNetwork extends Closeable { /** * Returns the node whitelist controller * - * @return an instance of NodeWhitelistController, if set. + * @return an instance of NodeLocalConfigPermissioningController, if set. */ - Optional getNodeWhitelistController(); + Optional getNodeWhitelistController(); } diff --git a/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryAgent.java b/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryAgent.java index 44b66ca12a..a0af74bbb7 100644 --- a/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryAgent.java +++ b/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryAgent.java @@ -34,7 +34,7 @@ import tech.pegasys.pantheon.ethereum.p2p.peers.Endpoint; import tech.pegasys.pantheon.ethereum.p2p.peers.PeerBlacklist; import tech.pegasys.pantheon.ethereum.p2p.wire.messages.DisconnectMessage; -import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController; +import tech.pegasys.pantheon.ethereum.permissioning.NodeLocalConfigPermissioningController; import tech.pegasys.pantheon.util.NetworkUtility; import tech.pegasys.pantheon.util.Subscribers; import tech.pegasys.pantheon.util.bytes.BytesValue; @@ -70,7 +70,7 @@ public abstract class PeerDiscoveryAgent implements DisconnectCallback { protected final List bootstrapPeers; private final PeerRequirement peerRequirement; private final PeerBlacklist peerBlacklist; - private final Optional nodeWhitelistController; + private final Optional nodeWhitelistController; /* The peer controller, which takes care of the state machine of peers. */ protected Optional controller = Optional.empty(); @@ -93,7 +93,7 @@ public PeerDiscoveryAgent( final DiscoveryConfiguration config, final PeerRequirement peerRequirement, final PeerBlacklist peerBlacklist, - final Optional nodeWhitelistController) { + final Optional nodeWhitelistController) { checkArgument(keyPair != null, "keypair cannot be null"); checkArgument(config != null, "provided configuration cannot be null"); diff --git a/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/VertxPeerDiscoveryAgent.java b/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/VertxPeerDiscoveryAgent.java index 3fd7e6caf4..76bd818a8d 100644 --- a/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/VertxPeerDiscoveryAgent.java +++ b/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/VertxPeerDiscoveryAgent.java @@ -24,7 +24,7 @@ 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.permissioning.NodeWhitelistController; +import tech.pegasys.pantheon.ethereum.permissioning.NodeLocalConfigPermissioningController; import tech.pegasys.pantheon.util.NetworkUtility; import tech.pegasys.pantheon.util.Preconditions; @@ -58,7 +58,7 @@ public VertxPeerDiscoveryAgent( final DiscoveryConfiguration config, final PeerRequirement peerRequirement, final PeerBlacklist peerBlacklist, - final Optional nodeWhitelistController) { + final Optional nodeWhitelistController) { super(keyPair, config, peerRequirement, peerBlacklist, nodeWhitelistController); checkArgument(vertx != null, "vertx instance cannot be null"); this.vertx = vertx; diff --git a/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/internal/PeerDiscoveryController.java b/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/internal/PeerDiscoveryController.java index 8f6745956a..08bbf31112 100644 --- a/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/internal/PeerDiscoveryController.java +++ b/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/internal/PeerDiscoveryController.java @@ -29,7 +29,7 @@ import tech.pegasys.pantheon.ethereum.p2p.discovery.internal.PeerTable.EvictResult.EvictOutcome; import tech.pegasys.pantheon.ethereum.p2p.peers.Peer; import tech.pegasys.pantheon.ethereum.p2p.peers.PeerBlacklist; -import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController; +import tech.pegasys.pantheon.ethereum.permissioning.NodeLocalConfigPermissioningController; import tech.pegasys.pantheon.ethereum.permissioning.node.NodePermissioningController; import tech.pegasys.pantheon.ethereum.permissioning.node.NodeWhitelistUpdatedEvent; import tech.pegasys.pantheon.util.Subscribers; @@ -117,7 +117,7 @@ public class PeerDiscoveryController { private final DiscoveryPeer localPeer; private final OutboundMessageHandler outboundMessageHandler; private final PeerBlacklist peerBlacklist; - private final Optional nodeWhitelistController; + private final Optional nodeWhitelistController; private RetryDelayFunction retryDelayFunction = RetryDelayFunction.linear(1.5, 2000, 60000); @@ -150,7 +150,7 @@ public PeerDiscoveryController( final long tableRefreshIntervalMs, final PeerRequirement peerRequirement, final PeerBlacklist peerBlacklist, - final Optional nodeWhitelistController, + final Optional nodeWhitelistController, final Subscribers> peerBondedObservers, final Subscribers> peerDroppedObservers) { this.timerUtil = timerUtil; diff --git a/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/internal/RecursivePeerRefreshState.java b/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/internal/RecursivePeerRefreshState.java index 5930464de8..330908266a 100644 --- a/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/internal/RecursivePeerRefreshState.java +++ b/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/internal/RecursivePeerRefreshState.java @@ -17,7 +17,7 @@ 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.permissioning.NodeWhitelistController; +import tech.pegasys.pantheon.ethereum.permissioning.NodeLocalConfigPermissioningController; import tech.pegasys.pantheon.util.bytes.BytesValue; import java.util.List; @@ -39,7 +39,7 @@ public class RecursivePeerRefreshState { private static final int MAX_CONCURRENT_REQUESTS = 3; private BytesValue target; private final PeerBlacklist peerBlacklist; - private final Optional peerWhitelist; + private final Optional peerWhitelist; private final PeerTable peerTable; private final BytesValue localPeerId; @@ -59,7 +59,7 @@ public class RecursivePeerRefreshState { RecursivePeerRefreshState( final PeerBlacklist peerBlacklist, - final Optional peerWhitelist, + final Optional peerWhitelist, final BondingAgent bondingAgent, final FindNeighbourDispatcher neighborFinder, final TimerUtil timerUtil, diff --git a/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/netty/NettyP2PNetwork.java b/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/netty/NettyP2PNetwork.java index a85c3b7e12..222c6bce02 100644 --- a/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/netty/NettyP2PNetwork.java +++ b/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/netty/NettyP2PNetwork.java @@ -37,7 +37,7 @@ 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.NodeLocalConfigPermissioningController; import tech.pegasys.pantheon.ethereum.permissioning.node.NodePermissioningController; import tech.pegasys.pantheon.metrics.Counter; import tech.pegasys.pantheon.metrics.LabelledMetric; @@ -161,9 +161,8 @@ public class NettyP2PNetwork implements P2PNetwork { private final LabelledMetric outboundMessagesCounter; - private final Optional nodeWhitelistController; - private final Optional nodePermissioningController; + private final Optional nodeWhitelistController; private final Optional blockchain; private OptionalLong blockAddedObserverId = OptionalLong.empty(); @@ -175,7 +174,7 @@ public NettyP2PNetwork( final PeerRequirement peerRequirement, final PeerBlacklist peerBlacklist, final MetricsSystem metricsSystem, - final Optional nodeWhitelistController) { + final Optional nodeWhitelistController) { this( vertx, keyPair, @@ -203,7 +202,7 @@ public NettyP2PNetwork( * @param peerBlacklist The peers with which this node will not connect * @param peerRequirement Queried to determine if enough peers are currently connected. * @param metricsSystem The metrics system to capture metrics with. - * @param nodeWhitelistController Controls the whitelist of nodes to which this node will connect. + * @param nodeLocalConfigPermissioningController local file config for permissioning * @param nodePermissioningController Controls node permissioning. * @param blockchain The blockchain to subscribe to BlockAddedEvents. */ @@ -215,13 +214,13 @@ public NettyP2PNetwork( final PeerRequirement peerRequirement, final PeerBlacklist peerBlacklist, final MetricsSystem metricsSystem, - final Optional nodeWhitelistController, + final Optional nodeLocalConfigPermissioningController, final NodePermissioningController nodePermissioningController, final Blockchain blockchain) { connections = new PeerConnectionRegistry(metricsSystem); this.peerBlacklist = peerBlacklist; - this.nodeWhitelistController = nodeWhitelistController; + this.nodePermissioningController = Optional.ofNullable(nodePermissioningController); this.peerMaintainConnectionList = new HashSet<>(); peerDiscoveryAgent = new VertxPeerDiscoveryAgent( @@ -230,7 +229,7 @@ public NettyP2PNetwork( config.getDiscovery(), peerRequirement, peerBlacklist, - nodeWhitelistController); + nodeLocalConfigPermissioningController); outboundMessagesCounter = metricsSystem.createLabelledCounter( @@ -301,7 +300,7 @@ public NettyP2PNetwork( throw new RuntimeException("Interrupted before startup completed", e); } - this.nodePermissioningController = Optional.ofNullable(nodePermissioningController); + this.nodeWhitelistController = nodeLocalConfigPermissioningController; this.blockchain = Optional.ofNullable(blockchain); } @@ -649,7 +648,7 @@ public boolean isP2pEnabled() { } @Override - public Optional getNodeWhitelistController() { + public Optional getNodeWhitelistController() { return nodeWhitelistController; } diff --git a/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/NettyP2PNetworkTest.java b/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/NettyP2PNetworkTest.java index ea45205b44..f69308d203 100644 --- a/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/NettyP2PNetworkTest.java +++ b/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/NettyP2PNetworkTest.java @@ -47,8 +47,8 @@ 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.ethereum.permissioning.LocalPermissioningConfiguration; +import tech.pegasys.pantheon.ethereum.permissioning.NodeLocalConfigPermissioningController; import tech.pegasys.pantheon.ethereum.permissioning.node.NodePermissioningController; import tech.pegasys.pantheon.metrics.noop.NoOpMetricsSystem; import tech.pegasys.pantheon.util.bytes.BytesValue; @@ -89,6 +89,10 @@ public final class NettyP2PNetworkTest { private final Vertx vertx = Vertx.vertx(); + private final String selfEnodeString = + "enode://5f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.10:1111"; + private final EnodeURL selfEnode = new EnodeURL(selfEnodeString); + @Before public void before() { when(blockchain.observeBlockAdded(observerCaptor.capture())).thenReturn(1L); @@ -441,13 +445,13 @@ public void rejectIncomingConnectionFromNonWhitelistedPeer() throws Exception { final BytesValue localId = localKp.getPublicKey().getEncodedBytes(); final PeerBlacklist localBlacklist = new PeerBlacklist(); final PeerBlacklist remoteBlacklist = new PeerBlacklist(); - final PermissioningConfiguration config = PermissioningConfiguration.createDefault(); + final LocalPermissioningConfiguration config = LocalPermissioningConfiguration.createDefault(); final Path tempFile = Files.createTempFile("test", "test"); tempFile.toFile().deleteOnExit(); config.setConfigurationFilePath(tempFile.toAbsolutePath().toString()); - final NodeWhitelistController localWhitelistController = - new NodeWhitelistController(config, Collections.emptyList()); + final NodeLocalConfigPermissioningController localWhitelistController = + new NodeLocalConfigPermissioningController(config, Collections.emptyList(), selfEnode); // turn on whitelisting by adding a different node NOT remote node localWhitelistController.addNodes(Arrays.asList(mockPeer().getEnodeURI())); diff --git a/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryTestHelper.java b/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryTestHelper.java index 9426d03480..ca76f971c2 100644 --- a/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryTestHelper.java +++ b/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryTestHelper.java @@ -23,7 +23,7 @@ import tech.pegasys.pantheon.ethereum.p2p.discovery.internal.PingPacketData; import tech.pegasys.pantheon.ethereum.p2p.peers.Peer; import tech.pegasys.pantheon.ethereum.p2p.peers.PeerBlacklist; -import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController; +import tech.pegasys.pantheon.ethereum.permissioning.NodeLocalConfigPermissioningController; import tech.pegasys.pantheon.util.bytes.BytesValue; import java.net.URI; @@ -173,7 +173,7 @@ public static class AgentBuilder { private final AtomicInteger nextAvailablePort; private PeerBlacklist blacklist = new PeerBlacklist(); - private Optional whitelist = Optional.empty(); + private Optional whitelist = Optional.empty(); private List bootstrapPeers = Collections.emptyList(); private boolean active = true; @@ -197,7 +197,8 @@ private List asEnodes(final List peers) { return peers.stream().map(Peer::getEnodeURI).map(URI::create).collect(Collectors.toList()); } - public AgentBuilder whiteList(final Optional whitelist) { + public AgentBuilder whiteList( + final Optional whitelist) { this.whitelist = whitelist; return this; } diff --git a/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/internal/MockPeerDiscoveryAgent.java b/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/internal/MockPeerDiscoveryAgent.java index 65728fecbf..a394be814d 100644 --- a/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/internal/MockPeerDiscoveryAgent.java +++ b/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/internal/MockPeerDiscoveryAgent.java @@ -18,7 +18,7 @@ import tech.pegasys.pantheon.ethereum.p2p.discovery.PeerDiscoveryAgent; import tech.pegasys.pantheon.ethereum.p2p.discovery.internal.PeerDiscoveryController.AsyncExecutor; import tech.pegasys.pantheon.ethereum.p2p.peers.PeerBlacklist; -import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController; +import tech.pegasys.pantheon.ethereum.permissioning.NodeLocalConfigPermissioningController; import tech.pegasys.pantheon.util.bytes.BytesValue; import java.net.InetSocketAddress; @@ -40,7 +40,7 @@ public MockPeerDiscoveryAgent( final DiscoveryConfiguration config, final PeerRequirement peerRequirement, final PeerBlacklist peerBlacklist, - final Optional nodeWhitelistController, + final Optional nodeWhitelistController, final Map agentNetwork) { super(keyPair, config, peerRequirement, peerBlacklist, nodeWhitelistController); this.agentNetwork = agentNetwork; diff --git a/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/internal/PeerDiscoveryControllerTest.java b/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/internal/PeerDiscoveryControllerTest.java index 97307f012b..975bfe3f4f 100644 --- a/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/internal/PeerDiscoveryControllerTest.java +++ b/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/internal/PeerDiscoveryControllerTest.java @@ -40,12 +40,13 @@ 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.permissioning.NodeWhitelistController; -import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration; +import tech.pegasys.pantheon.ethereum.permissioning.LocalPermissioningConfiguration; +import tech.pegasys.pantheon.ethereum.permissioning.NodeLocalConfigPermissioningController; import tech.pegasys.pantheon.util.Subscribers; import tech.pegasys.pantheon.util.bytes.Bytes32; import tech.pegasys.pantheon.util.bytes.BytesValue; import tech.pegasys.pantheon.util.bytes.MutableBytesValue; +import tech.pegasys.pantheon.util.enode.EnodeURL; import tech.pegasys.pantheon.util.uint.UInt256; import tech.pegasys.pantheon.util.uint.UInt256Value; @@ -86,6 +87,9 @@ public class PeerDiscoveryControllerTest { private KeyPair localKeyPair; private final AtomicInteger counter = new AtomicInteger(1); private final PeerDiscoveryTestHelper helper = new PeerDiscoveryTestHelper(); + private final String selfEnodeString = + "enode://5f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.10:1111"; + private final EnodeURL selfEnode = new EnodeURL(selfEnodeString); @Before public void initializeMocks() { @@ -990,20 +994,20 @@ public void shouldNotBondWithNonWhitelistedPeer() throws IOException { final DiscoveryPeer otherPeer2 = peers.get(2); final PeerBlacklist blacklist = new PeerBlacklist(); - final PermissioningConfiguration config = permissioningConfigurationWithTempFile(); - final NodeWhitelistController nodeWhitelistController = - new NodeWhitelistController(config, Collections.emptyList()); + final LocalPermissioningConfiguration config = permissioningConfigurationWithTempFile(); + final NodeLocalConfigPermissioningController nodeLocalConfigPermissioningController = + new NodeLocalConfigPermissioningController(config, Collections.emptyList(), selfEnode); // Whitelist peers - nodeWhitelistController.addNodes(Arrays.asList(discoPeer.getEnodeURI())); - nodeWhitelistController.addNodes(Arrays.asList(otherPeer2.getEnodeURI())); + nodeLocalConfigPermissioningController.addNodes(Arrays.asList(discoPeer.getEnodeURI())); + nodeLocalConfigPermissioningController.addNodes(Arrays.asList(otherPeer2.getEnodeURI())); final OutboundMessageHandler outboundMessageHandler = mock(OutboundMessageHandler.class); controller = getControllerBuilder() .peers(discoPeer) .blacklist(blacklist) - .whitelist(nodeWhitelistController) + .whitelist(nodeLocalConfigPermissioningController) .outboundMessageHandler(outboundMessageHandler) .build(); @@ -1053,16 +1057,16 @@ public void shouldNotRespondToPingFromNonWhitelistedDiscoveryPeer() throws IOExc final PeerBlacklist blacklist = new PeerBlacklist(); // don't add disco peer to whitelist - PermissioningConfiguration config = permissioningConfigurationWithTempFile(); + LocalPermissioningConfiguration config = permissioningConfigurationWithTempFile(); config.setNodeWhitelist(new ArrayList<>()); - NodeWhitelistController nodeWhitelistController = - new NodeWhitelistController(config, Collections.emptyList()); + NodeLocalConfigPermissioningController nodeLocalConfigPermissioningController = + new NodeLocalConfigPermissioningController(config, Collections.emptyList(), selfEnode); controller = getControllerBuilder() .peers(discoPeer) .blacklist(blacklist) - .whitelist(nodeWhitelistController) + .whitelist(nodeLocalConfigPermissioningController) .build(); final Packet pingPacket = mockPingPacket(peers.get(0), localPeer); @@ -1078,17 +1082,20 @@ public void whenObservingNodeWhitelistAndNodeIsRemovedShouldEvictPeerFromPeerTab final DiscoveryPeer peer = peers.get(0); peerTableSpy.tryAdd(peer); - final PermissioningConfiguration config = permissioningConfigurationWithTempFile(); + final LocalPermissioningConfiguration config = permissioningConfigurationWithTempFile(); final URI peerURI = URI.create(peer.getEnodeURI()); config.setNodeWhitelist(Lists.newArrayList(peerURI)); - final NodeWhitelistController nodeWhitelistController = - new NodeWhitelistController(config, Collections.emptyList()); + final NodeLocalConfigPermissioningController nodeLocalConfigPermissioningController = + new NodeLocalConfigPermissioningController(config, Collections.emptyList(), selfEnode); controller = - getControllerBuilder().whitelist(nodeWhitelistController).peerTable(peerTableSpy).build(); + getControllerBuilder() + .whitelist(nodeLocalConfigPermissioningController) + .peerTable(peerTableSpy) + .build(); controller.start(); - nodeWhitelistController.removeNodes(Lists.newArrayList(peerURI.toString())); + nodeLocalConfigPermissioningController.removeNodes(Lists.newArrayList(peerURI.toString())); verify(peerTableSpy).tryEvict(eq(DiscoveryPeer.fromURI(peerURI))); } @@ -1102,11 +1109,11 @@ public void whenObservingNodeWhitelistAndNodeIsRemovedShouldNotifyPeerDroppedObs final DiscoveryPeer peer = peers.get(0); peerTableSpy.tryAdd(peer); - final PermissioningConfiguration config = permissioningConfigurationWithTempFile(); + final LocalPermissioningConfiguration config = permissioningConfigurationWithTempFile(); final URI peerURI = URI.create(peer.getEnodeURI()); config.setNodeWhitelist(Lists.newArrayList(peerURI)); - final NodeWhitelistController nodeWhitelistController = - new NodeWhitelistController(config, Collections.emptyList()); + final NodeLocalConfigPermissioningController nodeLocalConfigPermissioningController = + new NodeLocalConfigPermissioningController(config, Collections.emptyList(), selfEnode); final Consumer peerDroppedEventConsumer = mock(Consumer.class); final Subscribers> peerDroppedSubscribers = new Subscribers(); @@ -1116,13 +1123,13 @@ public void whenObservingNodeWhitelistAndNodeIsRemovedShouldNotifyPeerDroppedObs controller = getControllerBuilder() - .whitelist(nodeWhitelistController) + .whitelist(nodeLocalConfigPermissioningController) .peerTable(peerTableSpy) .peerDroppedObservers(peerDroppedSubscribers) .build(); controller.start(); - nodeWhitelistController.removeNodes(Lists.newArrayList(peerURI.toString())); + nodeLocalConfigPermissioningController.removeNodes(Lists.newArrayList(peerURI.toString())); ArgumentCaptor captor = ArgumentCaptor.forClass(PeerDroppedEvent.class); verify(peerDroppedEventConsumer).accept(captor.capture()); @@ -1209,8 +1216,9 @@ private PeerDiscoveryController startPeerDiscoveryController( return controller; } - private PermissioningConfiguration permissioningConfigurationWithTempFile() throws IOException { - final PermissioningConfiguration config = PermissioningConfiguration.createDefault(); + private LocalPermissioningConfiguration permissioningConfigurationWithTempFile() + throws IOException { + final LocalPermissioningConfiguration config = LocalPermissioningConfiguration.createDefault(); Path tempFile = Files.createTempFile("test", "test"); tempFile.toFile().deleteOnExit(); config.setConfigurationFilePath(tempFile.toAbsolutePath().toString()); @@ -1220,7 +1228,7 @@ private PermissioningConfiguration permissioningConfigurationWithTempFile() thro static class ControllerBuilder { private Collection discoPeers = Collections.emptyList(); private PeerBlacklist blacklist = new PeerBlacklist(); - private Optional whitelist = Optional.empty(); + private Optional whitelist = Optional.empty(); private MockTimerUtil timerUtil = new MockTimerUtil(); private KeyPair keypair; private DiscoveryPeer localPeer; @@ -1249,7 +1257,7 @@ ControllerBuilder blacklist(final PeerBlacklist blacklist) { return this; } - ControllerBuilder whitelist(final NodeWhitelistController whitelist) { + ControllerBuilder whitelist(final NodeLocalConfigPermissioningController whitelist) { this.whitelist = Optional.of(whitelist); return this; } diff --git a/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/internal/RecursivePeerRefreshStateTest.java b/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/internal/RecursivePeerRefreshStateTest.java index 89958391d0..12be9fcbe0 100644 --- a/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/internal/RecursivePeerRefreshStateTest.java +++ b/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/internal/RecursivePeerRefreshStateTest.java @@ -27,9 +27,10 @@ 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.permissioning.NodeWhitelistController; -import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration; +import tech.pegasys.pantheon.ethereum.permissioning.LocalPermissioningConfiguration; +import tech.pegasys.pantheon.ethereum.permissioning.NodeLocalConfigPermissioningController; import tech.pegasys.pantheon.util.bytes.BytesValue; +import tech.pegasys.pantheon.util.enode.EnodeURL; import java.nio.file.Files; import java.nio.file.Path; @@ -46,6 +47,9 @@ public class RecursivePeerRefreshStateTest { private final BondingAgent bondingAgent = mock(BondingAgent.class); private final FindNeighbourDispatcher neighborFinder = mock(FindNeighbourDispatcher.class); private final MockTimerUtil timerUtil = new MockTimerUtil(); + private final String selfEnodeString = + "enode://5f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.10:1111"; + private final EnodeURL selfEnode = new EnodeURL(selfEnodeString); private final DiscoveryPeer peer1 = new DiscoveryPeer(createId(1), "127.0.0.1", 1, 1); private final DiscoveryPeer peer2 = new DiscoveryPeer(createId(2), "127.0.0.2", 2, 2); @@ -483,12 +487,13 @@ public void shouldNotBondWithNodesRejectedByWhitelist() throws Exception { final Path tempFile = Files.createTempFile("test", "test"); tempFile.toFile().deleteOnExit(); - final PermissioningConfiguration permissioningConfiguration = - PermissioningConfiguration.createDefault(); + final LocalPermissioningConfiguration permissioningConfiguration = + LocalPermissioningConfiguration.createDefault(); permissioningConfiguration.setConfigurationFilePath(tempFile.toAbsolutePath().toString()); - final NodeWhitelistController peerWhitelist = - new NodeWhitelistController(permissioningConfiguration, Collections.emptyList()); + final NodeLocalConfigPermissioningController peerWhitelist = + new NodeLocalConfigPermissioningController( + permissioningConfiguration, Collections.emptyList(), selfEnode); peerWhitelist.addNodes(Arrays.asList(peerA.getEnodeURI())); recursivePeerRefreshState = diff --git a/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/AccountWhitelistController.java b/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/AccountWhitelistController.java index b1acdafc90..a1db791a32 100644 --- a/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/AccountWhitelistController.java +++ b/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/AccountWhitelistController.java @@ -28,22 +28,23 @@ public class AccountWhitelistController { private static final Logger LOG = LogManager.getLogger(); private static final int ACCOUNT_BYTES_SIZE = 20; - private PermissioningConfiguration configuration; + private LocalPermissioningConfiguration configuration; private List accountWhitelist = new ArrayList<>(); private final WhitelistPersistor whitelistPersistor; - public AccountWhitelistController(final PermissioningConfiguration configuration) { + public AccountWhitelistController(final LocalPermissioningConfiguration configuration) { this(configuration, new WhitelistPersistor(configuration.getConfigurationFilePath())); } public AccountWhitelistController( - final PermissioningConfiguration configuration, final WhitelistPersistor whitelistPersistor) { + final LocalPermissioningConfiguration configuration, + final WhitelistPersistor whitelistPersistor) { this.configuration = configuration; this.whitelistPersistor = whitelistPersistor; readAccountsFromConfig(configuration); } - private void readAccountsFromConfig(final PermissioningConfiguration configuration) { + private void readAccountsFromConfig(final LocalPermissioningConfiguration configuration) { if (configuration != null && configuration.isAccountWhitelistEnabled()) { if (!configuration.getAccountWhitelist().isEmpty()) { addAccounts(configuration.getAccountWhitelist()); @@ -166,8 +167,8 @@ public synchronized void reload() throws RuntimeException { accountWhitelist.clear(); try { - final PermissioningConfiguration updatedConfig = - PermissioningConfigurationBuilder.permissioningConfigurationFromToml( + final LocalPermissioningConfiguration updatedConfig = + PermissioningConfigurationBuilder.permissioningConfiguration( configuration.getConfigurationFilePath(), configuration.isNodeWhitelistEnabled(), configuration.isAccountWhitelistEnabled()); diff --git a/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/LocalPermissioningConfiguration.java b/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/LocalPermissioningConfiguration.java new file mode 100644 index 0000000000..a59fd03f9d --- /dev/null +++ b/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/LocalPermissioningConfiguration.java @@ -0,0 +1,71 @@ +/* + * Copyright 2018 ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * 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.permissioning; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class LocalPermissioningConfiguration { + private List nodeWhitelist; + private List accountWhitelist; + private boolean nodeWhitelistEnabled; + private boolean accountWhitelistEnabled; + private String configurationFilePath; + + public List getNodeWhitelist() { + return nodeWhitelist; + } + + public static LocalPermissioningConfiguration createDefault() { + final LocalPermissioningConfiguration config = new LocalPermissioningConfiguration(); + config.nodeWhitelist = new ArrayList<>(); + config.accountWhitelist = new ArrayList<>(); + return config; + } + + public void setNodeWhitelist(final Collection nodeWhitelist) { + if (nodeWhitelist != null) { + this.nodeWhitelist.addAll(nodeWhitelist); + this.nodeWhitelistEnabled = true; + } + } + + public boolean isNodeWhitelistEnabled() { + return nodeWhitelistEnabled; + } + + public List getAccountWhitelist() { + return accountWhitelist; + } + + public void setAccountWhitelist(final Collection accountWhitelist) { + if (accountWhitelist != null) { + this.accountWhitelist.addAll(accountWhitelist); + this.accountWhitelistEnabled = true; + } + } + + public boolean isAccountWhitelistEnabled() { + return accountWhitelistEnabled; + } + + public String getConfigurationFilePath() { + return configurationFilePath; + } + + public void setConfigurationFilePath(final String configurationFilePath) { + this.configurationFilePath = configurationFilePath; + } +} diff --git a/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/NodeWhitelistController.java b/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/NodeLocalConfigPermissioningController.java similarity index 87% rename from ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/NodeWhitelistController.java rename to ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/NodeLocalConfigPermissioningController.java index fe84edf241..b908a6b50c 100644 --- a/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/NodeWhitelistController.java +++ b/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/NodeLocalConfigPermissioningController.java @@ -12,6 +12,7 @@ */ package tech.pegasys.pantheon.ethereum.permissioning; +import tech.pegasys.pantheon.ethereum.permissioning.node.NodePermissioningProvider; import tech.pegasys.pantheon.ethereum.permissioning.node.NodeWhitelistUpdatedEvent; import tech.pegasys.pantheon.util.Subscribers; import tech.pegasys.pantheon.util.enode.EnodeURL; @@ -31,39 +32,45 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -public class NodeWhitelistController { +public class NodeLocalConfigPermissioningController implements NodePermissioningProvider { private static final Logger LOG = LogManager.getLogger(); - private PermissioningConfiguration configuration; + private LocalPermissioningConfiguration configuration; private final List bootnodes; + private final EnodeURL selfEnode; private final List nodesWhitelist = new ArrayList<>(); private final WhitelistPersistor whitelistPersistor; private final Subscribers> nodeWhitelistUpdatedObservers = new Subscribers<>(); - public NodeWhitelistController( - final PermissioningConfiguration permissioningConfiguration, final List bootnodes) { + public NodeLocalConfigPermissioningController( + final LocalPermissioningConfiguration permissioningConfiguration, + final List bootnodes, + final EnodeURL selfEnode) { this( permissioningConfiguration, bootnodes, + selfEnode, new WhitelistPersistor(permissioningConfiguration.getConfigurationFilePath())); } - public NodeWhitelistController( - final PermissioningConfiguration configuration, + public NodeLocalConfigPermissioningController( + final LocalPermissioningConfiguration configuration, final List bootnodes, + final EnodeURL selfEnode, final WhitelistPersistor whitelistPersistor) { this.configuration = configuration; this.bootnodes = bootnodes; + this.selfEnode = selfEnode; this.whitelistPersistor = whitelistPersistor; readNodesFromConfig(configuration); } - private void readNodesFromConfig(final PermissioningConfiguration configuration) { + private void readNodesFromConfig(final LocalPermissioningConfiguration configuration) { if (configuration.isNodeWhitelistEnabled() && configuration.getNodeWhitelist() != null) { for (URI uri : configuration.getNodeWhitelist()) { - nodesWhitelist.add(new EnodeURL(uri.toString())); + addNode(new EnodeURL(uri.toString())); } } } @@ -81,6 +88,13 @@ public NodesWhitelistResult addNodes(final List enodeURLs) { WhitelistOperationResult.ERROR_EXISTING_ENTRY, String.format("Specified peer: %s already exists in whitelist.", peer.getNodeId())); } + if (peer.equals(selfEnode)) { + return new NodesWhitelistResult( + WhitelistOperationResult.ERROR_SELF_CANNOT_BE_ADDED, + String.format( + "Specified peer %s is equal to self. Cannot add self to whitelist", + peer.getNodeId())); + } } final List oldWhitelist = new ArrayList<>(this.nodesWhitelist); @@ -96,7 +110,12 @@ public NodesWhitelistResult addNodes(final List enodeURLs) { } private boolean addNode(final EnodeURL enodeURL) { - return nodesWhitelist.add(enodeURL); + // must not add self to whitelist + if (!enodeURL.equals(selfEnode)) { + return nodesWhitelist.add(enodeURL); + } else { + return false; + } } public NodesWhitelistResult removeNodes(final List enodeURLs) { @@ -192,7 +211,7 @@ public boolean isPermitted(final String enodeURL) { return isPermitted(new EnodeURL(enodeURL)); } - private boolean isPermitted(final EnodeURL node) { + public boolean isPermitted(final EnodeURL node) { return nodesWhitelist.stream() .anyMatch( p -> { @@ -218,8 +237,8 @@ public synchronized void reload() throws RuntimeException { nodesWhitelist.clear(); try { - final PermissioningConfiguration updatedConfig = - PermissioningConfigurationBuilder.permissioningConfigurationFromToml( + final LocalPermissioningConfiguration updatedConfig = + PermissioningConfigurationBuilder.permissioningConfiguration( configuration.getConfigurationFilePath(), configuration.isNodeWhitelistEnabled(), configuration.isAccountWhitelistEnabled()); @@ -292,4 +311,9 @@ public Optional message() { return message; } } + + @Override + public boolean isPermitted(final EnodeURL sourceEnode, final EnodeURL destinationEnode) { + return isPermitted(sourceEnode) || isPermitted(destinationEnode); + } } diff --git a/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/NodePermissioningControllerFactory.java b/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/NodePermissioningControllerFactory.java new file mode 100644 index 0000000000..457bdbf04d --- /dev/null +++ b/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/NodePermissioningControllerFactory.java @@ -0,0 +1,69 @@ +/* + * Copyright 2019 ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * 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.permissioning; + +import tech.pegasys.pantheon.ethereum.core.Synchronizer; +import tech.pegasys.pantheon.ethereum.permissioning.node.NodePermissioningController; +import tech.pegasys.pantheon.ethereum.permissioning.node.NodePermissioningProvider; +import tech.pegasys.pantheon.ethereum.permissioning.node.provider.SyncStatusNodePermissioningProvider; +import tech.pegasys.pantheon.ethereum.transaction.TransactionSimulator; +import tech.pegasys.pantheon.util.enode.EnodeURL; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Optional; + +public class NodePermissioningControllerFactory { + + public NodePermissioningController create( + final PermissioningConfiguration permissioningConfiguration, + final Synchronizer synchronizer, + final Collection bootnodes, + final EnodeURL selfEnode, + final TransactionSimulator transactionSimulator) { + + Optional syncStatusProviderOptional; + + List providers = new ArrayList<>(); + if (permissioningConfiguration.getLocalConfig().isPresent()) { + LocalPermissioningConfiguration localPermissioningConfiguration = + permissioningConfiguration.getLocalConfig().get(); + if (localPermissioningConfiguration.isNodeWhitelistEnabled()) { + NodeLocalConfigPermissioningController localProvider = + new NodeLocalConfigPermissioningController( + localPermissioningConfiguration, new ArrayList<>(bootnodes), selfEnode); + providers.add(localProvider); + } + } + + if (permissioningConfiguration.getSmartContractConfig().isPresent()) { + SmartContractPermissioningConfiguration smartContractPermissioningConfiguration = + permissioningConfiguration.getSmartContractConfig().get(); + if (smartContractPermissioningConfiguration.isSmartContractNodeWhitelistEnabled()) { + SmartContractPermissioningController smartContractProvider = + new SmartContractPermissioningController( + smartContractPermissioningConfiguration.getSmartContractAddress(), + transactionSimulator); + providers.add(smartContractProvider); + } + + final SyncStatusNodePermissioningProvider syncStatusProvider = + new SyncStatusNodePermissioningProvider(synchronizer, bootnodes); + syncStatusProviderOptional = Optional.of(syncStatusProvider); + } else { + syncStatusProviderOptional = Optional.empty(); + } + return new NodePermissioningController(syncStatusProviderOptional, providers); + } +} diff --git a/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/PermissioningConfiguration.java b/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/PermissioningConfiguration.java index c38544e6c7..89abe7dc8c 100644 --- a/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/PermissioningConfiguration.java +++ b/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/PermissioningConfiguration.java @@ -12,60 +12,24 @@ */ package tech.pegasys.pantheon.ethereum.permissioning; -import java.net.URI; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; +import java.util.Optional; public class PermissioningConfiguration { - private List nodeWhitelist; - private List accountWhitelist; - private boolean nodeWhitelistEnabled; - private boolean accountWhitelistEnabled; - private String configurationFilePath; + private Optional localConfig; + private Optional smartContractConfig; - public List getNodeWhitelist() { - return nodeWhitelist; + public PermissioningConfiguration( + final Optional localConfig, + final Optional smartContractConfig) { + this.localConfig = localConfig; + this.smartContractConfig = smartContractConfig; } - public static PermissioningConfiguration createDefault() { - final PermissioningConfiguration config = new PermissioningConfiguration(); - config.nodeWhitelist = new ArrayList<>(); - config.accountWhitelist = new ArrayList<>(); - return config; + public Optional getLocalConfig() { + return localConfig; } - public void setNodeWhitelist(final Collection nodeWhitelist) { - if (nodeWhitelist != null) { - this.nodeWhitelist.addAll(nodeWhitelist); - this.nodeWhitelistEnabled = true; - } - } - - public boolean isNodeWhitelistEnabled() { - return nodeWhitelistEnabled; - } - - public List getAccountWhitelist() { - return accountWhitelist; - } - - public void setAccountWhitelist(final Collection accountWhitelist) { - if (accountWhitelist != null) { - this.accountWhitelist.addAll(accountWhitelist); - this.accountWhitelistEnabled = true; - } - } - - public boolean isAccountWhitelistEnabled() { - return accountWhitelistEnabled; - } - - public String getConfigurationFilePath() { - return configurationFilePath; - } - - public void setConfigurationFilePath(final String configurationFilePath) { - this.configurationFilePath = configurationFilePath; + public Optional getSmartContractConfig() { + return smartContractConfig; } } diff --git a/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/PermissioningConfigurationBuilder.java b/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/PermissioningConfigurationBuilder.java index f01bed504d..74cb9b0e92 100644 --- a/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/PermissioningConfigurationBuilder.java +++ b/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/PermissioningConfigurationBuilder.java @@ -12,6 +12,7 @@ */ package tech.pegasys.pantheon.ethereum.permissioning; +import tech.pegasys.pantheon.ethereum.core.Address; import tech.pegasys.pantheon.util.enode.EnodeURL; import java.net.URI; @@ -26,18 +27,16 @@ public class PermissioningConfigurationBuilder { public static final String ACCOUNTS_WHITELIST = "accounts-whitelist"; public static final String NODES_WHITELIST = "nodes-whitelist"; - // will be used to reload the config from a file while node is running - public static PermissioningConfiguration permissioningConfigurationFromToml( - final String configFilePath, - final boolean permissionedNodeEnabled, - final boolean permissionedAccountEnabled) - throws Exception { - - return permissioningConfiguration( - configFilePath, permissionedNodeEnabled, permissionedAccountEnabled); + public static SmartContractPermissioningConfiguration smartContractPermissioningConfiguration( + final Address address, final boolean smartContractPermissionedNodeEnabled) { + SmartContractPermissioningConfiguration config = new SmartContractPermissioningConfiguration(); + config.setSmartContractAddress(address); + config.setSmartContractNodeWhitelistEnabled(smartContractPermissionedNodeEnabled); + return config; } - public static PermissioningConfiguration permissioningConfiguration( + // will be used to reload the config from a file while node is running + public static LocalPermissioningConfiguration permissioningConfiguration( final String configFilePath, final boolean permissionedNodeEnabled, final boolean permissionedAccountEnabled) @@ -55,8 +54,8 @@ public static PermissioningConfiguration permissioningConfiguration( TomlArray accountWhitelistTomlArray = permToml.getArray(ACCOUNTS_WHITELIST); TomlArray nodeWhitelistTomlArray = permToml.getArray(NODES_WHITELIST); - final PermissioningConfiguration permissioningConfiguration = - PermissioningConfiguration.createDefault(); + final LocalPermissioningConfiguration permissioningConfiguration = + LocalPermissioningConfiguration.createDefault(); permissioningConfiguration.setConfigurationFilePath(configFilePath); if (permissionedAccountEnabled) { if (accountWhitelistTomlArray != null) { diff --git a/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/SmartContractPermissioningConfiguration.java b/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/SmartContractPermissioningConfiguration.java new file mode 100644 index 0000000000..9c9a0a4b59 --- /dev/null +++ b/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/SmartContractPermissioningConfiguration.java @@ -0,0 +1,37 @@ +/* + * Copyright 2018 ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * 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.permissioning; + +import tech.pegasys.pantheon.ethereum.core.Address; + +public class SmartContractPermissioningConfiguration { + private boolean smartContractNodeWhitelistEnabled; + private Address smartContractAddress; + + public boolean isSmartContractNodeWhitelistEnabled() { + return smartContractNodeWhitelistEnabled; + } + + public void setSmartContractNodeWhitelistEnabled( + final boolean smartContractNodeWhitelistEnabled) { + this.smartContractNodeWhitelistEnabled = smartContractNodeWhitelistEnabled; + } + + public Address getSmartContractAddress() { + return smartContractAddress; + } + + public void setSmartContractAddress(final Address smartContractAddress) { + this.smartContractAddress = smartContractAddress; + } +} diff --git a/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/WhitelistOperationResult.java b/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/WhitelistOperationResult.java index 6ada2a5bae..cc86edfe3d 100644 --- a/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/WhitelistOperationResult.java +++ b/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/WhitelistOperationResult.java @@ -20,6 +20,7 @@ public enum WhitelistOperationResult { ERROR_INVALID_ENTRY, ERROR_ABSENT_ENTRY, ERROR_BOOTNODE_CANNOT_BE_REMOVED, + ERROR_SELF_CANNOT_BE_ADDED, ERROR_WHITELIST_PERSIST_FAIL, ERROR_WHITELIST_FILE_SYNC } diff --git a/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/node/NodePermissioningController.java b/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/node/NodePermissioningController.java index 7bcd57680a..ce1bf9b87e 100644 --- a/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/node/NodePermissioningController.java +++ b/ethereum/permissioning/src/main/java/tech/pegasys/pantheon/ethereum/permissioning/node/NodePermissioningController.java @@ -15,8 +15,10 @@ import tech.pegasys.pantheon.ethereum.permissioning.node.provider.SyncStatusNodePermissioningProvider; import tech.pegasys.pantheon.util.enode.EnodeURL; +import java.util.List; import java.util.Optional; +import com.google.common.annotations.VisibleForTesting; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -25,26 +27,43 @@ public class NodePermissioningController { private static final Logger LOG = LogManager.getLogger(); private final Optional syncStatusNodePermissioningProvider; + private List providers; public NodePermissioningController( - final SyncStatusNodePermissioningProvider syncStatusNodePermissioningProvider) { - this.syncStatusNodePermissioningProvider = Optional.of(syncStatusNodePermissioningProvider); - } - - public NodePermissioningController() { - this.syncStatusNodePermissioningProvider = Optional.empty(); + final Optional syncStatusNodePermissioningProvider, + final List providers) { + this.providers = providers; + this.syncStatusNodePermissioningProvider = syncStatusNodePermissioningProvider; } public boolean isPermitted(final EnodeURL sourceEnode, final EnodeURL destinationEnode) { LOG.trace("Checking node permission: {} -> {}", sourceEnode, destinationEnode); - return syncStatusNodePermissioningProvider - .map((provider) -> provider.isPermitted(sourceEnode, destinationEnode)) - .orElse(true); + if (syncStatusNodePermissioningProvider.isPresent() + && !syncStatusNodePermissioningProvider.get().isPermitted(sourceEnode, destinationEnode)) { + return false; + } else { + for (NodePermissioningProvider provider : providers) { + if (!provider.isPermitted(sourceEnode, destinationEnode)) { + return false; + } + } + } + return true; } public void startPeerDiscoveryCallback(final Runnable peerDiscoveryCallback) { syncStatusNodePermissioningProvider.ifPresent( (p) -> p.setHasReachedSyncCallback(peerDiscoveryCallback)); } + + @VisibleForTesting + Optional getSyncStatusNodePermissioningProvider() { + return syncStatusNodePermissioningProvider; + } + + @VisibleForTesting + List getProviders() { + return providers; + } } diff --git a/ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/AccountWhitelistControllerTest.java b/ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/AccountWhitelistControllerTest.java index 4823617af5..4f1bff5b64 100644 --- a/ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/AccountWhitelistControllerTest.java +++ b/ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/AccountWhitelistControllerTest.java @@ -40,7 +40,7 @@ public class AccountWhitelistControllerTest { private AccountWhitelistController controller; - @Mock private PermissioningConfiguration permissioningConfig; + @Mock private LocalPermissioningConfiguration permissioningConfig; @Mock private WhitelistPersistor whitelistPersistor; @Before diff --git a/ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/PermissioningConfigurationBuilderTest.java b/ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/LocalPermissioningConfigurationBuilderTest.java similarity index 93% rename from ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/PermissioningConfigurationBuilderTest.java rename to ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/LocalPermissioningConfigurationBuilderTest.java index a6208535af..5b35588651 100644 --- a/ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/PermissioningConfigurationBuilderTest.java +++ b/ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/LocalPermissioningConfigurationBuilderTest.java @@ -26,7 +26,7 @@ import com.google.common.io.Resources; import org.junit.Test; -public class PermissioningConfigurationBuilderTest { +public class LocalPermissioningConfigurationBuilderTest { private static final String PERMISSIONING_CONFIG_VALID = "permissioning_config.toml"; private static final String PERMISSIONING_CONFIG_ACCOUNT_WHITELIST_ONLY = @@ -57,7 +57,7 @@ public void permissioningConfig() throws Exception { final URL configFile = Resources.getResource(PERMISSIONING_CONFIG_VALID); final Path toml = createTempFile("toml", Resources.toByteArray(configFile)); - PermissioningConfiguration permissioningConfiguration = permissioningConfig(toml); + LocalPermissioningConfiguration permissioningConfiguration = permissioningConfig(toml); assertThat(permissioningConfiguration.isAccountWhitelistEnabled()).isTrue(); assertThat(permissioningConfiguration.getAccountWhitelist()) @@ -74,7 +74,7 @@ public void permissioningConfigWithOnlyNodeWhitelistSet() throws Exception { final URL configFile = Resources.getResource(PERMISSIONING_CONFIG_NODE_WHITELIST_ONLY); final Path toml = createTempFile("toml", Resources.toByteArray(configFile)); - PermissioningConfiguration permissioningConfiguration = + LocalPermissioningConfiguration permissioningConfiguration = PermissioningConfigurationBuilder.permissioningConfiguration( toml.toAbsolutePath().toString(), true, false); @@ -88,7 +88,7 @@ public void permissioningConfigWithOnlyAccountWhitelistSet() throws Exception { final URL configFile = Resources.getResource(PERMISSIONING_CONFIG_ACCOUNT_WHITELIST_ONLY); final Path toml = createTempFile("toml", Resources.toByteArray(configFile)); - PermissioningConfiguration permissioningConfiguration = + LocalPermissioningConfiguration permissioningConfiguration = PermissioningConfigurationBuilder.permissioningConfiguration( toml.toAbsolutePath().toString(), false, true); @@ -127,7 +127,7 @@ public void permissioningConfigWithEmptyWhitelistMustNotError() throws Exception final URL configFile = Resources.getResource(PERMISSIONING_CONFIG_EMPTY_WHITELISTS); final Path toml = createTempFile("toml", Resources.toByteArray(configFile)); - PermissioningConfiguration permissioningConfiguration = permissioningConfig(toml); + LocalPermissioningConfiguration permissioningConfiguration = permissioningConfig(toml); assertThat(permissioningConfiguration.isNodeWhitelistEnabled()).isTrue(); assertThat(permissioningConfiguration.getNodeWhitelist()).isEmpty(); @@ -173,9 +173,8 @@ public void permissioningConfigFromFileMustSetFilePath() throws Exception { final URL configFile = Resources.getResource(PERMISSIONING_CONFIG_VALID); final Path toml = createTempFile("toml", Resources.toByteArray(configFile)); - PermissioningConfiguration permissioningConfiguration = - PermissioningConfigurationBuilder.permissioningConfigurationFromToml( - toml.toString(), true, true); + LocalPermissioningConfiguration permissioningConfiguration = + PermissioningConfigurationBuilder.permissioningConfiguration(toml.toString(), true, true); assertThat(permissioningConfiguration.getConfigurationFilePath()).isEqualTo(toml.toString()); } @@ -194,15 +193,15 @@ public void permissioningConfigFromNonexistentFileMustThrowException() { public void permissioningConfigFromMultilineFileMustParseCorrectly() throws Exception { final URL configFile = Resources.getResource(PERMISSIONING_CONFIG_NODE_WHITELIST_ONLY_MULTILINE); - final PermissioningConfiguration permissioningConfiguration = - PermissioningConfigurationBuilder.permissioningConfigurationFromToml( + final LocalPermissioningConfiguration permissioningConfiguration = + PermissioningConfigurationBuilder.permissioningConfiguration( configFile.getPath(), true, false); assertThat(permissioningConfiguration.isNodeWhitelistEnabled()).isTrue(); assertThat(permissioningConfiguration.getNodeWhitelist().size()).isEqualTo(5); } - private PermissioningConfiguration permissioningConfig(final Path toml) throws Exception { + private LocalPermissioningConfiguration permissioningConfig(final Path toml) throws Exception { return PermissioningConfigurationBuilder.permissioningConfiguration( toml.toAbsolutePath().toString(), true, true); } diff --git a/ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/PermissioningConfigurationTest.java b/ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/LocalPermissioningConfigurationTest.java similarity index 78% rename from ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/PermissioningConfigurationTest.java rename to ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/LocalPermissioningConfigurationTest.java index f4ca73710e..f117429d36 100644 --- a/ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/PermissioningConfigurationTest.java +++ b/ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/LocalPermissioningConfigurationTest.java @@ -19,7 +19,7 @@ import org.junit.Test; -public class PermissioningConfigurationTest { +public class LocalPermissioningConfigurationTest { final URI[] nodes = { URI.create("enode://001@123:4567"), @@ -29,7 +29,8 @@ public class PermissioningConfigurationTest { @Test public void defaultConfiguration() { - final PermissioningConfiguration configuration = PermissioningConfiguration.createDefault(); + final LocalPermissioningConfiguration configuration = + LocalPermissioningConfiguration.createDefault(); assertThat(configuration.getNodeWhitelist()).isEmpty(); assertThat(configuration.isNodeWhitelistEnabled()).isFalse(); assertThat(configuration.getAccountWhitelist()).isEmpty(); @@ -38,7 +39,8 @@ public void defaultConfiguration() { @Test public void setNodeWhitelist() { - final PermissioningConfiguration configuration = PermissioningConfiguration.createDefault(); + final LocalPermissioningConfiguration configuration = + LocalPermissioningConfiguration.createDefault(); configuration.setNodeWhitelist(Arrays.asList(nodes)); assertThat(configuration.getNodeWhitelist()).containsExactlyInAnyOrder(nodes); assertThat(configuration.isNodeWhitelistEnabled()).isTrue(); @@ -46,7 +48,8 @@ public void setNodeWhitelist() { @Test public void setNodeWhiteListPassingNull() { - final PermissioningConfiguration configuration = PermissioningConfiguration.createDefault(); + final LocalPermissioningConfiguration configuration = + LocalPermissioningConfiguration.createDefault(); configuration.setNodeWhitelist(null); assertThat(configuration.getNodeWhitelist()).isEmpty(); assertThat(configuration.isNodeWhitelistEnabled()).isFalse(); @@ -55,7 +58,8 @@ public void setNodeWhiteListPassingNull() { @Test public void setAccountWhitelist() { final String[] accounts = {"1111111111111111", "2222222222222222", "ffffffffffffffff"}; - final PermissioningConfiguration configuration = PermissioningConfiguration.createDefault(); + final LocalPermissioningConfiguration configuration = + LocalPermissioningConfiguration.createDefault(); configuration.setAccountWhitelist(Arrays.asList(accounts)); assertThat(configuration.getAccountWhitelist()).containsExactlyInAnyOrder(accounts); assertThat(configuration.isAccountWhitelistEnabled()).isTrue(); @@ -63,7 +67,8 @@ public void setAccountWhitelist() { @Test public void setAccountWhiteListPassingNull() { - final PermissioningConfiguration configuration = PermissioningConfiguration.createDefault(); + final LocalPermissioningConfiguration configuration = + LocalPermissioningConfiguration.createDefault(); configuration.setAccountWhitelist(null); assertThat(configuration.getAccountWhitelist()).isEmpty(); assertThat(configuration.isAccountWhitelistEnabled()).isFalse(); diff --git a/ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/NodeWhitelistControllerTest.java b/ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/NodeLocalConfigPermissioningControllerTest.java similarity index 86% rename from ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/NodeWhitelistControllerTest.java rename to ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/NodeLocalConfigPermissioningControllerTest.java index 0f2b97f6dd..01fb14db44 100644 --- a/ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/NodeWhitelistControllerTest.java +++ b/ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/NodeLocalConfigPermissioningControllerTest.java @@ -24,7 +24,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; -import static tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController.NodesWhitelistResult; +import static tech.pegasys.pantheon.ethereum.permissioning.NodeLocalConfigPermissioningController.NodesWhitelistResult; import tech.pegasys.pantheon.ethereum.permissioning.node.NodeWhitelistUpdatedEvent; import tech.pegasys.pantheon.util.enode.EnodeURL; @@ -48,23 +48,28 @@ import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) -public class NodeWhitelistControllerTest { +public class NodeLocalConfigPermissioningControllerTest { @Mock private WhitelistPersistor whitelistPersistor; private final List bootnodesList = new ArrayList<>(); - private NodeWhitelistController controller; + private NodeLocalConfigPermissioningController controller; private final String enode1 = "enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.10:4567"; private final String enode2 = "enode://5f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.10:4567"; + private final String selfEnode = + "enode://5f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.10:1111"; @Before public void setUp() { bootnodesList.clear(); controller = - new NodeWhitelistController( - PermissioningConfiguration.createDefault(), bootnodesList, whitelistPersistor); + new NodeLocalConfigPermissioningController( + LocalPermissioningConfiguration.createDefault(), + bootnodesList, + new EnodeURL(selfEnode), + whitelistPersistor); } @Test @@ -76,6 +81,17 @@ public void whenAddNodesWithValidInputShouldReturnSuccess() { assertThat(controller.getNodesWhitelist()).containsExactly(enode1); } + @Test + public void whenAddNodesInputContainsSelfShouldReturnAddingSelfError() { + controller.addNodes(Arrays.asList(enode1)); + + NodesWhitelistResult expected = + new NodesWhitelistResult(WhitelistOperationResult.ERROR_SELF_CANNOT_BE_ADDED); + NodesWhitelistResult actualResult = controller.addNodes(Lists.newArrayList(selfEnode, enode1)); + + assertThat(actualResult).isEqualToComparingOnlyGivenFields(expected, "result"); + } + @Test public void whenAddNodesInputHasExistingNodeShouldReturnAddErrorExistingEntry() { controller.addNodes(Arrays.asList(enode1)); @@ -211,6 +227,15 @@ public void whenCheckingIfNodeIsPermittedTcpPortShouldBeConsideredIfPresent() { assertThat(controller.isPermitted(peerWithTcpPortSet)).isFalse(); } + @Test + public void whenCheckingIfNodeIsPermittedOrderDoesNotMatter() { + controller.addNodes(Arrays.asList(enode1)); + assertThat(controller.isPermitted(new EnodeURL(enode1), new EnodeURL(selfEnode))).isTrue(); + assertThat(controller.isPermitted(new EnodeURL(selfEnode), new EnodeURL(enode1))).isTrue(); + + assertThat(controller.isPermitted(new EnodeURL(selfEnode), new EnodeURL(selfEnode))).isFalse(); + } + @Test public void stateShouldRevertIfWhitelistPersistFails() throws IOException, WhitelistFileSyncException { @@ -238,14 +263,17 @@ public void reloadNodeWhitelistWithValidConfigFileShouldUpdateWhitelist() throws final String expectedEnodeURL = "enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.9:4567"; final Path permissionsFile = createPermissionsFileWithNode(expectedEnodeURL); - final PermissioningConfiguration permissioningConfig = mock(PermissioningConfiguration.class); + final LocalPermissioningConfiguration permissioningConfig = + mock(LocalPermissioningConfiguration.class); when(permissioningConfig.getConfigurationFilePath()) .thenReturn(permissionsFile.toAbsolutePath().toString()); when(permissioningConfig.isNodeWhitelistEnabled()).thenReturn(true); when(permissioningConfig.getNodeWhitelist()) .thenReturn(Arrays.asList(URI.create(expectedEnodeURL))); - controller = new NodeWhitelistController(permissioningConfig, bootnodesList); + controller = + new NodeLocalConfigPermissioningController( + permissioningConfig, bootnodesList, new EnodeURL(selfEnode)); controller.reload(); @@ -256,13 +284,16 @@ public void reloadNodeWhitelistWithValidConfigFileShouldUpdateWhitelist() throws public void reloadNodeWhitelistWithErrorReadingConfigFileShouldKeepOldWhitelist() { final String expectedEnodeURI = "enode://aaaa80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.9:4567"; - final PermissioningConfiguration permissioningConfig = mock(PermissioningConfiguration.class); + final LocalPermissioningConfiguration permissioningConfig = + mock(LocalPermissioningConfiguration.class); when(permissioningConfig.getConfigurationFilePath()).thenReturn("foo"); when(permissioningConfig.isNodeWhitelistEnabled()).thenReturn(true); when(permissioningConfig.getNodeWhitelist()) .thenReturn(Arrays.asList(URI.create(expectedEnodeURI))); - controller = new NodeWhitelistController(permissioningConfig, bootnodesList); + controller = + new NodeLocalConfigPermissioningController( + permissioningConfig, bootnodesList, new EnodeURL(selfEnode)); final Throwable thrown = catchThrowable(() -> controller.reload()); @@ -347,7 +378,8 @@ public void whenRemovingBootnodeShouldReturnRemoveBootnodeError() { @SuppressWarnings("unchecked") public void whenReloadingWhitelistShouldNotifyWhitelistModifiedSubscribers() throws Exception { final Path permissionsFile = createPermissionsFileWithNode(enode2); - final PermissioningConfiguration permissioningConfig = mock(PermissioningConfiguration.class); + final LocalPermissioningConfiguration permissioningConfig = + mock(LocalPermissioningConfiguration.class); final Consumer consumer = mock(Consumer.class); final NodeWhitelistUpdatedEvent expectedEvent = new NodeWhitelistUpdatedEvent( @@ -357,7 +389,9 @@ public void whenReloadingWhitelistShouldNotifyWhitelistModifiedSubscribers() thr .thenReturn(permissionsFile.toAbsolutePath().toString()); when(permissioningConfig.isNodeWhitelistEnabled()).thenReturn(true); when(permissioningConfig.getNodeWhitelist()).thenReturn(Arrays.asList(URI.create(enode1))); - controller = new NodeWhitelistController(permissioningConfig, bootnodesList); + controller = + new NodeLocalConfigPermissioningController( + permissioningConfig, bootnodesList, new EnodeURL(selfEnode)); controller.subscribeToListUpdatedEvent(consumer); controller.reload(); @@ -370,14 +404,17 @@ public void whenReloadingWhitelistShouldNotifyWhitelistModifiedSubscribers() thr public void whenReloadingWhitelistAndNothingChangesShouldNotNotifyWhitelistModifiedSubscribers() throws Exception { final Path permissionsFile = createPermissionsFileWithNode(enode1); - final PermissioningConfiguration permissioningConfig = mock(PermissioningConfiguration.class); + final LocalPermissioningConfiguration permissioningConfig = + mock(LocalPermissioningConfiguration.class); final Consumer consumer = mock(Consumer.class); when(permissioningConfig.getConfigurationFilePath()) .thenReturn(permissionsFile.toAbsolutePath().toString()); when(permissioningConfig.isNodeWhitelistEnabled()).thenReturn(true); when(permissioningConfig.getNodeWhitelist()).thenReturn(Arrays.asList(URI.create(enode1))); - controller = new NodeWhitelistController(permissioningConfig, bootnodesList); + controller = + new NodeLocalConfigPermissioningController( + permissioningConfig, bootnodesList, new EnodeURL(selfEnode)); controller.subscribeToListUpdatedEvent(consumer); controller.reload(); diff --git a/ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/node/NodePermissioningControllerFactoryTest.java b/ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/node/NodePermissioningControllerFactoryTest.java new file mode 100644 index 0000000000..bc47eab5ff --- /dev/null +++ b/ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/node/NodePermissioningControllerFactoryTest.java @@ -0,0 +1,138 @@ +/* + * Copyright 2019 ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * 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.permissioning.node; + +import static org.assertj.core.api.Assertions.assertThat; + +import tech.pegasys.pantheon.ethereum.core.Address; +import tech.pegasys.pantheon.ethereum.core.Synchronizer; +import tech.pegasys.pantheon.ethereum.permissioning.LocalPermissioningConfiguration; +import tech.pegasys.pantheon.ethereum.permissioning.NodeLocalConfigPermissioningController; +import tech.pegasys.pantheon.ethereum.permissioning.NodePermissioningControllerFactory; +import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration; +import tech.pegasys.pantheon.ethereum.permissioning.SmartContractPermissioningConfiguration; +import tech.pegasys.pantheon.ethereum.permissioning.SmartContractPermissioningController; +import tech.pegasys.pantheon.ethereum.transaction.TransactionSimulator; +import tech.pegasys.pantheon.util.enode.EnodeURL; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class NodePermissioningControllerFactoryTest { + + @Mock private Synchronizer synchronizer; + @Mock private TransactionSimulator transactionSimulator; + + private final String enode = + "enode://5f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.10:1111"; + Collection bootnodes = Collections.emptyList(); + EnodeURL selfEnode = new EnodeURL(enode); + LocalPermissioningConfiguration localPermissioningConfig; + SmartContractPermissioningConfiguration smartContractPermissioningConfiguration; + PermissioningConfiguration config; + + @Test + public void testCreateWithNeitherPermissioningEnabled() { + config = new PermissioningConfiguration(Optional.empty(), Optional.empty()); + NodePermissioningControllerFactory factory = new NodePermissioningControllerFactory(); + NodePermissioningController controller = + factory.create(config, synchronizer, bootnodes, selfEnode, transactionSimulator); + + List providers = controller.getProviders(); + assertThat(providers.size()).isEqualTo(0); + assertThat(controller.getSyncStatusNodePermissioningProvider()).isNotPresent(); + } + + @Test + public void testCreateWithSmartContractNodePermissioningEnabledOnly() { + smartContractPermissioningConfiguration = new SmartContractPermissioningConfiguration(); + smartContractPermissioningConfiguration.setSmartContractAddress( + Address.fromHexString("0x0000000000000000000000000000000000001234")); + smartContractPermissioningConfiguration.setSmartContractNodeWhitelistEnabled(true); + config = + new PermissioningConfiguration( + Optional.empty(), Optional.of(smartContractPermissioningConfiguration)); + + NodePermissioningControllerFactory factory = new NodePermissioningControllerFactory(); + NodePermissioningController controller = + factory.create(config, synchronizer, bootnodes, selfEnode, transactionSimulator); + + List providers = controller.getProviders(); + assertThat(providers.size()).isEqualTo(1); + + NodePermissioningProvider p1 = providers.get(0); + assertThat(p1).isInstanceOf(SmartContractPermissioningController.class); + assertThat(controller.getSyncStatusNodePermissioningProvider()).isPresent(); + } + + @Test + public void testCreateWithLocalNodePermissioningEnabledOnly() { + localPermissioningConfig = LocalPermissioningConfiguration.createDefault(); + localPermissioningConfig.setNodeWhitelist(Collections.emptyList()); + localPermissioningConfig.setConfigurationFilePath("fake-file-path"); + config = + new PermissioningConfiguration(Optional.of(localPermissioningConfig), Optional.empty()); + + NodePermissioningControllerFactory factory = new NodePermissioningControllerFactory(); + NodePermissioningController controller = + factory.create(config, synchronizer, bootnodes, selfEnode, transactionSimulator); + + List providers = controller.getProviders(); + assertThat(providers.size()).isEqualTo(1); + + NodePermissioningProvider p1 = providers.get(0); + assertThat(p1).isInstanceOf(NodeLocalConfigPermissioningController.class); + assertThat(controller.getSyncStatusNodePermissioningProvider()).isNotPresent(); + } + + @Test + public void testCreateWithLocalNodeAndSmartContractPermissioningEnabled() { + localPermissioningConfig = LocalPermissioningConfiguration.createDefault(); + localPermissioningConfig.setNodeWhitelist(Collections.emptyList()); + localPermissioningConfig.setConfigurationFilePath("fake-file-path"); + + smartContractPermissioningConfiguration = new SmartContractPermissioningConfiguration(); + smartContractPermissioningConfiguration.setSmartContractAddress( + Address.fromHexString("0x0000000000000000000000000000000000001234")); + smartContractPermissioningConfiguration.setSmartContractNodeWhitelistEnabled(true); + config = + new PermissioningConfiguration( + Optional.of(localPermissioningConfig), + Optional.of(smartContractPermissioningConfiguration)); + + NodePermissioningControllerFactory factory = new NodePermissioningControllerFactory(); + NodePermissioningController controller = + factory.create(config, synchronizer, bootnodes, selfEnode, transactionSimulator); + + List providers = controller.getProviders(); + assertThat(providers.size()).isEqualTo(2); + + NodePermissioningProvider p1 = providers.get(0); + NodePermissioningProvider p2 = providers.get(1); + if (p1.getClass() == NodeLocalConfigPermissioningController.class) { + assertThat(p2).isInstanceOf(SmartContractPermissioningController.class); + } else { + assertThat(p2).isInstanceOf(NodeLocalConfigPermissioningController.class); + assertThat(p1).isInstanceOf(SmartContractPermissioningController.class); + } + assertThat(controller.getSyncStatusNodePermissioningProvider()).isPresent(); + } +} diff --git a/ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/node/NodePermissioningControllerTest.java b/ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/node/NodePermissioningControllerTest.java index ccd6d88bd2..09b2546ab2 100644 --- a/ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/node/NodePermissioningControllerTest.java +++ b/ethereum/permissioning/src/test/java/tech/pegasys/pantheon/ethereum/permissioning/node/NodePermissioningControllerTest.java @@ -12,13 +12,20 @@ */ package tech.pegasys.pantheon.ethereum.permissioning.node; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import tech.pegasys.pantheon.ethereum.permissioning.NodeLocalConfigPermissioningController; import tech.pegasys.pantheon.ethereum.permissioning.node.provider.SyncStatusNodePermissioningProvider; import tech.pegasys.pantheon.util.enode.EnodeURL; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -36,12 +43,19 @@ public class NodePermissioningControllerTest { "enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.3:5678"); @Mock private SyncStatusNodePermissioningProvider syncStatusNodePermissioningProvider; + Optional syncStatusNodePermissioningProviderOptional; + @Mock private NodeLocalConfigPermissioningController localConfigNodePermissioningProvider; + @Mock private NodePermissioningProvider otherPermissioningProvider; private NodePermissioningController controller; @Before public void before() { - this.controller = new NodePermissioningController(syncStatusNodePermissioningProvider); + syncStatusNodePermissioningProviderOptional = Optional.of(syncStatusNodePermissioningProvider); + List emptyProviders = new ArrayList<>(); + this.controller = + new NodePermissioningController( + syncStatusNodePermissioningProviderOptional, emptyProviders); } @Test @@ -57,4 +71,59 @@ public void peerDiscoveryCallbackShouldBeDelegatedToSyncStatusNodePermissioningP verify(syncStatusNodePermissioningProvider).setHasReachedSyncCallback(any(Runnable.class)); } + + @Test + public void whenNoSyncStatusProviderWeShouldDelegateToLocalConfigNodePermissioningProvider() { + List providers = new ArrayList<>(); + providers.add(localConfigNodePermissioningProvider); + this.controller = new NodePermissioningController(Optional.empty(), providers); + + controller.isPermitted(enode1, enode2); + + verify(localConfigNodePermissioningProvider).isPermitted(eq(enode1), eq(enode2)); + } + + @Test + public void + whenInSyncWeShouldDelegateToAnyOtherNodePermissioningProviderAndIsPermittedIfAllPermitted() { + List providers = getNodePermissioningProviders(); + this.controller = + new NodePermissioningController(syncStatusNodePermissioningProviderOptional, providers); + + when(syncStatusNodePermissioningProvider.isPermitted(eq(enode1), eq(enode2))).thenReturn(true); + when(localConfigNodePermissioningProvider.isPermitted(eq(enode1), eq(enode2))).thenReturn(true); + when(otherPermissioningProvider.isPermitted(eq(enode1), eq(enode2))).thenReturn(true); + + assertThat(controller.isPermitted(enode1, enode2)).isTrue(); + + verify(syncStatusNodePermissioningProvider).isPermitted(eq(enode1), eq(enode2)); + verify(localConfigNodePermissioningProvider).isPermitted(eq(enode1), eq(enode2)); + verify(otherPermissioningProvider).isPermitted(eq(enode1), eq(enode2)); + } + + private List getNodePermissioningProviders() { + List providers = new ArrayList<>(); + providers.add(localConfigNodePermissioningProvider); + providers.add(otherPermissioningProvider); + return providers; + } + + @Test + public void + whenInSyncWeShouldDelegateToAnyOtherNodePermissioningProviderAndIsNotPermittedIfAnyNotPermitted() { + List providers = getNodePermissioningProviders(); + + this.controller = + new NodePermissioningController(syncStatusNodePermissioningProviderOptional, providers); + + when(syncStatusNodePermissioningProvider.isPermitted(eq(enode1), eq(enode2))).thenReturn(true); + when(localConfigNodePermissioningProvider.isPermitted(eq(enode1), eq(enode2))).thenReturn(true); + when(otherPermissioningProvider.isPermitted(eq(enode1), eq(enode2))).thenReturn(false); + + assertThat(controller.isPermitted(enode1, enode2)).isFalse(); + + verify(syncStatusNodePermissioningProvider).isPermitted(eq(enode1), eq(enode2)); + verify(localConfigNodePermissioningProvider).isPermitted(eq(enode1), eq(enode2)); + verify(otherPermissioningProvider).isPermitted(eq(enode1), eq(enode2)); + } } diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/RunnerBuilder.java b/pantheon/src/main/java/tech/pegasys/pantheon/RunnerBuilder.java index e2710b1c44..b48943a795 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/RunnerBuilder.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/RunnerBuilder.java @@ -53,8 +53,8 @@ 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.permissioning.LocalPermissioningConfiguration; +import tech.pegasys.pantheon.ethereum.permissioning.NodeLocalConfigPermissioningController; import tech.pegasys.pantheon.ethereum.worldstate.WorldStateArchive; import tech.pegasys.pantheon.metrics.MetricsSystem; import tech.pegasys.pantheon.metrics.prometheus.MetricsConfiguration; @@ -90,7 +90,12 @@ public class RunnerBuilder { private Collection bannedNodeIds; private MetricsConfiguration metricsConfiguration; private MetricsSystem metricsSystem; - private Optional permissioningConfiguration = Optional.empty(); + private Optional permissioningConfiguration = Optional.empty(); + + private EnodeURL getSelfEnode() { + String nodeId = pantheonController.getLocalNodeKeyPair().getPublicKey().toString(); + return new EnodeURL(nodeId, discoveryHost, listenPort); + } public RunnerBuilder vertx(final Vertx vertx) { this.vertx = vertx; @@ -143,7 +148,7 @@ public RunnerBuilder webSocketConfiguration(final WebSocketConfiguration webSock } public RunnerBuilder permissioningConfiguration( - final PermissioningConfiguration permissioningConfiguration) { + final LocalPermissioningConfiguration permissioningConfiguration) { this.permissioningConfiguration = Optional.of(permissioningConfiguration); return this; } @@ -219,10 +224,13 @@ public Runner build() { discoveryConfiguration.getBootstrapPeers().stream() .map(p -> new EnodeURL(p.getEnodeURI())) .collect(Collectors.toList()); - final Optional nodeWhitelistController = + final Optional nodeWhitelistController = permissioningConfiguration - .filter(PermissioningConfiguration::isNodeWhitelistEnabled) - .map(config -> new NodeWhitelistController(config, bootnodesAsEnodeURLs)); + .filter(LocalPermissioningConfiguration::isNodeWhitelistEnabled) + .map( + config -> + new NodeLocalConfigPermissioningController( + config, bootnodesAsEnodeURLs, getSelfEnode())); final Synchronizer synchronizer = pantheonController.getSynchronizer(); @@ -250,7 +258,7 @@ public Runner build() { final MiningCoordinator miningCoordinator = pantheonController.getMiningCoordinator(); final Optional accountWhitelistController = permissioningConfiguration - .filter(PermissioningConfiguration::isAccountWhitelistEnabled) + .filter(LocalPermissioningConfiguration::isAccountWhitelistEnabled) .map( configuration -> { final AccountWhitelistController whitelistController = diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java b/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java index c905c1a5e4..4b5ab58fe1 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java @@ -49,7 +49,7 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.RpcApi; import tech.pegasys.pantheon.ethereum.jsonrpc.RpcApis; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration; -import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration; +import tech.pegasys.pantheon.ethereum.permissioning.LocalPermissioningConfiguration; import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfigurationBuilder; import tech.pegasys.pantheon.metrics.MetricCategory; import tech.pegasys.pantheon.metrics.MetricsSystem; @@ -605,7 +605,7 @@ public void run() { try { final JsonRpcConfiguration jsonRpcConfiguration = jsonRpcConfiguration(); final WebSocketConfiguration webSocketConfiguration = webSocketConfiguration(); - final Optional permissioningConfiguration = + final Optional permissioningConfiguration = permissioningConfiguration(); permissioningConfiguration.ifPresent( p -> ensureAllBootnodesAreInWhitelist(ethNetworkConfig, p)); @@ -634,7 +634,7 @@ private NetworkName getNetwork() { private void ensureAllBootnodesAreInWhitelist( final EthNetworkConfig ethNetworkConfig, - final PermissioningConfiguration permissioningConfiguration) { + final LocalPermissioningConfiguration permissioningConfiguration) { try { PermissioningConfigurationValidator.areAllBootnodesAreInWhitelist( ethNetworkConfig, permissioningConfiguration); @@ -779,7 +779,7 @@ MetricsConfiguration metricsConfiguration() { return metricsConfiguration; } - private Optional permissioningConfiguration() throws Exception { + private Optional permissioningConfiguration() throws Exception { if (!permissionsAccountsEnabled && !permissionsNodesEnabled) { if (rpcHttpApis.contains(RpcApis.PERM) || rpcWsApis.contains(RpcApis.PERM)) { @@ -789,8 +789,8 @@ private Optional permissioningConfiguration() throws return Optional.empty(); } - final PermissioningConfiguration permissioningConfiguration = - PermissioningConfigurationBuilder.permissioningConfigurationFromToml( + final LocalPermissioningConfiguration permissioningConfiguration = + PermissioningConfigurationBuilder.permissioningConfiguration( getPermissionsConfigFile(), permissionsNodesEnabled, permissionsAccountsEnabled); return Optional.of(permissioningConfiguration); } @@ -839,7 +839,7 @@ private void synchronize( final JsonRpcConfiguration jsonRpcConfiguration, final WebSocketConfiguration webSocketConfiguration, final MetricsConfiguration metricsConfiguration, - final Optional permissioningConfiguration) { + final Optional permissioningConfiguration) { checkNotNull(runnerBuilder); diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/util/PermissioningConfigurationValidator.java b/pantheon/src/main/java/tech/pegasys/pantheon/util/PermissioningConfigurationValidator.java index 9a112e1c17..f5a58e8561 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/util/PermissioningConfigurationValidator.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/util/PermissioningConfigurationValidator.java @@ -13,7 +13,7 @@ package tech.pegasys.pantheon.util; import tech.pegasys.pantheon.cli.EthNetworkConfig; -import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration; +import tech.pegasys.pantheon.ethereum.permissioning.LocalPermissioningConfiguration; import java.net.URI; import java.util.ArrayList; @@ -25,7 +25,7 @@ public class PermissioningConfigurationValidator { public static void areAllBootnodesAreInWhitelist( final EthNetworkConfig ethNetworkConfig, - final PermissioningConfiguration permissioningConfiguration) + final LocalPermissioningConfiguration permissioningConfiguration) throws Exception { List bootnodesNotInWhitelist = new ArrayList<>(); final Collection bootnodes = ethNetworkConfig.getBootNodes(); diff --git a/pantheon/src/test/java/tech/pegasys/pantheon/RunnerTest.java b/pantheon/src/test/java/tech/pegasys/pantheon/RunnerTest.java index e351f61be4..874c992444 100644 --- a/pantheon/src/test/java/tech/pegasys/pantheon/RunnerTest.java +++ b/pantheon/src/test/java/tech/pegasys/pantheon/RunnerTest.java @@ -39,7 +39,7 @@ import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule; import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSpec; import tech.pegasys.pantheon.ethereum.p2p.peers.Peer; -import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration; +import tech.pegasys.pantheon.ethereum.permissioning.LocalPermissioningConfiguration; import tech.pegasys.pantheon.ethereum.storage.StorageProvider; import tech.pegasys.pantheon.ethereum.storage.keyvalue.RocksDbStorageProvider; import tech.pegasys.pantheon.metrics.MetricsSystem; @@ -136,7 +136,8 @@ private void syncFromGenesis(final SyncMode mode) throws Exception { final JsonRpcConfiguration aheadJsonRpcConfiguration = jsonRpcConfiguration(); final WebSocketConfiguration aheadWebSocketConfiguration = wsRpcConfiguration(); final MetricsConfiguration aheadMetricsConfiguration = metricsConfiguration(); - final PermissioningConfiguration aheadPermissioningConfiguration = permissioningConfiguration(); + final LocalPermissioningConfiguration aheadPermissioningConfiguration = + permissioningConfiguration(); final RunnerBuilder runnerBuilder = new RunnerBuilder() .vertx(Vertx.vertx()) @@ -304,8 +305,8 @@ private MetricsConfiguration metricsConfiguration() { return configuration; } - private PermissioningConfiguration permissioningConfiguration() { - return PermissioningConfiguration.createDefault(); + private LocalPermissioningConfiguration permissioningConfiguration() { + return LocalPermissioningConfiguration.createDefault(); } private static void setupState( diff --git a/pantheon/src/test/java/tech/pegasys/pantheon/cli/CommandTestAbstract.java b/pantheon/src/test/java/tech/pegasys/pantheon/cli/CommandTestAbstract.java index 3ab957c85d..a4fd7f3858 100644 --- a/pantheon/src/test/java/tech/pegasys/pantheon/cli/CommandTestAbstract.java +++ b/pantheon/src/test/java/tech/pegasys/pantheon/cli/CommandTestAbstract.java @@ -26,7 +26,7 @@ import tech.pegasys.pantheon.ethereum.eth.sync.SynchronizerConfiguration; import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration; -import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration; +import tech.pegasys.pantheon.ethereum.permissioning.LocalPermissioningConfiguration; import tech.pegasys.pantheon.metrics.prometheus.MetricsConfiguration; import tech.pegasys.pantheon.util.BlockImporter; @@ -84,7 +84,7 @@ public abstract class CommandTestAbstract { @Captor ArgumentCaptor wsRpcConfigArgumentCaptor; @Captor ArgumentCaptor metricsConfigArgumentCaptor; - @Captor ArgumentCaptor permissioningConfigurationArgumentCaptor; + @Captor ArgumentCaptor permissioningConfigurationArgumentCaptor; @Rule public final TemporaryFolder temp = new TemporaryFolder(); diff --git a/pantheon/src/test/java/tech/pegasys/pantheon/cli/PantheonCommandTest.java b/pantheon/src/test/java/tech/pegasys/pantheon/cli/PantheonCommandTest.java index ae5aad1402..6d7e196369 100644 --- a/pantheon/src/test/java/tech/pegasys/pantheon/cli/PantheonCommandTest.java +++ b/pantheon/src/test/java/tech/pegasys/pantheon/cli/PantheonCommandTest.java @@ -44,7 +44,7 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcConfiguration; import tech.pegasys.pantheon.ethereum.jsonrpc.RpcApi; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketConfiguration; -import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration; +import tech.pegasys.pantheon.ethereum.permissioning.LocalPermissioningConfiguration; import tech.pegasys.pantheon.metrics.MetricCategory; import tech.pegasys.pantheon.metrics.prometheus.MetricsConfiguration; import tech.pegasys.pantheon.util.bytes.BytesValue; @@ -359,8 +359,8 @@ public void permissionsTomlPathMustUseOption() throws IOException { parseCommand( "--permissions-accounts-enabled", "--permissions-config-file", permToml.toString()); - final PermissioningConfiguration permissioningConfiguration = - PermissioningConfiguration.createDefault(); + final LocalPermissioningConfiguration permissioningConfiguration = + LocalPermissioningConfiguration.createDefault(); permissioningConfiguration.setConfigurationFilePath(permToml.toString()); permissioningConfiguration.setAccountWhitelist( Collections.singletonList("0x0000000000000000000000000000000000000009")); diff --git a/pantheon/src/test/java/tech/pegasys/pantheon/util/PermissioningConfigurationValidatorTest.java b/pantheon/src/test/java/tech/pegasys/pantheon/util/LocalPermissioningConfigurationValidatorTest.java similarity index 92% rename from pantheon/src/test/java/tech/pegasys/pantheon/util/PermissioningConfigurationValidatorTest.java rename to pantheon/src/test/java/tech/pegasys/pantheon/util/LocalPermissioningConfigurationValidatorTest.java index b4cf39c40a..3c11131aa1 100644 --- a/pantheon/src/test/java/tech/pegasys/pantheon/util/PermissioningConfigurationValidatorTest.java +++ b/pantheon/src/test/java/tech/pegasys/pantheon/util/LocalPermissioningConfigurationValidatorTest.java @@ -17,7 +17,7 @@ import tech.pegasys.pantheon.cli.EthNetworkConfig; import tech.pegasys.pantheon.cli.NetworkName; -import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration; +import tech.pegasys.pantheon.ethereum.permissioning.LocalPermissioningConfiguration; import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfigurationBuilder; import java.net.URL; @@ -27,7 +27,7 @@ import com.google.common.io.Resources; import org.junit.Test; -public class PermissioningConfigurationValidatorTest { +public class LocalPermissioningConfigurationValidatorTest { static final String PERMISSIONING_CONFIG_ROPSTEN_BOOTNODES = "permissioning_config_ropsten_bootnodes.toml"; @@ -43,7 +43,7 @@ public void ropstenWithNodesWhitelistOptionWhichDoesIncludeRopstenBootnodesMustN final Path toml = Files.createTempFile("toml", ""); Files.write(toml, Resources.toByteArray(configFile)); - PermissioningConfiguration permissioningConfiguration = + LocalPermissioningConfiguration permissioningConfiguration = PermissioningConfigurationBuilder.permissioningConfiguration( toml.toAbsolutePath().toString(), true, true); @@ -61,7 +61,7 @@ public void nodesWhitelistOptionWhichDoesNotIncludeBootnodesMustError() throws E toml.toFile().deleteOnExit(); Files.write(toml, Resources.toByteArray(configFile)); - PermissioningConfiguration permissioningConfiguration = + LocalPermissioningConfiguration permissioningConfiguration = PermissioningConfigurationBuilder.permissioningConfiguration( toml.toAbsolutePath().toString(), true, true);