Skip to content

Commit 456a3e6

Browse files
authored
Merge pull request #66 from bloxbean/ogmios_660
Ogmios 6.6.0 and Conway era cost model changes (WIP)
2 parents d3a4e3d + faace05 commit 456a3e6

21 files changed

+715
-694
lines changed

applications/cli/config/download.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#Please specify either the version or the full url for the following components
22
node.version=9.1.0
3-
ogmios.version=6.5.0
3+
ogmios.version=6.6.0
44
kupo.version=2.9.0
55
yaci.store.version=0.1.0-rc5
66

applications/cli/config/node.properties

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#protocolMagic=42
22
#maxKESEvolutions=60
3-
#securityParam=300
3+
#securityParam=80
44
#slotsPerKESPeriod=129600
55
#updateQuorum=1
66
#peerSharing=true
@@ -79,3 +79,21 @@
7979
## CC Members
8080
#ccMembers[0].hash=scriptHash-8fc13431159fdda66347a38c55105d50d77d67abc1c368b876d52ad1
8181
#ccMembers[0].term=340
82+
83+
########################################################################################################
84+
# Workaround for : https://github.com/bloxbean/yaci-devkit/issues/65
85+
#
86+
# The following parameters are enabled for a V2 cost model-related issue where there are 10 extra elements if the devnet
87+
# is started with the Conway era at epoch 0. The following parameters are enabled to configure the Conway era hard fork (HF) at epoch 1.
88+
# The network will start in the Babbage era and then hard fork (HF) to the Conway era at epoch 1.
89+
90+
# The shiftStartTimeBehind=true flag is enabled to shift the start time of the network to a time behind the current time by adjusting security parameter
91+
# which changes the stability window. This is to speed up the process of reaching the Conway era.
92+
#
93+
# This should only be done in a development environment because if the stability window is larger than the epoch length, the reward/treasury calculations will be incorrect or ignored.
94+
# Therefore, for a real multi-node network, you should start the network at the current time and allow it to reach the Conway era at epoch 1.
95+
# So, the shiftStartTimeBehind flag should be "false" for non-development / multi-node networks.
96+
#
97+
#########################################################################################################
98+
conwayHardForkAtEpoch=1
99+
shiftStartTimeBehind=true

applications/cli/docker/download-ogmios.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ case $1 in
1515
esac
1616

1717

18-
version=v6.5.0
18+
version=v6.6.0
1919
file=ogmios-${version}-${SUFFIX}-linux.zip
2020
wget https://github.com/CardanoSolutions/ogmios/releases/download/${version}/$file
2121

applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterCommands.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public void createCluster(@ShellOption(value = {"-n", "--name"}, defaultValue =
9797
@ShellOption(value = {"--submit-api-port"}, help = "Submit Api Port", defaultValue = "8090") int submitApiPort,
9898
@ShellOption(value = {"-s", "--slot-length"}, help = "Slot Length in sec. (0.1 to ..)", defaultValue = "1") double slotLength,
9999
@ShellOption(value = {"-b", "--block-time"}, help = "Block time in sec. (1 - 20)", defaultValue = "1") double blockTime,
100-
@ShellOption(value = {"-e", "--epoch-length"}, help = "No of slots in an epoch", defaultValue = "500") int epochLength,
100+
@ShellOption(value = {"-e", "--epoch-length"}, help = "No of slots in an epoch", defaultValue = "600") int epochLength,
101101
@ShellOption(value = {"-o", "--overwrite"}, defaultValue = "false", help = "Overwrite existing node directory. default: false") boolean overwrite,
102102
@ShellOption(value = {"--start"}, defaultValue = "false", help = "Automatically start the node after create. default: false") boolean start,
103103
@ShellOption(value = {"--era"}, defaultValue = "conway", help = "Era (babbage, conway)") String era,
@@ -118,11 +118,15 @@ public void createCluster(@ShellOption(value = {"-n", "--name"}, defaultValue =
118118
return;
119119
}
120120

121-
if (epochLength < 20) {
122-
writeLn(error("Epoch length should be 20 or more"));
121+
if (epochLength < 5) {
122+
writeLn(error("Epoch length below 5 is not allowed."));
123123
return;
124124
}
125125

126+
if (epochLength < 20) {
127+
writeLn(warn("Epoch length is too small. The node may behave unexpectedly if the epoch length is too small. Keep it at least 20 or more."));
128+
}
129+
126130
//Era check
127131
Era nodeEra;
128132
if (era == null || era.isEmpty())
@@ -137,6 +141,7 @@ else if (era.equalsIgnoreCase("conway"))
137141
}
138142

139143
long protocolMagic = genesisConfig.getProtocolMagic();
144+
long slotsPerKESPeriod = genesisConfig.getSlotsPerKESPeriod();
140145

141146
//stop any cluster if running
142147
localClusterService.stopCluster(msg -> writeLn(msg));
@@ -148,6 +153,7 @@ else if (era.equalsIgnoreCase("conway"))
148153
.slotLength(slotLength)
149154
.blockTime(blockTime)
150155
.epochLength(epochLength)
156+
.slotsPerKESPeriod(slotsPerKESPeriod)
151157
.protocolMagic(protocolMagic)
152158
.p2pEnabled(true)
153159
.masterNode(true)

applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterInfo.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ public class ClusterInfo {
1919
private double slotLength;
2020
private double blockTime;
2121
private int epochLength;
22+
private long slotsPerKESPeriod;
23+
private long securityParam;
24+
private double activeSlotsCoeff;
2225
private boolean p2pEnabled;
2326
private long startTime;
2427
private boolean masterNode;

applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterPortInfoHelper.java

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,40 +24,43 @@ public void printUrls(String clusteName, ClusterInfo clusterInfo) {
2424
if (isDocker) {
2525
writeLn(header(AnsiColors.CYAN_BOLD, "###### Node Details (Container) ######"));
2626
} else {
27-
writeLn(successLabel("Admin Port", String.valueOf(applicationConfig.getAdminPort())));
27+
writeLn(infoLabel("Admin Port", String.valueOf(applicationConfig.getAdminPort())));
2828
writeLn(header(AnsiColors.CYAN_BOLD, "###### Node Details ######"));
2929
}
30-
writeLn(successLabel("Node port", String.valueOf(clusterInfo.getNodePort())));
31-
writeLn(successLabel("Node Socket Paths", ""));
30+
writeLn(infoLabel("Node port", String.valueOf(clusterInfo.getNodePort())));
31+
writeLn(infoLabel("Node Socket Paths", ""));
3232
writeLn(clusterInfo.getSocketPath());
33-
writeLn(successLabel("Submit Api Port", String.valueOf(clusterInfo.getSubmitApiPort())));
34-
writeLn(successLabel("Protocol Magic", String.valueOf(clusterInfo.getProtocolMagic())));
35-
writeLn(successLabel("Block Time", String.valueOf(clusterInfo.getBlockTime())) + " sec");
36-
writeLn(successLabel("Slot Length", String.valueOf(clusterInfo.getSlotLength())) + " sec");
37-
writeLn(successLabel("Start Time", String.valueOf(clusterInfo.getStartTime())));
33+
writeLn(infoLabel("Submit Api Port", String.valueOf(clusterInfo.getSubmitApiPort())));
34+
writeLn(infoLabel("Protocol Magic", String.valueOf(clusterInfo.getProtocolMagic())));
35+
writeLn(infoLabel("Block Time", String.valueOf(clusterInfo.getBlockTime())) + " sec");
36+
writeLn(infoLabel("Slot Length", String.valueOf(clusterInfo.getSlotLength())) + " sec");
37+
writeLn(infoLabel("Start Time", String.valueOf(clusterInfo.getStartTime())));
38+
writeLn(infoLabel("Epoch Length", String.valueOf(clusterInfo.getEpochLength())));
39+
writeLn(infoLabel("Security Param", String.valueOf(clusterInfo.getSecurityParam())));
40+
writeLn(infoLabel("SlotsPerKESPeriod", String.valueOf(clusterInfo.getSlotsPerKESPeriod())));
3841

3942
if (clusteName == null || !"default".equals(clusteName))
4043
return;
4144

4245
if (isDocker) {
4346
writeLn("\n");
4447
writeLn(header(AnsiColors.CYAN_BOLD, "#################### URLS (Host) ####################"));
45-
writeLn(successLabel("Yaci Viewer", String.format("http://localhost:%s", getViewerPort())));
46-
writeLn(successLabel("Yaci Store Swagger UI", String.format("http://localhost:%s/swagger-ui.html", getStorePort(clusterInfo))));
47-
writeLn(successLabel("Yaci Store Api URL", String.format("http://localhost:%s/api/v1/", getStorePort(clusterInfo))));
48-
writeLn(successLabel("Pool Id", "pool1wvqhvyrgwch4jq9aa84hc8q4kzvyq2z3xr6mpafkqmx9wce39zy"));
48+
writeLn(infoLabel("Yaci Viewer", String.format("http://localhost:%s", getViewerPort())));
49+
writeLn(infoLabel("Yaci Store Swagger UI", String.format("http://localhost:%s/swagger-ui.html", getStorePort(clusterInfo))));
50+
writeLn(infoLabel("Yaci Store Api URL", String.format("http://localhost:%s/api/v1/", getStorePort(clusterInfo))));
51+
writeLn(infoLabel("Pool Id", "pool1wvqhvyrgwch4jq9aa84hc8q4kzvyq2z3xr6mpafkqmx9wce39zy"));
4952

5053
if (enableOgmios) {
5154
writeLn("\n");
5255
writeLn(header(AnsiColors.CYAN_BOLD, "#################### Other URLS ####################"));
53-
writeLn(successLabel("Ogmios Url (Optional)", "ws://localhost:" + getOgmiosPort(clusterInfo)));
54-
writeLn(successLabel("Kupo Url (Optional)", "http://localhost:" + getKupoPort(clusterInfo)));
56+
writeLn(infoLabel("Ogmios Url (Optional)", "ws://localhost:" + getOgmiosPort(clusterInfo)));
57+
writeLn(infoLabel("Kupo Url (Optional)", "http://localhost:" + getKupoPort(clusterInfo)));
5558
}
5659

5760
writeLn("\n");
5861
writeLn(header(AnsiColors.CYAN_BOLD, "#################### Node Ports ####################"));
59-
writeLn(successLabel("n2n port", "localhost:" + getN2NPort(clusterInfo)));
60-
writeLn(successLabel("n2c port (socat)", "localhost:" + getN2cSocatPort(clusterInfo)));
62+
writeLn(infoLabel("n2n port", "localhost:" + getN2NPort(clusterInfo)));
63+
writeLn(infoLabel("n2c port (socat)", "localhost:" + getN2cSocatPort(clusterInfo)));
6164
}
6265
}
6366

applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterService.java

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ private void updateGenesis(Path clusterFolder, String clusterName, ClusterInfo c
285285
if (era == Era.Babbage) {
286286
srcByronGenesisFile = clusterFolder.resolve("genesis-templates").resolve("byron-genesis.json");
287287
srcShelleyGenesisFile = clusterFolder.resolve("genesis-templates").resolve("shelley-genesis.json");
288-
srcAlonzoGenesisFile = clusterFolder.resolve("genesis-templates").resolve("alonzo-genesis.json");
288+
srcAlonzoGenesisFile = clusterFolder.resolve("genesis-templates").resolve("alonzo-genesis.json.babbage");
289289
srcConwayGenesisFile = clusterFolder.resolve("genesis-templates").resolve("conway-genesis.json");
290290
} else if (era == Era.Conway) {
291291
srcByronGenesisFile = clusterFolder.resolve("genesis-templates").resolve("byron-genesis.json");
@@ -313,12 +313,32 @@ private void updateGenesis(Path clusterFolder, String clusterName, ClusterInfo c
313313
values.put("activeSlotsCoeff", String.valueOf(activeSlotsCoeff));
314314
values.put("epochLength", String.valueOf(epochLength));
315315

316-
//Check if protocol version should be minimun 10 and it's conway era
317-
if (era == Era.Conway && genesisConfig.getProtocolMajorVer() < 10) {
318-
values.put("protocolMajorVer", 10);
316+
//Check if protocol version should be minimun 9 and it's conway era
317+
if (era == Era.Conway && genesisConfig.getProtocolMajorVer() < 9) {
318+
values.put("protocolMajorVer", 9);
319319
values.put("protocolMinorVer", 0);
320320
}
321321

322+
//Derive security param
323+
long securityParam = genesisConfigCopy.getSecurityParam();
324+
325+
if (genesisConfig.getConwayHardForkAtEpoch() > 0 && genesisConfig.isShiftStartTimeBehind()) {
326+
//Workaround for https://github.com/bloxbean/yaci-devkit/issues/65
327+
//Calculate required securityParam to jump directly to epoch = 1
328+
long expectedStabilityWindow = Math.round(epochLength * 1.5);
329+
securityParam = Math.round(expectedStabilityWindow * activeSlotsCoeff) / 3;
330+
} else {
331+
if (securityParam == 0) {
332+
//For stabilityWindow = epochLength * stabilityWindowFactory (0-1) , k = (epochLength * coefficient) / (3 * 2)
333+
securityParam = Math.round(((epochLength * activeSlotsCoeff) / 3) * genesisConfig.getStabilityWindowFactor());
334+
}
335+
}
336+
337+
values.put("securityParam", securityParam);
338+
clusterInfo.setSecurityParam(securityParam);
339+
clusterInfo.setActiveSlotsCoeff(activeSlotsCoeff);
340+
writer.accept(info("Security parameter : %s", securityParam));
341+
322342
//Update Genesis files
323343
try {
324344
templateEngineHelper.replaceValues(srcByronGenesisFile, destByronGenesisFile, values);
@@ -329,6 +349,15 @@ private void updateGenesis(Path clusterFolder, String clusterName, ClusterInfo c
329349
throw new IOException(e);
330350
}
331351

352+
//Check security Parameter
353+
long stabilityWindow = Math.round((3 * securityParam) / activeSlotsCoeff);
354+
if (stabilityWindow > epochLength) {
355+
writer.accept(warn("Stability window is greater than epoch length. Stability window : %s, Epoch length : %s", stabilityWindow, epochLength));
356+
writer.accept(warn("You may want to adjust the security parameter to make sure stability window is less than epoch length. " +
357+
"\nThe features like rewards calculation which depends on stability window may not work as expected" +
358+
"\nIf you are using default configuration, you can ignore this warning. The transaction processing will work fine"));
359+
}
360+
332361
writer.accept(success("Slot length updated in genesis.json"));
333362
}
334363

applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterStartService.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.bloxbean.cardano.yacicli.localcluster;
22

33
import com.bloxbean.cardano.yaci.core.util.OSUtil;
4+
import com.bloxbean.cardano.yacicli.localcluster.config.GenesisConfig;
45
import com.bloxbean.cardano.yacicli.localcluster.model.RunStatus;
56
import com.bloxbean.cardano.yacicli.util.PortUtil;
67
import com.bloxbean.cardano.yacicli.util.ProcessUtil;
@@ -24,7 +25,6 @@
2425
import java.util.List;
2526
import java.util.Queue;
2627
import java.util.concurrent.*;
27-
import java.util.concurrent.atomic.AtomicBoolean;
2828
import java.util.function.Consumer;
2929

3030
import static com.bloxbean.cardano.yacicli.util.ConsoleWriter.*;
@@ -36,6 +36,7 @@ public class ClusterStartService {
3636
private final ClusterConfig clusterConfig;
3737
private final ClusterPortInfoHelper clusterPortInfoHelper;
3838
private final ProcessUtil processUtil;
39+
private final GenesisConfig genesisConfig;
3940

4041
private ObjectMapper objectMapper = new ObjectMapper();
4142
private List<Process> processes = new ArrayList<>();
@@ -252,6 +253,18 @@ private boolean setupFirstRun(ClusterInfo clusterInfo, Path clusterFolder, Consu
252253
//Update Byron Genesis file
253254
ObjectNode jsonNode = (ObjectNode) objectMapper.readTree(byronGenesis.toFile());
254255
long byronStartTime = Instant.now().getEpochSecond();
256+
257+
if (genesisConfig.getConwayHardForkAtEpoch() > 0 && genesisConfig.isShiftStartTimeBehind()) {
258+
long stabilityWindow = (long) Math.floor((3 * clusterInfo.getSecurityParam()) / clusterInfo.getActiveSlotsCoeff());
259+
260+
long maxBehindBySecond = stabilityWindow - 5;
261+
if (stabilityWindow > clusterInfo.getEpochLength()) {
262+
maxBehindBySecond = clusterInfo.getEpochLength();
263+
}
264+
265+
byronStartTime = byronStartTime - maxBehindBySecond;
266+
writer.accept(success("Updating Start time to current time - " + maxBehindBySecond + " in byron-genesis.json"));
267+
}
255268
jsonNode.set("startTime", new LongNode(byronStartTime));
256269
objectMapper.writer(new DefaultPrettyPrinter()).writeValue(byronGenesis.toFile(), jsonNode);
257270

@@ -265,7 +278,7 @@ private boolean setupFirstRun(ClusterInfo clusterInfo, Path clusterFolder, Consu
265278
clusterInfo.setStartTime(byronStartTime);
266279
saveClusterInfo(clusterFolder, clusterInfo);
267280

268-
writer.accept(success("Update Start time"));
281+
writer.accept(success("Updated Start time"));
269282
return true;
270283
}
271284

applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/config/GenesisConfig.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ public class GenesisConfig {
1616
private String networkId = "Testnet";
1717
private long protocolMagic = 42;
1818
private int maxKESEvolutions = 60;
19-
private int securityParam = 300;
19+
private double stabilityWindowFactor = 0.5; //This is used to automatically derive the security parameter from epoch length
20+
private int securityParam = 0;
2021
private long slotsPerKESPeriod = 129600;
2122
private int updateQuorum = 1;
2223
private boolean peerSharing = true;
@@ -157,6 +158,11 @@ public class GenesisConfig {
157158
// new NonAvvmBalances("2657WMsDfac6if177KSAP7hosuDveRHN3ZsyP2EQNgTaQ5tqFTnmw1EMZcGreMHva", "3340000000", true)
158159
);
159160

161+
162+
//Introduced for the issue https://github.com/bloxbean/yaci-devkit/issues/65
163+
private int conwayHardForkAtEpoch = 0;
164+
private boolean shiftStartTimeBehind = false;
165+
160166
@PostConstruct
161167
public void postInit() {
162168
if (faucets.size() == 0 && !disableFaucet) {
@@ -250,6 +256,7 @@ public Map getConfigMap() {
250256
}
251257
map.put("protocolMagic", protocolMagic);
252258
map.put("maxKESEvolutions", maxKESEvolutions);
259+
map.put("stabilityWindowFactor", stabilityWindowFactor);
253260
map.put("securityParam", securityParam);
254261
map.put("slotsPerKESPeriod", slotsPerKESPeriod);
255262
map.put("updateQuorum", updateQuorum);
@@ -337,6 +344,9 @@ public Map getConfigMap() {
337344
map.put("genesisDelegs", genesisDelegs);
338345
map.put("nonAvvmBalances", nonAvvmBalances);
339346

347+
map.put("conwayHardForkAtEpoch", conwayHardForkAtEpoch);
348+
map.put("shiftStartTimeBehind", shiftStartTimeBehind);
349+
340350
return map;
341351
}
342352

@@ -345,6 +355,7 @@ public GenesisConfig copy() {
345355
genesisConfig.setNetworkId(networkId);
346356
genesisConfig.setProtocolMagic(protocolMagic);
347357
genesisConfig.setMaxKESEvolutions(maxKESEvolutions);
358+
genesisConfig.setStabilityWindowFactor(stabilityWindowFactor);
348359
genesisConfig.setSecurityParam(securityParam);
349360
genesisConfig.setSlotsPerKESPeriod(slotsPerKESPeriod);
350361
genesisConfig.setUpdateQuorum(updateQuorum);
@@ -423,6 +434,9 @@ public GenesisConfig copy() {
423434
genesisConfig.setGenesisDelegs(new ArrayList<>(genesisDelegs));
424435
genesisConfig.setNonAvvmBalances(new ArrayList<>(nonAvvmBalances));
425436

437+
genesisConfig.setConwayHardForkAtEpoch(conwayHardForkAtEpoch);
438+
genesisConfig.setShiftStartTimeBehind(shiftStartTimeBehind);
439+
426440
return genesisConfig;
427441
}
428442

applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/peer/PeerCommand.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,14 +131,17 @@ private void printClusterInfo(String clusterName) throws IOException {
131131
ClusterInfo clusterInfo = clusterService.getClusterInfo(clusterName);
132132
writeLn("");
133133
writeLn(header(AnsiColors.CYAN_BOLD, "###### Node Details ######"));
134-
writeLn(successLabel("Node port", String.valueOf(clusterInfo.getNodePort())));
135-
writeLn(successLabel("Node Socket Paths", ""));
134+
writeLn(infoLabel("Node port", String.valueOf(clusterInfo.getNodePort())));
135+
writeLn(infoLabel("Node Socket Paths", ""));
136136
writeLn(clusterInfo.getSocketPath());
137-
writeLn(successLabel("Submit Api Port", String.valueOf(clusterInfo.getSubmitApiPort())));
138-
writeLn(successLabel("Protocol Magic", String.valueOf(clusterInfo.getProtocolMagic())));
139-
writeLn(successLabel("Block Time", String.valueOf(clusterInfo.getBlockTime())) + " sec");
140-
writeLn(successLabel("Slot Length", String.valueOf(clusterInfo.getSlotLength())) + " sec");
141-
writeLn(successLabel("Start Time", String.valueOf(clusterInfo.getStartTime())));
137+
writeLn(infoLabel("Submit Api Port", String.valueOf(clusterInfo.getSubmitApiPort())));
138+
writeLn(infoLabel("Protocol Magic", String.valueOf(clusterInfo.getProtocolMagic())));
139+
writeLn(infoLabel("Block Time", String.valueOf(clusterInfo.getBlockTime())) + " sec");
140+
writeLn(infoLabel("Slot Length", String.valueOf(clusterInfo.getSlotLength())) + " sec");
141+
writeLn(infoLabel("Start Time", String.valueOf(clusterInfo.getStartTime())));
142+
writeLn(infoLabel("Epoch Length", String.valueOf(clusterInfo.getEpochLength())));
143+
writeLn(infoLabel("Security Param", String.valueOf(clusterInfo.getSecurityParam())));
144+
writeLn(infoLabel("SlotsPerKESPeriod", String.valueOf(clusterInfo.getSlotsPerKESPeriod())));
142145
}
143146

144147
public Availability peerCommandAvailability() {

0 commit comments

Comments
 (0)