Skip to content

Commit

Permalink
use deterministic validator-engine-console and lite-server keys;
Browse files Browse the repository at this point in the history
upgrade TON binaries to 2024.09 release.
  • Loading branch information
neodix42 committed Sep 13, 2024
1 parent 48c9dc4 commit 752c621
Show file tree
Hide file tree
Showing 12 changed files with 134 additions and 14 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/commit-macos-arm64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on: [ push,workflow_dispatch,workflow_call ]

jobs:
build:
runs-on: macos-13-xlarge
runs-on: macos-14

steps:
- uses: actions/checkout@v3
Expand Down
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,40 @@ for ARM64 architecture use:

`java -jar MyLocalTon-arm64.jar`

### Parameters

* `nogui` - used to run MyLocalTon without GUI interface. Can be used in Docker or server with headless Java.
* `ton-http-api` - enables ton-http-api service on start. Runs on port `8081`.
* `explorer` - enables native ton blockchain explorer on start. Runs on port `8000`.
* `ip.addr.xxx.xxx` - used to bind specific IP to MyLocalTon instead of 127.0.0.1.
* `with-validators-N` - used to start MyLocalTon with N additional validators.
* `debug` - used to start MyLocalTon in debug mode, that produces lots of useful log files.

### Lite-client

MyLocalTon uses deterministic (permanent) private and public keys for lite-server and validator-engine-console access.
These keys can be found [here](./src/main/resources/org/ton/certs).
Once MyLocalTon is ready, you can use lite-client with the base64 key:

`lite-client -a 127.0.0.1:4443 -b E7XwFSQzNkcRepUC23J2nRpASXpnsEKmyyHYV4u/FZY= -c last`

or validator-engine-console in this way:

`validator-engine-console -a 127.0.0.1:4441 -k <absolute-path>/myLocalTon/genesis/bin/certs/client -p <absolute-path>/myLocalTon/genesis/bin/certs/server.pub`

### Log files

* **MyLocalTon** log files can be found under `./myLocalTon/MyLocalTon.log`.
* **validator-engine** log files can be found under `./myLocalTon/genesis/db/log`.

### Reporting an issue

* delete the current folder .`/myLocalTon` next to MyLocalTon*.jar
* execute `java -jar MyLocalTon*.jar debug`. (`*` replace with architecture and branch if needed)
* wait till the error appears and shutdown MyLocalTon.
* then send zipped above log files to Telegram @neodix or attach to issue at GitHub.
* Thanks for reporting. You are making MyLocalTon better.

## Upgrade

Today upgrade is not supported, that means once you have a new version of MyLocalTon just overwrite the existing
Expand Down
12 changes: 6 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,27 +33,27 @@
<jetty.version>11.0.14</jetty.version>
<jprocesses.version>1.6.5</jprocesses.version>
<richtextfx.version>0.10.7</richtextfx.version>
<ton4j.version>0.5.3</ton4j.version>
<ton4j.version>0.6.0</ton4j.version>
<objectdb.version>2.8.6</objectdb.version>
<javax.persistence.version>2.1.0</javax.persistence.version>
<jta.version>1.1</jta.version>
<log4j.version>2.17.1</log4j.version>

<linux.amd64.ton.binaries.uri>
https://cicd.neodix.io/view/pipelines/job/neodix-mylocalton-${ton_branch}-pipeline/lastSuccessfulBuild/artifact/artifacts/ton-x86-64-linux-portable.zip
https://cicd.neodix.io/view/pipelines/job/${ton_branch}-pipeline/lastSuccessfulBuild/artifact/artifacts/ton-x86-64-linux-portable.zip
</linux.amd64.ton.binaries.uri>
<mac.amd64.ton.binaries.uri>
https://cicd.neodix.io/view/pipelines/job/neodix-mylocalton-${ton_branch}-pipeline/lastSuccessfulBuild/artifact/artifacts/ton-x86-64-macos-portable.zip
https://cicd.neodix.io/view/pipelines/job/${ton_branch}-pipeline/lastSuccessfulBuild/artifact/artifacts/ton-x86-64-macos-portable.zip
</mac.amd64.ton.binaries.uri>
<win.amd64.ton.binaries.uri>
https://cicd.neodix.io/view/pipelines/job/neodix-mylocalton-${ton_branch}-pipeline/lastSuccessfulBuild/artifact/artifacts/ton-x86-64-windows.zip
https://cicd.neodix.io/view/pipelines/job/${ton_branch}-pipeline/lastSuccessfulBuild/artifact/artifacts/ton-x86-64-windows.zip
</win.amd64.ton.binaries.uri>

