diff --git a/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java b/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java index 09f98f5e8ae..59fc22f8059 100644 --- a/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java +++ b/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java @@ -55,6 +55,7 @@ public class PeerExplorer { private final Map pendingFindNodeRequests = new ConcurrentHashMap<>(); private final Map establishedConnections = new ConcurrentHashMap<>(); + private final Integer networkId; private UDPChannel udpChannel; @@ -72,12 +73,12 @@ public class PeerExplorer { private long requestTimeout; - public PeerExplorer(List initialBootNodes, Node localNode, NodeDistanceTable distanceTable, ECKey key, long reqTimeOut, long updatePeriod, long cleanPeriod) { + public PeerExplorer(List initialBootNodes, Node localNode, NodeDistanceTable distanceTable, ECKey key, long reqTimeOut, long updatePeriod, long cleanPeriod, Integer networkId) { this.localNode = localNode; this.key = key; this.distanceTable = distanceTable; this.updateEntryLock = new ReentrantLock(); - + this.networkId = networkId; loadInitialBootNodes(initialBootNodes); this.cleaner = new PeerExplorerCleaner(this, updatePeriod, cleanPeriod); @@ -111,6 +112,12 @@ public void setUDPChannel(UDPChannel udpChannel) { public void handleMessage(DiscoveryEvent event) { DiscoveryMessageType type = event.getMessage().getMessageType(); + //If this is not from my network ignore it. But if the messages do not + //have a networkId in the message yet, then just let them through, for now. + if (event.getMessage().getNetworkId().isPresent() && + event.getMessage().getNetworkId().getAsInt() != this.networkId) { + return; + } if (type == DiscoveryMessageType.PING) { this.handlePingMessage(event.getAddressIp(), (PingPeerMessage) event.getMessage()); } @@ -198,7 +205,10 @@ public PingPeerMessage sendPing(InetSocketAddress nodeAddress, int attempt, Node InetSocketAddress localAddress = this.localNode.getAddress(); String id = UUID.randomUUID().toString(); - nodeMessage = PingPeerMessage.create(localAddress.getAddress().getHostAddress(), localAddress.getPort(), id, this.key); + nodeMessage = PingPeerMessage.create( + localAddress.getAddress().getHostAddress(), + localAddress.getPort(), + id, this.key, this.networkId); udpChannel.write(new DiscoveryEvent(nodeMessage, nodeAddress)); PeerDiscoveryRequest request = PeerDiscoveryRequestBuilder.builder().messageId(id) @@ -231,7 +241,7 @@ private PingPeerMessage checkPendingPeerToAddress(InetSocketAddress address) { public PongPeerMessage sendPong(String ip, PingPeerMessage message) { InetSocketAddress localAddress = this.localNode.getAddress(); - PongPeerMessage pongPeerMessage = PongPeerMessage.create(localAddress.getHostName(), localAddress.getPort(), message.getMessageId(), this.key); + PongPeerMessage pongPeerMessage = PongPeerMessage.create(localAddress.getHostName(), localAddress.getPort(), message.getMessageId(), this.key, this.networkId); InetSocketAddress nodeAddress = new InetSocketAddress(ip, message.getPort()); udpChannel.write(new DiscoveryEvent(pongPeerMessage, nodeAddress)); @@ -241,7 +251,7 @@ public PongPeerMessage sendPong(String ip, PingPeerMessage message) { public FindNodePeerMessage sendFindNode(Node node) { InetSocketAddress nodeAddress = node.getAddress(); String id = UUID.randomUUID().toString(); - FindNodePeerMessage findNodePeerMessage = FindNodePeerMessage.create(this.key.getNodeId(), id, this.key); + FindNodePeerMessage findNodePeerMessage = FindNodePeerMessage.create(this.key.getNodeId(), id, this.key, this.networkId); udpChannel.write(new DiscoveryEvent(findNodePeerMessage, nodeAddress)); PeerDiscoveryRequest request = PeerDiscoveryRequestBuilder.builder().messageId(id).relatedNode(node) .message(findNodePeerMessage).address(nodeAddress).expectedResponse(DiscoveryMessageType.NEIGHBORS) @@ -253,7 +263,7 @@ public FindNodePeerMessage sendFindNode(Node node) { public NeighborsPeerMessage sendNeighbors(InetSocketAddress nodeAddress, List nodes, String id) { List nodesToSend = getRandomizeLimitedList(nodes, MAX_NODES_PER_MSG, 5); - NeighborsPeerMessage sendNodesMessage = NeighborsPeerMessage.create(nodesToSend, id, this.key); + NeighborsPeerMessage sendNodesMessage = NeighborsPeerMessage.create(nodesToSend, id, this.key, networkId); udpChannel.write(new DiscoveryEvent(sendNodesMessage, nodeAddress)); logger.debug(" [{}] Neighbors Sent to ip:[{}] port:[{}]", nodesToSend.size(), nodeAddress.getAddress().getHostAddress(), nodeAddress.getPort()); diff --git a/rskj-core/src/main/java/co/rsk/net/discovery/message/FindNodePeerMessage.java b/rskj-core/src/main/java/co/rsk/net/discovery/message/FindNodePeerMessage.java index c5350dde154..764c473bf96 100644 --- a/rskj-core/src/main/java/co/rsk/net/discovery/message/FindNodePeerMessage.java +++ b/rskj-core/src/main/java/co/rsk/net/discovery/message/FindNodePeerMessage.java @@ -20,13 +20,15 @@ import org.apache.commons.lang3.builder.ToStringBuilder; import org.ethereum.crypto.ECKey; -import org.ethereum.util.RLP; -import org.ethereum.util.RLPItem; -import org.ethereum.util.RLPList; +import org.ethereum.util.*; import org.spongycastle.util.encoders.Hex; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import java.util.OptionalInt; + +import static org.ethereum.util.ByteUtil.intToBytes; +import static org.ethereum.util.ByteUtil.stripLeadingZeroes; /** * Created by mario on 16/02/17. @@ -44,20 +46,24 @@ public FindNodePeerMessage(byte[] wire, byte[] mdc, byte[] signature, byte[] typ private FindNodePeerMessage() { } - public static FindNodePeerMessage create(byte[] nodeId, String check, ECKey privKey) { + public static FindNodePeerMessage create(byte[] nodeId, String check, ECKey privKey, Integer networkId) { /* RLP Encode data */ byte[] rlpCheck = RLP.encodeElement(check.getBytes(StandardCharsets.UTF_8)); byte[] rlpNodeId = RLP.encodeElement(nodeId); byte[] type = new byte[]{(byte) DiscoveryMessageType.FIND_NODE.getTypeValue()}; - byte[] data = RLP.encodeList(rlpNodeId, rlpCheck); + + byte[] data; + byte[] rlpNetworkId = RLP.encodeElement(stripLeadingZeroes(intToBytes(networkId))); + data = RLP.encodeList(rlpNodeId, rlpCheck, rlpNetworkId); FindNodePeerMessage message = new FindNodePeerMessage(); message.encode(type, data, privKey); message.messageId = check; message.nodeId = nodeId; + message.setNetworkId(OptionalInt.of(networkId)); return message; } @@ -72,6 +78,8 @@ public final void parse(byte[] data) { RLPItem nodeRlp = (RLPItem) dataList.get(0); this.nodeId = nodeRlp.getRLPData(); + + this.setNetworkIdWithRLP(dataList.size()>2?dataList.get(2):null); } @@ -88,6 +96,7 @@ public DiscoveryMessageType getMessageType() { public String toString() { return new ToStringBuilder(this) .append(Hex.toHexString(this.nodeId)) + .append(this.getNetworkId()) .append(this.messageId).toString(); } diff --git a/rskj-core/src/main/java/co/rsk/net/discovery/message/NeighborsPeerMessage.java b/rskj-core/src/main/java/co/rsk/net/discovery/message/NeighborsPeerMessage.java index 7b174d4ecbb..a6afd03115e 100644 --- a/rskj-core/src/main/java/co/rsk/net/discovery/message/NeighborsPeerMessage.java +++ b/rskj-core/src/main/java/co/rsk/net/discovery/message/NeighborsPeerMessage.java @@ -30,6 +30,10 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; +import java.util.OptionalInt; + +import static org.ethereum.util.ByteUtil.intToBytes; +import static org.ethereum.util.ByteUtil.stripLeadingZeroes; /** * Created by mario on 16/02/17. @@ -62,9 +66,11 @@ public final void parse(byte[] data) { RLPItem chk = (RLPItem) list.get(1); this.messageId = new String(chk.getRLPData(), Charset.forName("UTF-8")); + + this.setNetworkIdWithRLP(list.size()>2?list.get(2):null); } - public static NeighborsPeerMessage create(List nodes, String check, ECKey privKey) { + public static NeighborsPeerMessage create(List nodes, String check, ECKey privKey, Integer networkId) { byte[][] nodeRLPs = null; if (nodes != null) { @@ -80,10 +86,14 @@ public static NeighborsPeerMessage create(List nodes, String check, ECKey byte[] rlpCheck = RLP.encodeElement(check.getBytes(StandardCharsets.UTF_8)); byte[] type = new byte[]{(byte) DiscoveryMessageType.NEIGHBORS.getTypeValue()}; - byte[] data = RLP.encodeList(rlpListNodes, rlpCheck); + byte[] data; + byte[] tmpNetworkId = intToBytes(networkId); + byte[] rlpNetworkId = RLP.encodeElement(stripLeadingZeroes(tmpNetworkId)); + data = RLP.encodeList(rlpListNodes, rlpCheck, rlpNetworkId); NeighborsPeerMessage neighborsMessage = new NeighborsPeerMessage(); neighborsMessage.encode(type, data, privKey); + neighborsMessage.setNetworkId(OptionalInt.of(networkId)); neighborsMessage.nodes = nodes; neighborsMessage.messageId = check; @@ -111,7 +121,8 @@ public int countNodes() { public String toString() { return new ToStringBuilder(this) .append(this.nodes) - .append(this.messageId).toString(); + .append(this.messageId) + .append(this.getNetworkId()).toString(); } } diff --git a/rskj-core/src/main/java/co/rsk/net/discovery/message/PeerDiscoveryMessage.java b/rskj-core/src/main/java/co/rsk/net/discovery/message/PeerDiscoveryMessage.java index 353707da37d..90bf55a0a92 100644 --- a/rskj-core/src/main/java/co/rsk/net/discovery/message/PeerDiscoveryMessage.java +++ b/rskj-core/src/main/java/co/rsk/net/discovery/message/PeerDiscoveryMessage.java @@ -22,12 +22,16 @@ import org.apache.commons.lang3.builder.ToStringBuilder; import org.ethereum.crypto.ECKey; import org.ethereum.crypto.HashUtil; +import org.ethereum.util.ByteUtil; +import org.ethereum.util.RLPElement; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spongycastle.util.BigIntegers; import org.spongycastle.util.encoders.Hex; import java.security.SignatureException; +import java.util.Optional; +import java.util.OptionalInt; import static org.ethereum.crypto.HashUtil.keccak256; import static org.ethereum.util.ByteUtil.merge; @@ -41,6 +45,7 @@ public abstract class PeerDiscoveryMessage { private byte[] signature; private byte[] type; private byte[] data; + private OptionalInt networkId; public PeerDiscoveryMessage() {} @@ -51,6 +56,7 @@ public PeerDiscoveryMessage(byte[] wire, byte[] mdc, byte[] signature, byte[] ty this.data = data; this.wire = wire; } + public PeerDiscoveryMessage encode(byte[] type, byte[] data, ECKey privKey) { /* [1] Calc sha3 - prepare for sig */ byte[] payload = new byte[type.length + data.length]; @@ -110,6 +116,22 @@ public ECKey getKey() { return outKey; } + public OptionalInt getNetworkId() { + return this.networkId; + } + + protected void setNetworkId(final OptionalInt networkId) { + this.networkId = networkId; + } + + protected void setNetworkIdWithRLP(final RLPElement networkId) { + Integer setValue = null; + if (networkId != null) { + setValue = ByteUtil.byteArrayToInt(networkId.getRLPData()); + } + this.setNetworkId(Optional.ofNullable(setValue).map(OptionalInt::of).orElseGet(OptionalInt::empty)); + } + public NodeID getNodeId() { byte[] nodeID = new byte[64]; diff --git a/rskj-core/src/main/java/co/rsk/net/discovery/message/PingPeerMessage.java b/rskj-core/src/main/java/co/rsk/net/discovery/message/PingPeerMessage.java index 1f8f01a2fc0..b08e52b974e 100644 --- a/rskj-core/src/main/java/co/rsk/net/discovery/message/PingPeerMessage.java +++ b/rskj-core/src/main/java/co/rsk/net/discovery/message/PingPeerMessage.java @@ -27,7 +27,9 @@ import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import java.util.OptionalInt; +import static org.ethereum.util.ByteUtil.intToBytes; import static org.ethereum.util.ByteUtil.longToBytes; import static org.ethereum.util.ByteUtil.stripLeadingZeroes; @@ -46,7 +48,7 @@ public PingPeerMessage(byte[] wire, byte[] mdc, byte[] signature, byte[] type, b private PingPeerMessage() {} - public static PingPeerMessage create(String host, int port, String check, ECKey privKey) { + public static PingPeerMessage create(String host, int port, String check, ECKey privKey, Integer networkId) { /* RLP Encode data */ byte[] rlpIp = RLP.encodeElement(host.getBytes(StandardCharsets.UTF_8)); @@ -56,17 +58,19 @@ public static PingPeerMessage create(String host, int port, String check, ECKey byte[] rlpIpTo = RLP.encodeElement(host.getBytes(StandardCharsets.UTF_8)); byte[] tmpPortTo = longToBytes(port); byte[] rlpPortTo = RLP.encodeElement(stripLeadingZeroes(tmpPortTo)); - - byte[] rlpCheck = RLP.encodeElement(check.getBytes(StandardCharsets.UTF_8)); - byte[] type = new byte[]{(byte) DiscoveryMessageType.PING.getTypeValue()}; byte[] rlpFromList = RLP.encodeList(rlpIp, rlpPort, rlpPort); byte[] rlpToList = RLP.encodeList(rlpIpTo, rlpPortTo, rlpPortTo); - byte[] data = RLP.encodeList(rlpFromList, rlpToList, rlpCheck); + byte[] rlpCheck = RLP.encodeElement(check.getBytes(StandardCharsets.UTF_8)); + byte[] data; + byte[] tmpNetworkId = intToBytes(networkId); + byte[] rlpNetworkID = RLP.encodeElement(stripLeadingZeroes(tmpNetworkId)); + data = RLP.encodeList(rlpFromList, rlpToList, rlpCheck, rlpNetworkID); PingPeerMessage message = new PingPeerMessage(); message.encode(type, data, privKey); + message.setNetworkId(OptionalInt.of(networkId)); message.messageId = check; message.host = host; message.port = port; @@ -85,8 +89,10 @@ public final void parse(byte[] data) { this.host = new String(ipB, Charset.forName("UTF-8")); this.port = ByteUtil.byteArrayToInt(fromList.get(1).getRLPData()); this.messageId = new String(chk.getRLPData(), Charset.forName("UTF-8")); - } + //Message from nodes that do not have this + this.setNetworkIdWithRLP(dataList.size()>3?dataList.get(3):null); + } public String getMessageId() { return this.messageId; diff --git a/rskj-core/src/main/java/co/rsk/net/discovery/message/PongPeerMessage.java b/rskj-core/src/main/java/co/rsk/net/discovery/message/PongPeerMessage.java index d2cb3508f80..ac7cf831d5f 100644 --- a/rskj-core/src/main/java/co/rsk/net/discovery/message/PongPeerMessage.java +++ b/rskj-core/src/main/java/co/rsk/net/discovery/message/PongPeerMessage.java @@ -27,7 +27,9 @@ import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import java.util.OptionalInt; +import static org.ethereum.util.ByteUtil.intToBytes; import static org.ethereum.util.ByteUtil.longToBytes; import static org.ethereum.util.ByteUtil.stripLeadingZeroes; @@ -47,7 +49,7 @@ public PongPeerMessage(byte[] wire, byte[] mdc, byte[] signature, byte[] type, b private PongPeerMessage() { } - public static PongPeerMessage create(String host, int port, String check, ECKey privKey) { + public static PongPeerMessage create(String host, int port, String check, ECKey privKey, Integer networkId) { /* RLP Encode data */ byte[] rlpIp = RLP.encodeElement(host.getBytes(StandardCharsets.UTF_8)); @@ -63,11 +65,16 @@ public static PongPeerMessage create(String host, int port, String check, ECKey byte[] type = new byte[]{(byte) DiscoveryMessageType.PONG.getTypeValue()}; byte[] rlpFromList = RLP.encodeList(rlpIp, rlpPort, rlpPort); byte[] rlpToList = RLP.encodeList(rlpIpTo, rlpPortTo, rlpPortTo); - byte[] data = RLP.encodeList(rlpFromList, rlpToList, rlpCheck); + byte[] data; + + byte[] tmpNetworkId = intToBytes(networkId); + byte[] rlpNetworkID = RLP.encodeElement(stripLeadingZeroes(tmpNetworkId)); + data = RLP.encodeList(rlpFromList, rlpToList, rlpCheck, rlpNetworkID); PongPeerMessage message = new PongPeerMessage(); message.encode(type, data, privKey); + message.setNetworkId(OptionalInt.of(networkId)); message.messageId = check; message.host = host; message.port = port; @@ -95,6 +102,9 @@ public final void parse(byte[] data) { RLPItem chk = (RLPItem) dataList.get(2); this.messageId = new String(chk.getRLPData(), Charset.forName("UTF-8")); + + //Message from nodes that do not have this + this.setNetworkIdWithRLP(dataList.size()>3?dataList.get(3):null); } public String getMessageId() { diff --git a/rskj-core/src/main/java/org/ethereum/config/DefaultConfig.java b/rskj-core/src/main/java/org/ethereum/config/DefaultConfig.java index e57eb01278e..5f48770ccfb 100644 --- a/rskj-core/src/main/java/org/ethereum/config/DefaultConfig.java +++ b/rskj-core/src/main/java/org/ethereum/config/DefaultConfig.java @@ -206,6 +206,7 @@ public BlockValidationRule minerServerBlockValidationRule( @Bean public PeerExplorer peerExplorer(RskSystemProperties rskConfig) { ECKey key = rskConfig.getMyKey(); + Integer networkId = rskConfig.networkId(); Node localNode = new Node(key.getNodeId(), rskConfig.getPublicIp(), rskConfig.getPeerPort()); NodeDistanceTable distanceTable = new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, localNode); long msgTimeOut = rskConfig.peerDiscoveryMessageTimeOut(); @@ -219,7 +220,7 @@ public PeerExplorer peerExplorer(RskSystemProperties rskConfig) { initialBootNodes.add(address.getHostName() + ":" + address.getPort()); } } - return new PeerExplorer(initialBootNodes, localNode, distanceTable, key, msgTimeOut, refreshPeriod, cleanPeriod); + return new PeerExplorer(initialBootNodes, localNode, distanceTable, key, msgTimeOut, refreshPeriod, cleanPeriod, networkId); } @Bean diff --git a/rskj-core/src/test/java/co/rsk/net/discovery/NodeChallengeManagerTest.java b/rskj-core/src/test/java/co/rsk/net/discovery/NodeChallengeManagerTest.java index 8a6588c118c..691aac78c77 100644 --- a/rskj-core/src/test/java/co/rsk/net/discovery/NodeChallengeManagerTest.java +++ b/rskj-core/src/test/java/co/rsk/net/discovery/NodeChallengeManagerTest.java @@ -28,6 +28,7 @@ import org.spongycastle.util.encoders.Hex; import java.util.ArrayList; +import java.util.OptionalInt; import java.util.UUID; /** @@ -38,6 +39,7 @@ public class NodeChallengeManagerTest { private static final String KEY_1 = "bd1d20e480dfb1c9c07ba0bc8cf9052f89923d38b5128c5dbfc18d4eea38261f"; private static final String HOST_1 = "localhost"; private static final int PORT_1 = 44035; + private static final int NETWORK_ID = 1; private static final String KEY_2 = "bd2d20e480dfb1c9c07ba0bc8cf9052f89923d38b5128c5dbfc18d4eea38262f"; private static final String HOST_2 = "localhost"; @@ -63,7 +65,7 @@ public void startChallenge() { Node node3 = new Node(key3.getNodeId(), HOST_3, PORT_3); NodeDistanceTable distanceTable = new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, node1); - PeerExplorer peerExplorer = new PeerExplorer(new ArrayList<>(), node1, distanceTable, new ECKey(), TIMEOUT, UPDATE, CLEAN); + PeerExplorer peerExplorer = new PeerExplorer(new ArrayList<>(), node1, distanceTable, new ECKey(), TIMEOUT, UPDATE, CLEAN, NETWORK_ID); peerExplorer.setUDPChannel(Mockito.mock(UDPChannel.class)); NodeChallengeManager manager = new NodeChallengeManager(); diff --git a/rskj-core/src/test/java/co/rsk/net/discovery/PacketDecoderTest.java b/rskj-core/src/test/java/co/rsk/net/discovery/PacketDecoderTest.java index 8ee33c9f7ef..364bb4b1728 100644 --- a/rskj-core/src/test/java/co/rsk/net/discovery/PacketDecoderTest.java +++ b/rskj-core/src/test/java/co/rsk/net/discovery/PacketDecoderTest.java @@ -31,6 +31,7 @@ import java.net.InetSocketAddress; import java.util.ArrayList; +import java.util.OptionalInt; import java.util.UUID; /** @@ -38,6 +39,7 @@ */ public class PacketDecoderTest { + private static final int NETWORK_ID = 1; private static final String KEY_1 = "bd1d20e480dfb1c9c07ba0bc8cf9052f89923d38b5128c5dbfc18d4eea38261f"; @Test @@ -50,22 +52,22 @@ public void decode() throws Exception { PacketDecoder decoder = new PacketDecoder(); //Decode Ping Message - PingPeerMessage nodeMessage = PingPeerMessage.create("localhost", 44035, check, key1); + PingPeerMessage nodeMessage = PingPeerMessage.create("localhost", 44035, check, key1, NETWORK_ID); InetSocketAddress sender = new InetSocketAddress("localhost", 44035); this.assertDecodedMessage(decoder.decodeMessage(ctx, nodeMessage.getPacket(), sender), sender, DiscoveryMessageType.PING); //Decode Pong Message - PongPeerMessage pongPeerMessage = PongPeerMessage.create("localhost", 44036, check, key1); + PongPeerMessage pongPeerMessage = PongPeerMessage.create("localhost", 44036, check, key1, NETWORK_ID); sender = new InetSocketAddress("localhost", 44036); this.assertDecodedMessage(decoder.decodeMessage(ctx, pongPeerMessage.getPacket(), sender), sender, DiscoveryMessageType.PONG); //Decode Find Node Message - FindNodePeerMessage findNodePeerMessage = FindNodePeerMessage.create(key1.getNodeId(), check, key1); + FindNodePeerMessage findNodePeerMessage = FindNodePeerMessage.create(key1.getNodeId(), check, key1, NETWORK_ID); sender = new InetSocketAddress("localhost", 44037); this.assertDecodedMessage(decoder.decodeMessage(ctx, findNodePeerMessage.getPacket(), sender), sender, DiscoveryMessageType.FIND_NODE); //Decode Neighbors Message - NeighborsPeerMessage neighborsPeerMessage = NeighborsPeerMessage.create(new ArrayList<>(), check, key1); + NeighborsPeerMessage neighborsPeerMessage = NeighborsPeerMessage.create(new ArrayList<>(), check, key1, NETWORK_ID); sender = new InetSocketAddress("localhost", 44038); this.assertDecodedMessage(decoder.decodeMessage(ctx, neighborsPeerMessage.getPacket(), sender), sender, DiscoveryMessageType.NEIGHBORS); diff --git a/rskj-core/src/test/java/co/rsk/net/discovery/PeerDiscoveryRequestTest.java b/rskj-core/src/test/java/co/rsk/net/discovery/PeerDiscoveryRequestTest.java index 69706ee18d6..b0752142a26 100644 --- a/rskj-core/src/test/java/co/rsk/net/discovery/PeerDiscoveryRequestTest.java +++ b/rskj-core/src/test/java/co/rsk/net/discovery/PeerDiscoveryRequestTest.java @@ -27,6 +27,7 @@ import org.junit.Test; import java.net.InetSocketAddress; +import java.util.OptionalInt; import java.util.UUID; /** @@ -34,12 +35,14 @@ */ public class PeerDiscoveryRequestTest { + public static final int NETWORK_ID = 1; + @Test public void create() { ECKey key = new ECKey(); String check = UUID.randomUUID().toString(); - PingPeerMessage pingPeerMessage = PingPeerMessage.create("localhost", 80, check, key); - PongPeerMessage pongPeerMessage = PongPeerMessage.create("localhost", 80, check, key); + PingPeerMessage pingPeerMessage = PingPeerMessage.create("localhost", 80, check, key, NETWORK_ID); + PongPeerMessage pongPeerMessage = PongPeerMessage.create("localhost", 80, check, key, NETWORK_ID); InetSocketAddress address = new InetSocketAddress("localhost", 8080); PeerDiscoveryRequest request = PeerDiscoveryRequestBuilder.builder().messageId(check) diff --git a/rskj-core/src/test/java/co/rsk/net/discovery/PeerExplorerTest.java b/rskj-core/src/test/java/co/rsk/net/discovery/PeerExplorerTest.java index cbfa0b78b60..2547bbed498 100644 --- a/rskj-core/src/test/java/co/rsk/net/discovery/PeerExplorerTest.java +++ b/rskj-core/src/test/java/co/rsk/net/discovery/PeerExplorerTest.java @@ -33,10 +33,7 @@ import org.spongycastle.util.encoders.Hex; import java.net.InetSocketAddress; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.UUID; +import java.util.*; /** * Created by mario on 15/02/17. @@ -62,11 +59,14 @@ public class PeerExplorerTest { private static final long UPDATE = 60000; private static final long CLEAN = 60000; + private static final int NETWORK_ID1 = 1; + private static final int NETWORK_ID2 = 2; + @Test public void sendInitialMessageToNodesNoNodes() { Node node = new Node(new ECKey().getNodeId(), HOST_2, PORT_2); NodeDistanceTable distanceTable = new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, node); - PeerExplorer peerExplorer = new PeerExplorer(new ArrayList<>(), node, distanceTable, new ECKey(), TIMEOUT, UPDATE, CLEAN); + PeerExplorer peerExplorer = new PeerExplorer(new ArrayList<>(), node, distanceTable, new ECKey(), TIMEOUT, UPDATE, CLEAN, NETWORK_ID1); peerExplorer.setUDPChannel(Mockito.mock(UDPChannel.class)); @@ -74,7 +74,7 @@ public void sendInitialMessageToNodesNoNodes() { Assert.assertTrue(CollectionUtils.isEmpty(nodesWithMessage)); - peerExplorer = new PeerExplorer(null, node, distanceTable, new ECKey(), TIMEOUT, UPDATE, CLEAN); + peerExplorer = new PeerExplorer(null, node, distanceTable, new ECKey(), TIMEOUT, UPDATE, CLEAN, NETWORK_ID1); peerExplorer.setUDPChannel(Mockito.mock(UDPChannel.class)); nodesWithMessage = peerExplorer.startConversationWithNewNodes(); @@ -94,7 +94,8 @@ public void sendInitialMessageToNodes() { Node node = new Node(new ECKey().getNodeId(), HOST_1, PORT_1); NodeDistanceTable distanceTable = new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, node); - PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, new ECKey(), TIMEOUT, UPDATE, CLEAN); + + PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, new ECKey(), TIMEOUT, UPDATE, CLEAN, NETWORK_ID1); UDPChannel channel = new UDPChannel(Mockito.mock(Channel.class), peerExplorer); peerExplorer.setUDPChannel(channel); @@ -106,6 +107,35 @@ public void sendInitialMessageToNodes() { Assert.assertTrue(nodesWithMessage.contains("localhost/127.0.0.1:3306")); } + @Test + public void handlePingMessageFromDifferentNetwork() throws Exception { + List nodes = new ArrayList<>(); + + ECKey key2 = ECKey.fromPrivate(Hex.decode(KEY_2)).decompress(); + + Node node = new Node(key2.getNodeId(), HOST_2, PORT_2); + NodeDistanceTable distanceTable = new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, node); + PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, key2, TIMEOUT, UPDATE, CLEAN, NETWORK_ID1); + + Channel internalChannel = Mockito.mock(Channel.class); + UDPTestChannel channel = new UDPTestChannel(internalChannel, peerExplorer); + ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); + peerExplorer.setUDPChannel(channel); + + Assert.assertTrue(CollectionUtils.isEmpty(peerExplorer.getNodes())); + + ECKey key1 = ECKey.fromPrivate(Hex.decode(KEY_1)).decompress(); + String check = UUID.randomUUID().toString(); + PingPeerMessage pingPeerMessageWithDifferentNetwork = PingPeerMessage.create(HOST_1, PORT_1, check, key1, this.NETWORK_ID2); + DiscoveryEvent incomingPingEvent = new DiscoveryEvent(pingPeerMessageWithDifferentNetwork, new InetSocketAddress(HOST_1, PORT_1)); + + //A message is received + channel.channelRead0(ctx, incomingPingEvent); + //There should be no response, since they are from different networks. + List sentEvents = channel.getEventsWritten(); + Assert.assertEquals(0, sentEvents.size()); + } + @Test public void handlePingMessage() throws Exception { List nodes = new ArrayList<>(); @@ -114,7 +144,8 @@ public void handlePingMessage() throws Exception { Node node = new Node(key2.getNodeId(), HOST_2, PORT_2); NodeDistanceTable distanceTable = new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, node); - PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, key2, TIMEOUT, UPDATE, CLEAN); + + PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, key2, TIMEOUT, UPDATE, CLEAN, NETWORK_ID1); Channel internalChannel = Mockito.mock(Channel.class); UDPTestChannel channel = new UDPTestChannel(internalChannel, peerExplorer); @@ -125,7 +156,7 @@ public void handlePingMessage() throws Exception { ECKey key1 = ECKey.fromPrivate(Hex.decode(KEY_1)).decompress(); String check = UUID.randomUUID().toString(); - PingPeerMessage nodeMessage = PingPeerMessage.create(HOST_1, PORT_1, check, key1); + PingPeerMessage nodeMessage = PingPeerMessage.create(HOST_1, PORT_1, check, key1, this.NETWORK_ID1); DiscoveryEvent incomingPingEvent = new DiscoveryEvent(nodeMessage, new InetSocketAddress(HOST_1, PORT_1)); //A message is received @@ -144,7 +175,7 @@ public void handlePingMessage() throws Exception { Assert.assertEquals(new InetSocketAddress(HOST_1, PORT_1), pingEvent.getAddress()); //After a pong returns from a node, when we receive a ping from that node, we only answer with a pong (no additional ping) - PongPeerMessage pongResponseFromSender = PongPeerMessage.create(HOST_1, PORT_1, toSenderPing.getMessageId(), key1); + PongPeerMessage pongResponseFromSender = PongPeerMessage.create(HOST_1, PORT_1, toSenderPing.getMessageId(), key1, NETWORK_ID1); DiscoveryEvent incomingPongEvent = new DiscoveryEvent(pongResponseFromSender, new InetSocketAddress(HOST_1, PORT_1)); channel.channelRead0(ctx, incomingPongEvent); channel.clearEvents(); @@ -169,7 +200,7 @@ public void handlePongMessage() throws Exception { Node node = new Node(key2.getNodeId(), HOST_2, PORT_2); NodeDistanceTable distanceTable = new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, node); - PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, key2, TIMEOUT, UPDATE, CLEAN); + PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, key2, TIMEOUT, UPDATE, CLEAN, NETWORK_ID1); Channel internalChannel = Mockito.mock(Channel.class); UDPTestChannel channel = new UDPTestChannel(internalChannel, peerExplorer); @@ -179,7 +210,7 @@ public void handlePongMessage() throws Exception { //A incoming pong for a Ping we did not sent. String check = UUID.randomUUID().toString(); - PongPeerMessage incomingPongMessage = PongPeerMessage.create(HOST_1, PORT_1, check, key1); + PongPeerMessage incomingPongMessage = PongPeerMessage.create(HOST_1, PORT_1, check, key1, NETWORK_ID1); DiscoveryEvent incomingPongEvent = new DiscoveryEvent(incomingPongMessage, new InetSocketAddress(HOST_1, PORT_1)); channel.clearEvents(); channel.channelRead0(ctx, incomingPongEvent); @@ -191,7 +222,7 @@ public void handlePongMessage() throws Exception { peerExplorer.startConversationWithNewNodes(); sentEvents = channel.getEventsWritten(); Assert.assertEquals(2, sentEvents.size()); - incomingPongMessage = PongPeerMessage.create(HOST_1, PORT_1, ((PingPeerMessage) sentEvents.get(0).getMessage()).getMessageId(), key1); + incomingPongMessage = PongPeerMessage.create(HOST_1, PORT_1, ((PingPeerMessage) sentEvents.get(0).getMessage()).getMessageId(), key1, NETWORK_ID1); incomingPongEvent = new DiscoveryEvent(incomingPongMessage, new InetSocketAddress(HOST_1, PORT_1)); channel.clearEvents(); List addedNodes = peerExplorer.getNodes(); @@ -213,7 +244,8 @@ public void handleFindNodeMessage() throws Exception { Node node = new Node(key2.getNodeId(), HOST_2, PORT_2); NodeDistanceTable distanceTable = new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, node); - PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, key2, TIMEOUT, UPDATE, CLEAN); + + PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, key2, TIMEOUT, UPDATE, CLEAN, NETWORK_ID1); Channel internalChannel = Mockito.mock(Channel.class); UDPTestChannel channel = new UDPTestChannel(internalChannel, peerExplorer); @@ -222,7 +254,7 @@ public void handleFindNodeMessage() throws Exception { //We try to handle a findNode message from an unkown sender, no message should be send as a response String check = UUID.randomUUID().toString(); - FindNodePeerMessage findNodePeerMessage = FindNodePeerMessage.create(key1.getNodeId(), check, key1); + FindNodePeerMessage findNodePeerMessage = FindNodePeerMessage.create(key1.getNodeId(), check, key1, NETWORK_ID1); channel.clearEvents(); channel.channelRead0(ctx, new DiscoveryEvent(findNodePeerMessage, new InetSocketAddress(HOST_1, PORT_1))); List sentEvents = channel.getEventsWritten(); @@ -230,16 +262,16 @@ public void handleFindNodeMessage() throws Exception { //Now we send the ping first peerExplorer.startConversationWithNewNodes(); - PongPeerMessage incomingPongMessage = PongPeerMessage.create(HOST_1, PORT_1, ((PingPeerMessage) sentEvents.get(0).getMessage()).getMessageId(), key1); + PongPeerMessage incomingPongMessage = PongPeerMessage.create(HOST_1, PORT_1, ((PingPeerMessage) sentEvents.get(0).getMessage()).getMessageId(), key1, NETWORK_ID1); DiscoveryEvent incomingPongEvent = new DiscoveryEvent(incomingPongMessage, new InetSocketAddress(HOST_1, PORT_1)); channel.channelRead0(ctx, incomingPongEvent); - incomingPongMessage = PongPeerMessage.create(HOST_3, PORT_3, ((PingPeerMessage) sentEvents.get(0).getMessage()).getMessageId(), key1); + incomingPongMessage = PongPeerMessage.create(HOST_3, PORT_3, ((PingPeerMessage) sentEvents.get(0).getMessage()).getMessageId(), key1, NETWORK_ID1); incomingPongEvent = new DiscoveryEvent(incomingPongMessage, new InetSocketAddress(HOST_3, PORT_3)); channel.channelRead0(ctx, incomingPongEvent); check = UUID.randomUUID().toString(); - findNodePeerMessage = FindNodePeerMessage.create(key1.getNodeId(), check, key1); + findNodePeerMessage = FindNodePeerMessage.create(key1.getNodeId(), check, key1, NETWORK_ID1); channel.clearEvents(); channel.channelRead0(ctx, new DiscoveryEvent(findNodePeerMessage, new InetSocketAddress(HOST_1, PORT_1))); sentEvents = channel.getEventsWritten(); @@ -260,7 +292,7 @@ public void handleFindNodeMessageWithExtraNodes() throws Exception { Node node = new Node(key2.getNodeId(), HOST_2, PORT_2); NodeDistanceTable distanceTable = new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, node); - PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, key2, TIMEOUT, UPDATE, CLEAN); + PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, key2, TIMEOUT, UPDATE, CLEAN, NETWORK_ID1); Channel internalChannel = Mockito.mock(Channel.class); UDPTestChannel channel = new UDPTestChannel(internalChannel, peerExplorer); @@ -272,9 +304,9 @@ public void handleFindNodeMessageWithExtraNodes() throws Exception { peerExplorer.startConversationWithNewNodes(); List sentEvents = channel.getEventsWritten(); Assert.assertEquals(2, sentEvents.size()); - PongPeerMessage incomingPongMessage1 = PongPeerMessage.create(HOST_1, PORT_1, ((PingPeerMessage) sentEvents.get(0).getMessage()).getMessageId(), key1); + PongPeerMessage incomingPongMessage1 = PongPeerMessage.create(HOST_1, PORT_1, ((PingPeerMessage) sentEvents.get(0).getMessage()).getMessageId(), key1, NETWORK_ID1); DiscoveryEvent incomingPongEvent1 = new DiscoveryEvent(incomingPongMessage1, new InetSocketAddress(HOST_1, PORT_1)); - PongPeerMessage incomingPongMessage2 = PongPeerMessage.create(HOST_3, PORT_3, ((PingPeerMessage) sentEvents.get(1).getMessage()).getMessageId(), key3); + PongPeerMessage incomingPongMessage2 = PongPeerMessage.create(HOST_3, PORT_3, ((PingPeerMessage) sentEvents.get(1).getMessage()).getMessageId(), key3, NETWORK_ID1); DiscoveryEvent incomingPongEvent2 = new DiscoveryEvent(incomingPongMessage2, new InetSocketAddress(HOST_3, PORT_3)); channel.clearEvents(); @@ -287,7 +319,7 @@ public void handleFindNodeMessageWithExtraNodes() throws Exception { Assert.assertEquals(NODE_ID_1, Hex.toHexString(foundNodes.get(1).getId().getID())); String check = UUID.randomUUID().toString(); - FindNodePeerMessage findNodePeerMessage = FindNodePeerMessage.create(key1.getNodeId(), check, key1); + FindNodePeerMessage findNodePeerMessage = FindNodePeerMessage.create(key1.getNodeId(), check, key1, NETWORK_ID1); channel.clearEvents(); channel.channelRead0(ctx, new DiscoveryEvent(findNodePeerMessage, new InetSocketAddress(HOST_1, PORT_1))); sentEvents = channel.getEventsWritten(); @@ -305,6 +337,7 @@ private boolean cotainsNode(String nodeId, List nodes) { } return false; } + @Test public void handleNeighbors() throws Exception { List nodes = new ArrayList<>(); @@ -316,7 +349,8 @@ public void handleNeighbors() throws Exception { Node node1 = new Node(key1.getNodeId(), HOST_1, PORT_1); Node node2 = new Node(key2.getNodeId(), HOST_2, PORT_2); NodeDistanceTable distanceTable = new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, node2); - PeerExplorer peerExplorer = new PeerExplorer(nodes, node2, distanceTable, key2, TIMEOUT, UPDATE, CLEAN); + + PeerExplorer peerExplorer = new PeerExplorer(nodes, node2, distanceTable, key2, TIMEOUT, UPDATE, CLEAN, NETWORK_ID1); Channel internalChannel = Mockito.mock(Channel.class); UDPTestChannel channel = new UDPTestChannel(internalChannel, peerExplorer); @@ -327,7 +361,7 @@ public void handleNeighbors() throws Exception { //We try to process a Message without previous connection List newNodes = new ArrayList<>(); newNodes.add(new Node(Hex.decode(NODE_ID_3), HOST_3, PORT_3)); - NeighborsPeerMessage neighborsPeerMessage = NeighborsPeerMessage.create(newNodes, UUID.randomUUID().toString(), key1); + NeighborsPeerMessage neighborsPeerMessage = NeighborsPeerMessage.create(newNodes, UUID.randomUUID().toString(), key1, NETWORK_ID1); DiscoveryEvent neighborsEvent = new DiscoveryEvent(neighborsPeerMessage, new InetSocketAddress(HOST_1, PORT_1)); channel.clearEvents(); channel.channelRead0(ctx, neighborsEvent); @@ -336,7 +370,7 @@ public void handleNeighbors() throws Exception { //we establish a connection but we dont send the findnode message. peerExplorer.startConversationWithNewNodes(); - PongPeerMessage incomingPongMessage = PongPeerMessage.create(HOST_1, PORT_1, ((PingPeerMessage) sentEvents.get(0).getMessage()).getMessageId(), key1); + PongPeerMessage incomingPongMessage = PongPeerMessage.create(HOST_1, PORT_1, ((PingPeerMessage) sentEvents.get(0).getMessage()).getMessageId(), key1, NETWORK_ID1); DiscoveryEvent incomingPongEvent = new DiscoveryEvent(incomingPongMessage, new InetSocketAddress(HOST_1, PORT_1)); channel.channelRead0(ctx, incomingPongEvent); channel.clearEvents(); @@ -349,7 +383,7 @@ public void handleNeighbors() throws Exception { channel.clearEvents(); peerExplorer.sendFindNode(node1); FindNodePeerMessage findNodePeerMessage = (FindNodePeerMessage) channel.getEventsWritten().get(0).getMessage(); - neighborsPeerMessage = NeighborsPeerMessage.create(newNodes, findNodePeerMessage.getMessageId(), key1); + neighborsPeerMessage = NeighborsPeerMessage.create(newNodes, findNodePeerMessage.getMessageId(), key1, NETWORK_ID1); neighborsEvent = new DiscoveryEvent(neighborsPeerMessage, new InetSocketAddress(HOST_1, PORT_1)); channel.clearEvents(); channel.channelRead0(ctx, neighborsEvent); @@ -373,7 +407,7 @@ public void testCleanPeriod() throws InterruptedException, Exception{ Node node = new Node(key2.getNodeId(), HOST_2, PORT_2); NodeDistanceTable distanceTable = new NodeDistanceTable(1, 1, node); - PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, key2, 199, UPDATE, 200); + PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, key2, 199, UPDATE, CLEAN, NETWORK_ID1); Channel internalChannel = Mockito.mock(Channel.class); UDPTestChannel channel = new UDPTestChannel(internalChannel, peerExplorer); @@ -383,7 +417,7 @@ public void testCleanPeriod() throws InterruptedException, Exception{ //A incoming pong for a Ping we did not sent. String check = UUID.randomUUID().toString(); - PongPeerMessage incomingPongMessage = PongPeerMessage.create(HOST_1, PORT_1, check, key1); + PongPeerMessage incomingPongMessage = PongPeerMessage.create(HOST_1, PORT_1, check, key1, NETWORK_ID1); DiscoveryEvent incomingPongEvent = new DiscoveryEvent(incomingPongMessage, new InetSocketAddress(HOST_1, PORT_1)); channel.clearEvents(); channel.channelRead0(ctx, incomingPongEvent); @@ -395,9 +429,9 @@ public void testCleanPeriod() throws InterruptedException, Exception{ peerExplorer.startConversationWithNewNodes(); sentEvents = channel.getEventsWritten(); Assert.assertEquals(2, sentEvents.size()); - incomingPongMessage = PongPeerMessage.create(HOST_1, PORT_1, ((PingPeerMessage) sentEvents.get(0).getMessage()).getMessageId(), key1); + incomingPongMessage = PongPeerMessage.create(HOST_1, PORT_1, ((PingPeerMessage) sentEvents.get(0).getMessage()).getMessageId(), key1, NETWORK_ID1); incomingPongEvent = new DiscoveryEvent(incomingPongMessage, new InetSocketAddress(HOST_1, PORT_1)); - PongPeerMessage incomingPongMessage3 = PongPeerMessage.create(HOST_3, PORT_3, ((PingPeerMessage) sentEvents.get(1).getMessage()).getMessageId(), key3); + PongPeerMessage incomingPongMessage3 = PongPeerMessage.create(HOST_3, PORT_3, ((PingPeerMessage) sentEvents.get(1).getMessage()).getMessageId(), key3, NETWORK_ID1); DiscoveryEvent incomingPongEvent3 = new DiscoveryEvent(incomingPongMessage3, new InetSocketAddress(HOST_3, PORT_3)); channel.clearEvents(); List addedNodes = peerExplorer.getNodes(); diff --git a/rskj-core/src/test/java/co/rsk/net/discovery/PeerMessagesTest.java b/rskj-core/src/test/java/co/rsk/net/discovery/PeerMessagesTest.java new file mode 100644 index 00000000000..7e44bc2e764 --- /dev/null +++ b/rskj-core/src/test/java/co/rsk/net/discovery/PeerMessagesTest.java @@ -0,0 +1,100 @@ +package co.rsk.net.discovery; + +import co.rsk.net.discovery.message.DiscoveryMessageType; +import co.rsk.net.discovery.message.FindNodePeerMessage; +import co.rsk.net.discovery.message.PingPeerMessage; +import co.rsk.net.discovery.message.PongPeerMessage; +import org.ethereum.crypto.ECKey; +import org.junit.Assert; +import org.junit.Test; +import org.spongycastle.util.encoders.Hex; + +import java.util.*; + +public class PeerMessagesTest { + + private static final String GOOD_HOST = "localhost"; + private static final int GOOD_PORT = 8080; + + private static byte[] wirePingPongPeerMessage = new byte[]{113,-5,-63,15,-4,21,-42,93,-10,19,-95,-37,-29,63,-92,-125,28,-27,-60,99,-85,-33,43,86,-12,-74,66,100,-31,-41,32,107,-69,20,-38,-122,-33,-110,-118,-126,-12,-85,20,91,44,44,-5,79,-101,-53,124,-57,-29,118,-81,-48,-89,-99,-29,-93,8,-17,113,-87,100,-123,-124,-77,-99,76,-51,54,4,-78,-41,116,84,-116,35,-35,-30,-12,16,-87,23,-32,-73,124,71,-26,-105,-28,-14,91,122,-114,1,1,-8,76,-48,-119,108,111,99,97,108,104,111,115,116,-126,31,-112,-126,31,-112,-48,-119,108,111,99,97,108,104,111,115,116,-126,31,-112,-126,31,-112,-92,48,97,57,54,55,56,53,53,45,99,102,98,97,45,52,98,49,98,45,57,56,57,48,45,102,54,99,57,51,49,97,52,97,55,97,48,-124,-59,3,-58,-55}; + private static byte[] mdcPingPongPeerMessage = new byte[]{113,-5,-63,15,-4,21,-42,93,-10,19,-95,-37,-29,63,-92,-125,28,-27,-60,99,-85,-33,43,86,-12,-74,66,100,-31,-41,32,107}; + private static byte[] signaturePingPongPeerMessage = new byte[]{-69,20,-38,-122,-33,-110,-118,-126,-12,-85,20,91,44,44,-5,79,-101,-53,124,-57,-29,118,-81,-48,-89,-99,-29,-93,8,-17,113,-87,100,-123,-124,-77,-99,76,-51,54,4,-78,-41,116,84,-116,35,-35,-30,-12,16,-87,23,-32,-73,124,71,-26,-105,-28,-14,91,122,-114,1}; + private static byte[] dataWithNetworkIdPingPongPeerMessage = new byte[]{-8,76,-48,-119,108,111,99,97,108,104,111,115,116,-126,31,-112,-126,31,-112,-48,-119,108,111,99,97,108,104,111,115,116,-126,31,-112,-126,31,-112,-92,48,97,57,54,55,56,53,53,45,99,102,98,97,45,52,98,49,98,45,57,56,57,48,45,102,54,99,57,51,49,97,52,97,55,97,48,-124,-59,3,-58,-55}; + private static byte[] dataWithoutNetworkIdPingPongPeerMessage = new byte[]{-8,71,-48,-119,108,111,99,97,108,104,111,115,116,-126,31,-112,-126,31,-112,-48,-119,108,111,99,97,108,104,111,115,116,-126,31,-112,-126,31,-112,-92,55,52,56,49,99,49,51,57,45,98,99,102,99,45,52,53,52,50,45,97,55,55,48,45,53,99,97,52,57,97,52,101,97,97,55,97}; + private static byte[] typePong = new byte[]{(byte) DiscoveryMessageType.PONG.getTypeValue()}; + private static byte[] typePing = new byte[]{(byte) DiscoveryMessageType.PING.getTypeValue()}; + + private static byte[] signatureFindNodePeerMessage = new byte[]{-88,-13,-116,63,18,39,-90,-30,120,126,94,-25,-90,90,93,63,-124,120,-3,-116,-62,-38,41,-84,39,-69,-114,114,73,52,117,6,49,66,68,14,-31,17,-115,19,82,9,80,-57,-111,119,-15,108,-19,-89,105,-59,-7,-52,-4,-73,-66,111,-11,68,39,-46,42,-120,1}; + private static byte[] typeFindNodePeerMessage = new byte[]{3}; + private static byte[] wireFindNodePeerMessage = new byte[]{-23,116,115,41,75,96,-74,89,-26,-64,-33,-84,-81,-65,-34,-32,-89,-112,125,25,48,94,-75,114,109,28,-58,-55,-83,-64,-46,69,-74,-122,61,12,-101,26,-14,-28,72,-93,26,-125,-12,-38,55,80,31,33,-105,110,54,-25,80,45,18,-44,-127,-22,-50,-88,-78,77,116,-66,-56,-54,126,-5,-118,-91,-88,-76,52,56,-103,121,59,1,72,109,94,-14,118,47,62,-76,41,-63,82,103,125,-100,13,-88,0,3,-16,-118,-2,-74,-97,-8,69,1,67,49,16,99,49,56,51,56,100,52,100,45,49,122,-92,99,52,55,45,52,49,98,50,45,57,99,54,55,45,52,57,51,97,57,56,55,101,98,48,48,99}; + private static byte[] mdcFindNodePeerMessage = new byte[]{127,110,79,83,31,7,86,104,42,124,86,-57,76,-92,93,6,82,-37,97,-127,-54,72,86,-29,-81,-97,-10,94,-23,-102,-16,-82}; + private static byte[] dataWithoutNetworkId = new byte[]{-16,-118,55,-9,-121,-84,69,-97,31,36,-115,111,-92,98,101,48,52,97,98,98,98,45,54,48,50,102,45,52,99,49,50,45,56,99,48,56,45,101,55,52,101,51,49,101,54,54,48,97,97}; + private static byte[] dataWithNetworkId = new byte[]{-11,-118,86,54,14,-30,58,118,14,-123,57,84,-92,54,53,98,52,54,57,99,54,45,98,97,54,57,45,52,50,51,56,45,98,102,53,97,45,97,52,56,53,99,48,50,52,101,51,99,101,-124,-112,-104,-118,19}; + + + @Test + public void testParsePongPeerMessageWithoutNetworkId(){ + PongPeerMessage pongPeerMessage = new PongPeerMessage(wirePingPongPeerMessage, mdcPingPongPeerMessage, signaturePingPongPeerMessage, typePong, dataWithoutNetworkIdPingPongPeerMessage); + Assert.assertFalse(pongPeerMessage.getNetworkId().isPresent()); + Assert.assertEquals("7481c139-bcfc-4542-a770-5ca49a4eaa7a",pongPeerMessage.getMessageId()); + Assert.assertEquals(GOOD_HOST,pongPeerMessage.getHost()); + Assert.assertEquals(GOOD_PORT,pongPeerMessage.getPort()); + Assert.assertEquals(DiscoveryMessageType.PONG.getTypeValue() ,pongPeerMessage.getType()[0]); + } + + @Test + public void testParsePongPeerMessageWithNetworkId() { + PongPeerMessage pongPeerMessage = new PongPeerMessage(wirePingPongPeerMessage, mdcPingPongPeerMessage, signaturePingPongPeerMessage, typePong, dataWithNetworkIdPingPongPeerMessage); + Assert.assertTrue(pongPeerMessage.getNetworkId().isPresent()); + Assert.assertEquals(-989608247,pongPeerMessage.getNetworkId().getAsInt()); + Assert.assertEquals("0a967855-cfba-4b1b-9890-f6c931a4a7a0",pongPeerMessage.getMessageId()); + Assert.assertEquals(GOOD_HOST,pongPeerMessage.getHost()); + Assert.assertEquals(GOOD_PORT,pongPeerMessage.getPort()); + Assert.assertEquals(DiscoveryMessageType.PONG.getTypeValue() ,pongPeerMessage.getType()[0]); + } + + @Test + public void testParsePingPeerMessageWithoutNetworkId(){ + PingPeerMessage pingPeerMessage = new PingPeerMessage(wirePingPongPeerMessage, mdcPingPongPeerMessage, signaturePingPongPeerMessage,typePing, dataWithoutNetworkIdPingPongPeerMessage); + Assert.assertFalse(pingPeerMessage.getNetworkId().isPresent()); + Assert.assertEquals("7481c139-bcfc-4542-a770-5ca49a4eaa7a",pingPeerMessage.getMessageId()); + Assert.assertEquals(GOOD_HOST,pingPeerMessage.getHost()); + Assert.assertEquals(GOOD_PORT,pingPeerMessage.getPort()); + Assert.assertEquals(DiscoveryMessageType.PING.getTypeValue() ,pingPeerMessage.getType()[0]); + } + + @Test + public void testParsePingPeerMessageWithNetworkId() { + PingPeerMessage pingPeerMessage = new PingPeerMessage(wirePingPongPeerMessage, mdcPingPongPeerMessage, signaturePingPongPeerMessage,typePing, dataWithNetworkIdPingPongPeerMessage); + Assert.assertTrue(pingPeerMessage.getNetworkId().isPresent()); + Assert.assertEquals(-989608247,pingPeerMessage.getNetworkId().getAsInt()); + Assert.assertEquals("0a967855-cfba-4b1b-9890-f6c931a4a7a0",pingPeerMessage.getMessageId()); + Assert.assertEquals(GOOD_HOST,pingPeerMessage.getHost()); + Assert.assertEquals(GOOD_PORT,pingPeerMessage.getPort()); + Assert.assertEquals(DiscoveryMessageType.PING.getTypeValue() ,pingPeerMessage.getType()[0]); + } + + @Test + public void testParseFindNodePeerMessageWithoutNetworkId() { + FindNodePeerMessage findNodePeerMessageExpected = new FindNodePeerMessage(wireFindNodePeerMessage,mdcFindNodePeerMessage,signatureFindNodePeerMessage,typeFindNodePeerMessage,dataWithoutNetworkId); + Assert.assertFalse(findNodePeerMessageExpected.getNetworkId().isPresent()); + Assert.assertEquals("be04abbb-602f-4c12-8c08-e74e31e660aa", findNodePeerMessageExpected.getMessageId()); + Assert.assertTrue(Arrays.equals(findNodePeerMessageExpected.getMdc(), mdcFindNodePeerMessage)); + Assert.assertTrue(Arrays.equals(findNodePeerMessageExpected.getPacket(), wireFindNodePeerMessage)); + Assert.assertTrue(Arrays.equals(findNodePeerMessageExpected.getType(), typeFindNodePeerMessage)); + Assert.assertTrue(Arrays.equals(findNodePeerMessageExpected.getSignature(), signatureFindNodePeerMessage)); + } + + @Test + public void testParseFindNodePeerMessage() { + FindNodePeerMessage findNodePeerMessageExpected = new FindNodePeerMessage(wireFindNodePeerMessage,mdcFindNodePeerMessage,signatureFindNodePeerMessage,typeFindNodePeerMessage,dataWithNetworkId); + Assert.assertTrue(findNodePeerMessageExpected.getNetworkId().isPresent()); + Assert.assertEquals(-1869051373,findNodePeerMessageExpected.getNetworkId().getAsInt()); + Assert.assertEquals("65b469c6-ba69-4238-bf5a-a485c024e3ce", findNodePeerMessageExpected.getMessageId()); + Assert.assertTrue(Arrays.equals(findNodePeerMessageExpected.getMdc(), mdcFindNodePeerMessage)); + Assert.assertTrue(Arrays.equals(findNodePeerMessageExpected.getPacket(), wireFindNodePeerMessage)); + Assert.assertTrue(Arrays.equals(findNodePeerMessageExpected.getType(), typeFindNodePeerMessage)); + Assert.assertTrue(Arrays.equals(findNodePeerMessageExpected.getSignature(), signatureFindNodePeerMessage)); + } + +} diff --git a/rskj-core/src/test/java/co/rsk/net/discovery/UDPChannelTest.java b/rskj-core/src/test/java/co/rsk/net/discovery/UDPChannelTest.java index 0efbbfedfba..43a360ce73a 100644 --- a/rskj-core/src/test/java/co/rsk/net/discovery/UDPChannelTest.java +++ b/rskj-core/src/test/java/co/rsk/net/discovery/UDPChannelTest.java @@ -27,6 +27,7 @@ import org.mockito.Mockito; import java.net.InetSocketAddress; +import java.util.OptionalInt; import java.util.UUID; /** @@ -34,6 +35,8 @@ */ public class UDPChannelTest { + private static final int NETWORK_ID = 1; + @Test public void create() { Channel channel = Mockito.mock(Channel.class); @@ -59,7 +62,7 @@ public void channelRead0() throws Exception { public void write() { String check = UUID.randomUUID().toString(); ECKey key = new ECKey(); - PingPeerMessage nodeMessage = PingPeerMessage.create("localhost", 80, check, key); + PingPeerMessage nodeMessage = PingPeerMessage.create("localhost", 80, check, key, NETWORK_ID); Channel channel = Mockito.mock(Channel.class); PeerExplorer peerExplorer = Mockito.mock(PeerExplorer.class); diff --git a/rskj-core/src/test/java/co/rsk/net/discovery/UDPServerTest.java b/rskj-core/src/test/java/co/rsk/net/discovery/UDPServerTest.java index e08b3d6f12e..7ef23bdc0c2 100644 --- a/rskj-core/src/test/java/co/rsk/net/discovery/UDPServerTest.java +++ b/rskj-core/src/test/java/co/rsk/net/discovery/UDPServerTest.java @@ -29,6 +29,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.OptionalInt; import java.util.concurrent.TimeUnit; /** @@ -49,6 +50,7 @@ public class UDPServerTest { private static final int PORT_1 = 40305; private static final int PORT_2 = 40306; private static final int PORT_3 = 40307; + private static final int NETWORK_ID = 1; private static final long TIMEOUT = 30000; private static final long UPDATE = 60000; @@ -77,9 +79,9 @@ public void run3NodesFullTest() throws InterruptedException { NodeDistanceTable distanceTable2 = new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, node2); NodeDistanceTable distanceTable3 = new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, node3); - PeerExplorer peerExplorer1 = new PeerExplorer(node1BootNode, node1, distanceTable1, key1, TIMEOUT, UPDATE, CLEAN); - PeerExplorer peerExplorer2 = new PeerExplorer(node2BootNode, node2, distanceTable2, key2, TIMEOUT, UPDATE, CLEAN); - PeerExplorer peerExplorer3 = new PeerExplorer(node3BootNode, node3, distanceTable3, key3, TIMEOUT, UPDATE, CLEAN); + PeerExplorer peerExplorer1 = new PeerExplorer(node1BootNode, node1, distanceTable1, key1, TIMEOUT, UPDATE, CLEAN, NETWORK_ID); + PeerExplorer peerExplorer2 = new PeerExplorer(node2BootNode, node2, distanceTable2, key2, TIMEOUT, UPDATE, CLEAN, NETWORK_ID); + PeerExplorer peerExplorer3 = new PeerExplorer(node3BootNode, node3, distanceTable3, key3, TIMEOUT, UPDATE, CLEAN, NETWORK_ID); Assert.assertEquals(0, peerExplorer1.getNodes().size()); Assert.assertEquals(0, peerExplorer2.getNodes().size());