Skip to content

Commit

Permalink
Tonlib builder now supports lite-server index - liteServerIndex();
Browse files Browse the repository at this point in the history
Tonlib builder has a new parameter of type TonGlobalConfig, .globalConfig() - anyone can construct custom global.config now;
Also in case of connection failure automatically tries to connect to other lite-servers from the list - WIP.
  • Loading branch information
neodiX committed Aug 4, 2024
1 parent 68943cd commit 014bfd8
Show file tree
Hide file tree
Showing 24 changed files with 691 additions and 65 deletions.
2 changes: 1 addition & 1 deletion cell/src/test/java/org/ton/java/hashmaps/TestHashMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public void testHashMapSerialization() {
log.info("serialized cell: \n{}", cell.print());

log.info("cell hash {}", Utils.bytesToHex(cell.hash()));

log.info("cell hash ref0 {}", Utils.bytesToHex(cell.getRefs().get(0).hash()));
log.info("cell hash ref1 {}", Utils.bytesToHex(cell.getRefs().get(1).hash()));

Expand Down
106 changes: 70 additions & 36 deletions tonlib/src/main/java/org/ton/java/tonlib/Tonlib.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonParser;
import com.google.gson.ToNumberPolicy;
import com.sun.jna.Native;
import lombok.Builder;
Expand All @@ -14,6 +13,7 @@
import org.ton.java.cell.CellBuilder;
import org.ton.java.tonlib.queries.*;
import org.ton.java.tonlib.types.*;
import org.ton.java.tonlib.types.globalconfig.*;
import org.ton.java.utils.Utils;

import java.io.InputStream;
Expand Down Expand Up @@ -62,6 +62,8 @@ public class Tonlib {
* if not specified and pathToGlobalConfig is filled then pathToGlobalConfig is used;
*/
private String globalConfigAsString;

private TonGlobalConfig globalConfig;
/**
* Valid values are:<br>
* 0 - FATAL<br>
Expand All @@ -83,6 +85,8 @@ public class Tonlib {

private String keystorePath;

private Integer liteServerIndex;

/**
* Default value 5
*/
Expand All @@ -98,9 +102,8 @@ public class Tonlib {

private final long tonlib;

private boolean synced;

RunResultParser runResultParser;

LibraryResultParser libraryResultParser;

public static class TonlibBuilder {
Expand Down Expand Up @@ -151,6 +154,10 @@ public Tonlib build() {
super.keystorePath = ".";
}

if (isNull(super.liteServerIndex)) {
super.liteServerIndex = -1;
}

super.keystorePath = super.keystorePath.replace("\\", "/");

if (super.receiveRetryTimes == 0) {
Expand All @@ -165,11 +172,10 @@ public Tonlib build() {
super.ignoreCache = true;
}

super.synced = false;
super.runResultParser = new RunResultParser();
super.libraryResultParser = new LibraryResultParser();

String configData;
String originalGlobalConfig;
if (isNull(super.pathToGlobalConfig)) {

if (isNull(super.globalConfigAsString)) {
Expand All @@ -181,22 +187,36 @@ public Tonlib build() {
super.pathToGlobalConfig = "global-config.json (integrated resource)";
config = Tonlib.class.getClassLoader().getResourceAsStream("global-config.json");
}
configData = Utils.streamToString(config);
originalGlobalConfig = Utils.streamToString(config);

if (nonNull(config)) {
config.close();
}
} else {
configData = super.globalConfigAsString;
originalGlobalConfig = super.globalConfigAsString;
}
} else if (nonNull(super.globalConfig)) {
originalGlobalConfig = gson.toJson(super.globalConfig);
} else {
if (Files.exists(Paths.get(super.pathToGlobalConfig))) {
configData = new String(Files.readAllBytes(Paths.get(super.pathToGlobalConfig)));
originalGlobalConfig = new String(Files.readAllBytes(Paths.get(super.pathToGlobalConfig)));
} else {
throw new RuntimeException("Global config is not found in path: " + super.pathToGlobalConfig);
}
}

TonGlobalConfig globalConfigInternal = gson.fromJson(originalGlobalConfig, TonGlobalConfig.class);

if (super.liteServerIndex != -1) {
if (super.liteServerIndex > globalConfigInternal.getLiteservers().length - 1) {
throw new RuntimeException("Specified lite-server index is greater than total number of lite-servers in config.");
}
LiteServers[] liteServers = globalConfigInternal.getLiteservers();
LiteServers[] newLiteServers = new LiteServers[1];
newLiteServers[0] = liteServers[super.liteServerIndex];
globalConfigInternal.setLiteservers(newLiteServers);
}

super.tonlibJson = Native.load(super.pathToTonlibSharedLib, TonlibJsonI.class);
super.tonlib = super.tonlibJson.tonlib_client_json_create();

Expand All @@ -207,6 +227,10 @@ public Tonlib build() {
"Keystore path: %s\n" +
"Path to global config: %s\n" +
"Global config as string: %s\n" +
"lite-servers found: %s\n" +
"dht-nodes found: %s\n" +
"init-block seqno: %s\n" +
"%s\n" +
"Ignore cache: %s\n" +
"Testnet: %s\n" +
"Receive timeout: %s seconds\n" +
Expand All @@ -219,50 +243,60 @@ public Tonlib build() {
super.pathToGlobalConfig,
(super.globalConfigAsString != null && super.globalConfigAsString.length() > 33) ?
super.globalConfigAsString.substring(0, 33) : "",
globalConfigInternal.getLiteservers().length,
globalConfigInternal.getDht().getStatic_nodes().getNodes().length,
globalConfigInternal.getValidator().getInit_block().getSeqno(),
(super.liteServerIndex == -1) ? "using lite-servers: all" : "using lite-server at index: " + super.liteServerIndex + " (" + Utils.int2ip(globalConfigInternal.getLiteservers()[0].getIp()) + ")",
super.ignoreCache,
super.testnet,
super.receiveTimeout,
super.receiveRetryTimes);

// set verbosity
VerbosityLevelQuery verbosityLevelQuery = VerbosityLevelQuery.builder().new_verbosity_level(super.verbosityLevel.ordinal()).build();

super.tonlibJson.tonlib_client_json_send(super.tonlib, gson.toJson(verbosityLevelQuery));
super.tonlibJson.tonlib_client_json_receive(super.tonlib, super.receiveTimeout);

String result = super.tonlibJson.tonlib_client_json_receive(super.tonlib, super.receiveTimeout);
System.out.println("set verbosityLevel result: " + result);

String initTemplate = Utils.streamToString(Tonlib.class.getClassLoader().getResourceAsStream("init.json"));

String dataQuery = JsonParser.parseString(configData).getAsJsonObject().toString();

String q = initTemplate.replace("CFG_PLACEHOLDER", dataQuery);
q = q.replace("IGNORE_CACHE", super.ignoreCache.toString());
if (super.keystoreInMemory) {
String keystoreMemory = " 'keystore_type': { '@type': 'keyStoreTypeInMemory' }";
q = q.replace("KEYSTORE_TYPE", keystoreMemory);
} else {
String keystoreDirectory = "'keystore_type': {'@type': 'keyStoreTypeDirectory', 'directory': '.' } ";
if (super.keystorePath.equals(".")) {
q = q.replace("KEYSTORE_TYPE", keystoreDirectory);
} else {
q = q.replace("KEYSTORE_TYPE", keystoreDirectory.replace(".", super.keystorePath));
}
}

String setupQueryQ = JsonParser.parseString(q).getAsJsonObject().toString();

super.tonlibJson.tonlib_client_json_send(super.tonlib, setupQueryQ);

result = super.tonlibJson.tonlib_client_json_receive(super.tonlib, super.receiveTimeout);
System.out.println("set tonlib configuration result " + result);
initTonlibConfig(globalConfigInternal);

} catch (Exception e) {
throw new RuntimeException("Error creating tonlib instance: " + e.getMessage());
}
return super.build();
}

private void initTonlibConfig(TonGlobalConfig tonGlobalConfig) {

TonlibSetup tonlibSetup = TonlibSetup.builder()
.type("init")
.options(TonlibOptions.builder()
.type("options")
.config(TonlibConfig.builder()
.type("config")
.config(gson.toJson(tonGlobalConfig))
.use_callbacks_for_network(false)
.blockchain_name("")
.ignore_cache(true)
.build())
.keystore_type(
super.keystoreInMemory ?
KeyStoreTypeMemory.builder()
.type("keyStoreTypeInMemory")
.build()
:
KeyStoreTypeDirectory.builder()
.type("keyStoreTypeDirectory")
.directory(super.keystorePath.equals(".") ? "." : super.keystorePath)
.build())
.build())
.build();

super.tonlibJson.tonlib_client_json_send(super.tonlib, gson.toJson(tonlibSetup));
super.tonlibJson.tonlib_client_json_receive(super.tonlib, super.receiveTimeout);
}
}


public void destroy() {
tonlibJson.tonlib_client_json_destroy(tonlib);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.ton.java.tonlib.types.globalconfig;

import com.google.gson.annotations.SerializedName;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

@Builder
@Setter
@Getter
public class AddrList {
@SerializedName(value = "@type")
String type;
DhtAddr[] addrs;
long version;
long reinit_date;
long priority;
long expire_at;

@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.ton.java.tonlib.types.globalconfig;

import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

@Builder
@Setter
@Getter
public class BlockInfo {

private String file_hash;
private String root_hash;
private long seqno;
private long workchain;
private long shard;

@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.ton.java.tonlib.types.globalconfig;

import com.google.gson.annotations.SerializedName;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

@Builder
@Setter
@Getter
public class Dht {
@SerializedName(value = "@type")
String type;
int a;
int k;
StaticNodes static_nodes;

@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.ton.java.tonlib.types.globalconfig;

import com.google.gson.annotations.SerializedName;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

@Builder
@Setter
@Getter
public class DhtAddr {
@SerializedName(value = "@type")
String type;
long ip;
long port;

@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.ton.java.tonlib.types.globalconfig;

import com.google.gson.annotations.SerializedName;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

@Builder
@Setter
@Getter
public class DhtNode {
@SerializedName(value = "@type")
String type;
DhtNodeId id;
AddrList addr_list;
long version;
String signature;

@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.ton.java.tonlib.types.globalconfig;

import com.google.gson.annotations.SerializedName;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

@Builder
@Setter
@Getter
public class DhtNodeId {
@SerializedName(value = "@type")
String type;
String key;

@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package org.ton.java.tonlib.types.globalconfig;

public interface KeyStoreType {

}
Loading

0 comments on commit 014bfd8

Please sign in to comment.