<linux.arm64.ton.binaries.uri>
https://cicd.neodix.io/view/pipelines/job/neodix-mylocalton-${ton_branch}-pipeline/lastSuccessfulBuild/artifact/artifacts/ton-arm64-linux-portable.zip
https://cicd.neodix.io/view/pipelines/job/${ton_branch}-pipeline/lastSuccessfulBuild/artifact/artifacts/ton-arm64-linux-portable.zip
</linux.arm64.ton.binaries.uri>
<mac.arm64.ton.binaries.uri>
https://cicd.neodix.io/view/pipelines/job/neodix-mylocalton-${ton_branch}-pipeline/lastSuccessfulBuild/artifact/artifacts/ton-arm64-macos-portable.zip
https://cicd.neodix.io/view/pipelines/job/${ton_branch}-pipeline/lastSuccessfulBuild/artifact/artifacts/ton-arm64-macos-portable.zip
</mac.arm64.ton.binaries.uri>
</properties>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.ton.utils.Extractor;

import java.io.File;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
Expand Down Expand Up @@ -47,6 +48,36 @@ public void generateClientCertificate(Node node, String serverIdHuman) throws Ex
}
}

public void getClientCertificate(Node node, String serverIdHuman) throws Exception {
// Generating server certificate
if (Files.exists(Paths.get(node.getTonBinDir() + "certs" + File.separator + "client"))) {
log.info("Found existing client certificate, skipping");
} else {
log.debug("Getting client certificate for remote control");
String clientIdHex = "C0E4A79C30225D8A9864AE03806A0FBF4BD1F988E889C191D1BD78D8681CB0F1";
String clientIdBase64 = "wOSnnDAiXYqYZK4DgGoPv0vR+YjoicGR0b142GgcsPE=";
log.debug("Generated client private certificate for {}: {} {}", node.getNodeName(), clientIdHex, clientIdBase64);

InputStream stream = Extractor.class.getClassLoader().getResourceAsStream("org/ton/certs/client");
Files.copy(stream, Paths.get(node.getTonBinDir() + "certs" + File.separator + "client"), StandardCopyOption.REPLACE_EXISTING);
stream.close();

stream = Extractor.class.getClassLoader().getResourceAsStream("org/ton/certs/client.pub");
Files.copy(stream, Paths.get(node.getTonBinDir() + "certs" + File.separator + "client.pub"), StandardCopyOption.REPLACE_EXISTING);
stream.close();

//Adding client permissions
String content = Files.readString(Paths.get(Extractor.MY_LOCAL_TON_ROOT_DIR + "templates" + File.separator + "control.template"), StandardCharsets.UTF_8);
String replacedTemplate = StringUtils.replace(content, "CONSOLE-PORT", String.valueOf(node.getConsolePort()));
replacedTemplate = StringUtils.replace(replacedTemplate, "SERVER-ID", "\"" + serverIdHuman + "\"");
replacedTemplate = StringUtils.replace(replacedTemplate, "CLIENT-ID", "\"" + clientIdBase64 + "\"");

String configFile = Files.readString(Paths.get(node.getTonDbDir() + "config.json"), StandardCharsets.UTF_8);
String configNew = StringUtils.replace(configFile, "\"control\" : [", replacedTemplate);
Files.writeString(Paths.get(node.getTonDbDir() + "config.json"), configNew, StandardOpenOption.CREATE);
}
}

/**
* Creates server key in db and puts into directory db/keyring/hex.
*/
Expand All @@ -68,6 +99,33 @@ public String generateServerCertificate(Node node) throws Exception {
}
}

public String getServerCertificate(Node node) throws Exception {
// Generating server certificate
if (Files.exists(Paths.get(node.getTonBinDir() + "certs" + File.separator + "server"))) {
log.info("Found existing server certificate, skipping!");
return null;
} else {
String serverIdHex = "40C90E768C026594EFABA6A190C89AC4DB0B5F08EFC72CA06FD7E7E949A068F1";
String serverIdBase64 = "QMkOdowCZZTvq6ahkMiaxNsLXwjvxyygb9fn6UmgaPE=";

log.debug("Server IDs for {}: {} {}", node.getNodeName(), serverIdHex, serverIdBase64);

InputStream stream = Extractor.class.getClassLoader().getResourceAsStream("org/ton/certs/server");
Files.copy(stream, Paths.get(node.getTonDbKeyringDir() + serverIdHex), StandardCopyOption.REPLACE_EXISTING);
stream.close();

stream = Extractor.class.getClassLoader().getResourceAsStream("org/ton/certs/server");
Files.copy(stream, Paths.get(node.getTonBinDir() + "certs" + File.separator + "server"), StandardCopyOption.REPLACE_EXISTING);
stream.close();

stream = Extractor.class.getClassLoader().getResourceAsStream("org/ton/certs/server.pub");
Files.copy(stream, Paths.get(node.getTonBinDir() + "certs" + File.separator + "server.pub"), StandardCopyOption.REPLACE_EXISTING);
stream.close();

return serverIdBase64;
}
}

