Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement protocols #12

Merged
merged 5 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ out/
/test

### Local Chain Spec
/src/main/webapp/genesis/westend-local.json
/src/main/webapp/genesis/westend-local.json
.smarttomcat/
4 changes: 2 additions & 2 deletions src/main/java/com/limechain/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import com.limechain.client.HostNode;
import com.limechain.client.LightClient;
import com.limechain.rpc.Function;
import com.limechain.rpc.RPCFunction;
import com.limechain.rpc.RpcClient;
import com.limechain.rpc.server.RpcApp;
import com.limechain.utils.DivLogger;
Expand Down Expand Up @@ -34,5 +34,5 @@ public static void main(String[] args) {

@JSBody(params = {"f", "apiName"}, script = "window[apiName] = f;" +
"isRpcExported = true;")
private static native void exportAPI(Function f, JSString apiName);
private static native void exportAPI(RPCFunction f, JSString apiName);
}
115 changes: 22 additions & 93 deletions src/main/java/com/limechain/network/Network.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.limechain.network;

import com.limechain.chain.Chain;
import com.limechain.chain.ChainService;
import com.limechain.config.HostConfig;
import com.limechain.network.kad.KademliaService;
import com.limechain.network.protocol.blockannounce.BlockAnnounceService;
import com.limechain.network.protocol.grandpa.GrandpaService;
import com.limechain.network.protocol.warp.WarpSyncService;
import com.limechain.network.protocol.warp.dto.WarpSyncResponse;
import com.limechain.rpc.server.AppBean;
Expand All @@ -14,23 +14,21 @@
import java.util.Random;
import java.util.logging.Level;

import static com.limechain.network.kad.KademliaService.REPLICATION;

