Skip to content

Commit

Permalink
Merge pull request #8 from bloxbean/priv_network
Browse files Browse the repository at this point in the history
feat: relay/bp node creation, Node 8.1.1 support
  • Loading branch information
satran004 authored Jul 7, 2023
2 parents bfa3cfb + 3c463ef commit 0d55629
Show file tree
Hide file tree
Showing 36 changed files with 1,762 additions and 563 deletions.
10 changes: 7 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,13 @@ dependencies {
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'
implementation 'org.springframework.boot:spring-boot-starter-logging'

implementation 'com.bloxbean.cardano:yaci:0.1.12'
implementation 'com.bloxbean.cardano:cardano-client-lib:0.4.3'
implementation 'com.bloxbean.cardano:cardano-client-backend:0.4.3'
implementation('com.bloxbean.cardano:yaci:0.2.0-beta2') {
exclude group: 'com.bloxbean.cardano', module: 'cardano-client-core'
}
implementation 'com.bloxbean.cardano:cardano-client-lib:0.5.0-alpha.3'
implementation 'com.bloxbean.cardano:cardano-client-backend:0.5.0-alpha.3'
implementation 'com.bloxbean.cardano:cardano-client-backend-blockfrost:0.5.0-alpha.3'
implementation 'com.bloxbean.cardano:cardano-client-supplier-local:0.5.0-alpha.3'

implementation 'org.jeasy:easy-rules-core:4.1.0'
implementation 'org.jeasy:easy-rules-mvel:4.1.0'
Expand Down
1 change: 1 addition & 0 deletions config/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ topup_addresses=addr_test1qqxnp3khzm7kcj9t23hskehat7428ghsenk0pfew4rqy5v9frnmht7
addr_test1qqwpl7h3g84mhr36wpetk904p7fchx2vst0z696lxk8ujsjyruqwmlsm344gfux3nsj6njyzj3ppvrqtt36cp9xyydzqzumz82:10000

yaci.store.enabled=false
bp.create.enabled=false

Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
package com.bloxbean.cardano.yacicli;

import com.bloxbean.cardano.yacicli.commands.localcluster.ClusterCommands;
import com.bloxbean.cardano.yacicli.commands.localcluster.ClusterInfo;
import com.bloxbean.cardano.yacicli.commands.localcluster.ClusterService;
import com.bloxbean.cardano.yacicli.common.CommandContext;
import lombok.RequiredArgsConstructor;
import org.jline.utils.AttributedString;
import org.jline.utils.AttributedStyle;
import org.springframework.shell.jline.PromptProvider;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

@Component
@RequiredArgsConstructor
public class YaciCliPromptProvider implements PromptProvider {
private final ClusterService clusterService;

@Override
public AttributedString getPrompt() {
if (CommandContext.INSTANCE.getCurrentMode() == CommandContext.Mode.REGULAR) {
Expand All @@ -19,7 +26,26 @@ public AttributedString getPrompt() {
if (clusterName == null)
clusterName = "";

return new AttributedString("local-cluster:" + clusterName + ">",
String promptName = "devnet";
try {
if (StringUtils.hasText(clusterName)) {
ClusterInfo clusterInfo = clusterService.getClusterInfo(clusterName);
if (clusterInfo != null) {
if (clusterInfo.isMasterNode())
promptName = "devnet";
else {
if (clusterInfo.isBlockProducer())
promptName = "devnet-peer/bp";
else
promptName = "devnet-peer/relay";
}
}
}
} catch (Exception e) {
//ignore
}

return new AttributedString(promptName + ":" + clusterName + ">",
AttributedStyle.DEFAULT.foreground(AttributedStyle.GREEN).bold());
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.bloxbean.cardano.yacicli.commands.localcluster;

import com.bloxbean.cardano.client.api.model.Utxo;
import com.bloxbean.cardano.client.transaction.spec.PlutusData;
import com.bloxbean.cardano.client.transaction.spec.serializers.PlutusDataJsonConverter;
import com.bloxbean.cardano.client.plutus.spec.PlutusData;
import com.bloxbean.cardano.client.plutus.spec.serializers.PlutusDataJsonConverter;
import com.bloxbean.cardano.yaci.core.protocol.chainsync.messages.Point;
import com.bloxbean.cardano.yaci.core.util.HexUtil;
import com.bloxbean.cardano.yacicli.commands.common.Groups;
Expand All @@ -21,8 +21,6 @@
import com.bloxbean.cardano.yacicli.output.OutputFormatter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.shell.Availability;
import org.springframework.shell.standard.*;
Expand All @@ -47,18 +45,18 @@ public class ClusterCommands {
private final ShellHelper shellHelper;
private final ApplicationEventPublisher publisher;

@ShellMethod(value = "List local clusters (Babbage)", key = "list-clusters")
@ShellMethod(value = "List devnet nodes. Use `list-nodes`. Deprecated: `list-clusters`", key = {"list-nodes", "list-clusters"})
public void listLocalClusters() {
try {
List<String> clusters = localClusterService.listClusters();
writeLn("Available Clusters:");
writeLn("Available DevNet nodes:");
clusters.forEach(cluster -> writeLn(cluster));
} catch (Exception e) {
writeLn(error("Cluster listing failed. " + e.getMessage()));
writeLn(error("DevNet listing failed. " + e.getMessage()));
}
}

@ShellMethod(value = "Enter local cluster mode(Babbage)", key = "cluster")
@ShellMethod(value = "Enter local devnet node mode. Use `node` command. Deprecated: `cluster`", key = {"node", "cluster"})
public void startLocalClusterContext(@ShellOption(value = {"-n", "--name"}, defaultValue = "default", help = "Cluster Name") String clusterName) {
try {
if (CommandContext.INSTANCE.getCurrentMode() == CommandContext.Mode.LOCAL_CLUSTER) {
Expand All @@ -75,15 +73,15 @@ public void startLocalClusterContext(@ShellOption(value = {"-n", "--name"}, defa
}
}

@ShellMethod(value = "Create a local cluster (Babbage)", key = "create-cluster")
public void createCluster(@ShellOption(value = {"-n", "--name"}, defaultValue = "default", help = "Cluster Name") String clusterName,
@ShellMethod(value = "Create a local devnet node. Use `create-node`. Deprecated: `create-node`", key = {"create-node", "create-cluster"})
public void createCluster(@ShellOption(value = {"-n", "--name"}, defaultValue = "default", help = "Node Name") String clusterName,
@ShellOption(value = {"--port"}, help = "Node port (Used with --create option only)", defaultValue = "3001") int port,
@ShellOption(value = {"--submit-api-port"}, help = "Submit Api Port", defaultValue = "8090") int submitApiPort,
@ShellOption(value = {"-s", "--slot-length"}, help = "Slot Length in sec. (0.1 to ..)", defaultValue = "1") double slotLength,
@ShellOption(value = {"-b", "--block-time"}, help = "Block time in sec. (1 - 20)", defaultValue = "1") double blockTime,
@ShellOption(value = {"-e", "--epoch-length"}, help = "No of slots in an epoch", defaultValue = "500") int epochLength,
@ShellOption(value = {"-o", "--overwrite"}, defaultValue = "false", help = "Overwrite existing cluster directory. default: false") boolean overwrite,
@ShellOption(value = {"--start"}, defaultValue = "false", help = "Automatically start the cluster after create. default: false") boolean start
@ShellOption(value = {"-o", "--overwrite"}, defaultValue = "false", help = "Overwrite existing node directory. default: false") boolean overwrite,
@ShellOption(value = {"--start"}, defaultValue = "false", help = "Automatically start the node after create. default: false") boolean start
) {

try {
Expand All @@ -108,9 +106,19 @@ public void createCluster(@ShellOption(value = {"-n", "--name"}, defaultValue =
localClusterService.stopCluster(msg -> writeLn(msg));
publisher.publishEvent(new ClusterStopped(clusterName));

boolean success = localClusterService.createClusterFolder(clusterName, port, submitApiPort, slotLength, blockTime,
epochLength,
protocolMagic, overwrite, (msg) -> writeLn(msg));
ClusterInfo clusterInfo = ClusterInfo.builder()
.nodePort(port)
.submitApiPort(submitApiPort)
.slotLength(slotLength)
.blockTime(blockTime)
.epochLength(epochLength)
.protocolMagic(protocolMagic)
.p2pEnabled(false)
.masterNode(true)
.isBlockProducer(true)
.build();

boolean success = localClusterService.createNodeClusterFolder(clusterName, clusterInfo, overwrite, (msg) -> writeLn(msg));

if (success) {
printClusterInfo(clusterName);
Expand All @@ -128,7 +136,7 @@ public void createCluster(@ShellOption(value = {"-n", "--name"}, defaultValue =
}
}

@ShellMethod(value = "Get cluster info", key = "info")
@ShellMethod(value = "Get devnet info", key = "info")
@ShellMethodAvailability("localClusterCmdAvailability")
private void getClusterInfo() {
String clusterName = CommandContext.INSTANCE.getProperty(CUSTER_NAME);
Expand All @@ -153,21 +161,26 @@ private void printClusterInfo(String clusterName) throws IOException {
writeLn(successLabel("Start Time", String.valueOf(clusterInfo.getStartTime())));
}

@ShellMethod(value = "Delete a local cluster", key = "delete-cluster")
public void deleteLocalCluster(@ShellOption(value = {"-n", "--name"}, help = "Cluster Name") String clusterName) {
@ShellMethod(value = "Delete a local devnet node. Use `delete-node`. Deprecated: `delete-cluster`", key = {"delete-node", "delete-cluster"})
@ShellMethodAvailability("localClusterCmdAvailability")
public void deleteLocalCluster(@ShellOption(value = {"-n", "--name"}, help = "Node Name") String nodeName) {
if (nodeName == null || nodeName.isEmpty()) {
writeLn(error("Node name is required"));
return;
}
try {
localClusterService.deleteCluster(clusterName, (msg) -> {
localClusterService.deleteCluster(nodeName, (msg) -> {
writeLn(msg);
});
publisher.publishEvent(new ClusterDeleted(clusterName));
publisher.publishEvent(new ClusterDeleted(nodeName));
} catch (IOException e) {
if (log.isDebugEnabled())
log.error("Delete error", e);
writeLn(error("Deletion failed for cluster: %s", clusterName));
writeLn(error("Deletion failed for devnet node: %s", nodeName));
}
}

@ShellMethod(value = "Start a local cluster (Babbage)", key = "start")
@ShellMethod(value = "Start local devnet", key = "start")
@ShellMethodAvailability("localClusterCmdAvailability")
public void startLocalCluster() {
String clusterName = CommandContext.INSTANCE.getProperty(CUSTER_NAME);
Expand All @@ -191,7 +204,7 @@ public void startLocalCluster() {

}

@ShellMethod(value = "Stop the running local cluster (Babbage)", key = "stop")
@ShellMethod(value = "Stop the running local devnet", key = "stop")
@ShellMethodAvailability("localClusterCmdAvailability")
public void stopLocalCluster() {
String clusterName = CommandContext.INSTANCE.getProperty(CUSTER_NAME);
Expand All @@ -200,7 +213,7 @@ public void stopLocalCluster() {
publisher.publishEvent(new ClusterStopped(clusterName));
}

@ShellMethod(value = "Reset local cluster. Delete data and logs folder and restart.", key = "reset")
@ShellMethod(value = "Reset local devnet. Delete data and logs folder and restart.", key = "reset")
@ShellMethodAvailability("localClusterCmdAvailability")
public void resetLocalCluster() {
String clusterName = CommandContext.INSTANCE.getProperty(CUSTER_NAME);
Expand All @@ -221,7 +234,7 @@ public void resetLocalCluster() {
}
}

@ShellMethod(value = "Show recent logs for running cluster", key = "logs")
@ShellMethod(value = "Show recent logs for running devnet node", key = "logs")
@ShellMethodAvailability("localClusterCmdAvailability")
public void logsLocalCluster() {
localClusterService.logs(msg -> writeLn(msg));
Expand All @@ -233,7 +246,7 @@ public void logsSubmitApi() {
localClusterService.submitApiLogs(msg -> writeLn(msg));
}

@ShellMethod(value = "Tail local cluster", key = "ltail")
@ShellMethod(value = "Tail local devnet", key = "ltail")
@ShellMethodAvailability("localClusterCmdAvailability")
public void ltail(
@ShellOption(value = {"-c", "--show-mint"}, defaultValue = "true", help = "Show mint outputs") boolean showMint,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.bloxbean.cardano.yacicli.commands.localcluster;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
Expand All @@ -17,6 +16,8 @@
public class ClusterConfig {
public final static String CLUSTER_INFO_FILE = "cluster-info.json";
public final static String NODE_FOLDER_PREFIX = "node-spo";
public final static String NODE_RELAY_SCRIPT = "node-relay";
public final static String NODE_BP_SCRIPT = "node-bp";

@Value("${local.cluster.home:#{null}}")
private String clusterHome;
Expand Down Expand Up @@ -47,4 +48,8 @@ public String getYaciStoreBinPath() {
else
return Path.of(yaciStoreBinFolder).toAbsolutePath().toString();
}

public String getPoolKeysHome() {
return Path.of(YACI_CLI_HOME, "pool-keys").toAbsolutePath().toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,10 @@ public class ClusterInfo {
private long protocolMagic;
private double slotLength;
private double blockTime;
private int epochLength;
private boolean p2pEnabled;
private long startTime;
private boolean masterNode;
private boolean isBlockProducer;
private String adminNodeUrl; //Only for peer nodes
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,15 @@ public Path getClusterFolder(String clusterName) {
return Path.of(clusterConfig.getClusterHome(), clusterName);
}

public boolean createClusterFolder(String clusterName, int port, int submitApiPort,
double slotLength, double blockTime, int epochLength,
long protocolMagic, boolean overwrite, Consumer<String> writer) throws IOException {
public Path getPoolKeys(String clusterName) {
return Path.of(clusterConfig.getPoolKeysHome(), clusterName);
}

// public boolean createMasterNodeClusterFolder(String clusterName, ClusterInfo clusterInfo, boolean overwrite, Consumer<String> writer) throws IOException {
// return createNodeClusterFolder(clusterName, clusterInfo, overwrite, writer);
// }

public boolean createNodeClusterFolder(String clusterName, ClusterInfo clusterInfo, boolean overwrite, Consumer<String> writer) throws IOException {
if(!checkCardanoNodeBin(writer)) return false;

Path destPath = getClusterFolder(clusterName);
Expand Down Expand Up @@ -190,17 +196,20 @@ public boolean createClusterFolder(String clusterName, int port, int submitApiPo
copy(sourcePath, destPath);
FileUtils.deleteDirectory(tempLocalCluster.toFile());

double activeCoeff = slotLength / blockTime;
double activeCoeff = clusterInfo.getSlotLength() / clusterInfo.getBlockTime();
//Update configuration
updatePorts(destPath, port, 1);
updatePorts(destPath, clusterInfo.getNodePort(), 1);

//Update genesis
updateGenesis(destPath, slotLength, activeCoeff, epochLength, protocolMagic, writer);
updateGenesis(destPath, clusterInfo.getSlotLength(), activeCoeff, clusterInfo.getEpochLength(), clusterInfo.getProtocolMagic(), writer);

//Update P2P configuration
updateConfiguration(destPath, clusterInfo.isP2pEnabled(), writer);

updateSubmitApiFiles(destPath, protocolMagic, submitApiPort);
updateSubmitApiFiles(destPath, clusterInfo.getProtocolMagic(), clusterInfo.getSubmitApiPort());

//Update node config
saveClusterInfo(destPath, port, submitApiPort, slotLength, blockTime, protocolMagic);
saveClusterInfo(destPath, clusterInfo);

writer.accept(success("Update ports"));
writer.accept(success("Create Cluster : %s", clusterName));
Expand Down Expand Up @@ -283,21 +292,20 @@ private void updateSubmitApiFiles(Path destPath, long protocolMagic, int submitA
}
}

private ClusterInfo saveClusterInfo(Path clusterFolder, int nodePort, int submitApiPort, double slotLength, double blockTime, long protocolMagic) throws IOException {
String socketPath = clusterFolder.resolve(NODE_FOLDER_PREFIX + 1).resolve("node.sock").toString();
private void updateConfiguration(Path clusterFolder, boolean enableP2P, Consumer<String> writer) throws IOException {
//Shelley genesis file
Path configurationPath = clusterFolder.resolve("configuration.yaml");
Map<String, String> values = new HashMap<>();
values.put("enableP2P", String.valueOf(enableP2P));

//Create node_config
ClusterInfo clusterInfo = ClusterInfo.builder()
.nodePort(nodePort)
.submitApiPort(submitApiPort)
.socketPath(socketPath)
.slotLength(slotLength)
.blockTime(blockTime)
.protocolMagic(protocolMagic)
.build();

saveClusterInfo(clusterFolder, clusterInfo);
return clusterInfo;
//Update Configuration file
try {
templateEngine.replaceValues(configurationPath, values);
} catch (Exception e) {
throw new IOException(e);
}

writer.accept(success("Updated configuration.yaml"));
}

public ClusterInfo getClusterInfo(String clusterName) throws IOException {
Expand All @@ -319,6 +327,9 @@ public void saveClusterInfo(Path clusterFolder, ClusterInfo clusterInfo) throws
throw new IllegalStateException("Cluster folder not found - " + clusterFolder);
}

String socketPath = clusterFolder.resolve(NODE_FOLDER_PREFIX + 1).resolve("node.sock").toString();
clusterInfo.setSocketPath(socketPath);

String clusterInfoPath = clusterFolder.resolve(ClusterConfig.CLUSTER_INFO_FILE).toAbsolutePath().toString();
objectMapper.writer(new DefaultPrettyPrinter()).writeValue(new File(clusterInfoPath), clusterInfo);
}
Expand Down Expand Up @@ -348,7 +359,7 @@ private void copy(Path sourceDir, Path destDir) throws IOException {
}


private String getOSSpecificScriptName(String script) {
public String getOSSpecificScriptName(String script) {
return OSUtil.getOperatingSystem() == OSUtil.OS.WINDOWS ? script + ".bat" : script + ".sh";
}

Expand Down Expand Up @@ -376,4 +387,5 @@ public void ltail(String clusterName, boolean showMint, boolean showInputs, bool
public boolean isFirstRunt(String clusterName) {
return clusterStartService.checkIfFirstRun(getClusterFolder(clusterName));
}

}
Loading

0 comments on commit 0d55629

Please sign in to comment.