public Pair<String, String> generateLiteServerKeys(Node node) throws Exception {
String liteserverKeys = new RandomIdExecutor().execute(node, "-m", "keys", "-n", node.getTonDbKeyringDir() + "liteserver");
String[] liteServerHexBase64 = liteserverKeys.split(" ");
Expand All @@ -78,4 +136,24 @@ public Pair<String, String> generateLiteServerKeys(Node node) throws Exception {
Files.copy(Paths.get(node.getTonDbKeyringDir() + "liteserver"), Paths.get(node.getTonDbKeyringDir() + liteServerIdHex), StandardCopyOption.REPLACE_EXISTING);
return Pair.of(liteServerIdHex, liteServerIdBase64);
}

public Pair<String, String> getLiteServerKeys(Node node) throws Exception {
String liteServerIdHex = "DA46DE8CCCED9AB6F29447B334636FBE07F7F4CAE6B6833D26AF1240A1BB34B1";
String liteServerIdBase64 = "2kbejMztmrbylEezNGNvvgf39MrmtoM9Jq8SQKG7NLE=";
log.debug("liteServerIdHex {}, liteServerIdBase64 {} on {}", liteServerIdHex, liteServerIdBase64, node.getNodeName());

InputStream stream = Extractor.class.getClassLoader().getResourceAsStream("org/ton/certs/liteserver");
Files.copy(stream, Paths.get(node.getTonDbKeyringDir() + liteServerIdHex), StandardCopyOption.REPLACE_EXISTING);
stream.close();

stream = Extractor.class.getClassLoader().getResourceAsStream("org/ton/certs/liteserver");
Files.copy(stream, Paths.get(node.getTonDbKeyringDir() + "liteserver"), StandardCopyOption.REPLACE_EXISTING);
stream.close();

stream = Extractor.class.getClassLoader().getResourceAsStream("org/ton/certs/liteserver.pub");
Files.copy(stream, Paths.get(node.getTonDbKeyringDir() + "liteserver.pub"), StandardCopyOption.REPLACE_EXISTING);
stream.close();

return Pair.of(liteServerIdHex, liteServerIdBase64);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ public void initFullnode(Node node, String sharedGlobalConfig) throws Exception

//enable access to full node from validator-engine-console - required if you want to become validator later
GenerateRandomId generateRandomId = new GenerateRandomId();
String serverIdBase64 = generateRandomId.generateServerCertificate(node);
generateRandomId.generateClientCertificate(node, serverIdBase64);
String serverIdBase64 = generateRandomId.getServerCertificate(node);
generateRandomId.getClientCertificate(node, serverIdBase64);
}
}