/**
* A Network class that handles all peer connections and Kademlia
*/
@Log
public class Network {
private static final Random RANDOM = new Random();
@Getter
private final Chain chain;
@Getter
private final String[] bootNodes;
// private final ConnectionManager connectionManager;
@Getter
private KademliaService kademliaService;
private WarpSyncService warpSyncService;
private GrandpaService grandpaService;
private BlockAnnounceService blockAnnounceService;
private boolean started = false;
private int bootPeerIndex = 0;

/**
* Initializes a host for the peer connection,
Expand All @@ -39,30 +37,26 @@ public class Network {
* Connects Kademlia to boot nodes
*
* @param chainService chain specification information containing boot nodes
* @param hostConfig host configuration containing current network
*/
public Network(ChainService chainService, HostConfig hostConfig) {
public Network(ChainService chainService) {
this.bootNodes = chainService.getChainSpec().getBootNodes();
this.chain = hostConfig.getChain();
// this.connectionManager = ConnectionManager.getInstance();
this.initializeProtocols(chainService, hostConfig);
this.initializeProtocols(chainService);
}

private void initializeProtocols(ChainService chainService,
HostConfig hostConfig) {
private void initializeProtocols(ChainService chainService) {

//
String chainId = chainService.getChainSpec().getProtocolId();
String warpProtocolId = ProtocolUtils.getWarpSyncProtocol(chainId);
// String lightProtocolId = ProtocolUtils.getLightMessageProtocol(chainId);
// String blockAnnounceProtocolId = ProtocolUtils.getBlockAnnounceProtocol(chainId);
// String grandpaProtocolId = ProtocolUtils.getGrandpaProtocol(chainId);
String blockAnnounceProtocolId = ProtocolUtils.getBlockAnnounceProtocol(chainId);
String grandpaProtocolId = ProtocolUtils.getGrandpaProtocol();

kademliaService = new KademliaService();
warpSyncService = new WarpSyncService(warpProtocolId);
}
blockAnnounceService = new BlockAnnounceService(blockAnnounceProtocolId);
grandpaService = new GrandpaService(grandpaProtocolId);

WarpSyncService warpSyncService;
}

// private Ed25519PrivateKey loadPrivateKeyFromDB(KVRepository<String, Object> repository) {
// Ed25519PrivateKey privateKey;
Expand Down Expand Up @@ -95,43 +89,10 @@ public void stop() {
log.log(Level.INFO, "Stopped network module!");
}

public boolean updateCurrentSelectedPeerWithNextBootnode() {
// if (bootPeerIndex > kademliaService.getBootNodePeerIds().size())
// return false;
// this.currentSelectedPeer = this.kademliaService.getBootNodePeerIds().get(bootPeerIndex);
bootPeerIndex++;
return true;
}

public boolean updateCurrentSelectedPeerWithBootnode(int index) {
// if (index >= 0 && index < this.kademliaService.getBootNodePeerIds().size()) {
// this.currentSelectedPeer = this.kademliaService.getBootNodePeerIds().get(index);
// return true;
// }
return false;
}

public void updateCurrentSelectedPeer() {
// if (connectionManager.getPeerIds().isEmpty()) return;
// this.currentSelectedPeer = connectionManager.getPeerIds().stream()
// .skip(RANDOM.nextInt(connectionManager.getPeerIds().size())).findAny().orElse(null);
kademliaService.updateSuccessfulBootNodes();
}

// public String getPeerId() {
// return this.host.getPeerId().toString();
// }

public String[] getListenAddresses() {
// TODO Bug: .listenAddresses() returns empty list
// return this.host.listenAddresses().stream().map(Multiaddr::toString).toArray(String[]::new);
return null;
}

public int getPeersCount() {
return 0;//connectionManager.getPeerIds().size();
}

/**
* Periodically searches for new peers and connects to them
* Logs the number of connected peers excluding boot nodes
Expand All @@ -142,31 +103,11 @@ public void findPeers() {
if (!started) {
return;
}
if (getPeersCount() >= REPLICATION) {
log.log(Level.INFO,
"Connections have reached replication factor(" + REPLICATION + "). " +
"No need to search for new ones yet.");
return;
}

log.log(Level.INFO, "Searching for peers...");
kademliaService.findNewPeers();

// if (this.currentSelectedPeer == null) {
// updateCurrentSelectedPeer();
// }

log.log(Level.INFO, String.format("Connected peers: %s", getPeersCount()));
}

// @Scheduled(fixedDelay = 1, timeUnit = TimeUnit.MINUTES)
public void pingPeers() {
// TODO: This needs to by synchronized with the findPeers method
if (getPeersCount() == 0) {
log.log(Level.INFO, "No peers to ping.");
return;
}

log.log(Level.INFO, "Pinging peers...");
// connectionManager.getPeerIds().forEach(this::ping);
}
Expand Down Expand Up @@ -212,7 +153,8 @@ public WarpSyncResponse makeWarpSyncRequest(String blockHash) {
return this.warpSyncService.getProtocol().warpSyncRequest(
blockHash);
}
//

//
// public LightClientMessage.Response makeRemoteReadRequest(String blockHash, String[] keys) {
// if (isPeerInvalid()) return null;
//
Expand All @@ -237,31 +179,18 @@ public WarpSyncResponse makeWarpSyncRequest(String blockHash) {
// return false;
// }
//
// public void handshakeBootNodes() {
// kademliaService.getBootNodePeerIds()
// .stream()
// .distinct()
// .forEach(this::sendGrandpaHandshake);
// }
//
// private void sendGrandpaHandshake(PeerId peerId) {
// //TODO:
// // when using threads we connect to more than 10 peers, but have some unhandled exceptions,
// // without them we connect to only 2 peers
// new Thread(() ->
// blockAnnounceService.sendHandshake(this.host, this.host.getAddressBook(), peerId)
// ).start();
// }

public void sendBlockAnnounceHandshake() {
new Thread(() ->
blockAnnounceService.sendHandshake()
).start();
}

// @Scheduled(fixedRate = 5, initialDelay = 5, timeUnit = TimeUnit.MINUTES)
public void sendNeighbourMessages() {
if (!AppBean.getBean(WarpSyncState.class).isWarpSyncFinished()) {
return;
}
// connectionManager.getPeerIds().forEach(peerId -> grandpaService.sendNeighbourMessage(this.host, peerId));
grandpaService.sendHandshake();
}
//
// public void sendNeighbourMessage(PeerId peerId) {
// grandpaService.sendNeighbourMessage(this.host, peerId);
// }
}
24 changes: 2 additions & 22 deletions src/main/java/com/limechain/network/ProtocolUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,10 @@
public final class ProtocolUtils {
public static final String PING_PROTOCOL = "/ipfs/ping/1.0.0";

public static String getLightMessageProtocol(String chainId) {
return String.format("/%s/light/2", chainId);
}

public static String getWarpSyncProtocol(String chainId) {
return String.format("/%s/sync/warp", chainId);
}

public static String getSyncProtocol(String chainId) {
return String.format("/%s/sync/2", chainId);
}

public static String getStateProtocol(String chainId) {
return String.format("/%s/state/2", chainId);
}

public static String getBlockAnnounceProtocol(String chainId) {
return String.format("/%s/block-announces/1", chainId);
}
Expand All @@ -31,16 +19,8 @@ public static String getKadProtocol(String chainId) {
return String.format("/%s/kad", chainId);
}

public static String getGrandpaProtocol(String chainId) {
return String.format("/%s/grandpa/1", grandpaProtocolChain(chainId));
}

//TODO: figure out a more elegant solution
private static String grandpaProtocolChain(String chainId) {
return chainId.equals("dot") ? "paritytech" : chainId;
public static String getGrandpaProtocol() {
return "/paritytech/grandpa/1";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we sticking to the legacy protocol string?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Until we add configuration for the host, yes

}

public static String getTransactionsProtocol(String chainId) {
return String.format("/%s/transactions/1", chainId);
}
}

This file was deleted.

This file was deleted.

Loading
Loading