diff --git a/libs/nabu-v0.0.1-SNAPSHOT-jar-with-dependencies.jar b/libs/nabu-v0.0.1-SNAPSHOT-jar-with-dependencies.jar index 98aed7f65..1890a54b7 100644 Binary files a/libs/nabu-v0.0.1-SNAPSHOT-jar-with-dependencies.jar and b/libs/nabu-v0.0.1-SNAPSHOT-jar-with-dependencies.jar differ diff --git a/src/main/java/com/limechain/network/kad/KademliaService.java b/src/main/java/com/limechain/network/kad/KademliaService.java index c755bf66a..ccbeff5c8 100644 --- a/src/main/java/com/limechain/network/kad/KademliaService.java +++ b/src/main/java/com/limechain/network/kad/KademliaService.java @@ -11,6 +11,8 @@ import org.peergos.protocol.dht.RamProviderStore; import org.peergos.protocol.dht.RamRecordStore; +import java.net.InetAddress; +import java.net.UnknownHostException; import java.util.List; import java.util.Random; import java.util.logging.Level; @@ -52,6 +54,7 @@ private void initialize(String protocolId, Multihash hostId, boolean localEnable */ public void connectBootNodes(String[] bootNodes) { var bootstrapMultiAddress = List.of(bootNodes).stream() + .map(KademliaService::dnsNodeToIp4) .map(MultiAddress::new) .collect(Collectors.toList()); int successfulBootNodes = dht.bootstrapRoutingTable(host, bootstrapMultiAddress, addr -> !addr.contains("wss")); @@ -67,4 +70,31 @@ public void findNewPeers() { Multihash randomPeerId = new Multihash(Multihash.Type.sha2_256, hash); dht.findClosestPeers(randomPeerId, REPLICATION, host); } + + /** + * Makes a dns lookup and changes the address to an equal ip4 address + * Implementation is necessary due to a bug in jvm-libp2p that involves resolving dns addresses + * https://github.com/Peergos/nabu/issues/22#issuecomment-1495687079 + * + * @param bootNode + * @return bootNode in ip4 format + */ + public static String dnsNodeToIp4(String bootNode) { + int prefixEnd = bootNode.indexOf('/', 1) + 1; + String prefix = bootNode.substring(0, prefixEnd); + + if (prefix.equals("/dns/")) { + int domainEnd = bootNode.indexOf('/', prefixEnd); + String domain = bootNode.substring(prefixEnd, domainEnd); + String postfix = bootNode.substring(domainEnd); + + try { + InetAddress address = InetAddress.getByName(domain); + bootNode = "/ip4/" + address.getHostAddress() + postfix; + } catch (UnknownHostException e) { + log.log(Level.WARNING, "Unknown domain for bootstrap node address", e); + } + } + return bootNode; + } } diff --git a/src/main/java/com/limechain/network/substream/lightclient/LightMessagesProtocol.java b/src/main/java/com/limechain/network/substream/lightclient/LightMessagesProtocol.java index 08a5d31fe..f0ba121b7 100644 --- a/src/main/java/com/limechain/network/substream/lightclient/LightMessagesProtocol.java +++ b/src/main/java/com/limechain/network/substream/lightclient/LightMessagesProtocol.java @@ -35,7 +35,40 @@ protected CompletableFuture onStartInitiator(Stream str stream.pushHandler(handler); return CompletableFuture.completedFuture(handler); } - + + @Override + protected CompletableFuture onStartResponder(Stream stream) { + stream.pushHandler(new ProtobufVarint32FrameDecoder()); + stream.pushHandler(new ProtobufDecoder(LightClientMessage.Request.getDefaultInstance())); + + stream.pushHandler((new ProtobufVarint32LengthFieldPrepender())); + stream.pushHandler((new ProtobufEncoder())); + + Receiver handler = new Receiver(engine); + stream.pushHandler(handler); + return CompletableFuture.completedFuture(handler); + } + + // Class for handling incoming requests + static class Receiver implements ProtocolMessageHandler, LightMessagesController { + private final LightMessagesEngine engine; + + public Receiver(LightMessagesEngine engine) { + this.engine = engine; + } + + @Override + public void onMessage(Stream stream, LightClientMessage.Request msg) { + engine.receiveRequest(msg, stream); + } + + @Override + public CompletableFuture send(LightClientMessage.Request msg) { + throw new IllegalStateException("Host can't process inbound requests yet!"); + } + + } + // Class for handling outgoing requests static class Sender implements ProtocolMessageHandler, diff --git a/src/test/java/com/limechain/network/kad/KademliaServiceTest.java b/src/test/java/com/limechain/network/kad/KademliaServiceTest.java new file mode 100644 index 000000000..9f8f77a70 --- /dev/null +++ b/src/test/java/com/limechain/network/kad/KademliaServiceTest.java @@ -0,0 +1,42 @@ +package com.limechain.network.kad; + +import org.junit.jupiter.api.Test; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +import static com.limechain.network.kad.KademliaService.dnsNodeToIp4; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class KademliaServiceTest { + + /** + * Test might throw UnknownHostException and fail if domain is no longer accessible + * + * @throws UnknownHostException + */ + @Test + public void dnsNodeToIp4_TransformDnsNode() throws UnknownHostException { + //CHECKSTYLE.OFF + String bootNode = "/dns/p2p.0.polkadot.network/tcp/30333/p2p/12D3KooWHsvEicXjWWraktbZ4MQBizuyADQtuEGr3NbDvtm5rFA5"; + InetAddress address = InetAddress.getByName("p2p.0.polkadot.network"); + String expected = "/ip4/" + address.getHostAddress() + "/tcp/30333/p2p/12D3KooWHsvEicXjWWraktbZ4MQBizuyADQtuEGr3NbDvtm5rFA5"; + //CHECKSTYLE.ON + + assertEquals(expected, dnsNodeToIp4(bootNode)); + } + + @Test + public void dnsNodeToIp4_UnchangedAddress_ifInvalidDomain() { + String bootNode2 = "/dns/invalid.domain.limechain/tcp/12345"; + + assertEquals(bootNode2, dnsNodeToIp4(bootNode2)); + } + + @Test + public void dnsNodeToIp4_UnchangedAddress_IfNotDns() { + String bootNode3 = "/ip4/192.168.1.1/tcp/12345"; + + assertEquals(bootNode3, dnsNodeToIp4(bootNode3)); + } +}