diff --git a/CHANGELOG.md b/CHANGELOG.md index 83302dee4fc..49e3b77e978 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ ### Additions and Improvements - Add IPv6 dual-stack support for DiscV5 peer discovery (enabled via `--Xv5-discovery-enabled`): new `--p2p-host-ipv6`, `--p2p-interface-ipv6`, and `--p2p-port-ipv6` CLI options enable a second UDP discovery socket; `--p2p-ipv6-outbound-enabled` controls whether IPv6 is preferred for outbound connections when a peer advertises both address families [#9763](https://github.com/hyperledger/besu/pull/9763); RLPx now also binds a second TCP socket on the IPv6 interface so IPv6-only peers can establish connections [#9873](https://github.com/hyperledger/besu/pull/9873) +- `--net-restrict` now supports IPv6 CIDR notation (e.g. `fd00::/64`) in addition to IPv4, enabling subnet-based peer filtering in IPv6 and dual-stack deployments [#10028](https://github.com/besu-eth/besu/pull/10028) - Stop EngineQosTimer as part of shutdown [#9903](https://github.com/hyperledger/besu/pull/9903) - Add `--max-blobs-per-transaction` CLI option to configure the maximum number of blobs per transaction [#9912](https://github.com/hyperledger/besu/pull/9912) - Add `--max-blobs-per-block` CLI option to configure the maximum number of blobs per block when block building [#9983](https://github.com/hyperledger/besu/pull/9983) diff --git a/app/build.gradle b/app/build.gradle index 149348e6e74..7c17787b020 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -71,7 +71,7 @@ dependencies { implementation 'com.google.guava:guava' implementation 'com.google.dagger:dagger' implementation 'com.graphql-java:graphql-java' - implementation 'commons-net:commons-net' + implementation 'com.github.seancfoley:ipaddress' implementation 'info.picocli:picocli' implementation 'io.vertx:vertx-core' implementation 'io.vertx:vertx-web' diff --git a/app/src/main/java/org/hyperledger/besu/RunnerBuilder.java b/app/src/main/java/org/hyperledger/besu/RunnerBuilder.java index 0901658cd24..ce505942858 100644 --- a/app/src/main/java/org/hyperledger/besu/RunnerBuilder.java +++ b/app/src/main/java/org/hyperledger/besu/RunnerBuilder.java @@ -143,9 +143,9 @@ import com.google.common.base.Preconditions; import com.google.common.base.Strings; import graphql.GraphQL; +import inet.ipaddr.IPAddress; import io.vertx.core.Vertx; import io.vertx.core.VertxOptions; -import org.apache.commons.net.util.SubnetUtils.SubnetInfo; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.units.bigints.UInt256; import org.slf4j.Logger; @@ -194,7 +194,7 @@ public class RunnerBuilder { private RpcEndpointServiceImpl rpcEndpointServiceImpl; private JsonRpcIpcConfiguration jsonRpcIpcConfiguration; private Optional enodeDnsConfiguration; - private List allowedSubnets = new ArrayList<>(); + private List allowedSubnets = new ArrayList<>(); private boolean poaDiscoveryRetryBootnodes = true; private TransactionValidatorServiceImpl transactionValidatorService; @@ -610,7 +610,7 @@ public RunnerBuilder enodeDnsConfiguration(final EnodeDnsConfiguration enodeDnsC * @param allowedSubnets the allowedSubnets * @return the runner builder */ - public RunnerBuilder allowedSubnets(final List allowedSubnets) { + public RunnerBuilder allowedSubnets(final List allowedSubnets) { this.allowedSubnets = allowedSubnets; return this; } diff --git a/app/src/main/java/org/hyperledger/besu/cli/converter/SubnetCidrConverter.java b/app/src/main/java/org/hyperledger/besu/cli/converter/SubnetCidrConverter.java new file mode 100644 index 00000000000..c422c610509 --- /dev/null +++ b/app/src/main/java/org/hyperledger/besu/cli/converter/SubnetCidrConverter.java @@ -0,0 +1,41 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.cli.converter; + +import inet.ipaddr.IPAddress; +import inet.ipaddr.IPAddressString; +import picocli.CommandLine; + +/** Converts CIDR notation strings to IPAddress prefix blocks. Supports both IPv4 and IPv6. */ +public class SubnetCidrConverter implements CommandLine.ITypeConverter { + /** Default Constructor. */ + public SubnetCidrConverter() {} + + /** + * Converts an IP address with CIDR notation into an IPAddress prefix block. + * + * @param value The IP address with CIDR notation (e.g. "192.168.1.0/24" or "fd00::/64"). + * @return the IPAddress prefix block + */ + @Override + public IPAddress convert(final String value) { + final IPAddressString addrString = new IPAddressString(value); + if (!addrString.isValid() || addrString.getNetworkPrefixLength() == null) { + throw new CommandLine.TypeConversionException( + "Invalid CIDR notation: " + value + ". Expected format: /"); + } + return addrString.getAddress().toPrefixBlock(); + } +} diff --git a/app/src/main/java/org/hyperledger/besu/cli/converter/SubnetInfoConverter.java b/app/src/main/java/org/hyperledger/besu/cli/converter/SubnetInfoConverter.java deleted file mode 100644 index 9ad9db9d14e..00000000000 --- a/app/src/main/java/org/hyperledger/besu/cli/converter/SubnetInfoConverter.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright contributors to Hyperledger Besu. - * - * 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. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.hyperledger.besu.cli.converter; - -import org.apache.commons.net.util.SubnetUtils; -import org.apache.commons.net.util.SubnetUtils.SubnetInfo; -import picocli.CommandLine; - -/** The SubnetInfo converter for CLI options. */ -public class SubnetInfoConverter implements CommandLine.ITypeConverter { - /** Default Constructor. */ - public SubnetInfoConverter() {} - - /** - * Converts an IP addresses with CIDR notation into SubnetInfo - * - * @param value The IP addresses with CIDR notation. - * @return the SubnetInfo - */ - @Override - public SubnetInfo convert(final String value) { - return new SubnetUtils(value).getInfo(); - } -} diff --git a/app/src/main/java/org/hyperledger/besu/cli/options/P2PDiscoveryOptions.java b/app/src/main/java/org/hyperledger/besu/cli/options/P2PDiscoveryOptions.java index 3f280921bdc..9a7a293d76e 100644 --- a/app/src/main/java/org/hyperledger/besu/cli/options/P2PDiscoveryOptions.java +++ b/app/src/main/java/org/hyperledger/besu/cli/options/P2PDiscoveryOptions.java @@ -16,7 +16,7 @@ import org.hyperledger.besu.cli.DefaultCommandValues; import org.hyperledger.besu.cli.converter.PercentageConverter; -import org.hyperledger.besu.cli.converter.SubnetInfoConverter; +import org.hyperledger.besu.cli.converter.SubnetCidrConverter; import org.hyperledger.besu.cli.util.CommandLineUtils; import org.hyperledger.besu.ethereum.p2p.discovery.P2PDiscoveryConfiguration; import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl; @@ -34,7 +34,7 @@ import java.util.stream.Collectors; import com.google.common.net.InetAddresses; -import org.apache.commons.net.util.SubnetUtils; +import inet.ipaddr.IPAddress; import org.apache.tuweni.bytes.Bytes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -257,10 +257,10 @@ public InetAddress autoDiscoverDefaultIP() { names = {"--net-restrict"}, arity = "1..*", split = ",", - converter = SubnetInfoConverter.class, + converter = SubnetCidrConverter.class, description = "Comma-separated list of allowed IP subnets (e.g., '192.168.1.0/24,10.0.0.0/8').") - private List allowedSubnets; + private List allowedSubnets; @Override public P2PDiscoveryConfiguration toDomainObject() { diff --git a/app/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java b/app/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java index b4132438cfc..9a09100996b 100644 --- a/app/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java +++ b/app/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java @@ -103,6 +103,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import com.google.common.base.Splitter; import com.google.common.io.Resources; import io.vertx.core.json.JsonObject; import org.apache.tuweni.bytes.Bytes; @@ -1315,22 +1316,23 @@ public void parsesValidSyncMinPeersOption() { assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); } - @Test - public void netRestrictParsedCorrectly() { - final String subnet1 = "127.0.0.1/24"; - final String subnet2 = "10.0.0.1/24"; - parseCommand("--net-restrict", String.join(",", subnet1, subnet2)); + @ParameterizedTest + @ValueSource( + strings = {"127.0.0.0/24,10.0.0.0/24", "fd00::/64,fe80::/10", "127.0.0.0/24,fd00::/64"}) + public void netRestrictParsedCorrectly(final String subnets) { + parseCommand("--net-restrict", subnets); verify(mockRunnerBuilder).allowedSubnets(allowedSubnetsArgumentCaptor.capture()); - assertThat(allowedSubnetsArgumentCaptor.getValue().size()).isEqualTo(2); - assertThat(allowedSubnetsArgumentCaptor.getValue().get(0).getCidrSignature()) - .isEqualTo(subnet1); - assertThat(allowedSubnetsArgumentCaptor.getValue().get(1).getCidrSignature()) - .isEqualTo(subnet2); + final List expected = Splitter.on(',').splitToList(subnets); + assertThat(allowedSubnetsArgumentCaptor.getValue()).hasSize(expected.size()); + for (int i = 0; i < expected.size(); i++) { + assertThat(allowedSubnetsArgumentCaptor.getValue().get(i).toString()) + .isEqualTo(expected.get(i)); + } } - @Test - public void netRestrictInvalidShouldFail() { - final String subnet = "127.0.0.1/abc"; + @ParameterizedTest + @ValueSource(strings = {"127.0.0.1/abc", "abc", ""}) + public void netRestrictInvalidShouldFail(final String subnet) { parseCommand("--net-restrict", subnet); verifyNoInteractions(mockRunnerBuilder); assertThat(commandErrorOutput.toString(UTF_8)) diff --git a/app/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java b/app/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java index 91e8e3b3c46..6a07d1d965a 100644 --- a/app/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java +++ b/app/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java @@ -114,12 +114,12 @@ import java.util.function.Function; import java.util.function.Supplier; +import inet.ipaddr.IPAddress; import io.opentelemetry.api.GlobalOpenTelemetry; import io.vertx.core.Vertx; import io.vertx.core.json.JsonObject; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; -import org.apache.commons.net.util.SubnetUtils.SubnetInfo; import org.apache.commons.text.StringEscapeUtils; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; @@ -276,7 +276,7 @@ public abstract class CommandTestAbstract { @Captor protected ArgumentCaptor apiConfigurationCaptor; @Captor protected ArgumentCaptor ethstatsOptionsArgumentCaptor; - @Captor protected ArgumentCaptor> allowedSubnetsArgumentCaptor; + @Captor protected ArgumentCaptor> allowedSubnetsArgumentCaptor; @BeforeEach public void initMocks() throws Exception { diff --git a/app/src/test/java/org/hyperledger/besu/cli/converter/SubnetInfoConverterTest.java b/app/src/test/java/org/hyperledger/besu/cli/converter/SubnetCidrConverterTest.java similarity index 50% rename from app/src/test/java/org/hyperledger/besu/cli/converter/SubnetInfoConverterTest.java rename to app/src/test/java/org/hyperledger/besu/cli/converter/SubnetCidrConverterTest.java index aaeb4536142..e4c0f49d829 100644 --- a/app/src/test/java/org/hyperledger/besu/cli/converter/SubnetInfoConverterTest.java +++ b/app/src/test/java/org/hyperledger/besu/cli/converter/SubnetCidrConverterTest.java @@ -15,45 +15,58 @@ package org.hyperledger.besu.cli.converter; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.assertj.core.api.Assertions.assertThatThrownBy; -import org.apache.commons.net.util.SubnetUtils.SubnetInfo; +import inet.ipaddr.IPAddress; import org.junit.jupiter.api.Test; +import picocli.CommandLine; -public class SubnetInfoConverterTest { +public class SubnetCidrConverterTest { @Test void testCreateIpRestrictionHandlerWithValidSubnets() { String subnet = "192.168.1.0/24"; - assertThat(parseSubnetRules(subnet).getCidrSignature()).isEqualTo(subnet); + IPAddress result = parseSubnetRules(subnet); + assertThat(result.toString()).isEqualTo(subnet); + } + + @Test + void testCreateIpRestrictionHandlerWithValidIpv6Subnet() { + IPAddress result = parseSubnetRules("fd00::/64"); + assertThat(result.toString()).isEqualTo("fd00::/64"); } @Test void testCreateIpRestrictionHandlerWithInvalidSubnet() { - assertThrows(IllegalArgumentException.class, () -> parseSubnetRules("abc")); + assertThatThrownBy(() -> parseSubnetRules("abc")) + .isInstanceOf(CommandLine.TypeConversionException.class); } @Test void testCreateIpRestrictionHandlerMissingCIDR() { - assertThrows(IllegalArgumentException.class, () -> parseSubnetRules("192.168.1.0")); + assertThatThrownBy(() -> parseSubnetRules("192.168.1.0")) + .isInstanceOf(CommandLine.TypeConversionException.class); } @Test void testCreateIpRestrictionHandlerBigCIDR() { - assertThrows(IllegalArgumentException.class, () -> parseSubnetRules("192.168.1.0:25")); + assertThatThrownBy(() -> parseSubnetRules("192.168.1.0:25")) + .isInstanceOf(CommandLine.TypeConversionException.class); } @Test void testCreateIpRestrictionHandlerWithInvalidCIDR() { - assertThrows(IllegalArgumentException.class, () -> parseSubnetRules("192.168.1.0/abc")); + assertThatThrownBy(() -> parseSubnetRules("192.168.1.0/abc")) + .isInstanceOf(CommandLine.TypeConversionException.class); } @Test void testCreateIpRestrictionHandlerWithEmptyString() { - assertThrows(IllegalArgumentException.class, () -> parseSubnetRules("")); + assertThatThrownBy(() -> parseSubnetRules("")) + .isInstanceOf(CommandLine.TypeConversionException.class); } - private SubnetInfo parseSubnetRules(final String subnet) { - return new SubnetInfoConverter().convert(subnet); + private IPAddress parseSubnetRules(final String subnet) { + return new SubnetCidrConverter().convert(subnet); } } diff --git a/ethereum/p2p/build.gradle b/ethereum/p2p/build.gradle index 8f599bceddb..cd14a720cb2 100644 --- a/ethereum/p2p/build.gradle +++ b/ethereum/p2p/build.gradle @@ -56,7 +56,7 @@ dependencies { implementation 'org.jetbrains.kotlin:kotlin-stdlib' implementation 'org.owasp.encoder:encoder' implementation 'org.xerial.snappy:snappy-java' - implementation 'commons-net:commons-net' + implementation 'com.github.seancfoley:ipaddress' annotationProcessor "org.immutables:value" implementation "org.immutables:value-annotations" diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/P2PDiscoveryConfiguration.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/P2PDiscoveryConfiguration.java index 0a4c3b06073..8a0ef672905 100644 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/P2PDiscoveryConfiguration.java +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/P2PDiscoveryConfiguration.java @@ -20,7 +20,7 @@ import java.util.List; import java.util.Optional; -import org.apache.commons.net.util.SubnetUtils; +import inet.ipaddr.IPAddress; import org.apache.tuweni.bytes.Bytes; public record P2PDiscoveryConfiguration( @@ -37,7 +37,7 @@ public record P2PDiscoveryConfiguration( Percentage maxRemoteConnectionsPercentage, Boolean randomPeerPriority, Collection bannedNodeIds, - List allowedSubnets, + List allowedSubnets, Boolean poaDiscoveryRetryBootnodes, List bootNodes, String discoveryDnsUrl, diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/permissions/PeerPermissionSubnet.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/permissions/PeerPermissionSubnet.java index 720cd4dd609..bc24564b654 100644 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/permissions/PeerPermissionSubnet.java +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/permissions/PeerPermissionSubnet.java @@ -18,7 +18,8 @@ import java.util.List; -import org.apache.commons.net.util.SubnetUtils.SubnetInfo; +import inet.ipaddr.IPAddress; +import inet.ipaddr.IPAddressString; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,6 +30,8 @@ * allows for the configuration of permitted subnets and uses these configurations to determine * whether a peer should be allowed or denied access based on its IP address. * + *

