diff --git a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/Endpoint.java b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/Endpoint.java index 41cec4ac5f3..763ca4cc6a8 100644 --- a/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/Endpoint.java +++ b/ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/discovery/Endpoint.java @@ -29,12 +29,15 @@ import com.google.common.net.InetAddresses; import org.apache.tuweni.bytes.Bytes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Encapsulates the network coordinates of a {@link DiscoveryPeer} as well as serialization logic * used in various Discovery messages. */ public class Endpoint { + private static final Logger LOG = LoggerFactory.getLogger(Endpoint.class); private final Optional host; private final int udpPort; private final Optional tcpPort; @@ -49,15 +52,16 @@ public Endpoint(final String host, final int udpPort, final Optional tc } public static Endpoint fromEnode(final EnodeURL enode) { - final int discoveryPort = - enode - .getDiscoveryPort() - .orElseThrow( - () -> - new IllegalArgumentException( - "Attempt to create a discovery endpoint for an enode with discovery disabled.")); + Optional discoveryPort = enode.getDiscoveryPort(); + + if (discoveryPort.isEmpty()) { + int defaultPort = EnodeURLImpl.DEFAULT_LISTENING_PORT; + LOG.debug("Discovery disabled for enode {}. Using default port {}.", enode, defaultPort); + return new Endpoint(enode.getIp().getHostAddress(), defaultPort, Optional.empty()); + } + final Optional listeningPort = enode.getListeningPort(); - return new Endpoint(enode.getIp().getHostAddress(), discoveryPort, listeningPort); + return new Endpoint(enode.getIp().getHostAddress(), discoveryPort.get(), listeningPort); } public EnodeURL toEnode(final Bytes nodeId) { diff --git a/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/PeerDiscoveryAgentTest.java b/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/PeerDiscoveryAgentTest.java index 57eb6f518b9..8205bad5864 100644 --- a/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/PeerDiscoveryAgentTest.java +++ b/ethereum/p2p/src/test/java/org/hyperledger/besu/ethereum/p2p/discovery/PeerDiscoveryAgentTest.java @@ -18,6 +18,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; @@ -45,6 +46,8 @@ import org.hyperledger.besu.ethereum.p2p.permissions.PeerPermissionsDenylist; import org.hyperledger.besu.plugin.data.EnodeURL; +import java.net.InetAddress; +import java.net.UnknownHostException; import java.util.Collections; import java.util.List; import java.util.Optional; @@ -898,6 +901,23 @@ public void assertHostCorrectlyRevertsOnIgnoredPacketFrom() { assertThat(PeerDiscoveryAgent.deriveHost(source, mockWellFormed)).isEqualTo(routableHost); } + @Test + void testFromEnodeWithDiscoveryDisabled() throws UnknownHostException { + EnodeURL enodeWithNoDiscovery = mock(EnodeURL.class); + when(enodeWithNoDiscovery.getDiscoveryPort()).thenReturn(Optional.empty()); + when(enodeWithNoDiscovery.getListeningPort()).thenReturn(Optional.of(8545)); + + when(enodeWithNoDiscovery.getIp()).thenReturn(InetAddress.getLoopbackAddress()); + + Endpoint result = Endpoint.fromEnode(enodeWithNoDiscovery); + + assertEquals("127.0.0.1", result.getHost()); + + assertEquals(EnodeURLImpl.DEFAULT_LISTENING_PORT, result.getUdpPort()); + + assertEquals(Optional.empty(), result.getTcpPort()); + } + protected void bondViaIncomingPing( final MockPeerDiscoveryAgent agent, final MockPeerDiscoveryAgent otherNode) { final Packet pingPacket = helper.createPingPacket(otherNode, agent);