[PAN-2347] nodepermissioningcontroller used for devp2p connection filtering (#1132)

Signed-off-by: Adrian Sutton <adrian.sutton@consensys.net>
This commit is contained in:
Chris Mckay
2019-03-20 09:35:16 +10:00
committed by GitHub
parent 82c5f70288
commit bc5d6eb45a
18 changed files with 128 additions and 102 deletions

View File

@@ -20,7 +20,7 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcErrorResp
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.PeerNotWhitelistedException;
import tech.pegasys.pantheon.ethereum.p2p.PeerNotPermittedException;
import tech.pegasys.pantheon.ethereum.p2p.api.P2PNetwork;
import tech.pegasys.pantheon.ethereum.p2p.peers.DefaultPeer;
import tech.pegasys.pantheon.ethereum.p2p.peers.Peer;
@@ -59,9 +59,9 @@ public class AdminAddPeer implements JsonRpcMethod {
return new JsonRpcErrorResponse(req.getId(), JsonRpcError.PARSE_ERROR);
} catch (final P2pDisabledException e) {
return new JsonRpcErrorResponse(req.getId(), JsonRpcError.P2P_DISABLED);
} catch (final PeerNotWhitelistedException e) {
} catch (final PeerNotPermittedException e) {
return new JsonRpcErrorResponse(
req.getId(), JsonRpcError.NON_WHITELISTED_NODE_CANNOT_BE_ADDED_AS_A_PEER);
req.getId(), JsonRpcError.NON_PERMITTED_NODE_CANNOT_BE_ADDED_AS_A_PEER);
} catch (final Exception e) {
LOG.error("Error processing request: " + req, e);
throw e;

View File

@@ -73,7 +73,7 @@ public class AdminNodeInfo implements JsonRpcMethod {
.getAdvertisedPeer()
.ifPresent(
advertisedPeer -> {
response.put("enode", advertisedPeer.getEnodeURI());
response.put("enode", advertisedPeer.getEnodeURLString());
ports.put("discovery", advertisedPeer.getEndpoint().getUdpPort());
response.put("ip", advertisedPeer.getEndpoint().getHost());
response.put(

View File

@@ -77,8 +77,7 @@ public enum JsonRpcError {
-32000,
"Error reloading permissions file. Please use perm_getAccountsWhitelist and perm_getNodesWhitelist to review the current state of the whitelists"),
PERMISSIONING_NOT_ENABLED(-32000, "Node/Account whitelisting has not been enabled"),
NON_WHITELISTED_NODE_CANNOT_BE_ADDED_AS_A_PEER(
-32000, "Cannot add a non-whitelisted node as a peer"),
NON_PERMITTED_NODE_CANNOT_BE_ADDED_AS_A_PEER(-32000, "Cannot add a non-permitted node as a peer"),
// Permissioning/Authorization errors
UNAUTHORIZED(-40100, "Unauthorized"),

View File

@@ -23,7 +23,7 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcErrorResp
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.PeerNotWhitelistedException;
import tech.pegasys.pantheon.ethereum.p2p.PeerNotPermittedException;
import tech.pegasys.pantheon.ethereum.p2p.api.P2PNetwork;
import org.junit.Before;
@@ -196,8 +196,7 @@ public class AdminAddPeerTest {
@Test
public void requestReturnsErrorWhenPeerNotWhitelisted() {
when(p2pNetwork.addMaintainConnectionPeer(any()))
.thenThrow(new PeerNotWhitelistedException("Cannot add peer that is not whitelisted"));
when(p2pNetwork.addMaintainConnectionPeer(any())).thenThrow(new PeerNotPermittedException());
final JsonRpcRequest request =
new JsonRpcRequest(
@@ -214,7 +213,7 @@ public class AdminAddPeerTest {
final JsonRpcResponse expectedResponse =
new JsonRpcErrorResponse(
request.getId(), JsonRpcError.NON_WHITELISTED_NODE_CANNOT_BE_ADDED_AS_A_PEER);
request.getId(), JsonRpcError.NON_PERMITTED_NODE_CANNOT_BE_ADDED_AS_A_PEER);
final JsonRpcResponse actualResponse = method.response(request);

View File

@@ -12,8 +12,12 @@
*/
package tech.pegasys.pantheon.ethereum.p2p;
public class PeerNotWhitelistedException extends RuntimeException {
public PeerNotWhitelistedException(final String message) {
public class PeerNotPermittedException extends RuntimeException {
public PeerNotPermittedException(final String message) {
super(message);
}
public PeerNotPermittedException() {
super("Cannot add a peer that is not permitted");
}
}

View File

@@ -34,7 +34,6 @@ import tech.pegasys.pantheon.ethereum.permissioning.node.NodePermissioningContro
import tech.pegasys.pantheon.ethereum.permissioning.node.NodeWhitelistUpdatedEvent;
import tech.pegasys.pantheon.util.Subscribers;
import tech.pegasys.pantheon.util.bytes.BytesValue;
import tech.pegasys.pantheon.util.enode.EnodeURL;
import java.util.Collection;
import java.util.List;
@@ -226,11 +225,7 @@ public class PeerDiscoveryController {
private boolean isPeerPermitted(final Peer sourcePeer, final Peer destinationPeer) {
return nodePermissioningController
.map(
c ->
c.isPermitted(
new EnodeURL(sourcePeer.getEnodeURI()),
new EnodeURL(destinationPeer.getEnodeURI())))
.map(c -> c.isPermitted(sourcePeer.getEnodeURL(), destinationPeer.getEnodeURL()))
.orElse(true);
}
@@ -254,7 +249,7 @@ public class PeerDiscoveryController {
}
if (!isPeerPermitted(sender, localPeer)) {
LOG.trace("Dropping packet from peer not in the whitelist ({})", sender.getEnodeURI());
LOG.trace("Dropping packet from peer not in the whitelist ({})", sender.getEnodeURLString());
return;
}

View File

@@ -19,7 +19,6 @@ import tech.pegasys.pantheon.ethereum.p2p.discovery.PeerDiscoveryStatus;
import tech.pegasys.pantheon.ethereum.p2p.peers.PeerBlacklist;
import tech.pegasys.pantheon.ethereum.permissioning.node.NodePermissioningController;
import tech.pegasys.pantheon.util.bytes.BytesValue;
import tech.pegasys.pantheon.util.enode.EnodeURL;
import java.util.List;
import java.util.Map;
@@ -191,10 +190,7 @@ public class RecursivePeerRefreshState {
private Boolean isPeerPermitted(final DiscoveryPeer discoPeer) {
return nodePermissioningController
.map(
controller ->
controller.isPermitted(
new EnodeURL(localPeer.getEnodeURI()), new EnodeURL(discoPeer.getEnodeURI())))
.map(controller -> controller.isPermitted(localPeer.getEnodeURL(), discoPeer.getEnodeURL()))
.orElse(true);
}

View File

@@ -17,7 +17,7 @@ import static com.google.common.base.Preconditions.checkState;
import tech.pegasys.pantheon.crypto.SECP256K1;
import tech.pegasys.pantheon.ethereum.chain.BlockAddedEvent;
import tech.pegasys.pantheon.ethereum.chain.Blockchain;
import tech.pegasys.pantheon.ethereum.p2p.PeerNotWhitelistedException;
import tech.pegasys.pantheon.ethereum.p2p.PeerNotPermittedException;
import tech.pegasys.pantheon.ethereum.p2p.api.DisconnectCallback;
import tech.pegasys.pantheon.ethereum.p2p.api.Message;
import tech.pegasys.pantheon.ethereum.p2p.api.P2PNetwork;
@@ -29,7 +29,6 @@ import tech.pegasys.pantheon.ethereum.p2p.discovery.PeerDiscoveryEvent.PeerBonde
import tech.pegasys.pantheon.ethereum.p2p.discovery.PeerDiscoveryEvent.PeerDroppedEvent;
import tech.pegasys.pantheon.ethereum.p2p.discovery.VertxPeerDiscoveryAgent;
import tech.pegasys.pantheon.ethereum.p2p.discovery.internal.PeerRequirement;
import tech.pegasys.pantheon.ethereum.p2p.peers.DefaultPeer;
import tech.pegasys.pantheon.ethereum.p2p.peers.Endpoint;
import tech.pegasys.pantheon.ethereum.p2p.peers.Peer;
import tech.pegasys.pantheon.ethereum.p2p.peers.PeerBlacklist;
@@ -46,6 +45,7 @@ import tech.pegasys.pantheon.metrics.MetricsSystem;
import tech.pegasys.pantheon.util.Subscribers;
import tech.pegasys.pantheon.util.enode.EnodeURL;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.Collection;
import java.util.HashSet;
@@ -350,10 +350,7 @@ public class NettyP2PNetwork implements P2PNetwork {
return;
}
final boolean isPeerBlacklisted = peerBlacklist.contains(connection);
final boolean isPeerNotWhitelisted = !isPeerWhitelisted(connection, ch);
if (isPeerBlacklisted || isPeerNotWhitelisted) {
if (!isPeerConnectionAllowed(connection)) {
connection.disconnect(DisconnectReason.UNKNOWN);
return;
}
@@ -367,28 +364,10 @@ public class NettyP2PNetwork implements P2PNetwork {
};
}
private boolean isPeerWhitelisted(final PeerConnection connection, final SocketChannel ch) {
return nodeWhitelistController
.map(
nwc ->
nwc.isPermitted(
new DefaultPeer(
connection.getPeer().getNodeId(),
ch.remoteAddress().getAddress().getHostAddress(),
connection.getPeer().getPort(),
connection.getPeer().getPort())
.getEnodeURI()))
.orElse(true);
}
private boolean isPeerWhitelisted(final Peer peer) {
return nodeWhitelistController.map(nwc -> nwc.isPermitted(peer.getEnodeURI())).orElse(true);
}
@Override
public boolean addMaintainConnectionPeer(final Peer peer) {
if (!isPeerWhitelisted(peer)) {
throw new PeerNotWhitelistedException("Cannot add a peer that is not whitelisted");
if (!isPeerAllowed(peer)) {
throw new PeerNotPermittedException();
}
final boolean added = peerMaintainConnectionList.add(peer);
if (added) {
@@ -562,24 +541,48 @@ public class NettyP2PNetwork implements P2PNetwork {
}
private boolean isPeerConnectionAllowed(final PeerConnection peerConnection) {
if (peerBlacklist.contains(peerConnection)) {
return false;
}
LOG.trace(
"Checking if connection with peer {} is permitted", peerConnection.getPeer().getNodeId());
final EnodeURL localPeerEnodeURL =
peerInfoToEnodeURL(ourPeerInfo, (InetSocketAddress) peerConnection.getLocalAddress());
final EnodeURL remotePeerEnodeURL =
peerInfoToEnodeURL(
peerConnection.getPeer(), (InetSocketAddress) peerConnection.getRemoteAddress());
return nodePermissioningController
.map(
c -> {
final EnodeURL localPeerEnodeURL =
peerInfoToEnodeURL(
ourPeerInfo, (InetSocketAddress) peerConnection.getLocalAddress());
final EnodeURL remotePeerEnodeURL =
peerInfoToEnodeURL(
peerConnection.getPeer(),
(InetSocketAddress) peerConnection.getRemoteAddress());
return c.isPermitted(localPeerEnodeURL, remotePeerEnodeURL);
})
.orElse(true);
}
private boolean isPeerAllowed(final Peer peer) {
if (peerBlacklist.contains(peer)) {
return false;
}
return nodePermissioningController
.map(c -> c.isPermitted(localPeerEnodeURL, remotePeerEnodeURL))
.map(
c -> {
final InetSocketAddress socket = (InetSocketAddress) server.channel().localAddress();
final EnodeURL localPeerEnodeUrl = peerInfoToEnodeURL(ourPeerInfo, socket);
return c.isPermitted(localPeerEnodeUrl, peer.getEnodeURL());
})
.orElse(true);
}
private EnodeURL peerInfoToEnodeURL(final PeerInfo ourPeerInfo, final InetSocketAddress address) {
final String localNodeId = ourPeerInfo.getNodeId().toString().substring(2);
final String localHostAddress = address.getHostString();
final int localPort = address.getPort();
final InetAddress localHostAddress = address.getAddress();
final int localPort = ourPeerInfo.getPort();
return new EnodeURL(localNodeId, localHostAddress, localPort);
}

View File

@@ -15,6 +15,7 @@ package tech.pegasys.pantheon.ethereum.p2p.peers;
import tech.pegasys.pantheon.crypto.SecureRandomProvider;
import tech.pegasys.pantheon.ethereum.rlp.RLPOutput;
import tech.pegasys.pantheon.util.bytes.BytesValue;
import tech.pegasys.pantheon.util.enode.EnodeURL;
import java.util.OptionalInt;
@@ -53,22 +54,28 @@ public interface Peer extends PeerId {
}
/**
* Returns this peer's enode URI.
* Returns this peer's enode URL.
*
* @return The enode URI as a String.
* @return The enode URL as a String.
*/
default String getEnodeURI() {
String url = this.getId().toUnprefixedString();
Endpoint endpoint = this.getEndpoint();
String nodeIp = endpoint.getHost();
OptionalInt tcpPort = endpoint.getTcpPort();
int udpPort = endpoint.getUdpPort();
default String getEnodeURLString() {
return this.getEnodeURL().toString();
}
default EnodeURL getEnodeURL() {
final Endpoint endpoint = this.getEndpoint();
final OptionalInt tcpPort = endpoint.getTcpPort();
final int udpPort = endpoint.getUdpPort();
if (tcpPort.isPresent() && (tcpPort.getAsInt() != udpPort)) {
return String.format(
"enode://%s@%s:%d?discport=%d", url, nodeIp, tcpPort.getAsInt(), udpPort);
return new EnodeURL(
this.getId().toUnprefixedString(),
endpoint.getHost(),
tcpPort.getAsInt(),
OptionalInt.of(endpoint.getUdpPort()));
} else {
return String.format("enode://%s@%s:%d", url, nodeIp, udpPort);
return new EnodeURL(this.getId().toUnprefixedString(), endpoint.getHost(), udpPort);
}
}
}

View File

@@ -23,6 +23,7 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -464,7 +465,10 @@ public final class NettyP2PNetworkTest {
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()));
localWhitelistController.addNodes(Arrays.asList(mockPeer().getEnodeURLString()));
final NodePermissioningController nodePermissioningController =
new NodePermissioningController(
Optional.empty(), Collections.singletonList(localWhitelistController));
final SubProtocol subprotocol = subProtocol();
final Capability cap = Capability.create(subprotocol.getName(), 63);
@@ -481,7 +485,8 @@ public final class NettyP2PNetworkTest {
localBlacklist,
new NoOpMetricsSystem(),
Optional.of(localWhitelistController),
Optional.empty());
Optional.of(nodePermissioningController),
blockchain);
final P2PNetwork remoteNetwork =
new NettyP2PNetwork(
vertx,
@@ -725,13 +730,15 @@ public final class NettyP2PNetworkTest {
final PeerConnection notPermittedPeerConnection =
mockPeerConnection(localPeer, notPermittedPeer);
final EnodeURL permittedEnodeURL = new EnodeURL(permittedPeer.getEnodeURI());
final EnodeURL notPermittedEnodeURL = new EnodeURL(notPermittedPeer.getEnodeURI());
final EnodeURL permittedEnodeURL = new EnodeURL(permittedPeer.getEnodeURLString());
final EnodeURL notPermittedEnodeURL = new EnodeURL(notPermittedPeer.getEnodeURLString());
nettyP2PNetwork.start();
nettyP2PNetwork.connect(permittedPeer).complete(permittedPeerConnection);
nettyP2PNetwork.connect(notPermittedPeer).complete(notPermittedPeerConnection);
reset(nodePermissioningController);
lenient()
.when(nodePermissioningController.isPermitted(any(), enodeEq(notPermittedEnodeURL)))
.thenReturn(false);
@@ -765,6 +772,7 @@ public final class NettyP2PNetworkTest {
private PeerConnection mockPeerConnection(final Peer localPeer, final Peer remotePeer) {
final PeerInfo peerInfo = mock(PeerInfo.class);
doReturn(remotePeer.getId()).when(peerInfo).getNodeId();
doReturn(remotePeer.getEndpoint().getTcpPort().getAsInt()).when(peerInfo).getPort();
final PeerConnection peerConnection = mock(PeerConnection.class);
when(peerConnection.getPeer()).thenReturn(peerInfo);
@@ -792,6 +800,8 @@ public final class NettyP2PNetworkTest {
.setSupportedProtocols(subProtocol())
.setRlpx(RlpxConfiguration.create().setBindPort(0));
lenient().when(nodePermissioningController.isPermitted(any(), any())).thenReturn(true);
return new NettyP2PNetwork(
mock(Vertx.class),
keyPair,
@@ -828,7 +838,7 @@ public final class NettyP2PNetworkTest {
when(peer.getId()).thenReturn(id);
when(peer.getEndpoint()).thenReturn(endpoint);
when(peer.getEnodeURI()).thenReturn(enodeURL);
when(peer.getEnodeURLString()).thenReturn(enodeURL);
return peer;
}

View File

@@ -36,18 +36,18 @@ public class NodePermissioningControllerTestHelper {
private boolean denyAll = false;
public NodePermissioningControllerTestHelper(final Peer localPeer) {
this.localNode = new EnodeURL(localPeer.getEnodeURI());
this.localNode = localPeer.getEnodeURL();
}
public NodePermissioningControllerTestHelper withPermittedPeers(final Peer... peers) {
this.permittedNodes.addAll(
Arrays.stream(peers).map(p -> new EnodeURL(p.getEnodeURI())).collect(Collectors.toList()));
Arrays.stream(peers).map(Peer::getEnodeURL).collect(Collectors.toList()));
return this;
}
public NodePermissioningControllerTestHelper withForbiddenPeers(final Peer... peers) {
this.notPermittedNodes.addAll(
Arrays.stream(peers).map(p -> new EnodeURL(p.getEnodeURI())).collect(Collectors.toList()));
Arrays.stream(peers).map(Peer::getEnodeURL).collect(Collectors.toList()));
return this;
}

View File

@@ -196,7 +196,10 @@ public class PeerDiscoveryTestHelper {
}
private List<URI> asEnodes(final List<DiscoveryPeer> peers) {
return peers.stream().map(Peer::getEnodeURI).map(URI::create).collect(Collectors.toList());
return peers.stream()
.map(Peer::getEnodeURLString)
.map(URI::create)
.collect(Collectors.toList());
}
public AgentBuilder whiteList(

View File

@@ -1079,7 +1079,7 @@ public class PeerDiscoveryControllerTest {
peerTableSpy.tryAdd(peer);
final LocalPermissioningConfiguration config = permissioningConfigurationWithTempFile();
final URI peerURI = URI.create(peer.getEnodeURI());
final URI peerURI = URI.create(peer.getEnodeURLString());
config.setNodeWhitelist(Lists.newArrayList(peerURI));
final NodeLocalConfigPermissioningController nodeLocalConfigPermissioningController =
new NodeLocalConfigPermissioningController(config, Collections.emptyList(), selfEnode);
@@ -1106,7 +1106,7 @@ public class PeerDiscoveryControllerTest {
peerTableSpy.tryAdd(peer);
final LocalPermissioningConfiguration config = permissioningConfigurationWithTempFile();
final URI peerURI = URI.create(peer.getEnodeURI());
final URI peerURI = URI.create(peer.getEnodeURLString());
config.setNodeWhitelist(Lists.newArrayList(peerURI));
final NodeLocalConfigPermissioningController nodeLocalConfigPermissioningController =
new NodeLocalConfigPermissioningController(config, Collections.emptyList(), selfEnode);
@@ -1129,7 +1129,8 @@ public class PeerDiscoveryControllerTest {
ArgumentCaptor<PeerDroppedEvent> captor = ArgumentCaptor.forClass(PeerDroppedEvent.class);
verify(peerDroppedEventConsumer).accept(captor.capture());
assertThat(captor.getValue().getPeer()).isEqualTo(DiscoveryPeer.fromURI(peer.getEnodeURI()));
assertThat(captor.getValue().getPeer())
.isEqualTo(DiscoveryPeer.fromURI(peer.getEnodeURLString()));
}
@Test

View File

@@ -32,7 +32,6 @@ import tech.pegasys.pantheon.ethereum.p2p.peers.PeerBlacklist;
import tech.pegasys.pantheon.ethereum.permissioning.LocalPermissioningConfiguration;
import tech.pegasys.pantheon.ethereum.permissioning.node.NodePermissioningController;
import tech.pegasys.pantheon.util.bytes.BytesValue;
import tech.pegasys.pantheon.util.enode.EnodeURL;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -494,10 +493,8 @@ public class RecursivePeerRefreshStateTest {
final NodePermissioningController nodeWhitelistController =
mock(NodePermissioningController.class);
when(nodeWhitelistController.isPermitted(any(), eq(new EnodeURL(peerA.getEnodeURI()))))
.thenReturn(true);
when(nodeWhitelistController.isPermitted(any(), eq(new EnodeURL(peerB.getEnodeURI()))))
.thenReturn(false);
when(nodeWhitelistController.isPermitted(any(), eq(peerA.getEnodeURL()))).thenReturn(true);
when(nodeWhitelistController.isPermitted(any(), eq(peerB.getEnodeURL()))).thenReturn(false);
recursivePeerRefreshState =
new RecursivePeerRefreshState(

View File

@@ -65,8 +65,7 @@ public class NodePermissioningController {
return syncStatusNodePermissioningProvider;
}
@VisibleForTesting
List<NodePermissioningProvider> getProviders() {
public List<NodePermissioningProvider> getProviders() {
return providers;
}
}

View File

@@ -226,20 +226,12 @@ public class RunnerBuilder {
final List<EnodeURL> bootnodesAsEnodeURLs =
discoveryConfiguration.getBootstrapPeers().stream()
.map(p -> new EnodeURL(p.getEnodeURI()))
.map(p -> new EnodeURL(p.getEnodeURLString()))
.collect(Collectors.toList());
final Optional<LocalPermissioningConfiguration> localPermissioningConfiguration =
permissioningConfiguration.flatMap(PermissioningConfiguration::getLocalConfig);
final Optional<NodeLocalConfigPermissioningController> nodeWhitelistController =
localPermissioningConfiguration
.filter(LocalPermissioningConfiguration::isNodeWhitelistEnabled)
.map(
config ->
new NodeLocalConfigPermissioningController(
config, bootnodesAsEnodeURLs, getSelfEnode()));
final Synchronizer synchronizer = pantheonController.getSynchronizer();
final TransactionSimulator transactionSimulator =
@@ -249,6 +241,15 @@ public class RunnerBuilder {
final Optional<NodePermissioningController> nodePermissioningController =
buildNodePermissioningController(bootnodesAsEnodeURLs, synchronizer, transactionSimulator);
final Optional<NodeLocalConfigPermissioningController> nodeWhitelistController =
nodePermissioningController
.flatMap(
n ->
n.getProviders().stream()
.filter(p -> p instanceof NodeLocalConfigPermissioningController)
.findFirst())
.map(n -> (NodeLocalConfigPermissioningController) n);
final NetworkRunner networkRunner =
NetworkRunner.builder()
.protocolManagers(protocolManagers)

View File

@@ -191,7 +191,7 @@ public final class RunnerTest {
new EthNetworkConfig(
EthNetworkConfig.jsonConfig(DEV),
DEV_NETWORK_ID,
Collections.singletonList(URI.create(advertisedPeer.getEnodeURI())));
Collections.singletonList(URI.create(advertisedPeer.getEnodeURLString())));
runnerBehind =
runnerBuilder
.pantheonController(controllerBehind)

View File

@@ -48,16 +48,28 @@ public class EnodeURL {
final String ip,
final Integer listeningPort,
final OptionalInt discoveryPort) {
this.nodeId = nodeId;
this.ip = InetAddresses.forUriString(ip);
this.listeningPort = listeningPort;
this.discoveryPort = discoveryPort;
this(nodeId, InetAddresses.forUriString(ip), listeningPort, discoveryPort);
}
public EnodeURL(final String nodeId, final String ip, final Integer listeningPort) {
this(nodeId, ip, listeningPort, OptionalInt.empty());
}
public EnodeURL(final String nodeId, final InetAddress address, final Integer listeningPort) {
this(nodeId, address, listeningPort, OptionalInt.empty());
}
public EnodeURL(
final String nodeId,
final InetAddress address,
final Integer listeningPort,
final OptionalInt discoveryPort) {
this.nodeId = nodeId;
this.ip = address;
this.listeningPort = listeningPort;
this.discoveryPort = discoveryPort;
}
public EnodeURL(final String value) {
checkArgument(
value != null && !value.isEmpty(), "Can't convert null/empty string to EnodeURLProperty.");