Supports both IPv4 and IPv6 subnets. + * *

Note: If no subnets are specified, all peers are considered permitted by default. * * @see PeerPermissions @@ -36,15 +39,15 @@ public class PeerPermissionSubnet extends PeerPermissions { private static final Logger LOG = LoggerFactory.getLogger(PeerPermissionSubnet.class); - private final List allowedSubnets; + private final List allowedSubnets; /** * Constructs a new {@code PeerPermissionSubnet} instance with specified allowed subnets. * - * @param allowedSubnets A list of {@link SubnetInfo} objects representing the subnets that are - * allowed to interact with the local node. Cannot be {@code null}. + * @param allowedSubnets A list of {@link IPAddress} prefix blocks representing the subnets that + * are allowed to interact with the local node. Cannot be {@code null}. */ - public PeerPermissionSubnet(final List allowedSubnets) { + public PeerPermissionSubnet(final List allowedSubnets) { this.allowedSubnets = allowedSubnets; } @@ -66,9 +69,14 @@ public boolean isPermitted(final Peer localNode, final Peer remotePeer, final Ac if (allowedSubnets == null || allowedSubnets.isEmpty()) { return true; } - String remotePeerHostAddress = remotePeer.getEnodeURL().getIpAsString(); - for (SubnetInfo subnet : allowedSubnets) { - if (subnet.isInRange(remotePeerHostAddress)) { + final String remotePeerHostAddress = remotePeer.getEnodeURL().getIpAsString(); + final IPAddress remoteAddress = new IPAddressString(remotePeerHostAddress).getAddress(); + if (remoteAddress == null) { + LOG.trace("Could not parse peer address: {}", remotePeerHostAddress); + return false; + } + for (final IPAddress subnet : allowedSubnets) { + if (subnet.contains(remoteAddress)) { return true; } } diff --git a/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/permissions/PeerPermissionsSubnetTest.java b/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/permissions/PeerPermissionsSubnetTest.java index 185858e658e..4659edfadc6 100644 --- a/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/permissions/PeerPermissionsSubnetTest.java +++ b/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/permissions/PeerPermissionsSubnetTest.java @@ -23,31 +23,31 @@ import java.util.List; -import org.apache.commons.net.util.SubnetUtils; -import org.apache.commons.net.util.SubnetUtils.SubnetInfo; +import inet.ipaddr.IPAddress; +import inet.ipaddr.IPAddressString; import org.junit.jupiter.api.Test; public class PeerPermissionsSubnetTest { - private final Peer remoteNode = createPeer(); + private final Peer remoteNode = createPeer("127.0.0.1"); @Test public void peerInSubnetRangeShouldBePermitted() { - List allowedSubnets = List.of(subnet("127.0.0.0/24")); + List allowedSubnets = List.of(subnet("127.0.0.0/24")); PeerPermissionSubnet peerPermissionSubnet = new PeerPermissionSubnet(allowedSubnets); checkPermissions(peerPermissionSubnet, remoteNode, true); } @Test public void peerInAtLeastOneSubnetRangeShouldBePermitted() { - List allowedSubnets = List.of(subnet("127.0.0.0/24"), subnet("10.0.0.1/24")); + List allowedSubnets = List.of(subnet("127.0.0.0/24"), subnet("10.0.0.1/24")); PeerPermissionSubnet peerPermissionSubnet = new PeerPermissionSubnet(allowedSubnets); checkPermissions(peerPermissionSubnet, remoteNode, true); } @Test public void peerOutSubnetRangeShouldNotBePermitted() { - List allowedSubnets = List.of(subnet("10.0.0.0/24")); + List allowedSubnets = List.of(subnet("10.0.0.0/24")); PeerPermissionSubnet peerPermissionSubnet = new PeerPermissionSubnet(allowedSubnets); checkPermissions(peerPermissionSubnet, remoteNode, false); } @@ -58,23 +58,39 @@ public void peerShouldBePermittedIfNoSubnets() { checkPermissions(peerPermissionSubnet, remoteNode, true); } + @Test + public void ipv6PeerInSubnetRangeShouldBePermitted() { + Peer ipv6Peer = createPeer("fd00::1"); + List allowedSubnets = List.of(subnet("fd00::/64")); + PeerPermissionSubnet peerPermissionSubnet = new PeerPermissionSubnet(allowedSubnets); + checkPermissions(peerPermissionSubnet, ipv6Peer, true); + } + + @Test + public void ipv6PeerOutSubnetRangeShouldNotBePermitted() { + Peer ipv6Peer = createPeer("fe80::1"); + List allowedSubnets = List.of(subnet("fd00::/64")); + PeerPermissionSubnet peerPermissionSubnet = new PeerPermissionSubnet(allowedSubnets); + checkPermissions(peerPermissionSubnet, ipv6Peer, false); + } + private void checkPermissions( final PeerPermissions peerPermissions, final Peer remotePeer, final boolean expectedResult) { for (Action action : Action.values()) { - assertThat(peerPermissions.isPermitted(createPeer(), remotePeer, action)) + assertThat(peerPermissions.isPermitted(createPeer("127.0.0.1"), remotePeer, action)) .isEqualTo(expectedResult); } } - private SubnetInfo subnet(final String subnet) { - return new SubnetUtils(subnet).getInfo(); + private IPAddress subnet(final String cidr) { + return new IPAddressString(cidr).getAddress().toPrefixBlock(); } - private Peer createPeer() { + private Peer createPeer(final String ip) { return DefaultPeer.fromEnodeURL( EnodeURLImpl.builder() .nodeId(Peer.randomId()) - .ipAddress("127.0.0.1") + .ipAddress(ip) .discoveryAndListeningPorts(EnodeURLImpl.DEFAULT_LISTENING_PORT) .build()); } diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 10264c16e9e..9315d954fed 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -567,6 +567,14 @@ + + + + + + + + @@ -1669,6 +1677,9 @@ + + + diff --git a/platform/build.gradle b/platform/build.gradle index 6070878141f..b362b07c390 100644 --- a/platform/build.gradle +++ b/platform/build.gradle @@ -94,9 +94,9 @@ dependencies { api 'com.squareup.okhttp3:okhttp:4.12.0' - api 'commons-io:commons-io:2.21.0' + api 'com.github.seancfoley:ipaddress:5.6.1' - api 'commons-net:commons-net:3.12.0' + api 'commons-io:commons-io:2.21.0' api 'dnsjava:dnsjava:3.6.4'