From ae528fc7cb375b16e9f4d2569422aaea5bf52634 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Tue, 5 Mar 2019 07:21:07 +1000 Subject: [PATCH] Ensure devp2p ports are written to ports file correctly (#1020) Start P2P network synchronously so the ports are guaranteed to be known before we write the ports file Include the P2P TCP port in ports file even when peer discovery is disabled. Load information from the advertised peer rather than the discovery listening socket. Fix admin_nodeInfo to include the ?discport param in the enode URI when the discovery port differs from the P2P port. Signed-off-by: Adrian Sutton --- .../eth/transactions/TestNodeList.java | 2 +- .../internal/methods/AdminNodeInfo.java | 37 +++++++++---------- .../internal/methods/AdminNodeInfoTest.java | 24 ++++++++---- .../ethereum/p2p/testing/MockNetwork.java | 8 ++-- .../pantheon/ethereum/p2p/NetworkRunner.java | 13 +------ .../pantheon/ethereum/p2p/NoopP2PNetwork.java | 8 ++-- .../pantheon/ethereum/p2p/api/P2PNetwork.java | 11 +++--- .../p2p/discovery/PeerDiscoveryAgent.java | 12 +----- .../internal/PeerDiscoveryController.java | 4 +- .../ethereum/p2p/netty/NettyP2PNetwork.java | 20 ++++------ .../pantheon/ethereum/p2p/peers/Peer.java | 4 +- .../ethereum/p2p/NettyP2PNetworkTest.java | 26 ++++++------- .../p2p/NetworkingServiceLifecycleTest.java | 37 +++++++++++-------- .../p2p/discovery/PeerDiscoveryAgentTest.java | 8 ++-- .../discovery/PeerDiscoveryBondingTest.java | 5 ++- .../PeerDiscoveryBootstrappingTest.java | 22 +++++++---- .../discovery/PeerDiscoveryObserversTest.java | 5 ++- .../discovery/PeerDiscoveryTestHelper.java | 3 +- .../PeerDiscoveryTimestampsTest.java | 4 +- .../internal/MockPeerDiscoveryAgent.java | 2 +- .../java/tech/pegasys/pantheon/Runner.java | 20 +++++++--- .../tech/pegasys/pantheon/RunnerTest.java | 18 +++------ .../pantheon/util/bytes/BytesValue.java | 5 +++ 23 files changed, 152 insertions(+), 146 deletions(-) diff --git a/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/transactions/TestNodeList.java b/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/transactions/TestNodeList.java index 86a928d3ef..071c9ecc26 100644 --- a/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/transactions/TestNodeList.java +++ b/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/transactions/TestNodeList.java @@ -61,7 +61,7 @@ public class TestNodeList implements Closeable { public void startNetworks() { for (final TestNode node : nodes) { - node.network.run(); + node.network.start(); } } diff --git a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/AdminNodeInfo.java b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/AdminNodeInfo.java index 301ba30b8e..75dc165744 100644 --- a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/AdminNodeInfo.java +++ b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/AdminNodeInfo.java @@ -22,15 +22,13 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcResponse; import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcSuccessResponse; import tech.pegasys.pantheon.ethereum.p2p.P2pDisabledException; import tech.pegasys.pantheon.ethereum.p2p.api.P2PNetwork; +import tech.pegasys.pantheon.ethereum.p2p.wire.PeerInfo; import tech.pegasys.pantheon.util.bytes.BytesValue; -import java.net.InetAddress; -import java.net.InetSocketAddress; import java.util.HashMap; import java.util.Map; import com.google.common.collect.ImmutableMap; -import com.google.common.net.InetAddresses; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -67,25 +65,26 @@ public class AdminNodeInfo implements JsonRpcMethod { try { final Map response = new HashMap<>(); - final BytesValue nodeId = peerNetwork.getLocalPeerInfo().getNodeId(); - final InetSocketAddress address = peerNetwork.getDiscoverySocketAddress(); - final int port = peerNetwork.getLocalPeerInfo().getPort(); + final Map ports = new HashMap<>(); - final InetAddress inetAddress = address.getAddress(); - response.put( - "enode", - "enode://" - + nodeId.toString().substring(2) - + "@" - + InetAddresses.toUriString(inetAddress) - + ":" - + port); + final PeerInfo peerInfo = peerNetwork.getLocalPeerInfo(); + final BytesValue nodeId = peerInfo.getNodeId(); + peerNetwork + .getAdvertisedPeer() + .ifPresent( + advertisedPeer -> { + response.put("enode", advertisedPeer.getEnodeURI()); + ports.put("discovery", advertisedPeer.getEndpoint().getUdpPort()); + response.put("ip", advertisedPeer.getEndpoint().getHost()); + response.put( + "listenAddr", + advertisedPeer.getEndpoint().getHost() + ":" + peerInfo.getPort()); + }); response.put("id", nodeId.toString().substring(2)); - // this doesn't provide a useful value yet. - // response.put("ip", inetAddress.getHostAddress()); - response.put("listenAddr", InetAddresses.toUriString(inetAddress) + ":" + port); response.put("name", clientVersion); - response.put("ports", ImmutableMap.of("discovery", port, "listener", port /*??*/)); + + ports.put("listener", peerInfo.getPort()); + response.put("ports", ports); final ChainHead chainHead = blockchainQueries.getBlockchain().getChainHead(); response.put( diff --git a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/AdminNodeInfoTest.java b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/AdminNodeInfoTest.java index 0471d1b42a..3a61914e7c 100644 --- a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/AdminNodeInfoTest.java +++ b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/AdminNodeInfoTest.java @@ -14,6 +14,7 @@ package tech.pegasys.pantheon.ethereum.jsonrpc.internal.methods; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.when; import tech.pegasys.pantheon.config.GenesisConfigOptions; @@ -25,11 +26,11 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.internal.JsonRpcRequest; import tech.pegasys.pantheon.ethereum.jsonrpc.internal.queries.BlockchainQueries; import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcSuccessResponse; import tech.pegasys.pantheon.ethereum.p2p.api.P2PNetwork; +import tech.pegasys.pantheon.ethereum.p2p.peers.DefaultPeer; import tech.pegasys.pantheon.ethereum.p2p.wire.PeerInfo; import tech.pegasys.pantheon.util.bytes.BytesValue; import tech.pegasys.pantheon.util.uint.UInt256; -import java.net.InetSocketAddress; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -51,17 +52,19 @@ public class AdminNodeInfoTest { private AdminNodeInfo method; - private final PeerInfo localPeer = - new PeerInfo(5, "0x0", Collections.emptyList(), 30303, BytesValue.EMPTY); - private final InetSocketAddress discoverySocketAddress = new InetSocketAddress("1.2.3.4", 7890); + private final BytesValue nodeId = + BytesValue.fromHexString( + "0x0f1b319e32017c3fcb221841f0f978701b4e9513fe6a567a2db43d43381a9c7e3dfe7cae13cbc2f56943400bacaf9082576ab087cd51983b17d729ae796f6807"); + private final PeerInfo localPeer = new PeerInfo(5, "0x0", Collections.emptyList(), 30303, nodeId); private final ChainHead testChainHead = new ChainHead(Hash.EMPTY, UInt256.ONE); private final GenesisConfigOptions genesisConfigOptions = new StubGenesisConfigOptions().chainId(2019); + private final DefaultPeer defaultPeer = new DefaultPeer(nodeId, "1.2.3.4", 7890, 30303); @Before public void setup() { when(p2pNetwork.getLocalPeerInfo()).thenReturn(localPeer); - when(p2pNetwork.getDiscoverySocketAddress()).thenReturn(discoverySocketAddress); + doReturn(Optional.of(this.defaultPeer)).when(p2pNetwork).getAdvertisedPeer(); when(blockchainQueries.getBlockchain()).thenReturn(blockchain); when(blockchainQueries.getBlockHashByNumber(anyLong())).thenReturn(Optional.of(Hash.EMPTY)); when(blockchain.getChainHead()).thenReturn(testChainHead); @@ -77,11 +80,16 @@ public class AdminNodeInfoTest { final JsonRpcSuccessResponse actual = (JsonRpcSuccessResponse) method.response(request); final Map expected = new HashMap<>(); - expected.put("enode", "enode://@1.2.3.4:30303"); - expected.put("id", ""); + expected.put( + "enode", + "enode://0f1b319e32017c3fcb221841f0f978701b4e9513fe6a567a2db43d43381a9c7e3dfe7cae13cbc2f56943400bacaf9082576ab087cd51983b17d729ae796f6807@1.2.3.4:30303?discport=7890"); + expected.put( + "id", + "0f1b319e32017c3fcb221841f0f978701b4e9513fe6a567a2db43d43381a9c7e3dfe7cae13cbc2f56943400bacaf9082576ab087cd51983b17d729ae796f6807"); + expected.put("ip", "1.2.3.4"); expected.put("listenAddr", "1.2.3.4:30303"); expected.put("name", "testnet/1.0/this/that"); - expected.put("ports", ImmutableMap.of("discovery", 30303, "listener", 30303)); + expected.put("ports", ImmutableMap.of("discovery", 7890, "listener", 30303)); expected.put( "protocols", ImmutableMap.of( 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 f48c27b2d9..b271f006cc 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 @@ -17,6 +17,7 @@ import tech.pegasys.pantheon.ethereum.p2p.api.Message; import tech.pegasys.pantheon.ethereum.p2p.api.MessageData; import tech.pegasys.pantheon.ethereum.p2p.api.P2PNetwork; import tech.pegasys.pantheon.ethereum.p2p.api.PeerConnection; +import tech.pegasys.pantheon.ethereum.p2p.peers.DefaultPeer; import tech.pegasys.pantheon.ethereum.p2p.peers.Peer; import tech.pegasys.pantheon.ethereum.p2p.wire.Capability; import tech.pegasys.pantheon.ethereum.p2p.wire.DefaultMessage; @@ -25,7 +26,6 @@ import tech.pegasys.pantheon.ethereum.p2p.wire.messages.DisconnectMessage.Discon import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController; import tech.pegasys.pantheon.util.Subscribers; -import java.net.InetSocketAddress; import java.net.SocketAddress; import java.util.ArrayList; import java.util.Collection; @@ -177,12 +177,12 @@ public final class MockNetwork { public void awaitStop() {} @Override - public InetSocketAddress getDiscoverySocketAddress() { - return null; + public Optional getAdvertisedPeer() { + return Optional.of(new DefaultPeer(self.getId(), "127.0.0.1", 0, 0)); } @Override - public void run() {} + public void start() {} @Override public void close() {} diff --git a/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/NetworkRunner.java b/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/NetworkRunner.java index e209c4d40c..0eee7adb9b 100644 --- a/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/NetworkRunner.java +++ b/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/NetworkRunner.java @@ -29,7 +29,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -37,7 +36,6 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Function; import java.util.stream.Collectors; -import com.google.common.util.concurrent.ThreadFactoryBuilder; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -48,9 +46,6 @@ public class NetworkRunner implements AutoCloseable { private final AtomicBoolean started = new AtomicBoolean(false); private final AtomicBoolean stopped = new AtomicBoolean(false); - private final ExecutorService networkExecutor = - Executors.newFixedThreadPool( - 1, new ThreadFactoryBuilder().setNameFormat(this.getClass().getSimpleName()).build()); private final ScheduledExecutorService networkCheckExecutor = Executors.newSingleThreadScheduledExecutor(); @@ -89,7 +84,7 @@ public class NetworkRunner implements AutoCloseable { if (started.compareAndSet(false, true)) { LOG.info("Starting Network."); setupHandlers(); - networkExecutor.submit(network); + network.start(); networkCheckExecutor.scheduleWithFixedDelay( network::checkMaintainedConnectionPeers, 60, 60, TimeUnit.SECONDS); } else { @@ -104,7 +99,6 @@ public class NetworkRunner implements AutoCloseable { for (final ProtocolManager protocolManager : protocolManagers) { protocolManager.stop(); } - networkExecutor.shutdown(); networkCheckExecutor.shutdown(); shutdown.countDown(); } else { @@ -118,11 +112,6 @@ public class NetworkRunner implements AutoCloseable { for (final ProtocolManager protocolManager : protocolManagers) { protocolManager.awaitStop(); } - if (!networkExecutor.awaitTermination(2L, TimeUnit.MINUTES)) { - LOG.error("Network executor did not shutdown cleanly."); - networkExecutor.shutdownNow(); - networkExecutor.awaitTermination(2L, TimeUnit.MINUTES); - } LOG.info("Network stopped."); } 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 7a0c01a71c..90e28175f6 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 @@ -22,7 +22,6 @@ import tech.pegasys.pantheon.ethereum.p2p.wire.PeerInfo; import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController; import java.io.IOException; -import java.net.InetSocketAddress; import java.util.Collection; import java.util.Optional; import java.util.concurrent.CompletableFuture; @@ -63,9 +62,8 @@ public class NoopP2PNetwork implements P2PNetwork { public void awaitStop() {} @Override - public InetSocketAddress getDiscoverySocketAddress() { - throw new P2pDisabledException( - "P2P networking disabled. Discovery socket address unavailable."); + public Optional getAdvertisedPeer() { + return Optional.empty(); } @Override @@ -92,5 +90,5 @@ public class NoopP2PNetwork implements P2PNetwork { public void close() throws IOException {} @Override - public void run() {} + public void start() {} } 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 97d88f7c31..ab02c38113 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 @@ -18,14 +18,15 @@ import tech.pegasys.pantheon.ethereum.p2p.wire.PeerInfo; import tech.pegasys.pantheon.ethereum.permissioning.NodeWhitelistController; import java.io.Closeable; -import java.net.InetSocketAddress; import java.util.Collection; import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.function.Consumer; /** P2P Network Interface. */ -public interface P2PNetwork extends Closeable, Runnable { +public interface P2PNetwork extends Closeable { + + void start(); /** * Returns a snapshot of the currently connected peer connections. @@ -44,8 +45,8 @@ public interface P2PNetwork extends Closeable, Runnable { /** * Subscribe a {@link Consumer} to all incoming {@link Message} of a given sub-protocol. Calling - * {@link #run()} on an implementation without at least having one subscribed {@link Consumer} per - * supported sub-protocol should throw a {@link RuntimeException}. + * {@link #start()} on an implementation without at least having one subscribed {@link Consumer} + * per supported sub-protocol should throw a {@link RuntimeException}. * * @param capability Capability (sub-protocol) to subscribe to. * @param consumer Consumer to subscribe @@ -87,7 +88,7 @@ public interface P2PNetwork extends Closeable, Runnable { /** Blocks until the P2P network layer has stopped. */ void awaitStop(); - InetSocketAddress getDiscoverySocketAddress(); + Optional getAdvertisedPeer(); /** * Returns {@link PeerInfo} object for this node 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 94a83c1f48..44b66ca12a 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 @@ -14,7 +14,6 @@ package tech.pegasys.pantheon.ethereum.p2p.discovery; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static tech.pegasys.pantheon.util.bytes.BytesValue.wrapBuffer; @@ -83,7 +82,6 @@ public abstract class PeerDiscoveryAgent implements DisconnectCallback { /* This is the {@link tech.pegasys.pantheon.ethereum.p2p.Peer} object holding who we are. */ private DiscoveryPeer advertisedPeer; - private InetSocketAddress localAddress; /* Is discovery enabled? */ private boolean isActive = false; @@ -135,7 +133,6 @@ public abstract class PeerDiscoveryAgent implements DisconnectCallback { .thenAccept( (InetSocketAddress localAddress) -> { // Once listener is set up, finish initializing - this.localAddress = localAddress; advertisedPeer = new DiscoveryPeer( id, config.getAdvertisedHost(), localAddress.getPort(), tcpPort); @@ -221,19 +218,14 @@ public abstract class PeerDiscoveryAgent implements DisconnectCallback { .orElse(Collections.emptyList()); } - public DiscoveryPeer getAdvertisedPeer() { - return advertisedPeer; + public Optional getAdvertisedPeer() { + return Optional.ofNullable(advertisedPeer); } public BytesValue getId() { return id; } - public InetSocketAddress localAddress() { - checkState(localAddress != null, "Uninitialized discovery agent"); - return localAddress; - } - /** * Adds an observer that will get called when a new peer is bonded with and added to the peer * table. 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 86bbd60daf..ac405bb6e3 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 @@ -164,7 +164,7 @@ public class PeerDiscoveryController { this.peerDroppedObservers = peerDroppedObservers; } - public CompletableFuture start() { + public void start() { if (!started.compareAndSet(false, true)) { throw new IllegalStateException("The peer table had already been started"); } @@ -199,8 +199,6 @@ public class PeerDiscoveryController { nodeWhitelistController.ifPresent( c -> c.subscribeToListUpdatedEvent(this::handleNodeWhitelistUpdatedEvent)); - - return CompletableFuture.completedFuture(null); } public CompletableFuture stop() { 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 8327f4445d..a3f6807123 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 @@ -467,16 +467,12 @@ public class NettyP2PNetwork implements P2PNetwork { } @Override - public void run() { - try { - peerDiscoveryAgent.start(ourPeerInfo.getPort()).join(); - peerBondedObserverId = - OptionalLong.of(peerDiscoveryAgent.observePeerBondedEvents(handlePeerBondedEvent())); - peerDroppedObserverId = - OptionalLong.of(peerDiscoveryAgent.observePeerDroppedEvents(handlePeerDroppedEvents())); - } catch (final Exception ex) { - throw new IllegalStateException(ex); - } + public void start() { + peerDiscoveryAgent.start(ourPeerInfo.getPort()).join(); + peerBondedObserverId = + OptionalLong.of(peerDiscoveryAgent.observePeerBondedEvents(handlePeerBondedEvent())); + peerDroppedObserverId = + OptionalLong.of(peerDiscoveryAgent.observePeerDroppedEvents(handlePeerDroppedEvents())); } private Consumer handlePeerBondedEvent() { @@ -546,8 +542,8 @@ public class NettyP2PNetwork implements P2PNetwork { } @Override - public InetSocketAddress getDiscoverySocketAddress() { - return peerDiscoveryAgent.localAddress(); + public Optional getAdvertisedPeer() { + return peerDiscoveryAgent.getAdvertisedPeer(); } @Override diff --git a/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/peers/Peer.java b/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/peers/Peer.java index a3bafdf49d..f6dcf9a7c2 100644 --- a/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/peers/Peer.java +++ b/ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/peers/Peer.java @@ -18,8 +18,6 @@ import tech.pegasys.pantheon.util.bytes.BytesValue; import java.util.OptionalInt; -import org.bouncycastle.util.encoders.Hex; - public interface Peer extends PeerId { /** @@ -60,7 +58,7 @@ public interface Peer extends PeerId { * @return The enode URI as a String. */ default String getEnodeURI() { - String url = Hex.toHexString(this.getId().extractArray()); + String url = this.getId().toUnprefixedString(); Endpoint endpoint = this.getEndpoint(); String nodeIp = endpoint.getHost(); OptionalInt tcpPort = endpoint.getTcpPort(); 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 f710ee2565..d637efe256 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 @@ -105,8 +105,8 @@ public final class NettyP2PNetworkTest { Optional.empty())) { final int listenPort = listener.getLocalPeerInfo().getPort(); - listener.run(); - connector.run(); + listener.start(); + connector.start(); final BytesValue listenId = listenKp.getPublicKey().getEncodedBytes(); assertThat( connector @@ -158,8 +158,8 @@ public final class NettyP2PNetworkTest { new NoOpMetricsSystem(), Optional.empty())) { final int listenPort = listener.getLocalPeerInfo().getPort(); - listener.run(); - connector.run(); + listener.start(); + connector.start(); final BytesValue listenId = listenKp.getPublicKey().getEncodedBytes(); assertThat( connector @@ -242,8 +242,8 @@ public final class NettyP2PNetworkTest { final int listenPort = listener.getLocalPeerInfo().getPort(); // Setup listener and first connection - listener.run(); - connector1.run(); + listener.start(); + connector1.start(); final BytesValue listenId = listenKp.getPublicKey().getEncodedBytes(); final Peer listeningPeer = new DefaultPeer( @@ -263,7 +263,7 @@ public final class NettyP2PNetworkTest { peerFuture.complete(peerConnection); reasonFuture.complete(reason); }); - connector2.run(); + connector2.start(); assertThat(connector2.connect(listeningPeer).get(30L, TimeUnit.SECONDS).getPeer().getNodeId()) .isEqualTo(listenId); assertThat(peerFuture.get(30L, TimeUnit.SECONDS).getPeer().getNodeId()).isEqualTo(listenId); @@ -308,8 +308,8 @@ public final class NettyP2PNetworkTest { new NoOpMetricsSystem(), Optional.empty())) { final int listenPort = listener.getLocalPeerInfo().getPort(); - listener.run(); - connector.run(); + listener.start(); + connector.start(); final BytesValue listenId = listenKp.getPublicKey().getEncodedBytes(); final Peer listenerPeer = @@ -383,8 +383,8 @@ public final class NettyP2PNetworkTest { // Blacklist the remote peer localBlacklist.add(remotePeer); - localNetwork.run(); - remoteNetwork.run(); + localNetwork.start(); + remoteNetwork.start(); // Setup disconnect listener final CompletableFuture peerFuture = new CompletableFuture<>(); @@ -461,8 +461,8 @@ public final class NettyP2PNetworkTest { localListenPort, OptionalInt.of(localListenPort))); - localNetwork.run(); - remoteNetwork.run(); + localNetwork.start(); + remoteNetwork.start(); // Setup disconnect listener final CompletableFuture peerFuture = new CompletableFuture<>(); diff --git a/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/NetworkingServiceLifecycleTest.java b/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/NetworkingServiceLifecycleTest.java index b1791a6020..784e4d5eb6 100644 --- a/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/NetworkingServiceLifecycleTest.java +++ b/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/NetworkingServiceLifecycleTest.java @@ -26,10 +26,10 @@ import tech.pegasys.pantheon.ethereum.p2p.discovery.PeerDiscoveryServiceExceptio import tech.pegasys.pantheon.ethereum.p2p.netty.NettyP2PNetwork; import tech.pegasys.pantheon.ethereum.p2p.peers.PeerBlacklist; import tech.pegasys.pantheon.metrics.noop.NoOpMetricsSystem; -import tech.pegasys.pantheon.util.NetworkUtility; import java.io.IOException; import java.util.Optional; +import java.util.OptionalInt; import io.vertx.core.Vertx; import org.assertj.core.api.Assertions; @@ -48,22 +48,27 @@ public class NetworkingServiceLifecycleTest { @Test public void createPeerDiscoveryAgent() { final SECP256K1.KeyPair keyPair = SECP256K1.KeyPair.generate(); + final NetworkingConfiguration config = configWithRandomPorts(); try (final NettyP2PNetwork service = new NettyP2PNetwork( vertx, keyPair, - configWithRandomPorts(), + config, emptyList(), () -> true, new PeerBlacklist(), new NoOpMetricsSystem(), Optional.empty())) { - service.run(); - final int port = service.getDiscoverySocketAddress().getPort(); + service.start(); + final int udpPort = service.getAdvertisedPeer().get().getEndpoint().getUdpPort(); + final OptionalInt tcpPort = service.getAdvertisedPeer().get().getEndpoint().getTcpPort(); assertEquals( - (NetworkUtility.isIPv6Available() ? "/0:0:0:0:0:0:0:0:" : "/0.0.0.0:") + port, - service.getDiscoverySocketAddress().toString()); + config.getDiscovery().getAdvertisedHost(), + service.getAdvertisedPeer().get().getEndpoint().getHost()); + assertThat(udpPort).isNotZero(); + assertThat(tcpPort).isPresent(); + assertThat(tcpPort.getAsInt()).isNotZero(); assertThat(service.getDiscoveryPeers()).hasSize(0); } } @@ -157,9 +162,9 @@ public class NetworkingServiceLifecycleTest { new PeerBlacklist(), new NoOpMetricsSystem(), Optional.empty())) { - service.run(); + service.start(); service.stop(); - service.run(); + service.start(); } } @@ -186,9 +191,9 @@ public class NetworkingServiceLifecycleTest { new PeerBlacklist(), new NoOpMetricsSystem(), Optional.empty())) { - service1.run(); + service1.start(); service1.stop(); - service2.run(); + service2.start(); service2.stop(); } } @@ -206,9 +211,11 @@ public class NetworkingServiceLifecycleTest { new PeerBlacklist(), new NoOpMetricsSystem(), Optional.empty())) { - service1.run(); + service1.start(); final NetworkingConfiguration config = configWithRandomPorts(); - config.getDiscovery().setBindPort(service1.getDiscoverySocketAddress().getPort()); + config + .getDiscovery() + .setBindPort(service1.getAdvertisedPeer().get().getEndpoint().getUdpPort()); try (final NettyP2PNetwork service2 = new NettyP2PNetwork( vertx, @@ -220,10 +227,10 @@ public class NetworkingServiceLifecycleTest { new NoOpMetricsSystem(), Optional.empty())) { try { - service2.run(); + service2.start(); } catch (final Exception e) { - assertThat(e.getCause()).hasCauseExactlyInstanceOf(PeerDiscoveryServiceException.class); - assertThat(e.getCause()) + assertThat(e).hasCauseExactlyInstanceOf(PeerDiscoveryServiceException.class); + assertThat(e) .hasMessageStartingWith( "tech.pegasys.pantheon.ethereum.p2p.discovery." + "PeerDiscoveryServiceException: Failed to bind Ethereum UDP discovery listener to 0.0.0.0:"); diff --git a/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryAgentTest.java b/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryAgentTest.java index 025241ba11..7332a05343 100644 --- a/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryAgentTest.java +++ b/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryAgentTest.java @@ -31,6 +31,7 @@ import tech.pegasys.pantheon.util.bytes.BytesValue; import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; import org.junit.Test; @@ -66,6 +67,7 @@ public class PeerDiscoveryAgentTest { final List otherPeers = otherAgents.stream() .map(MockPeerDiscoveryAgent::getAdvertisedPeer) + .map(Optional::get) .collect(Collectors.toList()); // Start another peer pointing to those 20 agents. @@ -84,7 +86,7 @@ public class PeerDiscoveryAgentTest { packet = Packet.create( PacketType.FIND_NEIGHBORS, - FindNeighborsPacketData.create(otherAgents.get(0).getAdvertisedPeer().getId()), + FindNeighborsPacketData.create(otherAgents.get(0).getAdvertisedPeer().get().getId()), testAgent.getKeyPair()); helper.sendMessageBetweenAgents(testAgent, agent, packet); @@ -108,7 +110,7 @@ public class PeerDiscoveryAgentTest { otherPeers.removeAll(neighbors.getNodes()); assertThat(otherPeers.size()).isBetween(4, 5); if (otherPeers.size() == 5) { - assertThat(neighbors.getNodes()).contains(testAgent.getAdvertisedPeer()); + assertThat(neighbors.getNodes()).contains(testAgent.getAdvertisedPeer().get()); } } @@ -116,7 +118,7 @@ public class PeerDiscoveryAgentTest { public void shouldEvictPeerOnDisconnect() { final MockPeerDiscoveryAgent peerDiscoveryAgent1 = helper.startDiscoveryAgent(); peerDiscoveryAgent1.start(BROADCAST_TCP_PORT).join(); - final DiscoveryPeer peer = peerDiscoveryAgent1.getAdvertisedPeer(); + final DiscoveryPeer peer = peerDiscoveryAgent1.getAdvertisedPeer().get(); final MockPeerDiscoveryAgent peerDiscoveryAgent2 = helper.startDiscoveryAgent(peer); peerDiscoveryAgent2.start(BROADCAST_TCP_PORT).join(); diff --git a/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryBondingTest.java b/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryBondingTest.java index 23846a3e9a..67555dde81 100644 --- a/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryBondingTest.java +++ b/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryBondingTest.java @@ -50,7 +50,7 @@ public class PeerDiscoveryBondingTest { final PongPacketData pong = otherAgentIncomingPongs.get(0).packet.getPacketData(PongPacketData.class).get(); - assertThat(pong.getTo()).isEqualTo(otherAgent.getAdvertisedPeer().getEndpoint()); + assertThat(pong.getTo()).isEqualTo(otherAgent.getAdvertisedPeer().get().getEndpoint()); // The agent considers the test peer BONDED. assertThat(agent.getPeers()).hasSize(1); @@ -87,7 +87,8 @@ public class PeerDiscoveryBondingTest { Optional maybePongData = incomingPongs.get(0).packet.getPacketData(PongPacketData.class); assertThat(maybePongData).isPresent(); - assertThat(maybePongData.get().getTo()).isEqualTo(otherNode.getAdvertisedPeer().getEndpoint()); + assertThat(maybePongData.get().getTo()) + .isEqualTo(otherNode.getAdvertisedPeer().get().getEndpoint()); // No more packets. assertThat(otherNode.getIncomingPackets()).hasSize(0); diff --git a/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryBootstrappingTest.java b/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryBootstrappingTest.java index be13dcc73b..fc2b31e39a 100644 --- a/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryBootstrappingTest.java +++ b/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryBootstrappingTest.java @@ -26,6 +26,7 @@ import tech.pegasys.pantheon.ethereum.p2p.peers.Peer; import tech.pegasys.pantheon.util.bytes.BytesValue; import java.util.List; +import java.util.Optional; import org.junit.Test; @@ -39,7 +40,8 @@ public class PeerDiscoveryBootstrappingTest { final MockPeerDiscoveryAgent testAgent = helper.startDiscoveryAgent(); // Start an agent. - final PeerDiscoveryAgent agent = helper.startDiscoveryAgent(testAgent.getAdvertisedPeer()); + final PeerDiscoveryAgent agent = + helper.startDiscoveryAgent(testAgent.getAdvertisedPeer().get()); final List incomingPackets = testAgent.getIncomingPackets().stream() @@ -47,13 +49,13 @@ public class PeerDiscoveryBootstrappingTest { .collect(toList()); assertThat(incomingPackets.size()).isEqualTo(1); Packet pingPacket = incomingPackets.get(0).packet; - assertThat(pingPacket.getNodeId()).isEqualTo(agent.getAdvertisedPeer().getId()); + assertThat(pingPacket.getNodeId()).isEqualTo(agent.getAdvertisedPeer().get().getId()); final PingPacketData pingData = pingPacket.getPacketData(PingPacketData.class).get(); assertThat(pingData.getExpiration()) .isGreaterThanOrEqualTo(System.currentTimeMillis() / 1000 - 10000); - assertThat(pingData.getFrom()).isEqualTo(agent.getAdvertisedPeer().getEndpoint()); - assertThat(pingData.getTo()).isEqualTo(testAgent.getAdvertisedPeer().getEndpoint()); + assertThat(pingData.getFrom()).isEqualTo(agent.getAdvertisedPeer().get().getEndpoint()); + assertThat(pingData.getTo()).isEqualTo(testAgent.getAdvertisedPeer().get().getEndpoint()); } @Test @@ -61,7 +63,10 @@ public class PeerDiscoveryBootstrappingTest { // Use these peers as bootstrap peers. final List bootstrapAgents = helper.startDiscoveryAgents(3); final List bootstrapPeers = - bootstrapAgents.stream().map(PeerDiscoveryAgent::getAdvertisedPeer).collect(toList()); + bootstrapAgents.stream() + .map(PeerDiscoveryAgent::getAdvertisedPeer) + .map(Optional::get) + .collect(toList()); // Start five agents. List agents = helper.startDiscoveryAgents(5, bootstrapPeers); @@ -78,6 +83,7 @@ public class PeerDiscoveryBootstrappingTest { final List agentIds = agents.stream() .map(PeerDiscoveryAgent::getAdvertisedPeer) + .map(Optional::get) .map(Peer::getId) .distinct() .collect(toList()); @@ -95,7 +101,7 @@ public class PeerDiscoveryBootstrappingTest { final PingPacketData ping = packet.getPacketData(PingPacketData.class).get(); assertThat(ping.getExpiration()) .isGreaterThanOrEqualTo(System.currentTimeMillis() / 1000 - 10000); - assertThat(ping.getTo()).isEqualTo(bootstrapAgent.getAdvertisedPeer().getEndpoint()); + assertThat(ping.getTo()).isEqualTo(bootstrapAgent.getAdvertisedPeer().get().getEndpoint()); } } } @@ -107,7 +113,7 @@ public class PeerDiscoveryBootstrappingTest { // Start other five agents, pointing to the one above as a bootstrap peer. final List otherAgents = - helper.startDiscoveryAgents(5, singletonList(bootstrapAgent.getAdvertisedPeer())); + helper.startDiscoveryAgents(5, singletonList(bootstrapAgent.getAdvertisedPeer().get())); final BytesValue[] otherPeersIds = otherAgents.stream().map(PeerDiscoveryAgent::getId).toArray(BytesValue[]::new); @@ -123,7 +129,7 @@ public class PeerDiscoveryBootstrappingTest { // and will // bond with them, ultimately adding all 7 nodes in the network to its table. final PeerDiscoveryAgent newAgent = - helper.startDiscoveryAgent(bootstrapAgent.getAdvertisedPeer()); + helper.startDiscoveryAgent(bootstrapAgent.getAdvertisedPeer().get()); assertThat(newAgent.getPeers()).hasSize(6); } } diff --git a/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryObserversTest.java b/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryObserversTest.java index c54610a4c5..cb084aefed 100644 --- a/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryObserversTest.java +++ b/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryObserversTest.java @@ -23,6 +23,7 @@ import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.Optional; import java.util.concurrent.TimeoutException; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -84,6 +85,7 @@ public class PeerDiscoveryObserversTest { final List peers1 = others1.stream() .map(MockPeerDiscoveryAgent::getAdvertisedPeer) + .map(Optional::get) .collect(Collectors.toList()); // Create two discovery agents pointing to the above as bootstrap peers. @@ -91,6 +93,7 @@ public class PeerDiscoveryObserversTest { final List peers2 = others2.stream() .map(MockPeerDiscoveryAgent::getAdvertisedPeer) + .map(Optional::get) .collect(Collectors.toList()); // A list of all peers. @@ -129,7 +132,7 @@ public class PeerDiscoveryObserversTest { // Create 3 discovery agents with no bootstrap peers. final List others = helper.startDiscoveryAgents(3, Collections.emptyList()); - final DiscoveryPeer peer = others.get(0).getAdvertisedPeer(); + final DiscoveryPeer peer = others.get(0).getAdvertisedPeer().get(); // Create a discovery agent (which we'll assert on), using the above two peers as bootstrap // peers. 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 c8faa4ec45..9426d03480 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 @@ -75,7 +75,8 @@ public class PeerDiscoveryTestHelper { return Packet.create( PacketType.PING, PingPacketData.create( - fromAgent.getAdvertisedPeer().getEndpoint(), toAgent.getAdvertisedPeer().getEndpoint()), + fromAgent.getAdvertisedPeer().get().getEndpoint(), + toAgent.getAdvertisedPeer().get().getEndpoint()), fromAgent.getKeyPair()); } diff --git a/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryTimestampsTest.java b/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryTimestampsTest.java index 7292be1bfc..889670067a 100644 --- a/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryTimestampsTest.java +++ b/ethereum/p2p/src/test/java/tech/pegasys/pantheon/ethereum/p2p/discovery/PeerDiscoveryTimestampsTest.java @@ -47,7 +47,7 @@ public class PeerDiscoveryTimestampsTest { final List peers = helper.createDiscoveryPeers(keypairs); final MockPeerDiscoveryAgent agent = mock(MockPeerDiscoveryAgent.class); - when(agent.getAdvertisedPeer()).thenReturn(peers.get(0)); + when(agent.getAdvertisedPeer()).thenReturn(Optional.of(peers.get(0))); DiscoveryPeer localPeer = peers.get(0); KeyPair localKeyPair = keypairs.get(0); @@ -55,7 +55,7 @@ public class PeerDiscoveryTimestampsTest { new PeerDiscoveryController( localKeyPair, localPeer, - new PeerTable(agent.getAdvertisedPeer().getId()), + new PeerTable(agent.getAdvertisedPeer().get().getId()), Collections.emptyList(), OutboundMessageHandler.NOOP, new MockTimerUtil(), 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 15d19e2f41..65728fecbf 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 @@ -51,7 +51,7 @@ public class MockPeerDiscoveryAgent extends PeerDiscoveryAgent { // This ensures that any data passed between agents is not shared final Packet packetClone = Packet.decode(packet.encode()); incomingPackets.add(new IncomingPacket(fromAgent, packetClone)); - handleIncomingPacket(fromAgent.getAdvertisedPeer().getEndpoint(), packetClone); + handleIncomingPacket(fromAgent.getAdvertisedPeer().get().getEndpoint(), packetClone); } /** diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/Runner.java b/pantheon/src/main/java/tech/pegasys/pantheon/Runner.java index 6fde46423a..c58267e4e1 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/Runner.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/Runner.java @@ -16,6 +16,8 @@ import tech.pegasys.pantheon.controller.PantheonController; import tech.pegasys.pantheon.ethereum.jsonrpc.JsonRpcHttpService; import tech.pegasys.pantheon.ethereum.jsonrpc.websocket.WebSocketService; import tech.pegasys.pantheon.ethereum.p2p.NetworkRunner; +import tech.pegasys.pantheon.ethereum.p2p.peers.Endpoint; +import tech.pegasys.pantheon.ethereum.p2p.peers.Peer; import tech.pegasys.pantheon.metrics.prometheus.MetricsService; import java.io.File; @@ -112,9 +114,17 @@ public class Runner implements AutoCloseable { private void writePantheonPortsToFile() { final Properties properties = new Properties(); - if (networkRunner.getNetwork().isListening()) { - properties.setProperty("discovery", String.valueOf(getP2pUdpPort())); - properties.setProperty("p2p", String.valueOf(getP2pTcpPort())); + if (networkRunner.getNetwork().isP2pEnabled()) { + networkRunner + .getNetwork() + .getAdvertisedPeer() + .ifPresent( + advertisedPeer -> { + final Endpoint endpoint = advertisedPeer.getEndpoint(); + properties.setProperty("discovery", String.valueOf(endpoint.getUdpPort())); + }); + final int tcpPort = networkRunner.getNetwork().getLocalPeerInfo().getPort(); + properties.setProperty("p2p", String.valueOf(tcpPort)); } if (getJsonRpcPort().isPresent()) { @@ -155,8 +165,8 @@ public class Runner implements AutoCloseable { } } - public int getP2pUdpPort() { - return networkRunner.getNetwork().getDiscoverySocketAddress().getPort(); + public Optional getAdvertisedPeer() { + return networkRunner.getNetwork().getAdvertisedPeer(); } public int getP2pTcpPort() { diff --git a/pantheon/src/test/java/tech/pegasys/pantheon/RunnerTest.java b/pantheon/src/test/java/tech/pegasys/pantheon/RunnerTest.java index 4aba5ac26e..76e7c8a2b6 100644 --- a/pantheon/src/test/java/tech/pegasys/pantheon/RunnerTest.java +++ b/pantheon/src/test/java/tech/pegasys/pantheon/RunnerTest.java @@ -38,6 +38,7 @@ import tech.pegasys.pantheon.ethereum.mainnet.MainnetProtocolSchedule; import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule; import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSpec; import tech.pegasys.pantheon.ethereum.p2p.peers.DefaultPeer; +import tech.pegasys.pantheon.ethereum.p2p.peers.Peer; import tech.pegasys.pantheon.ethereum.permissioning.PermissioningConfiguration; import tech.pegasys.pantheon.ethereum.storage.StorageProvider; import tech.pegasys.pantheon.ethereum.storage.keyvalue.RocksDbStorageProvider; @@ -159,16 +160,6 @@ public final class RunnerTest { executorService.submit(runnerAhead::execute); - // Wait for network to initialize to get the P2P UDP port - Awaitility.await() - .atMost(20, TimeUnit.SECONDS) - .ignoreExceptions() - .untilAsserted(() -> assertThat(runnerAhead.getP2pUdpPort()).isNotNull()); - Awaitility.await() - .atMost(20, TimeUnit.SECONDS) - .ignoreExceptions() - .untilAsserted(() -> assertThat(runnerAhead.getP2pTcpPort()).isNotNull()); - final SynchronizerConfiguration syncConfigBehind = SynchronizerConfiguration.builder() .syncMode(mode) @@ -193,6 +184,7 @@ public final class RunnerTest { PrivacyParameters.noPrivacy(), dataDirBehind, noOpMetricsSystem); + final Peer advertisedPeer = runnerAhead.getAdvertisedPeer().get(); final EthNetworkConfig behindEthNetworkConfiguration = new EthNetworkConfig( EthNetworkConfig.jsonConfig(DEV), @@ -200,9 +192,9 @@ public final class RunnerTest { Collections.singletonList( URI.create( new DefaultPeer( - aheadDbNodeKeys.getPublicKey().getEncodedBytes(), - listenHost, - runnerAhead.getP2pUdpPort(), + advertisedPeer.getId(), + advertisedPeer.getEndpoint().getHost(), + advertisedPeer.getEndpoint().getUdpPort(), runnerAhead.getP2pTcpPort()) .getEnodeURI()))); final Runner runnerBehind = diff --git a/util/src/main/java/tech/pegasys/pantheon/util/bytes/BytesValue.java b/util/src/main/java/tech/pegasys/pantheon/util/bytes/BytesValue.java index 72dee29c30..2021480915 100644 --- a/util/src/main/java/tech/pegasys/pantheon/util/bytes/BytesValue.java +++ b/util/src/main/java/tech/pegasys/pantheon/util/bytes/BytesValue.java @@ -549,4 +549,9 @@ public interface BytesValue extends Comparable { */ @Override String toString(); + + default String toUnprefixedString() { + final String prefixedHex = toString(); + return prefixedHex.startsWith("0x") ? prefixedHex.substring(2) : prefixedHex; + } }