Search in sources :

Example 1 with NodeDistanceTable

use of co.rsk.net.discovery.table.NodeDistanceTable in project rskj by rsksmart.

the class NodeChallengeManagerTest method startChallenge.

@Test
public void startChallenge() {
    ECKey key1 = ECKey.fromPrivate(Hex.decode(KEY_1)).decompress();
    ECKey key2 = ECKey.fromPrivate(Hex.decode(KEY_2)).decompress();
    ECKey key3 = ECKey.fromPrivate(Hex.decode(KEY_3)).decompress();
    Node node1 = new Node(key1.getNodeId(), HOST_1, PORT_1);
    Node node2 = new Node(key2.getNodeId(), HOST_2, PORT_2);
    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, REFRESH);
    peerExplorer.setUDPChannel(Mockito.mock(UDPChannel.class));
    NodeChallengeManager manager = new NodeChallengeManager();
    NodeChallenge challenge = manager.startChallenge(node2, node3, peerExplorer);
    Assert.assertNotNull(challenge);
    Assert.assertEquals(challenge.getChallengedNode(), node2);
    Assert.assertEquals(challenge.getChallenger(), node3);
    NodeChallenge anotherChallenge = manager.removeChallenge(UUID.randomUUID().toString());
    Assert.assertNull(anotherChallenge);
    anotherChallenge = manager.removeChallenge(challenge.getChallengeId());
    Assert.assertEquals(challenge, anotherChallenge);
}
Also used : NodeDistanceTable(co.rsk.net.discovery.table.NodeDistanceTable) Node(org.ethereum.net.rlpx.Node) ECKey(org.ethereum.crypto.ECKey) Test(org.junit.Test)

Example 2 with NodeDistanceTable

use of co.rsk.net.discovery.table.NodeDistanceTable in project rskj by rsksmart.

the class PeerExplorerTest method handleFindNodeMessage.

@Test
public void handleFindNodeMessage() throws Exception {
    List<String> nodes = new ArrayList<>();
    nodes.add(HOST_1 + ":" + PORT_1);
    nodes.add(HOST_3 + ":" + PORT_3);
    ECKey key1 = ECKey.fromPrivate(Hex.decode(KEY_1)).decompress();
    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, REFRESH);
    Channel internalChannel = Mockito.mock(Channel.class);
    UDPTestChannel channel = new UDPTestChannel(internalChannel, peerExplorer);
    ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class);
    peerExplorer.setUDPChannel(channel);
    // 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);
    channel.clearEvents();
    channel.channelRead0(ctx, new DiscoveryEvent(findNodePeerMessage, new InetSocketAddress(HOST_1, PORT_1)));
    List<DiscoveryEvent> sentEvents = channel.getEventsWritten();
    Assert.assertEquals(0, sentEvents.size());
    // Now we send the ping first
    peerExplorer.startConversationWithNewNodes();
    PongPeerMessage incomingPongMessage = PongPeerMessage.create(HOST_1, PORT_1, ((PingPeerMessage) sentEvents.get(0).getMessage()).getMessageId(), key1);
    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);
    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);
    channel.clearEvents();
    channel.channelRead0(ctx, new DiscoveryEvent(findNodePeerMessage, new InetSocketAddress(HOST_1, PORT_1)));
    sentEvents = channel.getEventsWritten();
    Assert.assertEquals(1, sentEvents.size());
    NeighborsPeerMessage neighborsPeerMessage = (NeighborsPeerMessage) sentEvents.get(0).getMessage();
    Assert.assertEquals(1, neighborsPeerMessage.getNodes().size());
}
Also used : InetSocketAddress(java.net.InetSocketAddress) Node(org.ethereum.net.rlpx.Node) Channel(io.netty.channel.Channel) ArrayList(java.util.ArrayList) ECKey(org.ethereum.crypto.ECKey) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) NodeDistanceTable(co.rsk.net.discovery.table.NodeDistanceTable) Test(org.junit.Test)

Example 3 with NodeDistanceTable

use of co.rsk.net.discovery.table.NodeDistanceTable in project rskj by rsksmart.

the class PeerExplorerTest method handleNeighbors.

@Test
public void handleNeighbors() throws Exception {
    List<String> nodes = new ArrayList<>();
    nodes.add(HOST_1 + ":" + PORT_1);
    ECKey key1 = ECKey.fromPrivate(Hex.decode(KEY_1)).decompress();
    ECKey key2 = ECKey.fromPrivate(Hex.decode(KEY_2)).decompress();
    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, REFRESH);
    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()));
    // We try to process a Message without previous connection
    List<Node> 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);
    DiscoveryEvent neighborsEvent = new DiscoveryEvent(neighborsPeerMessage, new InetSocketAddress(HOST_1, PORT_1));
    channel.clearEvents();
    channel.channelRead0(ctx, neighborsEvent);
    List<DiscoveryEvent> sentEvents = channel.getEventsWritten();
    Assert.assertEquals(0, sentEvents.size());
    // 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);
    DiscoveryEvent incomingPongEvent = new DiscoveryEvent(incomingPongMessage, new InetSocketAddress(HOST_1, PORT_1));
    channel.channelRead0(ctx, incomingPongEvent);
    channel.clearEvents();
    channel.channelRead0(ctx, neighborsEvent);
    sentEvents = channel.getEventsWritten();
    Assert.assertEquals(0, sentEvents.size());
    // We send a findNode first
    channel.clearEvents();
    peerExplorer.sendFindNode(node1);
    FindNodePeerMessage findNodePeerMessage = (FindNodePeerMessage) channel.getEventsWritten().get(0).getMessage();
    neighborsPeerMessage = NeighborsPeerMessage.create(newNodes, findNodePeerMessage.getMessageId(), key1);
    neighborsEvent = new DiscoveryEvent(neighborsPeerMessage, new InetSocketAddress(HOST_1, PORT_1));
    channel.clearEvents();
    channel.channelRead0(ctx, neighborsEvent);
    sentEvents = channel.getEventsWritten();
    Assert.assertEquals(1, sentEvents.size());
    DiscoveryEvent discoveryEvent = sentEvents.get(0);
    Assert.assertEquals(new InetSocketAddress(HOST_3, PORT_3), discoveryEvent.getAddress());
    Assert.assertEquals(DiscoveryMessageType.PING, discoveryEvent.getMessage().getMessageType());
}
Also used : InetSocketAddress(java.net.InetSocketAddress) Node(org.ethereum.net.rlpx.Node) Channel(io.netty.channel.Channel) ArrayList(java.util.ArrayList) ECKey(org.ethereum.crypto.ECKey) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) NodeDistanceTable(co.rsk.net.discovery.table.NodeDistanceTable) Test(org.junit.Test)

