Skip to content

Commit

Permalink
chore: #50 Prv test network support with new genesis/delegation keys
Browse files Browse the repository at this point in the history
  • Loading branch information
satran004 committed Jun 11, 2024
1 parent 90ad9c2 commit 3a1713c
Show file tree
Hide file tree
Showing 19 changed files with 1,042 additions and 121 deletions.
10 changes: 8 additions & 2 deletions applications/cli/config/node.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
#protocolMagic=42
#
#disableFaucet=true
#initialFunds.008c5bf0f2af6f1ef08bb3f6ec702dd16e1c514b7e1d12f7549b47db9f4d943c7af0aaec774757d4745d1a2c8dd3220e6ec2c9df23f757a2f8=40000
#initialFunds.005154f7a46e7fe9eb003e6a1a5a184685dbec77fa336c9f1abcf5c5e601b135a188a0e114739809762b650a2ca5ea8f20060d867bcca39a18=10000

#initialAddresses[0].address=addr_test1qzx9hu8j4ah3auytk0mwcupd69hpc52t0cw39a65ndrah86djs784u92a3m5w475w3w35tyd6v3qumkze80j8a6h5tuqq5xe8y
#initialAddresses[0].balance=450000000
#initialAddresses[0].staked=true
#
#initialAddresses[1].address=addr_test1qqwpl7h3g84mhr36wpetk904p7fchx2vst0z696lxk8ujsjyruqwmlsm344gfux3nsj6njyzj3ppvrqtt36cp9xyydzqzumz82
#initialAddresses[1].balance=250000000
#initialAddresses[1].staked=false
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ public void createCluster(@ShellOption(value = {"-n", "--name"}, defaultValue =
@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,
@ShellOption(value = {"--era"}, defaultValue = "babbage", help = "Era (babbage, conway)") String era,
@ShellOption(value = {"--genesis-profile",}, defaultValue = ShellOption.NULL, help = "Use a pre-defined genesis profile (Options: zero_fee)") GenesisProfile genesisProfile
@ShellOption(value = {"--genesis-profile",}, defaultValue = ShellOption.NULL, help = "Use a pre-defined genesis profile (Options: zero_fee)") GenesisProfile genesisProfile,
@ShellOption(value = {"--generate-new-keys"}, defaultValue = "false", help = "Generate new genesis keys, pool keys instead of default keys") boolean generateNewKeys,
@ShellOption(value = {"--no-genesis-keys"}, defaultValue = "1", help = "No of genesis keys to generate") int nGenesisKeys
) {

try {
Expand Down Expand Up @@ -138,7 +140,7 @@ else if (era.equalsIgnoreCase("conway"))
.genesisProfile(genesisProfile)
.build();

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

if (success) {
printClusterInfo(clusterName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,12 @@ public String getKupoHome() {
else
return Path.of(kupoFolder).toAbsolutePath().toString();
}

public Path getClusterFolder(String clusterName) {
return Path.of(getClusterHome(), clusterName);
}

public Path getPoolKeysFolder(String clusterName) {
return Path.of(getPoolKeysHome(), clusterName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.bloxbean.cardano.yacicli.commands.localcluster.config.GenesisConfig;
import com.bloxbean.cardano.yacicli.commands.localcluster.events.ClusterCreated;
import com.bloxbean.cardano.yacicli.commands.localcluster.events.ClusterStopped;
import com.bloxbean.cardano.yacicli.commands.localcluster.privnet.PrivNetService;
import com.bloxbean.cardano.yacicli.commands.localcluster.profiles.GenesisProfile;
import com.bloxbean.cardano.yacicli.commands.tail.BlockStreamerService;
import com.bloxbean.cardano.yacicli.output.OutputFormatter;
Expand All @@ -16,7 +17,6 @@
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.context.WebServerApplicationContext;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.core.io.Resource;
Expand Down Expand Up @@ -69,6 +69,9 @@ public class ClusterService {
@Autowired
private GenesisConfig genesisConfig;

@Autowired
private PrivNetService privNetService;

public ClusterService(ClusterConfig config, ClusterStartService clusterStartService, BlockStreamerService blockStreamerService) {
this.clusterConfig = config;
this.clusterStartService = clusterStartService;
Expand Down Expand Up @@ -156,11 +159,7 @@ public Path getClusterFolder(String clusterName) {
return Path.of(clusterConfig.getClusterHome(), clusterName);
}

public Path getPoolKeys(String clusterName) {
return Path.of(clusterConfig.getPoolKeysHome(), clusterName);
}

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

Path destPath = getClusterFolder(clusterName);
Expand Down Expand Up @@ -207,7 +206,17 @@ public boolean createNodeClusterFolder(String clusterName, ClusterInfo clusterIn
updatePorts(destPath, clusterInfo.getNodePort());

//Update genesis
updateGenesis(destPath, clusterInfo, clusterInfo.getEra(), clusterInfo.getSlotLength(), activeCoeff, clusterInfo.getEpochLength(), clusterInfo.getProtocolMagic(), writer);
updateGenesis(destPath,
clusterName,
clusterInfo,
clusterInfo.getEra(),
clusterInfo.getSlotLength(),
activeCoeff,
clusterInfo.getEpochLength(),
clusterInfo.getProtocolMagic(),
generateNewGenesisKeys,
nGenesisKeys,
writer);

//Update P2P configuration
updateConfiguration(destPath, clusterInfo, writer);
Expand Down Expand Up @@ -246,8 +255,9 @@ private boolean checkCardanoNodeBin(Consumer<String> writer) throws IOException
// FileUtils.copyURLToFile(url, Path.of(clusterConfig.getCLIBinFolder()).toFile());
}

private void updateGenesis(Path clusterFolder, ClusterInfo clusterInfo, Era era, double slotLength, double activeSlotsCoeff, int epochLength, long protocolMagic, Consumer<String> writer) throws IOException {

private void updateGenesis(Path clusterFolder, String clusterName, ClusterInfo clusterInfo, Era era, double slotLength,
double activeSlotsCoeff, int epochLength, long protocolMagic,
boolean generateNewGenesisKeys, int nGenesisKeys, Consumer<String> writer) throws IOException {
Path srcShelleyGenesisFile = null;
Path srcByronGenesisFile = null;
Path srcAlonzoGenesisFile = null;
Expand All @@ -273,6 +283,11 @@ private void updateGenesis(Path clusterFolder, ClusterInfo clusterInfo, Era era,
if (clusterInfo.getGenesisProfile() != null)
genesisConfigCopy = GenesisProfile.applyGenesisProfile(clusterInfo.getGenesisProfile(), genesisConfigCopy);

//override genesis keys if new keys are generated
if (generateNewGenesisKeys) {
privNetService.setupNewKeysAndDefaultPool(clusterFolder, clusterName, clusterInfo, genesisConfigCopy, activeSlotsCoeff, nGenesisKeys, writer);
}

Map values = genesisConfigCopy.getConfigMap();
values.put("slotLength", String.valueOf(slotLength));
values.put("activeSlotsCoeff", String.valueOf(activeSlotsCoeff));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.bloxbean.cardano.yacicli.commands.localcluster.config;

import com.bloxbean.cardano.client.address.Address;
import com.bloxbean.cardano.client.util.HexUtil;
import jakarta.annotation.PostConstruct;
import lombok.*;
import org.springframework.boot.context.properties.ConfigurationProperties;
Expand Down Expand Up @@ -49,7 +51,7 @@ public class GenesisConfig {
.publicKey("7301761068762f5900bde9eb7c1c15b09840285130f5b0f53606cc57")
.vrf("c2b62ffa92ad18ffc117ea3abeb161a68885000a466f9c71db5e4731d6630061")
.build());
private List<Delegator> defaultDelegators = List.of(new Delegator("295b987135610616f3c74e11c94d77b6ced5ccc93a7d719cfb135062", "7301761068762f5900bde9eb7c1c15b09840285130f5b0f53606cc57"));
private List<Delegator> defaultDelegators = List.of(new Delegator("295b987135610616f3c74e11c94d77b6ced5ccc93a7d719cfb135062", "7301761068762f5900bde9eb7c1c15b09840285130f5b0f53606cc57", true));

//Alonzo
private int collateralPercentage = 150;
Expand Down Expand Up @@ -94,6 +96,51 @@ public class GenesisConfig {
private Map<String, BigInteger> initialFunds = new LinkedHashMap<>();
private List<MapItem<String, BigInteger>> initialFundsList = new ArrayList<>();

private List<InitialAddress> initialAddresses = new ArrayList<>();

//Byron Genesis
private List<String> bootStakeHolders = List.of(
"4c23c4a699c4245f41c79d444e0a3322edbf66daa7efe001c6c8657c"
// "ca456dbf716c78fd4069ca352e3c56501ed37983534de76f7987cd33",
// "fe60e90aa8237e2fc643d38655aa5ee69c69e03db80a0f63eb8d42b4"
);

private List<HeavyDelegation> heavyDelegations = List.of(
new HeavyDelegation("4c23c4a699c4245f41c79d444e0a3322edbf66daa7efe001c6c8657c",
0,
"+AkxDu8deptOlFXf1QMC0ys/w0y7mjqHRCqybUequeotqUVCz1h1HSOCNK5eBPE5svg2tHyQJKQzToAfCiSDOg==",
"OBjvlmcUFmFHcRV27X2eRjBjAexq/Q0KiYDwkeEYbtJwT0xPnjn1+NE8oI4ePOA/M4mtHbtuYf40wLdvJVRCnw==",
"44327b2748c561d6bfed3d3f62dde3745d89b768a24dfa5977908433afb53611bdd841f70b33554ad57aef804448f9a09132c55ab08add5aa3b7dab150c2ae0b", true)
// new HeavyDelegation("ca456dbf716c78fd4069ca352e3c56501ed37983534de76f7987cd33",
// 0,
// "EQEJb8IW6YTdsBnksNkbRi086JA0K2ek20CZgxsMDaSUkatLQY7+guZsyX9/xv1Rx/dy2mrnZSBAxo53wZecOA==",
// "QeBvAkkrR0T5YoeqGa0u7wCio5D9dRIT0BoPRXfDVO0skNlO4TmJHTVJnCs2hWDtwaznWygJAx1AFk4tBvhu1A==",
// "7525bb530324039c1c5faa2088a95272c7195ff49a97f014a60d944b1c2212b11e1867c1fb69895609f8b976926bb8309489258b3be0b819b36f9c0a0c403d02", false),
// new HeavyDelegation("fe60e90aa8237e2fc643d38655aa5ee69c69e03db80a0f63eb8d42b4",
// 0,
// "h745CvlXG8yPF2y8MU/bSbMekN61YN+V+htnswdPvAIhIwi3XH9ZIxsdR6DCYq+maOfwzUvys5Z9WEholH3/EQ==",
// "5p4ntkX2uDoCsi/s136jaswzPLJr7qcaTaguGokToHuwdxRV+6LGuwvmWHs5kdQg518v+0ZCji1QLo8X4ApezA==",
// "abf663bac9650ee8547a98c33a4dca528493025f130556e9037c56885e2edbbe2d445b3714363b05f48d0bb6892cdae0ca27568f2aa7f1295cf11c5316da7b05", true)
);

private List<GenesisDeleg> genesisDelegs = List.of(
new GenesisDeleg("337bc5ef0f1abf205624555c13a37258c42b46b1259a6b1a6d82574e",
"41fd6bb31f34469320aa47cf6ccc3918e58a06d60ea1f2361efe2458",
"7053e3ecd2b19db13e5338aa75fb518fc08b6c218f56ad65760d3eb074be95d4", true)
// new GenesisDeleg("b5c3fed76c54bfdcda7993e4171eff2fb853f8ab920ab80047278a91",
// "fcb677a90948d1d5b358912f54f6baaf762ecf5cd6579c93bcb49cef",
// "c7715f726e8e4f7745ccc646f4350758460de71de5694b244a47761fb106ec6e", false),
// new GenesisDeleg("e34a75849b978bb20c366f531f978b3111b91aae0e469108dca8e433",
// "81babf3c139646f0f0268abed36d2a54757492a3a68cda2438a37f7e",
// "ca336185cd781a6543b6c1e62ee1eee53e237d5d1fb065f08412d40d61b6ca06", true)
);

private List<NonAvvmBalances> nonAvvmBalances = List.of(
new NonAvvmBalances("2657WMsDfac6EtPTiPEptLHDYUVYD5DtRpTmVWb6X95beFrKXqPULmyvCwmCxZEGN", "3340000000", true)
// new NonAvvmBalances("2657WMsDfac6PDUZWRH4fh4j6ARZaH3x7SaaQ48d8SkGcNxmpoxPthQSiEahDTzAB", "3340000000", false),
// new NonAvvmBalances("2657WMsDfac6if177KSAP7hosuDveRHN3ZsyP2EQNgTaQ5tqFTnmw1EMZcGreMHva", "3340000000", true)
);

@PostConstruct
public void postInit() {
if (faucets.size() == 0 && !disableFaucet) {
Expand All @@ -105,7 +152,7 @@ public void postInit() {
);
}

if (initialFunds.size() == 0) {
if (initialFunds.size() == 0 && initialAddresses.size() == 0) {
initialFunds.put( "00c8c47610a36034aac6fc58848bdae5c278d994ff502c05455e3b3ee8f8ed3a0eea0ef835ffa7bbfcde55f7fe9d2cc5d55ea62cecb42bab3c", BigInteger.valueOf(10000000000L));
initialFunds.put( "004048ff89ca4f88e66598e620aa0c7128c2145d9a181ae9a4a81ca8e3e849af38840c5562dd382be37c9e76545c8191f9d8f6df1d20cfcee0", BigInteger.valueOf(10000000000L));
initialFunds.put( "00ca6e1b1f320d543a24adeabc0aa4627635c7349b639f86f74bdfdd78d31b28c9619a58b3792a7394ab85deb36889c4d7b0632c8167b855d2", BigInteger.valueOf(10000000000L));
Expand All @@ -131,12 +178,60 @@ public void postInit() {
if (faucets.size() > 0 && !disableFaucet)
initialFunds.putAll(faucets);

// if (initialFunds.size() > 0) {
// initialFunds = initialFunds.entrySet()
// .stream()
// .collect(Collectors.toMap(
// entry -> transformAddrToHex(entry.getKey()), // Transform the key
// Map.Entry::getValue // Keep the value as is
// ));
// }

initialAddresses.stream()
.forEach(initialAddress -> {
var address = new Address(initialAddress.address);
initialFunds.put(HexUtil.encodeHexString(address.getBytes()), initialAddress.balance());
});

initialFundsList = createListWithLastFlag(initialFunds);

if (initialAddresses == null || initialAddresses.size() == 0) {
if (defaultDelegators != null && defaultDelegators.size() > 0) {
defaultDelegators.get(defaultDelegators.size() - 1).setLast(true);
}
} else {
defaultDelegators = new ArrayList<>();
initialAddresses.forEach(initialAddress -> {
if (!initialAddress.staked)
return;

Address address = new Address(initialAddress.address);
var stakeKeyHash = address.getDelegationCredentialHash()
.map(HexUtil::encodeHexString)
.orElse(null);
defaultDelegators.add(new Delegator(stakeKeyHash, null, false));
});

defaultDelegators.getLast().setLast(true);
}
}

private String transformAddrToHex(String key) {
if (key == null)
return null;
if (key.startsWith("addr")) {
var address = new Address(key);
return HexUtil.encodeHexString(address.getBytes());
} else
return key;
}

public Map getConfigMap() {
Map map = new HashMap();
map.put("networkId", networkId);
if ("Mainnet".equals(networkId)) {
map.put("mainnet", true);
}
map.put("protocolMagic", protocolMagic);
map.put("maxKESEvolutions", maxKESEvolutions);
map.put("securityParam", securityParam);
Expand All @@ -161,7 +256,13 @@ public Map getConfigMap() {
map.put("protocolMinorVer", protocolMinorVer);
map.put("monetaryExpansionRate", monetaryExpansionRate);
map.put("treasuryGrowthRate", treasuryGrowthRate);

if (pools != null && pools.size() > 0)
pools.getLast().setLast(true);
map.put("pools", pools);

if (defaultDelegators != null && defaultDelegators.size() >0)
defaultDelegators.getLast().setLast(true);
map.put("defaultDelegators", defaultDelegators);

map.put("collateralPercentage", collateralPercentage);
Expand Down Expand Up @@ -202,6 +303,10 @@ public Map getConfigMap() {

map.put("initialFunds", initialFundsList);

map.put("heavyDelegations", heavyDelegations);
map.put("genesisDelegs", genesisDelegs);
map.put("nonAvvmBalances", nonAvvmBalances);

return map;
}

Expand Down Expand Up @@ -274,6 +379,10 @@ public GenesisConfig copy() {
genesisConfig.setInitialFunds(initialFunds);
genesisConfig.setInitialFundsList(initialFundsList);

genesisConfig.setHeavyDelegations(new ArrayList<>(heavyDelegations));
genesisConfig.setGenesisDelegs(new ArrayList<>(genesisDelegs));
genesisConfig.setNonAvvmBalances(new ArrayList<>(nonAvvmBalances));

return genesisConfig;
}

Expand All @@ -290,21 +399,35 @@ private <K, V> List<MapItem<K, V>> createListWithLastFlag(Map<K, V> faucets) {
return faucetList;
}

}
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public static class Pool {
String poolHash;
BigInteger cost;
BigDecimal margin;
String publicKey;
String rewardAccountHash;
String rewardAccountType;
String vrf;
boolean last;
}

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
class Pool {
String poolHash;
BigInteger cost;
BigDecimal margin;
String publicKey;
String rewardAccountHash;
String rewardAccountType;
String vrf;
}
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public static class Delegator {
String stakeKeyHash;
String poolHash;
boolean last;
}

record Delegator(String stakeKeyHash, String poolHash) {}
record MapItem<K, V>(K key, V value, boolean last) {}
public record MapItem<K, V>(K key, V value, boolean last) {}
public record HeavyDelegation(String bootStakeDelegator, int omega, String issuerPk, String delegatePk, String cert, boolean last) {}
public record GenesisDeleg(String delegator, String delegate, String vrf, boolean last) {}
public record NonAvvmBalances(String address, String balance, boolean last) {}

public record InitialAddress(String address, BigInteger balance, boolean staked, boolean last) {}
}
Loading

0 comments on commit 3a1713c

Please sign in to comment.