Expand All @@ -111,7 +111,7 @@ public void enableLiteServer(Node node, String myGlobalConfig, boolean reinstall
} else {
log.info("Enabling lite-server...");

Pair<String, String> liteServerKeys = new GenerateRandomId().generateLiteServerKeys(node);
Pair<String, String> liteServerKeys = new GenerateRandomId().getLiteServerKeys(node);
String liteServers = "\"liteservers\" : [{\"id\":\"" + liteServerKeys.getRight() + "\",\"port\":\"" + node.getLiteServerPort() + "\"}";
log.debug("liteservers: {} ", liteServers);

Expand All @@ -135,9 +135,6 @@ public void enableLiteServer(Node node, String myGlobalConfig, boolean reinstall
//add new lite-server to the global config
String existingLiteserver = MyLocalTonUtils.sbb(myGlobalTonConfig, "\"liteservers\":[");
liteServerConfigNew = "{\"id\":{\"key\":\"" + liteserverPubkeyBase64 + "\", \"@type\":\"pub.ed25519\"}, \"port\": " + node.getLiteServerPort() + ", \"ip\": " + publicIpNum + "}\n]";
//liteServerConfigBoth = StringUtils.substring(existingLiteserver, 0, -1) + "," + liteServerConfigNew;
//myGlobalTonConfigNew = StringUtils.replace(myGlobalTonConfig, existingLiteserver, liteServerConfigBoth);
//FileUtils.writeStringToFile(new File(myGlobalConfig), myGlobalTonConfigNew, StandardCharsets.UTF_8);

//replace and create new config
myGlobalTonConfigNew = StringUtils.replace(myGlobalTonConfig, existingLiteserver, "[" + liteServerConfigNew);
Expand Down Expand Up @@ -352,7 +349,6 @@ public void generateValidatorKeys(Node node, boolean updateGenZeroStateFif) thro
// replace path to validator-key-1.pub in gen-zerostate.fif
String genZeroStateFif = FileUtils.readFileToString(new File(node.getGenesisGenZeroStateFifLocation()), StandardCharsets.UTF_8);
String genZeroStateFifNew = StringUtils.replace(genZeroStateFif, "// \"path_to_" + node.getNodeName() + "_pub_key\"", "\"" + node.getValidatorKeyPubLocation() + "\"");
// genZeroStateFifNew = StringUtils.replace(genZeroStateFifNew, "initial_stake_" + node.getNodeName(), node.getDefaultValidatorStake().min(BigDecimal.ONE).multiply(BigDecimal.valueOf(ONE_BLN)).toString());
genZeroStateFifNew = StringUtils.replace(genZeroStateFifNew, "initial_stake_" + node.getNodeName(), node.getDefaultValidatorStake().min(BigInteger.ONE).toString());
FileUtils.writeStringToFile(new File(node.getGenesisGenZeroStateFifLocation()), genZeroStateFifNew, StandardCharsets.UTF_8);
}
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/org/ton/ui/controllers/MainController.java
Original file line number Diff line number Diff line change
Expand Up @@ -2121,6 +2121,9 @@ public void updateValidationTabInfo() {
String previous = "Previous validators (Public key, ADNL address, weight): " + System.lineSeparator() + config32.getValidators().getValidators().stream().map(i -> i.getPublicKey() + " " + i.getAdnlAddress() + " " + i.getWeight()).collect(Collectors.joining(System.lineSeparator())) + System.lineSeparator() + System.lineSeparator();
String current = "Current validators: " + System.lineSeparator() + config34.getValidators().getValidators().stream().map(i -> i.getPublicKey() + " " + i.getAdnlAddress() + " " + i.getWeight()).collect(Collectors.joining(System.lineSeparator())) + System.lineSeparator() + System.lineSeparator();
String next = "Next validators (available only within a Break time): " + System.lineSeparator() + config36.getValidators().getValidators().stream().map(i -> i.getPublicKey() + " " + i.getAdnlAddress() + " " + i.getWeight()).collect(Collectors.joining(System.lineSeparator())) + System.lineSeparator();
log.debug("previous {}", previous);
log.debug("current {}", current);
log.debug("next {}", next);
totalValidators.setTooltip(new Tooltip(previous + current + next));

if (nonNull(v.getBlockchainLaunchTime())) {
Expand Down Expand Up @@ -2418,6 +2421,7 @@ private void updateValidator7TabPage(ValidationParam v) {
private void colorValidationTiming(ValidationParam v) {

long currentTime = System.currentTimeMillis() / 1000;
log.debug("colorValidationTiming: {}, {}", currentTime, MyLocalTonUtils.toUTC(currentTime));

if (v.getStartValidationCycle() > currentTime) {
startCycle.setTextFill(Color.GREEN);
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/org/ton/certs/client
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#hI�N8�����&�`��钞w0��g*+},
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/org/ton/certs/client.pub
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ƴHg ���j
O��h�ʆ�#H�=B�p��KV�
1 change: 1 addition & 0 deletions src/main/resources/org/ton/certs/liteserver
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#hIa��"fT� 2�#A*5:��'=���{z�V%0�
1 change: 1 addition & 0 deletions src/main/resources/org/ton/certs/liteserver.pub
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ƴH��$36Gz��rv�@Izg�B��!�W���
1 change: 1 addition & 0 deletions src/main/resources/org/ton/certs/server
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#hI�'�v����YgI0��7��A���H��o��
1 change: 1 addition & 0 deletions src/main/resources/org/ton/certs/server.pub
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ƴH �\"�(΋(y'��;���~���䎎��y�ýZ

0 comments on commit 752c621

Please sign in to comment.