Skip to content
Merged
2 changes: 1 addition & 1 deletion common/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ dependencies {
compile 'org.aspectj:aspectjrt:1.8.13'
compile 'org.aspectj:aspectjweaver:1.8.13'
compile 'org.aspectj:aspectjtools:1.8.13'
compile group: 'com.github.tronprotocol', name: 'libp2p', version: 'test-v0.2.19'
compile group: 'com.github.tronprotocol', name: 'libp2p', version: 'test-v0.2.20'
compile project(":protocol")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class CommonParameter {
public static CommonParameter PARAMETER = new CommonParameter();
@Setter
public static boolean ENERGY_LIMIT_HARD_FORK = false;
@Getter
@Parameter(names = {"-c", "--config"}, description = "Config file (default:config.conf)")
public String shellConfFileName = "";
@Getter
Expand Down Expand Up @@ -633,6 +634,14 @@ public class CommonParameter {
@Setter
public long dynamicEnergyMaxFactor = 0L;

@Getter
@Setter
public boolean dynamicConfigEnable;

@Getter
@Setter
public long dynamicConfigCheckInterval;

private static double calcMaxTimeRatio() {
//return max(2.0, min(5.0, 5 * 4.0 / max(Runtime.getRuntime().availableProcessors(), 1)));
return 5.0;
Expand Down
3 changes: 3 additions & 0 deletions common/src/main/java/org/tron/core/Constant.java
Original file line number Diff line number Diff line change
Expand Up @@ -365,4 +365,7 @@ public class Constant {
public static final String NODE_SHUTDOWN_BLOCK_COUNT = "node.shutdown.BlockCount";

public static final String BLOCK_CACHE_TIMEOUT = "node.blockCacheTimeout";

public static final String DYNAMIC_CONFIG_ENABLE = "node.dynamicConfig.enable";
public static final String DYNAMIC_CONFIG_CHECK_INTERVAL = "node.dynamicConfig.checkInterval";
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.tron.common.parameter.CommonParameter;
import org.tron.core.ChainBaseManager;
import org.tron.core.config.args.Args;
import org.tron.core.config.args.DynamicArgs;
import org.tron.core.consensus.ConsensusService;
import org.tron.core.db.Manager;
import org.tron.core.metrics.MetricsUtil;
Expand All @@ -32,6 +33,9 @@ public class ApplicationImpl implements Application {
@Autowired
private ConsensusService consensusService;

@Autowired
private DynamicArgs dynamicArgs;

@Override
public void setOptions(Args args) {
// not used
Expand Down Expand Up @@ -62,6 +66,7 @@ public void startup() {
}
consensusService.start();
MetricsUtil.init();
dynamicArgs.init();
}

@Override
Expand All @@ -80,6 +85,7 @@ public void shutdown() {
dbManager.stopRePushTriggerThread();
EventPluginLoader.getInstance().stopPlugin();
dbManager.stopFilterProcessThread();
dynamicArgs.close();
logger.info("******** end to shutdown ********");
FullNode.shutDownSign = true;
}
Expand Down
18 changes: 16 additions & 2 deletions framework/src/main/java/org/tron/core/config/args/Args.java
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,8 @@ public static void clearParam() {
PARAMETER.rateLimiterGlobalQps = 50000;
PARAMETER.rateLimiterGlobalIpQps = 10000;
PARAMETER.p2pDisable = false;
PARAMETER.dynamicConfigEnable = false;
PARAMETER.dynamicConfigCheckInterval = 600;
}

/**
Expand Down Expand Up @@ -1147,6 +1149,18 @@ public static void setParam(final String[] args, final String confFileName) {
Math.max(PARAMETER.dynamicEnergyMaxFactor, 0);
}

PARAMETER.dynamicConfigEnable = config.hasPath(Constant.DYNAMIC_CONFIG_ENABLE)
&& config.getBoolean(Constant.DYNAMIC_CONFIG_ENABLE);
if (config.hasPath(Constant.DYNAMIC_CONFIG_CHECK_INTERVAL)) {
PARAMETER.dynamicConfigCheckInterval
= config.getLong(Constant.DYNAMIC_CONFIG_CHECK_INTERVAL);
if (PARAMETER.dynamicConfigCheckInterval <= 0) {
PARAMETER.dynamicConfigCheckInterval = 600;
}
} else {
PARAMETER.dynamicConfigCheckInterval = 600;
}

logConfig();
}

Expand Down Expand Up @@ -1199,7 +1213,7 @@ private static RateLimiterInitialization getRateLimiterFromConfig(
return initialization;
}

private static List<InetSocketAddress> getInetSocketAddress(
public static List<InetSocketAddress> getInetSocketAddress(
final com.typesafe.config.Config config, String path, boolean filter) {
List<InetSocketAddress> ret = new ArrayList<>();
if (!config.hasPath(path)) {
Expand Down Expand Up @@ -1227,7 +1241,7 @@ private static List<InetSocketAddress> getInetSocketAddress(
return ret;
}

private static List<InetAddress> getInetAddress(
public static List<InetAddress> getInetAddress(
final com.typesafe.config.Config config, String path) {
List<InetAddress> ret = new ArrayList<>();
if (!config.hasPath(path)) {
Expand Down
114 changes: 114 additions & 0 deletions framework/src/main/java/org/tron/core/config/args/DynamicArgs.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package org.tron.core.config.args;

import static org.apache.commons.lang3.StringUtils.isNoneBlank;

import com.typesafe.config.Config;
import java.io.File;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.tron.common.parameter.CommonParameter;
import org.tron.core.Constant;
import org.tron.core.config.Configuration;
import org.tron.core.net.TronNetService;


@Slf4j(topic = "app")
@Component
public class DynamicArgs {
private final CommonParameter parameter = Args.getInstance();

private long lastModified = 0;

private ScheduledExecutorService reloadExecutor = Executors.newSingleThreadScheduledExecutor();

public void init() {
if (parameter.isDynamicConfigEnable()) {
logger.info("Start the dynamic loading configuration service");
long checkInterval = parameter.getDynamicConfigCheckInterval();
File config = getConfigFile();
if (config == null) {
return;
}
lastModified = config.lastModified();
reloadExecutor.scheduleWithFixedDelay(() -> {
try {
run();
} catch (Exception e) {
logger.error("Exception caught when reloading configuration", e);
}
}, 10, checkInterval, TimeUnit.SECONDS);
}
}

public void run() {
File config = getConfigFile();
if (config != null) {
long lastModifiedTime = config.lastModified();
if (lastModifiedTime > lastModified) {
reload();
lastModified = lastModifiedTime;
}
}
}

private File getConfigFile() {
String confFilePath;
if (isNoneBlank(parameter.getShellConfFileName())) {
confFilePath = parameter.getShellConfFileName();
} else {
confFilePath = Constant.TESTNET_CONF;
}

File confFile = new File(confFilePath);
if (!confFile.exists()) {
logger.warn("Configuration path is required! No such file {}", confFile);
return null;
}
return confFile;
}

public void reload() {
logger.debug("Reloading ... ");
Config config = Configuration.getByFileName(parameter.getShellConfFileName(),
Constant.TESTNET_CONF);

updateActiveNodes(config);

updateTrustNodes(config);
}

private void updateActiveNodes(Config config) {
List<InetSocketAddress> newActiveNodes =
Args.getInetSocketAddress(config, Constant.NODE_ACTIVE, true);
parameter.setActiveNodes(newActiveNodes);
List<InetSocketAddress> activeNodes = TronNetService.getP2pConfig().getActiveNodes();
activeNodes.clear();
activeNodes.addAll(newActiveNodes);
logger.debug("p2p active nodes : {}",
TronNetService.getP2pConfig().getActiveNodes().toString());
}

private void updateTrustNodes(Config config) {
List<InetAddress> newPassiveNodes = Args.getInetAddress(config, Constant.NODE_PASSIVE);
parameter.setPassiveNodes(newPassiveNodes);
List<InetAddress> trustNodes = TronNetService.getP2pConfig().getTrustNodes();
trustNodes.clear();
trustNodes.addAll(newPassiveNodes);
parameter.getActiveNodes().forEach(n -> trustNodes.add(n.getAddress()));
parameter.getFastForwardNodes().forEach(f -> trustNodes.add(f.getAddress()));
logger.debug("p2p trust nodes : {}",
TronNetService.getP2pConfig().getTrustNodes().toString());
}

public void close() {
logger.info("Closing the dynamic loading configuration service");
reloadExecutor.shutdown();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package org.tron.core.config.args;

import java.io.File;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.tron.common.application.TronApplicationContext;
import org.tron.common.parameter.CommonParameter;
import org.tron.common.utils.FileUtil;
import org.tron.common.utils.ReflectUtils;
import org.tron.core.Constant;
import org.tron.core.config.DefaultConfig;
import org.tron.core.net.TronNetService;
import org.tron.p2p.P2pConfig;

public class DynamicArgsTest {
protected TronApplicationContext context;
private DynamicArgs dynamicArgs;
private String dbPath = "output-dynamic-config-test";

@Before
public void init() {
Args.setParam(new String[]{"--output-directory", dbPath},
Constant.TEST_CONF);
context = new TronApplicationContext(DefaultConfig.class);
dynamicArgs = context.getBean(DynamicArgs.class);

}

@After
public void destroy() {
Args.clearParam();
context.destroy();
FileUtil.deleteDir(new File(dbPath));
}

@Test
public void start() {
CommonParameter parameter = Args.getInstance();
Assert.assertTrue(parameter.isDynamicConfigEnable());
Assert.assertEquals(600, parameter.getDynamicConfigCheckInterval());

dynamicArgs.init();
Assert.assertEquals(0, (long) ReflectUtils.getFieldObject(dynamicArgs, "lastModified"));

TronNetService tronNetService = context.getBean(TronNetService.class);
ReflectUtils.setFieldValue(tronNetService, "p2pConfig", new P2pConfig());
File config = new File(Constant.TESTNET_CONF);
if (!config.exists()) {
try {
config.createNewFile();
} catch (Exception e) {
return;
}
dynamicArgs.run();
try {
config.delete();
} catch (Exception e) {
return;
}
}
try {
dynamicArgs.reload();
} catch (Exception e) {
// no need to deal with
}

dynamicArgs.close();
}
}
5 changes: 4 additions & 1 deletion framework/src/test/resources/config-test.conf
Original file line number Diff line number Diff line change
Expand Up @@ -340,4 +340,7 @@ vm = {
}
committee = {
allowCreationOfContracts = 1 //mainnet:0 (reset by committee),test:1
}
}

node.dynamicConfig.enable = true
node.dynamicConfig.checkInterval = 0