Example 4 with NodeDistanceTable

use of co.rsk.net.discovery.table.NodeDistanceTable in project rskj by rsksmart.

the class PeerExplorerTest method handlePingMessage.

@Test
public void handlePingMessage() throws Exception {
    List<String> 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, REFRESH);
    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 nodeMessage = PingPeerMessage.create(HOST_1, PORT_1, check, key1);
    DiscoveryEvent incomingPingEvent = new DiscoveryEvent(nodeMessage, new InetSocketAddress(HOST_1, PORT_1));
    // A message is received
    channel.channelRead0(ctx, incomingPingEvent);
    // As part of the ping response, a Ping and a Pong are sent to the sender.
    List<DiscoveryEvent> sentEvents = channel.getEventsWritten();
    Assert.assertEquals(2, sentEvents.size());
    DiscoveryEvent pongEvent = sentEvents.get(0);
    PongPeerMessage toSenderPong = (PongPeerMessage) pongEvent.getMessage();
    Assert.assertEquals(DiscoveryMessageType.PONG, toSenderPong.getMessageType());
    Assert.assertEquals(new InetSocketAddress(HOST_1, PORT_1), pongEvent.getAddress());
    DiscoveryEvent pingEvent = sentEvents.get(1);
    PingPeerMessage toSenderPing = (PingPeerMessage) pingEvent.getMessage();
    Assert.assertEquals(DiscoveryMessageType.PING, toSenderPing.getMessageType());
    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);
    DiscoveryEvent incomingPongEvent = new DiscoveryEvent(pongResponseFromSender, new InetSocketAddress(HOST_1, PORT_1));
    channel.channelRead0(ctx, incomingPongEvent);
    channel.clearEvents();
    channel.channelRead0(ctx, incomingPingEvent);
    sentEvents = channel.getEventsWritten();
    Assert.assertEquals(1, sentEvents.size());
    pongEvent = sentEvents.get(0);
    toSenderPong = (PongPeerMessage) pongEvent.getMessage();
    Assert.assertEquals(DiscoveryMessageType.PONG, toSenderPong.getMessageType());
    Assert.assertEquals(new InetSocketAddress(HOST_1, PORT_1), pongEvent.getAddress());
    Assert.assertEquals(NODE_ID_2, Hex.toHexString(toSenderPong.getKey().getNodeId()));
}
Also used : InetSocketAddress(java.net.InetSocketAddress) Node(org.ethereum.net.rlpx.Node) Channel(io.netty.channel.Channel) ArrayList(java.util.ArrayList) ECKey(org.ethereum.crypto.ECKey) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) NodeDistanceTable(co.rsk.net.discovery.table.NodeDistanceTable) Test(org.junit.Test)

Example 5 with NodeDistanceTable

use of co.rsk.net.discovery.table.NodeDistanceTable in project rskj by rsksmart.

the class DefaultConfig method peerExplorer.

@Bean
public PeerExplorer peerExplorer(RskSystemProperties rskConfig) {
    ECKey key = rskConfig.getMyKey();
    Node localNode = new Node(key.getNodeId(), rskConfig.getPublicIp(), rskConfig.getPeerPort());
    NodeDistanceTable distanceTable = new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, localNode);
    long msgTimeOut = rskConfig.peerDiscoveryMessageTimeOut();
    long refreshPeriod = rskConfig.peerDiscoveryRefreshPeriod();
    List<String> initialBootNodes = rskConfig.peerDiscoveryIPList();
    List<Node> activePeers = rskConfig.peerActive();
    if (CollectionUtils.isNotEmpty(activePeers)) {
        for (Node n : activePeers) {
            InetSocketAddress address = n.getAddress();
            initialBootNodes.add(address.getHostName() + ":" + address.getPort());
        }
    }
    return new PeerExplorer(initialBootNodes, localNode, distanceTable, key, msgTimeOut, refreshPeriod);
}
Also used : NodeDistanceTable(co.rsk.net.discovery.table.NodeDistanceTable) PeerExplorer(co.rsk.net.discovery.PeerExplorer) InetSocketAddress(java.net.InetSocketAddress) Node(org.ethereum.net.rlpx.Node) ECKey(org.ethereum.crypto.ECKey) Bean(org.springframework.context.annotation.Bean)

Aggregations

NodeDistanceTable (co.rsk.net.discovery.table.NodeDistanceTable)10 ECKey (org.ethereum.crypto.ECKey)10 Node (org.ethereum.net.rlpx.Node)10 Test (org.junit.Test)9 ArrayList (java.util.ArrayList)7 Channel (io.netty.channel.Channel)6 InetSocketAddress (java.net.InetSocketAddress)6 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)5 PeerExplorer (co.rsk.net.discovery.PeerExplorer)1 Bean (org.springframework.context.annotation.Bean)1