Replace call to `GenerateConfig` with local JSON. Closes #5739

Signed-off-by: Pedro Pombeiro <pombeirp@users.noreply.github.com>
This commit is contained in:
Pedro Pombeiro 2018-09-07 11:53:43 +02:00
parent e69fb18de9
commit 4ab5e43616
No known key found for this signature in database
GPG Key ID: A65DEB11E4BBC647
10 changed files with 201 additions and 199 deletions

View File

@ -16,7 +16,7 @@ dependencies {
implementation 'com.instabug.library:instabug:3+'
implementation 'status-im:function:0.0.1'
String statusGoVersion = 'v0.14.1'
String statusGoVersion = 'v0.15.0'
final String statusGoGroup = 'status-im', statusGoName = 'status-go'
// Check if the local status-go jar exists, and compile against that if it does

View File

@ -151,66 +151,20 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
return null;
}
private String generateConfig(final JSONObject defaultConfig, final String root, final String keystoreDir, final String fleet) throws JSONException {
private String updateConfig(final String jsonConfigString, final String absRootDirPath, final String absKeystoreDirPath) throws JSONException {
final JSONObject jsonConfig = new JSONObject(jsonConfigString);
// retrieve parameters from app config, that will be applied onto the Go-side config later on
final String dataDir = root + defaultConfig.get("DataDir");
final int networkId = defaultConfig.getInt("NetworkId");
final Object upstreamConfig = defaultConfig.opt("UpstreamConfig");
final Boolean logEnabled = defaultConfig.getBoolean("LogEnabled");
final String logLevel = defaultConfig.optString("LogLevel", "ERROR");
// retrieve config from Go side, in order to use as the basis of the config
JSONObject jsonConfig = new JSONObject(
Statusgo.GenerateConfig(dataDir, fleet, networkId));
jsonConfig.put("NetworkId", networkId);
jsonConfig.put("DataDir", dataDir);
jsonConfig.put("KeyStoreDir", keystoreDir);
if (upstreamConfig != null) {
Log.d(TAG, "UpstreamConfig is not null");
jsonConfig.put("UpstreamConfig", upstreamConfig);
}
final String absDataDirPath = pathCombine(absRootDirPath, jsonConfig.getString("DataDir"));
final Boolean logEnabled = jsonConfig.getBoolean("LogEnabled");
final String gethLogFilePath = logEnabled ? prepareLogsFile() : null;
jsonConfig.put("LogEnabled", logEnabled);
jsonConfig.put("DataDir", absDataDirPath);
jsonConfig.put("KeyStoreDir", absKeystoreDirPath);
jsonConfig.put("LogFile", gethLogFilePath);
jsonConfig.put("LogLevel", TextUtils.isEmpty(logLevel) ? "ERROR" : logLevel);
// Setting up whisper config
JSONObject whisperConfig = jsonConfig.optJSONObject("WhisperConfig");
if (whisperConfig == null) {
whisperConfig = new JSONObject();
}
whisperConfig.put("LightClient", true);
jsonConfig.put("WhisperConfig", whisperConfig);
// Setting up cluster config
JSONObject clusterConfig = jsonConfig.optJSONObject("ClusterConfig");
if (clusterConfig != null) {
Log.d(TAG, "ClusterConfig is not null");
clusterConfig.put("Fleet", fleet);
jsonConfig.put("ClusterConfig", clusterConfig);
} else {
Log.w(TAG, "ClusterConfig: Cannot find ClusterConfig: doesn't exist or not a JSON object");
Log.w(TAG, "ClusterConfig: Fleet will be set to defaults");
}
return jsonConfig.toString();
}
private String generateConfigFromDefaultConfig(final String root, final String keystoreDir, final String fleet, final String defaultConfig) {
try {
JSONObject customConfig = new JSONObject(defaultConfig);
return generateConfig(customConfig, root, keystoreDir, fleet);
} catch (JSONException e) {
Log.d(TAG, "Something went wrong " + e.getMessage());
Log.d(TAG, "Default configuration will be used: ropsten, beta fleet");
return Statusgo.GenerateConfig(this.getTestnetDataDir(root), "eth.beta", TESTNET_NETWORK_ID);
}
}
private static void prettyPrintConfig(final String config) {
Log.d(TAG, "startNode() with config (see below)");
String configOutput = config;
@ -227,16 +181,22 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
Log.d(TAG, "******************* ENDOF NODE CONFIG *************************");
}
private String getTestnetDataDir(final String root) {
return root + "/ethereum/testnet";
private String getTestnetDataDir(final String absRootDirPath) {
return pathCombine(absRootDirPath, "ethereum/testnet");
}
private void doStartNode(final String defaultConfig, final String fleet) {
private String pathCombine(final String path1, final String path2) {
// Replace this logic with Paths.get(path1, path2) once API level 26+ becomes the minimum supported API level
final File file = new File(path1, path2);
return file.getAbsolutePath();
}
private void doStartNode(final String jsonConfigString) {
Activity currentActivity = getCurrentActivity();
final String root = currentActivity.getApplicationInfo().dataDir;
final String dataFolder = this.getTestnetDataDir(root);
final String absRootDirPath = currentActivity.getApplicationInfo().dataDir;
final String dataFolder = this.getTestnetDataDir(absRootDirPath);
Log.d(TAG, "Starting Geth node in folder: " + dataFolder);
try {
@ -247,11 +207,11 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
Log.e(TAG, "error making folder: " + dataFolder, e);
}
final String ropstenFlagPath = root + "/ropsten_flag";
final String ropstenFlagPath = pathCombine(absRootDirPath, "ropsten_flag");
final File ropstenFlag = new File(ropstenFlagPath);
if (!ropstenFlag.exists()) {
try {
final String chaindDataFolderPath = dataFolder + "/StatusIM/lightchaindata";
final String chaindDataFolderPath = pathCombine(dataFolder, "StatusIM/lightchaindata");
final File lightChainFolder = new File(chaindDataFolderPath);
if (lightChainFolder.isDirectory()) {
String[] children = lightChainFolder.list();
@ -266,10 +226,9 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
}
}
String testnetDataDir = dataFolder;
String oldKeystoreDir = testnetDataDir + "/keystore";
String newKeystoreDir = root + "/keystore";
String oldKeystoreDir = pathCombine(testnetDataDir, "keystore");
String newKeystoreDir = pathCombine(absRootDirPath, "keystore");
final File oldKeystore = new File(oldKeystoreDir);
if (oldKeystore.exists()) {
try {
@ -288,29 +247,34 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
}
}
final String config = this.generateConfigFromDefaultConfig(root, newKeystoreDir, fleet, defaultConfig);
try {
final String updatedJsonConfigString = this.updateConfig(jsonConfigString, absRootDirPath, newKeystoreDir);
prettyPrintConfig(config);
prettyPrintConfig(updatedJsonConfigString);
String res = Statusgo.StartNode(config);
if (res.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "StartNode result: " + res);
String res = Statusgo.StartNode(updatedJsonConfigString);
if (res.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "StartNode result: " + res);
Log.d(TAG, "Geth node started");
}
else {
Log.e(TAG, "StartNode failed: " + res);
}
status.sendMessage();
} catch (JSONException e) {
Log.e(TAG, "updateConfig failed: " + e.getMessage());
System.exit(1);
}
else {
Log.e(TAG, "StartNode failed: " + res);
}
Log.d(TAG, "Geth node started");
status.sendMessage();
}
private String getOldExternalDir() {
File extStore = Environment.getExternalStorageDirectory();
return extStore.exists() ? extStore.getAbsolutePath() + "/ethereum/testnet" : getNewInternalDir();
return extStore.exists() ? pathCombine(extStore.getAbsolutePath(), "ethereum/testnet") : getNewInternalDir();
}
private String getNewInternalDir() {
Activity currentActivity = getCurrentActivity();
return currentActivity.getApplicationInfo().dataDir + "/ethereum/testnet";
return pathCombine(currentActivity.getApplicationInfo().dataDir, "ethereum/testnet");
}
private void deleteDirectory(File folder) {
@ -384,7 +348,7 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
}
@ReactMethod
public void startNode(final String config, final String fleet) {
public void startNode(final String config) {
Log.d(TAG, "startNode");
if (!checkAvailability()) {
return;
@ -393,7 +357,7 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
Runnable r = new Runnable() {
@Override
public void run() {
doStartNode(config, fleet);
doStartNode(config);
}
};

View File

@ -37,7 +37,7 @@ ExternalProject_Add(StatusGo_ep
PREFIX ${StatusGo_PREFIX}
SOURCE_DIR ${StatusGo_SOURCE_DIR}
GIT_REPOSITORY https://github.com/status-im/status-go.git
GIT_TAG v0.14.1
GIT_TAG v0.15.0
BUILD_BYPRODUCTS ${StatusGo_STATIC_LIB}
CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/${CONFIGURE_SCRIPT} ${GO_ROOT_PATH} ${StatusGo_ROOT} ${StatusGo_SOURCE_DIR}
BUILD_COMMAND ""

View File

@ -18,6 +18,7 @@
#include <QVariantMap>
#include <QDir>
#include <QStandardPaths>
#include <QtConcurrent>
#include "libstatus.h"
@ -71,47 +72,39 @@ void RCTStatus::getDeviceUUID(double callbackId) {
}
void RCTStatus::startNode(QString configString, QString fleet) {
void RCTStatus::startNode(QString configString) {
Q_D(RCTStatus);
qDebug() << "call of RCTStatus::startNode with param configString:" << configString;
QJsonParseError jsonError;
QJsonDocument jsonDoc = QJsonDocument::fromJson(configString.toUtf8(), &jsonError);
const QJsonDocument& jsonDoc = QJsonDocument::fromJson(configString.toUtf8(), &jsonError);
if (jsonError.error != QJsonParseError::NoError){
qDebug() << jsonError.errorString();
}
qDebug() << " RCTStatus::startNode configString: " << jsonDoc.toVariant().toMap();
QVariantMap configJSON = jsonDoc.toVariant().toMap();
qDebug() << " RCTStatus::startNode configString: " << configJSON;
int networkId = configJSON["NetworkId"].toInt();
QString dataDir = configJSON["DataDir"].toString();
QString relativeDataDirPath = configJSON["DataDir"].toString();
if (!relativeDataDirPath.startsWith("/"))
relativeDataDirPath.prepend("/");
QString rootDirPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/";
QString networkDir = rootDirPath + dataDir;
QString keyStoreDir = rootDirPath + "keystore";
QDir dir(networkDir);
if (!dir.exists()) {
dir.mkpath(".");
}
qDebug()<<"RCTStatus::startNode networkDir: "<<networkDir;
char *configChars = GenerateConfig(networkDir.toUtf8().data(), fleet.toUtf8().data(), networkId);
qDebug() << "RCTStatus::startNode GenerateConfig result: " << statusGoResultError(configChars);
jsonDoc = QJsonDocument::fromJson(QString(configChars).toUtf8(), &jsonError);
if (jsonError.error != QJsonParseError::NoError){
qDebug() << jsonError.errorString();
QString rootDirPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
QDir rootDir(rootDirPath);
QString absDataDirPath = rootDirPath + relativeDataDirPath;
QDir dataDir(absDataDirPath);
if (!dataDir.exists()) {
dataDir.mkpath(".");
}
qDebug() << " RCTStatus::startNode GenerateConfig configString: " << jsonDoc.toVariant().toMap();
QVariantMap generatedConfig = jsonDoc.toVariant().toMap();
generatedConfig["KeyStoreDir"] = keyStoreDir;
generatedConfig["LogFile"] = networkDir + "/geth.log";
generatedConfig["ClusterConfig.Fleet"] = fleet;
configJSON["DataDir"] = absDataDirPath;
configJSON["KeyStoreDir"] = rootDir.absoluteFilePath("keystore");
configJSON["LogFile"] = dataDir.absoluteFilePath("geth.log");
const char* result = StartNode(QString(QJsonDocument::fromVariant(generatedConfig).toJson(QJsonDocument::Compact)).toUtf8().data());
const QJsonDocument& updatedJsonDoc = QJsonDocument::fromVariant(configJSON);
qDebug() << " RCTStatus::startNode updated configString: " << updatedJsonDoc.toVariant().toMap();
const char* result = StartNode(QString(updatedJsonDoc.toJson(QJsonDocument::Compact)).toUtf8().data());
qDebug() << "RCTStatus::startNode StartNode result: " << statusGoResultError(result);
}
@ -126,63 +119,77 @@ void RCTStatus::stopNode() {
void RCTStatus::createAccount(QString password, double callbackId) {
Q_D(RCTStatus);
qDebug() << "call of RCTStatus::createAccount with param callbackId: " << callbackId;
const char* result = CreateAccount(password.toUtf8().data());
qDebug() << "RCTStatus::createAccount CreateAccount result: " << statusGoResultError(result);
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
QtConcurrent::run([&](QString password, double callbackId) {
const char* result = CreateAccount(password.toUtf8().data());
qDebug() << "RCTStatus::createAccount CreateAccount result: " << statusGoResultError(result);
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
}, password, callbackId);
}
void RCTStatus::notifyUsers(QString token, QString payloadJSON, QString tokensJSON, double callbackId) {
Q_D(RCTStatus);
qDebug() << "call of RCTStatus::notifyUsers with param callbackId: " << callbackId;
const char* result = NotifyUsers(token.toUtf8().data(), payloadJSON.toUtf8().data(), tokensJSON.toUtf8().data());
qDebug() << "RCTStatus::notifyUsers Notify result: " << statusGoResultError(result);
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
QtConcurrent::run([&](QString token, QString payloadJSON, QString tokensJSON, double callbackId) {
const char* result = NotifyUsers(token.toUtf8().data(), payloadJSON.toUtf8().data(), tokensJSON.toUtf8().data());
qDebug() << "RCTStatus::notifyUsers Notify result: " << statusGoResultError(result);
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
}, token, payloadJSON, tokensJSON, callbackId);
}
void RCTStatus::addPeer(QString enode, double callbackId) {
Q_D(RCTStatus);
qDebug() << "call of RCTStatus::addPeer with param callbackId: " << callbackId;
const char* result = AddPeer(enode.toUtf8().data());
qDebug() << "RCTStatus::addPeer AddPeer result: " << statusGoResultError(result);
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
QtConcurrent::run([&](QString enode, double callbackId) {
const char* result = AddPeer(enode.toUtf8().data());
qDebug() << "RCTStatus::addPeer AddPeer result: " << statusGoResultError(result);
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
}, enode, callbackId);
}
void RCTStatus::recoverAccount(QString passphrase, QString password, double callbackId) {
Q_D(RCTStatus);
qDebug() << "call of RCTStatus::recoverAccount with param callbackId: " << callbackId;
const char* result = RecoverAccount(password.toUtf8().data(), passphrase.toUtf8().data());
qDebug() << "RCTStatus::recoverAccount RecoverAccount result: " << statusGoResultError(result);
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
QtConcurrent::run([&](QString passphrase, QString password, double callbackId) {
const char* result = RecoverAccount(password.toUtf8().data(), passphrase.toUtf8().data());
qDebug() << "RCTStatus::recoverAccount RecoverAccount result: " << statusGoResultError(result);
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
}, passphrase, password, callbackId);
}
void RCTStatus::login(QString address, QString password, double callbackId) {
Q_D(RCTStatus);
qDebug() << "call of RCTStatus::login with param callbackId: " << callbackId;
const char* result = Login(address.toUtf8().data(), password.toUtf8().data());
qDebug() << "RCTStatus::login Login result: " << statusGoResultError(result);
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
QtConcurrent::run([&](QString address, QString password, double callbackId) {
const char* result = Login(address.toUtf8().data(), password.toUtf8().data());
qDebug() << "RCTStatus::login Login result: " << statusGoResultError(result);
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
}, address, password, callbackId);
}
void RCTStatus::sendTransaction(QString txArgsJSON, QString password, double callbackId) {
Q_D(RCTStatus);
qDebug() << "call of RCTStatus::sendTransaction with param callbackId: " << callbackId;
const char* result = SendTransaction(txArgsJSON.toUtf8().data(), password.toUtf8().data());
qDebug() << "RCTStatus::sendTransaction SendTransaction result: " << statusGoResultError(result);
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
QtConcurrent::run([&](QString txArgsJSON, QString password, double callbackId) {
const char* result = SendTransaction(txArgsJSON.toUtf8().data(), password.toUtf8().data());
qDebug() << "RCTStatus::sendTransaction SendTransaction result: " << statusGoResultError(result);
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
}, txArgsJSON, password, callbackId);
}
void RCTStatus::signMessage(QString rpcParams, double callbackId) {
Q_D(RCTStatus);
qDebug() << "call of RCTStatus::signMessage with param callbackId: " << callbackId;
const char* result = SignMessage(rpcParams.toUtf8().data());
qDebug() << "RCTStatus::signMessage SignMessage result: " << statusGoResultError(result);
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
QtConcurrent::run([&](QString rpcParams, double callbackId) {
const char* result = SignMessage(rpcParams.toUtf8().data());
qDebug() << "RCTStatus::signMessage SignMessage result: " << statusGoResultError(result);
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
}, rpcParams, callbackId);
}
@ -210,17 +217,21 @@ void RCTStatus::clearStorageAPIs() {
void RCTStatus::callRPC(QString payload, double callbackId) {
Q_D(RCTStatus);
qDebug() << "call of RCTStatus::callRPC with param callbackId: " << callbackId;
const char* result = CallRPC(payload.toUtf8().data());
qDebug() << "RCTStatus::callRPC CallRPC result: " << statusGoResultError(result);
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
QtConcurrent::run([&](QString payload, double callbackId) {
const char* result = CallRPC(payload.toUtf8().data());
qDebug() << "RCTStatus::callRPC CallRPC result: " << statusGoResultError(result);
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
}, payload, callbackId);
}
void RCTStatus::callPrivateRPC(QString payload, double callbackId) {
Q_D(RCTStatus);
qDebug() << "call of RCTStatus::callPrivateRPC with param callbackId: " << callbackId;
const char* result = CallPrivateRPC(payload.toUtf8().data());
qDebug() << "RCTStatus::callPrivateRPC CallPrivateRPC result: " << statusGoResultError(result);
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
QtConcurrent::run([&](QString payload, double callbackId) {
const char* result = CallPrivateRPC(payload.toUtf8().data());
qDebug() << "RCTStatus::callPrivateRPC CallPrivateRPC result: " << statusGoResultError(result);
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
}, payload, callbackId);
}
void RCTStatus::closeApplication() {

View File

@ -32,7 +32,7 @@ public:
QList<ModuleMethod*> methodsToExport() override;
QVariantMap constantsToExport() override;
Q_INVOKABLE void startNode(QString configString, QString fleet);
Q_INVOKABLE void startNode(QString configString);
Q_INVOKABLE void stopNode();
Q_INVOKABLE void createAccount(QString password, double callbackId);
Q_INVOKABLE void notifyUsers(QString token, QString payloadJSON, QString tokensJSON, double callbackId);

View File

@ -65,8 +65,7 @@ RCT_EXPORT_MODULE();
////////////////////////////////////////////////////////////////////
#pragma mark - startNode
//////////////////////////////////////////////////////////////////// startNode
RCT_EXPORT_METHOD(startNode:(NSString *)configString
fleet:(NSString *)fleet) {
RCT_EXPORT_METHOD(startNode:(NSString *)configString) {
#if DEBUG
NSLog(@"StartNode() method called");
#endif
@ -75,18 +74,18 @@ RCT_EXPORT_METHOD(startNode:(NSString *)configString
NSURL *rootUrl =[[fileManager
URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]
lastObject];
NSURL *testnetFolderName = [rootUrl URLByAppendingPathComponent:@"ethereum/testnet"];
NSURL *absTestnetFolderName = [rootUrl URLByAppendingPathComponent:@"ethereum/testnet"];
if (![fileManager fileExistsAtPath:testnetFolderName.path])
[fileManager createDirectoryAtPath:testnetFolderName.path withIntermediateDirectories:YES attributes:nil error:&error];
if (![fileManager fileExistsAtPath:absTestnetFolderName.path])
[fileManager createDirectoryAtPath:absTestnetFolderName.path withIntermediateDirectories:YES attributes:nil error:&error];
NSURL *flagFolderUrl = [rootUrl URLByAppendingPathComponent:@"ropsten_flag"];
if(![fileManager fileExistsAtPath:flagFolderUrl.path]){
NSLog(@"remove lightchaindata");
NSURL *lightChainData = [testnetFolderName URLByAppendingPathComponent:@"StatusIM/lightchaindata"];
if([fileManager fileExistsAtPath:lightChainData.path]) {
[fileManager removeItemAtPath:lightChainData.path
NSURL *absLightChainDataUrl = [absTestnetFolderName URLByAppendingPathComponent:@"StatusIM/lightchaindata"];
if([fileManager fileExistsAtPath:absLightChainDataUrl.path]) {
[fileManager removeItemAtPath:absLightChainDataUrl.path
error:nil];
}
[fileManager createDirectoryAtPath:flagFolderUrl.path
@ -97,12 +96,12 @@ RCT_EXPORT_METHOD(startNode:(NSString *)configString
NSLog(@"after remove lightchaindata");
NSURL *oldKeystoreUrl = [testnetFolderName URLByAppendingPathComponent:@"keystore"];
NSURL *newKeystoreUrl = [rootUrl URLByAppendingPathComponent:@"keystore"];
if([fileManager fileExistsAtPath:oldKeystoreUrl.path]){
NSURL *absTestnetKeystoreUrl = [absTestnetFolderName URLByAppendingPathComponent:@"keystore"];
NSURL *absKeystoreUrl = [rootUrl URLByAppendingPathComponent:@"keystore"];
if([fileManager fileExistsAtPath:absTestnetKeystoreUrl.path]){
NSLog(@"copy keystore");
[fileManager copyItemAtPath:oldKeystoreUrl.path toPath:newKeystoreUrl.path error:nil];
[fileManager removeItemAtPath:oldKeystoreUrl.path error:nil];
[fileManager copyItemAtPath:absTestnetKeystoreUrl.path toPath:absKeystoreUrl.path error:nil];
[fileManager removeItemAtPath:absTestnetKeystoreUrl.path error:nil];
}
NSLog(@"after lightChainData");
@ -110,60 +109,34 @@ RCT_EXPORT_METHOD(startNode:(NSString *)configString
NSLog(@"preconfig: %@", configString);
NSData *configData = [configString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *configJSON = [NSJSONSerialization JSONObjectWithData:configData options:NSJSONReadingMutableContainers error:nil];
int networkId = [configJSON[@"NetworkId"] integerValue];
NSString *dataDir = [configJSON objectForKey:@"DataDir"];
NSString *upstreamURL = [configJSON valueForKeyPath:@"UpstreamConfig.URL"];
NSArray *bootnodes = [configJSON valueForKeyPath:@"ClusterConfig.BootNodes"];
NSString *networkDir = [rootUrl.path stringByAppendingString:dataDir];
NSString *devCluster = [ReactNativeConfig envFor:@"ETHEREUM_DEV_CLUSTER"];
NSString *logEnabled = [configJSON objectForKey:@"LogEnabled"];
NSString *logLevel = [configJSON objectForKey:@"LogLevel"];
char *configChars = GenerateConfig((char *)[networkDir UTF8String], (char *)[fleet UTF8String], networkId);
NSString *config = [NSString stringWithUTF8String: configChars];
configData = [config dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *resultingConfigJson = [NSJSONSerialization JSONObjectWithData:configData options:NSJSONReadingMutableContainers error:nil];
NSURL *networkDirUrl = [NSURL fileURLWithPath:networkDir];
NSURL *logUrl = [networkDirUrl URLByAppendingPathComponent:@"geth.log"];
[resultingConfigJson setValue:newKeystoreUrl.path forKey:@"KeyStoreDir"];
[resultingConfigJson setValue:logEnabled forKey:@"LogEnabled"];
[resultingConfigJson setValue:logUrl.path forKey:@"LogFile"];
[resultingConfigJson setValue:([logLevel length] == 0 ? [NSString stringWithUTF8String: "ERROR"] : logLevel) forKey:@"LogLevel"];
NSString *relativeDataDir = [configJSON objectForKey:@"DataDir"];
NSString *absDataDir = [rootUrl.path stringByAppendingString:relativeDataDir];
NSURL *absDataDirUrl = [NSURL fileURLWithPath:absDataDir];
NSURL *absLogUrl = [absDataDirUrl URLByAppendingPathComponent:@"geth.log"];
[configJSON setValue:absDataDirUrl.path forKey:@"DataDir"];
[configJSON setValue:absKeystoreUrl.path forKey:@"KeyStoreDir"];
[configJSON setValue:absLogUrl.path forKey:@"LogFile"];
[resultingConfigJson setValue:[NSNumber numberWithBool:YES] forKeyPath:@"WhisperConfig.LightClient"];
if(upstreamURL != nil) {
[resultingConfigJson setValue:[NSNumber numberWithBool:YES] forKeyPath:@"UpstreamConfig.Enabled"];
[resultingConfigJson setValue:upstreamURL forKeyPath:@"UpstreamConfig.URL"];
}
if(bootnodes != nil) {
[resultingConfigJson setValue:[NSNumber numberWithBool:YES] forKeyPath:@"ClusterConfig.Enabled"];
[resultingConfigJson setValue:bootnodes forKeyPath:@"ClusterConfig.BootNodes"];
}
if([fleet length] > 0) {
[resultingConfigJson setValue:fleet forKeyPath:@"ClusterConfig.Fleet"];
}
NSString *resultingConfig = [resultingConfigJson bv_jsonStringWithPrettyPrint:NO];
NSString *resultingConfig = [configJSON bv_jsonStringWithPrettyPrint:NO];
NSLog(@"node config %@", resultingConfig);
if(![fileManager fileExistsAtPath:networkDirUrl.path]) {
[fileManager createDirectoryAtPath:networkDirUrl.path withIntermediateDirectories:YES attributes:nil error:nil];
if(![fileManager fileExistsAtPath:absDataDirUrl.path]) {
[fileManager createDirectoryAtPath:absDataDirUrl.path withIntermediateDirectories:YES attributes:nil error:nil];
}
NSLog(@"logUrlPath %@", logUrl.path);
if(![fileManager fileExistsAtPath:logUrl.path]) {
NSLog(@"logUrlPath %@", absLogUrl.path);
if(![fileManager fileExistsAtPath:absLogUrl.path]) {
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:[NSNumber numberWithInt:511] forKey:NSFilePosixPermissions];
[fileManager createFileAtPath:logUrl.path contents:nil attributes:dict];
[fileManager createFileAtPath:absLogUrl.path contents:nil attributes:dict];
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^(void)
{
char *res = StartNode((char *) [resultingConfig UTF8String]);
NSLog(@"StartNode result %@", [NSString stringWithUTF8String: res]); });
NSLog(@"StartNode result %@", [NSString stringWithUTF8String: res]);
});
}
////////////////////////////////////////////////////////////////////

View File

@ -25,7 +25,7 @@
<artifactItem>
<groupId>status-im</groupId>
<artifactId>status-go-ios-simulator</artifactId>
<version>v0.14.1</version>
<version>v0.15.0</version>
<type>zip</type>
<overWrite>true</overWrite>
<outputDirectory>./</outputDirectory>

View File

@ -3,8 +3,8 @@
(def adjust-resize 16)
(defn start-node [config fleet]
(native-module/start-node config fleet))
(defn start-node [config]
(native-module/start-node config))
(defn stop-node []
(native-module/stop-node))

View File

@ -58,9 +58,9 @@
(when status
(call-module #(.stopNode status))))
(defn start-node [config fleet]
(defn start-node [config]
(when status
(call-module #(.startNode status config fleet))))
(call-module #(.startNode status config))))
(defonce account-creation? (atom false))

View File

@ -12,8 +12,7 @@
(vals $)
(map :address $))]
(if (seq bootnodes)
(assoc config :ClusterConfig {:Enabled true
:BootNodes bootnodes})
(assoc-in config [:ClusterConfig :BootNodes] bootnodes)
config)))
(defn- add-log-level [config log-level]
@ -24,11 +23,47 @@
:LogLevel log-level
:LogEnabled true)))
(defn get-network-genesis-hash-prefix
"returns the hex representation of the first 8 bytes of a network's genesis hash"
[network]
(case network
1 "d4e56740f876aef8"
3 "41941023680923e0"
4 "6341fd3daf94b748"
nil))
(defn get-les-topic
"returns discovery v5 topic derived from genesis of the provided network"
[network]
(let [les-discovery-identifier "LES2@"
hash-prefix (get-network-genesis-hash-prefix network)]
(when hash-prefix
(str les-discovery-identifier hash-prefix))))
(defn get-topics
[network]
(let [les-topic (get-les-topic network)]
(cond-> {"whisper" {:Min 2, :Max 2}}
les-topic (assoc les-topic {:Min 2, :Max 2}))))
(defn get-account-network [db address]
(get-in db [:accounts/accounts address :network]))
(defn- get-base-node-config [config]
(assoc config
:Name "StatusIM"))
(defn- pick-nodes
"Picks `limit` different nodes randomly from the list of nodes
if there is more than `limit` nodes in the list, otherwise return the list
of nodes"
[limit nodes]
(take limit (shuffle nodes)))
(defn- get-account-node-config [db address]
(let [accounts (get db :accounts/accounts)
current-fleet-key (fleet/current-fleet db address)
current-fleet (get fleet/fleets current-fleet-key)
{:keys [network
settings
bootnodes
@ -37,6 +72,24 @@
log-level (or (:log-level settings)
config/log-level-status-go)]
(cond-> (get-in networks [network :config])
:always
(get-base-node-config)
current-fleet
(assoc :NoDiscovery false
:ClusterConfig {:Enabled true
:Fleet (name current-fleet-key)
:BootNodes (pick-nodes 4 (vals (:boot current-fleet)))
:TrustedMailServers (pick-nodes 6 (vals (:mail current-fleet)))
:StaticNodes (pick-nodes 2 (vals (:whisper current-fleet)))})
:always
(assoc :WhisperConfig {:Enabled true
:LightClient true
:MinimumPoW 0.001
:EnableNTPSync true}
:RequireTopics (get-topics network))
(and
config/bootnodes-settings-enabled?
use-custom-bootnodes)
@ -47,6 +100,8 @@
(defn get-node-config [db network]
(-> (get-in (:networks/networks db) [network :config])
(get-base-node-config)
(assoc :NoDiscovery true)
(add-log-level config/log-level-status-go)))
(defn start
@ -59,11 +114,10 @@
node-config (if address
(get-account-node-config db address)
(get-node-config db network))
node-config-json (types/clj->json node-config)
fleet (name (fleet/current-fleet db address))]
node-config-json (types/clj->json node-config)]
(log/info "Node config: " node-config-json)
{:db (assoc db :network network)
:node/start [node-config-json fleet]})))
:node/start node-config-json})))
(defn restart
[]
@ -77,8 +131,8 @@
(re-frame/reg-fx
:node/start
(fn [[config fleet]]
(status/start-node config fleet)))
(fn [config]
(status/start-node config)))
(re-frame/reg-fx
:node/stop