From bd989fa52a3b2e9c15ade5d4570809aa37d5f13d Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Tue, 12 May 2026 17:50:20 +0800 Subject: [PATCH 01/10] optimze binding --- .../common/parameter/CommonParameter.java | 3 - .../core/config/args/CommitteeConfig.java | 64 ++---- .../tron/core/config/args/EventConfig.java | 67 ++---- .../org/tron/core/config/args/NodeConfig.java | 208 +++++++----------- .../org/tron/core/config/args/Overlay.java | 22 -- .../org/tron/core/config/args/Storage.java | 4 - .../tron/core/config/args/StorageConfig.java | 16 +- .../org/tron/core/config/args/VmConfig.java | 33 +-- common/src/main/resources/reference.conf | 19 +- .../core/config/args/CommitteeConfigTest.java | 8 +- .../tron/core/config/args/VmConfigTest.java | 2 +- .../java/org/tron/core/config/args/Args.java | 4 +- .../java/org/tron/common/ParameterTest.java | 1 - .../tron/core/config/args/OverlayTest.java | 40 ---- 14 files changed, 145 insertions(+), 346 deletions(-) delete mode 100644 common/src/main/java/org/tron/core/config/args/Overlay.java delete mode 100644 framework/src/test/java/org/tron/core/config/args/OverlayTest.java diff --git a/common/src/main/java/org/tron/common/parameter/CommonParameter.java b/common/src/main/java/org/tron/common/parameter/CommonParameter.java index 3fe1e878ffb..e1dc2f1019f 100644 --- a/common/src/main/java/org/tron/common/parameter/CommonParameter.java +++ b/common/src/main/java/org/tron/common/parameter/CommonParameter.java @@ -14,7 +14,6 @@ import org.tron.common.logsfilter.FilterQuery; import org.tron.common.setting.RocksDbSettings; import org.tron.core.Constant; -import org.tron.core.config.args.Overlay; import org.tron.core.config.args.SeedNode; import org.tron.core.config.args.Storage; import org.tron.p2p.P2pConfig; @@ -432,8 +431,6 @@ public class CommonParameter { @Getter public Storage storage; @Getter - public Overlay overlay; - @Getter public SeedNode seedNode; @Getter public EventPluginConfig eventPluginConfig; diff --git a/common/src/main/java/org/tron/core/config/args/CommitteeConfig.java b/common/src/main/java/org/tron/core/config/args/CommitteeConfig.java index 5cd9de842a0..0bd9e7e0e13 100644 --- a/common/src/main/java/org/tron/core/config/args/CommitteeConfig.java +++ b/common/src/main/java/org/tron/core/config/args/CommitteeConfig.java @@ -2,6 +2,7 @@ import com.typesafe.config.Config; import com.typesafe.config.ConfigBeanFactory; +import com.typesafe.config.ConfigValue; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; @@ -35,29 +36,10 @@ public class CommitteeConfig { private long allowProtoFilterNum = 0; private long allowAccountStateRoot = 0; private long changedDelegation = 0; - // NON-STANDARD NAMING: "allowPBFT" and "pBFTExpireNum" in config.conf contain - // consecutive uppercase letters ("PBFT"), which violates JavaBean naming convention. - // ConfigBeanFactory derives config keys from setter names using JavaBean rules: - // setPBFTExpireNum -> property "PBFTExpireNum" (capital P, per JavaBean spec) - // but config.conf uses "pBFTExpireNum" (lowercase p) -> mismatch -> binding fails. - // - // These two fields are excluded from auto-binding and handled manually in fromConfig(). - // TODO: Rename config keys to standard camelCase (allowPbft, pbftExpireNum) when - // PBFT feature is enabled and a breaking config change is acceptable. - @Getter(lombok.AccessLevel.NONE) - @Setter(lombok.AccessLevel.NONE) - private long allowPBFT = 0; - @Getter(lombok.AccessLevel.NONE) - @Setter(lombok.AccessLevel.NONE) - private long pBFTExpireNum = 20; - - // Only getters are exposed. No public setters — ConfigBeanFactory scans public - // setters via reflection and would derive key "PBFTExpireNum" / "AllowPBFT" - // (JavaBean uppercase rule), which does not match config keys "pBFTExpireNum" - // / "allowPBFT" and would throw. Values are assigned to fields directly in - // fromConfig() below. - public long getAllowPBFT() { return allowPBFT; } - public long getPBFTExpireNum() { return pBFTExpireNum; } + // "allowPBFT" / "pBFTExpireNum" in config.conf use non-standard casing; they are + // remapped to standard camelCase by normalizeNonStandardKeys() before binding. + private long allowPbft = 0; + private long pbftExpireNum = 20; private long allowTvmFreeze = 0; private long allowTvmVote = 0; private long allowTvmLondon = 0; @@ -85,32 +67,30 @@ public class CommitteeConfig { private long dynamicEnergyMaxFactor = 0; // proposalExpireTime is NOT a committee field — it's in block.* and handled by BlockConfig - // Defaults come from reference.conf (loaded globally via Configuration.java) - - /** - * Create CommitteeConfig from the "committee" section of the application config. - * - * Note: allowPBFT and pBFTExpireNum have non-standard JavaBean naming (consecutive - * uppercase letters) which causes ConfigBeanFactory key mismatch. These two fields - * are excluded from automatic binding and handled manually after. - */ - private static final String PBFT_EXPIRE_NUM_KEY = "pBFTExpireNum"; - private static final String ALLOW_PBFT_KEY = "allowPBFT"; - public static CommitteeConfig fromConfig(Config config) { - Config section = config.getConfig("committee"); - + Config section = normalizeNonStandardKeys(config.getConfig("committee")); CommitteeConfig cc = ConfigBeanFactory.create(section, CommitteeConfig.class); - // Ensure the manually-named fields get the right values from the original keys - cc.allowPBFT = section.hasPath(ALLOW_PBFT_KEY) ? section.getLong(ALLOW_PBFT_KEY) : 0; - cc.pBFTExpireNum = section.hasPath(PBFT_EXPIRE_NUM_KEY) - ? section.getLong(PBFT_EXPIRE_NUM_KEY) : 20; - cc.postProcess(); return cc; } + // "allowPBFT" and "pBFTExpireNum" use non-standard casing that JavaBean Introspector + // cannot derive correctly (setPBFTExpireNum -> property "PBFTExpireNum", not "pBFTExpireNum"). + // Remap them to standard camelCase keys so ConfigBeanFactory binds them normally. + // Config is immutable; withValue() returns a new object. + private static Config normalizeNonStandardKeys(Config section) { + if (section.hasPath("allowPBFT")) { + ConfigValue v = section.getValue("allowPBFT"); + section = section.withValue("allowPbft", v); + } + if (section.hasPath("pBFTExpireNum")) { + ConfigValue v = section.getValue("pBFTExpireNum"); + section = section.withValue("pbftExpireNum", v); + } + return section; + } + private void postProcess() { // clamp unfreezeDelayDays to 0-365 if (unfreezeDelayDays < 0) { diff --git a/common/src/main/java/org/tron/core/config/args/EventConfig.java b/common/src/main/java/org/tron/core/config/args/EventConfig.java index 43707956845..4df10ea3e7e 100644 --- a/common/src/main/java/org/tron/core/config/args/EventConfig.java +++ b/common/src/main/java/org/tron/core/config/args/EventConfig.java @@ -25,19 +25,15 @@ public class EventConfig { private String server = ""; private String dbconfig = ""; private boolean contractParse = true; - @Getter(lombok.AccessLevel.NONE) + // "native" is a Java reserved word; config key cannot match field name directly. + // @Setter(NONE) prevents ConfigBeanFactory from requiring a "nativeQueue" key. @Setter(lombok.AccessLevel.NONE) private NativeConfig nativeQueue = new NativeConfig(); - public NativeConfig getNativeQueue() { return nativeQueue; } - // Topics list has optional fields (ethCompatible, redundancy, solidified) that - // not all items have. ConfigBeanFactory requires all bean fields to exist in config. - // Excluded from auto-binding, read manually in fromConfig(). - @Getter(lombok.AccessLevel.NONE) + // Topics list items have optional fields; excluded from auto-binding. + // @Setter(NONE) prevents ConfigBeanFactory from requiring a "topics" key. @Setter(lombok.AccessLevel.NONE) private List topics = new ArrayList<>(); - - public List getTopics() { return topics; } private FilterConfig filter = new FilterConfig(); @Getter @@ -70,62 +66,39 @@ public static class FilterConfig { // Defaults come from reference.conf (loaded globally via Configuration.java) + // TopicConfig fields are optional per item; this fallback ensures all keys exist + // for ConfigBeanFactory binding. Values must match TopicConfig field defaults. + private static final Config TOPIC_DEFAULTS = ConfigFactory.parseString( + "triggerName=\"\", enable=false, topic=\"\", " + + "solidified=false, ethCompatible=false, redundancy=false"); + /** * Create EventConfig from the "event.subscribe" section of the application config. * - *

Note: HOCON key "native" is a Java reserved word, so the bean field is named - * "nativeQueue" but config key is "native". We handle this manually after binding. + *

"native" is a Java reserved word, so the field is named "nativeQueue" and the + * sub-section is read directly after binding. "topics" items may omit optional fields; + * TOPIC_DEFAULTS provides fallback values so ConfigBeanFactory can bind each item. */ public static EventConfig fromConfig(Config config) { Config section = config.getConfig("event.subscribe"); - // "native" is a Java reserved word, "topics" has optional fields per item — - // strip both before binding, read manually String nativeKey = "native"; String topicsKey = "topics"; Config bindable = section.withoutPath(nativeKey).withoutPath(topicsKey) .withoutPath("topicDefaults"); EventConfig ec = ConfigBeanFactory.create(bindable, EventConfig.class); - // manually bind "native" sub-section - Config nativeSection = section.hasPath(nativeKey) - ? section.getConfig(nativeKey) : ConfigFactory.empty(); - ec.nativeQueue = new NativeConfig(); - if (nativeSection.hasPath("useNativeQueue")) { - ec.nativeQueue.useNativeQueue = nativeSection.getBoolean("useNativeQueue"); - } - if (nativeSection.hasPath("bindport")) { - ec.nativeQueue.bindport = nativeSection.getInt("bindport"); - } - if (nativeSection.hasPath("sendqueuelength")) { - ec.nativeQueue.sendqueuelength = nativeSection.getInt("sendqueuelength"); - } + // "native" sub-section: bind via ConfigBeanFactory when present, use defaults otherwise + ec.nativeQueue = section.hasPath(nativeKey) + ? ConfigBeanFactory.create(section.getConfig(nativeKey), NativeConfig.class) + : new NativeConfig(); - // manually bind topics — each item may have optional fields + // topics: withFallback fills optional fields so ConfigBeanFactory can bind each item if (section.hasPath(topicsKey)) { ec.topics = new ArrayList<>(); for (com.typesafe.config.ConfigObject obj : section.getObjectList(topicsKey)) { - Config tc = obj.toConfig(); - TopicConfig topic = new TopicConfig(); - if (tc.hasPath("triggerName")) { - topic.triggerName = tc.getString("triggerName"); - } - if (tc.hasPath("enable")) { - topic.enable = tc.getBoolean("enable"); - } - if (tc.hasPath("topic")) { - topic.topic = tc.getString("topic"); - } - if (tc.hasPath("solidified")) { - topic.solidified = tc.getBoolean("solidified"); - } - if (tc.hasPath("ethCompatible")) { - topic.ethCompatible = tc.getBoolean("ethCompatible"); - } - if (tc.hasPath("redundancy")) { - topic.redundancy = tc.getBoolean("redundancy"); - } - ec.topics.add(topic); + ec.topics.add(ConfigBeanFactory.create( + obj.toConfig().withFallback(TOPIC_DEFAULTS), TopicConfig.class)); } } diff --git a/common/src/main/java/org/tron/core/config/args/NodeConfig.java b/common/src/main/java/org/tron/core/config/args/NodeConfig.java index ea9f26a06a0..f312f16f740 100644 --- a/common/src/main/java/org/tron/core/config/args/NodeConfig.java +++ b/common/src/main/java/org/tron/core/config/args/NodeConfig.java @@ -29,22 +29,17 @@ public class NodeConfig { private int syncFetchBatchNum = 2000; private int maxPendingBlockSize = 500; private int validateSignThreadNum = 0; // 0 = auto (availableProcessors) - private int maxConnections = 30; + private int maxConnections = 30; // legacy key maxActiveNodes private int minConnections = 8; private int minActiveConnections = 3; - private int maxConnectionsWithSameIp = 2; + private int maxConnectionsWithSameIp = 2; // legacy key maxActiveNodesWithSameIp private int maxHttpConnectNumber = 50; private int minParticipationRate = 0; private boolean openPrintLog = true; private boolean openTransactionSort = false; private int maxTps = 1000; private int maxBlockInvPerSecond = 10; - // Config key "isOpenFullTcpDisconnect" cannot auto-bind — read manually in fromConfig() - @Getter(lombok.AccessLevel.NONE) - @Setter(lombok.AccessLevel.NONE) - private boolean isOpenFullTcpDisconnect = false; - - public boolean isOpenFullTcpDisconnect() { return isOpenFullTcpDisconnect; } + private boolean openFullTcpDisconnect = false; //rename key // node.discovery.* — HOCON merges into node { discovery { ... } }, auto-bound private DiscoveryConfig discovery = new DiscoveryConfig(); @@ -52,24 +47,28 @@ public class NodeConfig { @Setter(lombok.AccessLevel.NONE) private String externalIP = ""; - // node.shutdown.* uses PascalCase keys (BlockTime, BlockHeight, BlockCount) - // that don't match JavaBean naming. Excluded, read manually. - @Getter(lombok.AccessLevel.NONE) + // node.shutdown.* uses PascalCase nested keys (shutdown.BlockTime, etc.). + // These are optional (not in reference.conf), so @Setter(NONE) prevents ConfigBeanFactory + // from requiring the keys; values are read manually in fromConfig(). @Setter(lombok.AccessLevel.NONE) private String shutdownBlockTime = ""; - @Getter(lombok.AccessLevel.NONE) @Setter(lombok.AccessLevel.NONE) private long shutdownBlockHeight = -1; - @Getter(lombok.AccessLevel.NONE) @Setter(lombok.AccessLevel.NONE) private long shutdownBlockCount = -1; - public boolean isDiscoveryEnable() { return discovery.isEnable(); } - public boolean isDiscoveryPersist() { return discovery.isPersist(); } - public String getDiscoveryExternalIp() { return externalIP; } - public String getShutdownBlockTime() { return shutdownBlockTime; } - public long getShutdownBlockHeight() { return shutdownBlockHeight; } - public long getShutdownBlockCount() { return shutdownBlockCount; } + public boolean isDiscoveryEnable() { + return discovery.isEnable(); + } + + public boolean isDiscoveryPersist() { + return discovery.isPersist(); + } + + public String getDiscoveryExternalIp() { + return externalIP; + } + private int inactiveThreshold = 600; private boolean metricsEnable = false; private int blockProducedTimeOut = 50; @@ -90,14 +89,14 @@ public class NodeConfig { private boolean unsolidifiedBlockCheck = false; private int maxUnsolidifiedBlocks = 54; private String zenTokenId = "000000"; - @Getter(lombok.AccessLevel.NONE) + // allowShieldedTransactionApi is optional (commented out in reference.conf) and has a + // legacy key fallback; @Setter(NONE) prevents ConfigBeanFactory from requiring the key. @Setter(lombok.AccessLevel.NONE) private boolean allowShieldedTransactionApi = false; + + //deprecate key private double activeConnectFactor = 0.1; private double connectFactor = 0.6; - // Legacy alias `maxActiveNodesWithSameIp` has no bean field: we only peek at it via - // section.hasPath() below. Keeping it field-less means reference.conf doesn't have to - // ship a default that would otherwise mask the modern `maxConnectionsWithSameIp` key. // ---- Sub-beans matching config's dot-notation nested structure ---- private ListenConfig listen = new ListenConfig(); @@ -105,11 +104,21 @@ public class NodeConfig { private SolidityConfig solidity = new SolidityConfig(); // Convenience getters for backward compatibility with applyNodeConfig - public int getListenPort() { return listen.getPort(); } - public int getFetchBlockTimeout() { return fetchBlock.getTimeout(); } - public int getSolidityThreads() { return solidity.getThreads(); } - public int getValidContractProtoThreads() { return validContractProto.getThreads(); } - public boolean isAllowShieldedTransactionApi() { return allowShieldedTransactionApi; } + public int getListenPort() { + return listen.getPort(); + } + + public int getFetchBlockTimeout() { + return fetchBlock.getTimeout(); + } + + public int getSolidityThreads() { + return solidity.getThreads(); + } + + public int getValidContractProtoThreads() { + return validContractProto.getThreads(); + } // ---- List fields (manually read) ---- private List active = new ArrayList<>(); @@ -136,6 +145,7 @@ public class NodeConfig { @Getter @Setter public static class DiscoveryConfig { + private boolean enable = false; private boolean persist = false; } @@ -143,36 +153,42 @@ public static class DiscoveryConfig { @Getter @Setter public static class ListenConfig { + private int port = 18888; } @Getter @Setter public static class FetchBlockConfig { + private int timeout = 500; } @Getter @Setter public static class SolidityConfig { + private int threads = 0; // 0 = auto (availableProcessors) } @Getter @Setter public static class ValidContractProtoConfig { + private int threads = 0; // 0 = auto (availableProcessors) } @Getter @Setter public static class P2pConfig { + private int version = 11111; } @Getter @Setter public static class HttpConfig { + private boolean fullNodeEnable = true; private int fullNodePort = 8090; private boolean solidityEnable = true; @@ -180,63 +196,21 @@ public static class HttpConfig { private long maxMessageSize = 4194304; private int maxNestingDepth = 100; private int maxTokenCount = 100_000; - // PBFT fields — handled manually (same naming issue as CommitteeConfig) - // Default must match CommonParameter.pBFTHttpEnable = true - @Getter(lombok.AccessLevel.NONE) - @Setter(lombok.AccessLevel.NONE) private boolean pBFTEnable = true; - @Getter(lombok.AccessLevel.NONE) - @Setter(lombok.AccessLevel.NONE) private int pBFTPort = 8092; - - public boolean isPBFTEnable() { - return pBFTEnable; - } - - public void setPBFTEnable(boolean v) { - this.pBFTEnable = v; - } - - public int getPBFTPort() { - return pBFTPort; - } - - public void setPBFTPort(int v) { - this.pBFTPort = v; - } } @Getter @Setter public static class RpcConfig { + private boolean enable = true; private int port = 50051; private boolean solidityEnable = true; private int solidityPort = 50061; - // PBFT fields — handled manually - @Getter(lombok.AccessLevel.NONE) - @Setter(lombok.AccessLevel.NONE) private boolean pBFTEnable = true; - @Getter(lombok.AccessLevel.NONE) - @Setter(lombok.AccessLevel.NONE) private int pBFTPort = 50071; - public boolean isPBFTEnable() { - return pBFTEnable; - } - - public void setPBFTEnable(boolean v) { - this.pBFTEnable = v; - } - - public int getPBFTPort() { - return pBFTPort; - } - - public void setPBFTPort(int v) { - this.pBFTPort = v; - } - private int thread = 0; private int maxConcurrentCallsPerConnection = 2147483647; private int flowControlWindow = 1048576; @@ -254,34 +228,14 @@ public void setPBFTPort(int v) { @Getter @Setter public static class JsonRpcConfig { + private boolean httpFullNodeEnable = false; private int httpFullNodePort = 8545; private boolean httpSolidityEnable = false; private int httpSolidityPort = 8555; - // PBFT fields — handled manually - @Getter(lombok.AccessLevel.NONE) - @Setter(lombok.AccessLevel.NONE) private boolean httpPBFTEnable = false; - @Getter(lombok.AccessLevel.NONE) - @Setter(lombok.AccessLevel.NONE) private int httpPBFTPort = 8565; - public boolean isHttpPBFTEnable() { - return httpPBFTEnable; - } - - public void setHttpPBFTEnable(boolean v) { - this.httpPBFTEnable = v; - } - - public int getHttpPBFTPort() { - return httpPBFTPort; - } - - public void setHttpPBFTPort(int v) { - this.httpPBFTPort = v; - } - private int maxBlockRange = 5000; private int maxSubTopics = 1000; private int maxBlockFilterNum = 50000; @@ -295,6 +249,7 @@ public void setHttpPBFTPort(int v) { @Getter @Setter public static class NodeBackupConfig { + private int priority = 0; private int port = 10001; private int keepAliveInterval = 3000; @@ -304,6 +259,7 @@ public static class NodeBackupConfig { @Getter @Setter public static class DynamicConfigSection { + private boolean enable = false; private long checkInterval = 600; } @@ -311,6 +267,7 @@ public static class DynamicConfigSection { @Getter @Setter public static class DnsConfig { + private List treeUrls = new ArrayList<>(); private boolean publish = false; private String dnsDomain = ""; @@ -327,40 +284,20 @@ public static class DnsConfig { private String awsHostZoneId = ""; } - // Defaults come from reference.conf (loaded globally via Configuration.java) - - // =========================================================================== - // Factory method - // =========================================================================== - /** * Create NodeConfig from the "node" section of the application config. * - *

Dot-notation keys (listen.port, fetchBlock.timeout, - * solidity.threads) become nested HOCON objects and cannot be auto-bound to flat - * Java fields. They are read manually after ConfigBeanFactory binding. - * - *

PBFT-named fields in http, rpc, and jsonrpc sub-beans have the same JavaBean - * naming issue as CommitteeConfig and are patched manually. - * *

List fields (active, passive, fastForward, disabledApi) are read manually * since ConfigBeanFactory expects typed bean lists, not string lists. */ public static NodeConfig fromConfig(Config config) { - // Normalize human-readable size values (e.g. "4m") to numeric bytes so - // ConfigBeanFactory's primitive int/long binding succeeds; same step - // enforces non-negative and <= Integer.MAX_VALUE before bean creation - // so failures point at the user-facing config path. - Config section = normalizeMaxMessageSizes(config).getConfig("node"); + Config section = normalizeNonStandardKeys( + normalizeMaxMessageSizes(config).getConfig("node")); // Auto-bind all fields and sub-beans. ConfigBeanFactory fails fast with a - // descriptive path on any `= null` value — external configs that use the - // HOCON null keyword should fix their config rather than rely on silent coercion. + // descriptive path on any `= null` value NodeConfig nc = ConfigBeanFactory.create(section, NodeConfig.class); - // isOpenFullTcpDisconnect: boolean "is" prefix breaks JavaBean pairing - nc.isOpenFullTcpDisconnect = getBool(section, "isOpenFullTcpDisconnect", false); - // --- Legacy key fallbacks (backward compatibility) --- // node.maxActiveNodes (old) -> maxConnections (new) if (section.hasPath("maxActiveNodes")) { @@ -394,14 +331,13 @@ public static NodeConfig fromConfig(Config config) { + "Please use [node.allowShieldedTransactionApi] instead."); } - // node.shutdown.* — PascalCase keys (BlockTime, BlockHeight), cannot auto-bind - nc.shutdownBlockTime = config.hasPath("node.shutdown.BlockTime") - ? config.getString("node.shutdown.BlockTime") : ""; - nc.shutdownBlockHeight = config.hasPath("node.shutdown.BlockHeight") - ? config.getLong("node.shutdown.BlockHeight") : -1; - nc.shutdownBlockCount = config.hasPath("node.shutdown.BlockCount") - ? config.getLong("node.shutdown.BlockCount") : -1; - + // node.shutdown.* — optional PascalCase nested keys, not in reference.conf by default + nc.shutdownBlockTime = section.hasPath("shutdown.BlockTime") + ? section.getString("shutdown.BlockTime") : ""; + nc.shutdownBlockHeight = section.hasPath("shutdown.BlockHeight") + ? section.getLong("shutdown.BlockHeight") : -1; + nc.shutdownBlockCount = section.hasPath("shutdown.BlockCount") + ? section.getLong("shutdown.BlockCount") : -1; nc.postProcess(); return nc; @@ -482,12 +418,10 @@ private void postProcess() { agreeNodeCount = MAX_ACTIVE_WITNESS_NUM; } - // dynamicConfigCheckInterval: minimum 600 if (dynamicConfig.checkInterval <= 0) { dynamicConfig.checkInterval = 600; } - // maxTrxCacheSize: minimum 2000 if (maxTrxCacheSize < 2000) { maxTrxCacheSize = 2000; } @@ -513,11 +447,25 @@ private static String getString(Config config, String path, String defaultValue) return config.hasPath(path) ? config.getString(path) : defaultValue; } - // Pre-normalize size paths so ConfigBeanFactory's primitive int/long binding succeeds - // for human-readable values like "4m" / "128MB". For each maxMessageSize key, parse - // via getMemorySize, validate non-negative and <= Integer.MAX_VALUE, and write the - // numeric byte value back into the Config tree. Validation errors propagate before - // bean creation so the failure points at the user-facing config path. + /** + * "isOpenFullTcpDisconnect" config key has an "is" prefix that the JavaBean Introspector + * strips from boolean getter names, so the derived property is "openFullTcpDisconnect" + */ + private static Config normalizeNonStandardKeys(Config section) { + if (section.hasPath("isOpenFullTcpDisconnect")) { + section = section.withValue("openFullTcpDisconnect", + section.getValue("isOpenFullTcpDisconnect")); + } + return section; + } + + /** + * Pre-normalize size paths so ConfigBeanFactory's primitive int/long binding succeeds + * for human-readable values like "4m" / "128MB". For each maxMessageSize key, parse + * via getMemorySize, validate non-negative and <= Integer.MAX_VALUE, and write the + * numeric byte value back into the Config tree. Validation errors propagate before + * bean creation so the failure points at the user-facing config path. + */ private static Config normalizeMaxMessageSizes(Config config) { String[] paths = { "node.rpc.maxMessageSize", diff --git a/common/src/main/java/org/tron/core/config/args/Overlay.java b/common/src/main/java/org/tron/core/config/args/Overlay.java deleted file mode 100644 index bdaa40724c7..00000000000 --- a/common/src/main/java/org/tron/core/config/args/Overlay.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.tron.core.config.args; - -import lombok.Getter; -import org.apache.commons.lang3.Range; - -public class Overlay { - - @Getter - private int port; - - /** - * Monitor port number. - */ - public void setPort(final int port) { - Range range = Range.between(0, 65535); - if (!range.contains(port)) { - throw new IllegalArgumentException("Port(" + port + ") must in [0, 65535]"); - } - - this.port = port; - } -} diff --git a/common/src/main/java/org/tron/core/config/args/Storage.java b/common/src/main/java/org/tron/core/config/args/Storage.java index 782a0ef07c8..64a9efab7f1 100644 --- a/common/src/main/java/org/tron/core/config/args/Storage.java +++ b/common/src/main/java/org/tron/core/config/args/Storage.java @@ -201,10 +201,6 @@ private static void applyPropertyOptions(StorageConfig.PropertyConfig pc, Option dbOptions.maxOpenFiles(pc.getMaxOpenFiles()); } - - /** - * Set propertyMap of Storage object from Config via StorageConfig bean. - */ /** * Set propertyMap from StorageConfig bean list. No Config parameter needed. */ diff --git a/common/src/main/java/org/tron/core/config/args/StorageConfig.java b/common/src/main/java/org/tron/core/config/args/StorageConfig.java index 3d7046ebae2..9376dd1df1d 100644 --- a/common/src/main/java/org/tron/core/config/args/StorageConfig.java +++ b/common/src/main/java/org/tron/core/config/args/StorageConfig.java @@ -39,30 +39,20 @@ public class StorageConfig { // Raw storage config sub-tree, kept for setCacheStrategies/setDbRoots which // have dynamic keys that ConfigBeanFactory cannot bind. - @Getter(lombok.AccessLevel.NONE) + // @Setter(NONE): not a config key, assigned directly in fromConfig(). @Setter(lombok.AccessLevel.NONE) private Config rawStorageConfig; - public Config getRawStorageConfig() { - return rawStorageConfig; - } - // LevelDB per-database option overrides (default, defaultM, defaultL). - // Excluded from auto-binding: optional partial overrides that ConfigBeanFactory cannot handle. - @Getter(lombok.AccessLevel.NONE) + // @Setter(NONE): optional keys commented out in reference.conf; ConfigBeanFactory + // would throw if it required them. Values are assigned in fromConfig(). @Setter(lombok.AccessLevel.NONE) private DbOptionOverride defaultDbOption; - @Getter(lombok.AccessLevel.NONE) @Setter(lombok.AccessLevel.NONE) private DbOptionOverride defaultMDbOption; - @Getter(lombok.AccessLevel.NONE) @Setter(lombok.AccessLevel.NONE) private DbOptionOverride defaultLDbOption; - public DbOptionOverride getDefaultDbOption() { return defaultDbOption; } - public DbOptionOverride getDefaultMDbOption() { return defaultMDbOption; } - public DbOptionOverride getDefaultLDbOption() { return defaultLDbOption; } - @Getter @Setter public static class DbConfig { diff --git a/common/src/main/java/org/tron/core/config/args/VmConfig.java b/common/src/main/java/org/tron/core/config/args/VmConfig.java index 00ba85aa6cc..3ff1136f33e 100644 --- a/common/src/main/java/org/tron/core/config/args/VmConfig.java +++ b/common/src/main/java/org/tron/core/config/args/VmConfig.java @@ -2,24 +2,18 @@ import com.typesafe.config.Config; import com.typesafe.config.ConfigBeanFactory; -import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; /** * VM configuration bean. Field names match config.conf keys under the "vm" section. - * Most fields are bound automatically via ConfigBeanFactory; opt-in fields that - * must stay absent from reference.conf are bound manually after hasPath checks. */ @Slf4j @Getter @Setter public class VmConfig { - private static final String CONSTANT_CALL_TIMEOUT_MS_KEY = "constantCallTimeoutMs"; - static final long MAX_CONSTANT_CALL_TIMEOUT_MS = Long.MAX_VALUE / 1_000L; - private boolean supportConstant = false; private long maxEnergyLimitForConstant = 100_000_000L; private int lruCacheSize = 500; @@ -32,10 +26,6 @@ public class VmConfig { private boolean saveInternalTx = false; private boolean saveFeaturedInternalTx = false; private boolean saveCancelAllUnfreezeV2Details = false; - // Excluded from ConfigBeanFactory binding (no setter): the property is - // intentionally absent from reference.conf so {@code Config#hasPath} alone - // signals operator opt-in. Bound manually in {@link #fromConfig}. - @Setter(AccessLevel.NONE) private long constantCallTimeoutMs = 0L; /** @@ -46,11 +36,11 @@ public class VmConfig { public static VmConfig fromConfig(Config config) { Config vmSection = config.getConfig("vm"); VmConfig vmConfig = ConfigBeanFactory.create(vmSection, VmConfig.class); - vmConfig.postProcess(vmSection); + vmConfig.postProcess(); return vmConfig; } - private void postProcess(Config vmSection) { + private void postProcess() { // clamp maxEnergyLimitForConstant if (maxEnergyLimitForConstant < 3_000_000L) { maxEnergyLimitForConstant = 3_000_000L; @@ -71,22 +61,9 @@ private void postProcess(Config vmSection) { + "vm.saveInternalTx or vm.saveFeaturedInternalTx is off."); } - // constantCallTimeoutMs is excluded from ConfigBeanFactory binding (no - // setter) and intentionally absent from reference.conf, so hasPath alone - // tells us whether the operator opted in. Only positive values that can be - // safely converted to microseconds are valid. - if (vmSection.hasPath(CONSTANT_CALL_TIMEOUT_MS_KEY)) { - long value = vmSection.getLong(CONSTANT_CALL_TIMEOUT_MS_KEY); - if (value <= 0L) { - throw new IllegalArgumentException( - "vm.constantCallTimeoutMs must be > 0 when configured, got " + value); - } - if (value > MAX_CONSTANT_CALL_TIMEOUT_MS) { - throw new IllegalArgumentException( - "vm.constantCallTimeoutMs must be <= " + MAX_CONSTANT_CALL_TIMEOUT_MS - + " to fit VM deadline conversion, got " + value); - } - constantCallTimeoutMs = value; + if (constantCallTimeoutMs < 0 || constantCallTimeoutMs > Long.MAX_VALUE / 1000) { + throw new IllegalArgumentException("vm.constantCallTimeoutMs must be >= 0 and <= " + + Long.MAX_VALUE / 1000 + " to fit VM deadline conversion, got " + constantCallTimeoutMs); } } } diff --git a/common/src/main/resources/reference.conf b/common/src/main/resources/reference.conf index 1e68da051e0..e704939893e 100644 --- a/common/src/main/resources/reference.conf +++ b/common/src/main/resources/reference.conf @@ -25,18 +25,16 @@ # Key naming rules (required for ConfigBeanFactory auto-binding): # - Use standard camelCase: maxConnections, syncFetchBatchNum, etc. # -# Keys that cannot auto-bind (handled manually in bean fromConfig): +# Keys that cannot auto-bind (handled via normalizeNonStandardKeys() or manual reads): # -# 1. committee.pBFTExpireNum — lowercase "p" then uppercase "BFT": -# setPBFTExpireNum -> property "PBFTExpireNum" (capital P), -# mismatches config key "pBFTExpireNum" (lowercase p). +# 1. committee.pBFTExpireNum / committee.allowPBFT — normalized to camelCase in +# CommitteeConfig.normalizeNonStandardKeys() before ConfigBeanFactory binding. # -# 2. node.isOpenFullTcpDisconnect — boolean "is" prefix: -# getter isOpenFullTcpDisconnect() -> property "openFullTcpDisconnect", -# mismatches config key "isOpenFullTcpDisconnect". +# 2. node.isOpenFullTcpDisconnect — normalized to "openFullTcpDisconnect" in +# NodeConfig.normalizeNonStandardKeys() before ConfigBeanFactory binding. # -# 3. node.shutdown.BlockTime/BlockHeight/BlockCount — PascalCase keys: -# setBlockTime -> property "blockTime", mismatches "BlockTime". +# 3. node.shutdown.BlockTime/BlockHeight/BlockCount — optional PascalCase nested keys; +# read manually in NodeConfig.fromConfig() after ConfigBeanFactory binding. # # ============================================================================= @@ -701,6 +699,9 @@ vm = { # Max retry time for executing transaction in estimating energy estimateEnergyMaxRetry = 3 + + # Specify constant call timeout + constantCallTimeoutMs = 0 } # Governance proposal toggle parameters. All default to 0 (disabled). diff --git a/common/src/test/java/org/tron/core/config/args/CommitteeConfigTest.java b/common/src/test/java/org/tron/core/config/args/CommitteeConfigTest.java index 962b6a349ab..559198100fb 100644 --- a/common/src/test/java/org/tron/core/config/args/CommitteeConfigTest.java +++ b/common/src/test/java/org/tron/core/config/args/CommitteeConfigTest.java @@ -20,8 +20,8 @@ private static Config withRef() { public void testDefaults() { CommitteeConfig cc = CommitteeConfig.fromConfig(withRef()); assertEquals(0, cc.getAllowCreationOfContracts()); - assertEquals(0, cc.getAllowPBFT()); - assertEquals(20, cc.getPBFTExpireNum()); + assertEquals(0, cc.getAllowPbft()); + assertEquals(20, cc.getPbftExpireNum()); assertEquals(0, cc.getUnfreezeDelayDays()); assertEquals(0, cc.getAllowDynamicEnergy()); } @@ -32,8 +32,8 @@ public void testFromConfig() { "committee { allowCreationOfContracts = 1, allowPBFT = 1, pBFTExpireNum = 30 }"); CommitteeConfig cc = CommitteeConfig.fromConfig(config); assertEquals(1, cc.getAllowCreationOfContracts()); - assertEquals(1, cc.getAllowPBFT()); - assertEquals(30, cc.getPBFTExpireNum()); + assertEquals(1, cc.getAllowPbft()); + assertEquals(30, cc.getPbftExpireNum()); } @Test diff --git a/common/src/test/java/org/tron/core/config/args/VmConfigTest.java b/common/src/test/java/org/tron/core/config/args/VmConfigTest.java index e406ef24e7b..7eae1ddf937 100644 --- a/common/src/test/java/org/tron/core/config/args/VmConfigTest.java +++ b/common/src/test/java/org/tron/core/config/args/VmConfigTest.java @@ -143,7 +143,7 @@ public void testConstantCallTimeoutNegativeRejected() { @Test public void testConstantCallTimeoutOverflowRejected() { - long value = VmConfig.MAX_CONSTANT_CALL_TIMEOUT_MS + 1L; + long value = Long.MAX_VALUE / 1000 + 1L; try { VmConfig.fromConfig(withRef("vm { constantCallTimeoutMs = " + value + " }")); org.junit.Assert.fail("expected IllegalArgumentException for overflowing ms"); diff --git a/framework/src/main/java/org/tron/core/config/args/Args.java b/framework/src/main/java/org/tron/core/config/args/Args.java index 7cc1c5b870b..f82203c65b3 100644 --- a/framework/src/main/java/org/tron/core/config/args/Args.java +++ b/framework/src/main/java/org/tron/core/config/args/Args.java @@ -466,8 +466,8 @@ private static void applyCommitteeConfig(CommitteeConfig cc) { PARAMETER.allowProtoFilterNum = cc.getAllowProtoFilterNum(); PARAMETER.allowAccountStateRoot = cc.getAllowAccountStateRoot(); PARAMETER.changedDelegation = cc.getChangedDelegation(); - PARAMETER.allowPBFT = cc.getAllowPBFT(); - PARAMETER.pBFTExpireNum = cc.getPBFTExpireNum(); + PARAMETER.allowPBFT = cc.getAllowPbft(); + PARAMETER.pBFTExpireNum = cc.getPbftExpireNum(); PARAMETER.allowTvmFreeze = cc.getAllowTvmFreeze(); PARAMETER.allowTvmVote = cc.getAllowTvmVote(); PARAMETER.allowTvmLondon = cc.getAllowTvmLondon(); diff --git a/framework/src/test/java/org/tron/common/ParameterTest.java b/framework/src/test/java/org/tron/common/ParameterTest.java index 563f487f635..91bb580a3b4 100644 --- a/framework/src/test/java/org/tron/common/ParameterTest.java +++ b/framework/src/test/java/org/tron/common/ParameterTest.java @@ -216,7 +216,6 @@ public void testCommonParameter() { assertEquals(1000, parameter.getRateLimiterGlobalQps()); parameter.setRateLimiterGlobalIpQps(100); assertEquals(100, parameter.getRateLimiterGlobalIpQps()); - assertNull(parameter.getOverlay()); assertNull(parameter.getEventPluginConfig()); assertNull(parameter.getEventFilter()); parameter.setCryptoEngine(ECKey_ENGINE); diff --git a/framework/src/test/java/org/tron/core/config/args/OverlayTest.java b/framework/src/test/java/org/tron/core/config/args/OverlayTest.java deleted file mode 100644 index 1b7045c5b21..00000000000 --- a/framework/src/test/java/org/tron/core/config/args/OverlayTest.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * java-tron is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * java-tron is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.tron.core.config.args; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -public class OverlayTest { - - private Overlay overlay = new Overlay(); - - @Before - public void setOverlay() { - overlay.setPort(8080); - } - - @Test(expected = IllegalArgumentException.class) - public void whenSetOutOfBoundsPort() { - overlay.setPort(-1); - } - - @Test - public void getOverlay() { - Assert.assertEquals(8080, overlay.getPort()); - } -} From b70fccc80714ae66ebea2092353742974a263bd5 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Wed, 13 May 2026 10:47:27 +0800 Subject: [PATCH 02/10] prune proto --- .../src/main/java/org/tron/core/config/args/StorageConfig.java | 1 - protocol/src/main/protos/api/api.proto | 1 - 2 files changed, 2 deletions(-) diff --git a/common/src/main/java/org/tron/core/config/args/StorageConfig.java b/common/src/main/java/org/tron/core/config/args/StorageConfig.java index 9376dd1df1d..5f8efffb9f3 100644 --- a/common/src/main/java/org/tron/core/config/args/StorageConfig.java +++ b/common/src/main/java/org/tron/core/config/args/StorageConfig.java @@ -39,7 +39,6 @@ public class StorageConfig { // Raw storage config sub-tree, kept for setCacheStrategies/setDbRoots which // have dynamic keys that ConfigBeanFactory cannot bind. - // @Setter(NONE): not a config key, assigned directly in fromConfig(). @Setter(lombok.AccessLevel.NONE) private Config rawStorageConfig; diff --git a/protocol/src/main/protos/api/api.proto b/protocol/src/main/protos/api/api.proto index 6082d989182..8b79c8cb0d3 100644 --- a/protocol/src/main/protos/api/api.proto +++ b/protocol/src/main/protos/api/api.proto @@ -2,7 +2,6 @@ syntax = "proto3"; package protocol; import "core/Tron.proto"; -import "google/api/annotations.proto"; import "core/contract/asset_issue_contract.proto"; import "core/contract/account_contract.proto"; From 953651dbe50d78c61018698c425673f3e69fbb52 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Wed, 13 May 2026 11:32:40 +0800 Subject: [PATCH 03/10] optimize external.ip --- .../core/config/args/CommitteeConfig.java | 56 ++++++++++++++----- .../org/tron/core/config/args/NodeConfig.java | 26 +++++---- 2 files changed, 57 insertions(+), 25 deletions(-) diff --git a/common/src/main/java/org/tron/core/config/args/CommitteeConfig.java b/common/src/main/java/org/tron/core/config/args/CommitteeConfig.java index 0bd9e7e0e13..660fa289e3b 100644 --- a/common/src/main/java/org/tron/core/config/args/CommitteeConfig.java +++ b/common/src/main/java/org/tron/core/config/args/CommitteeConfig.java @@ -82,11 +82,11 @@ public static CommitteeConfig fromConfig(Config config) { private static Config normalizeNonStandardKeys(Config section) { if (section.hasPath("allowPBFT")) { ConfigValue v = section.getValue("allowPBFT"); - section = section.withValue("allowPbft", v); + section = section.withValue("allowPbft", v); // rename allowPBFT -> allowPbft } if (section.hasPath("pBFTExpireNum")) { ConfigValue v = section.getValue("pBFTExpireNum"); - section = section.withValue("pbftExpireNum", v); + section = section.withValue("pbftExpireNum", v); // rename pBFTExpireNum -> pbftExpireNum } return section; } @@ -101,35 +101,61 @@ private void postProcess() { } // clamp allowDelegateOptimization to 0-1 - if (allowDelegateOptimization < 0) { allowDelegateOptimization = 0; } - if (allowDelegateOptimization > 1) { allowDelegateOptimization = 1; } + if (allowDelegateOptimization < 0) { + allowDelegateOptimization = 0; + } + if (allowDelegateOptimization > 1) { + allowDelegateOptimization = 1; + } // clamp allowDynamicEnergy to 0-1 - if (allowDynamicEnergy < 0) { allowDynamicEnergy = 0; } - if (allowDynamicEnergy > 1) { allowDynamicEnergy = 1; } + if (allowDynamicEnergy < 0) { + allowDynamicEnergy = 0; + } + if (allowDynamicEnergy > 1) { + allowDynamicEnergy = 1; + } // clamp dynamicEnergyThreshold to 0-100_000_000_000_000_000 - if (dynamicEnergyThreshold < 0) { dynamicEnergyThreshold = 0; } + if (dynamicEnergyThreshold < 0) { + dynamicEnergyThreshold = 0; + } if (dynamicEnergyThreshold > 100_000_000_000_000_000L) { dynamicEnergyThreshold = 100_000_000_000_000_000L; } // clamp dynamicEnergyIncreaseFactor to 0-10_000 - if (dynamicEnergyIncreaseFactor < 0) { dynamicEnergyIncreaseFactor = 0; } - if (dynamicEnergyIncreaseFactor > 10_000L) { dynamicEnergyIncreaseFactor = 10_000L; } + if (dynamicEnergyIncreaseFactor < 0) { + dynamicEnergyIncreaseFactor = 0; + } + if (dynamicEnergyIncreaseFactor > 10_000L) { + dynamicEnergyIncreaseFactor = 10_000L; + } // clamp dynamicEnergyMaxFactor to 0-100_000 - if (dynamicEnergyMaxFactor < 0) { dynamicEnergyMaxFactor = 0; } - if (dynamicEnergyMaxFactor > 100_000L) { dynamicEnergyMaxFactor = 100_000L; } + if (dynamicEnergyMaxFactor < 0) { + dynamicEnergyMaxFactor = 0; + } + if (dynamicEnergyMaxFactor > 100_000L) { + dynamicEnergyMaxFactor = 100_000L; + } // clamp allowNewReward to 0-1 (must run BEFORE the cross-field check below, // which depends on allowNewReward != 1) - if (allowNewReward < 0) { allowNewReward = 0; } - if (allowNewReward > 1) { allowNewReward = 1; } + if (allowNewReward < 0) { + allowNewReward = 0; + } + if (allowNewReward > 1) { + allowNewReward = 1; + } // clamp memoFee to 0-1_000_000_000 - if (memoFee < 0) { memoFee = 0; } - if (memoFee > 1_000_000_000L) { memoFee = 1_000_000_000L; } + if (memoFee < 0) { + memoFee = 0; + } + if (memoFee > 1_000_000_000L) { + memoFee = 1_000_000_000L; + } // cross-field: allowOldRewardOpt requires at least one reward/vote flag if (allowOldRewardOpt == 1 && allowNewRewardAlgorithm != 1 diff --git a/common/src/main/java/org/tron/core/config/args/NodeConfig.java b/common/src/main/java/org/tron/core/config/args/NodeConfig.java index f312f16f740..c2523dc2a97 100644 --- a/common/src/main/java/org/tron/core/config/args/NodeConfig.java +++ b/common/src/main/java/org/tron/core/config/args/NodeConfig.java @@ -43,9 +43,6 @@ public class NodeConfig { // node.discovery.* — HOCON merges into node { discovery { ... } }, auto-bound private DiscoveryConfig discovery = new DiscoveryConfig(); - @Getter(lombok.AccessLevel.NONE) - @Setter(lombok.AccessLevel.NONE) - private String externalIP = ""; // node.shutdown.* uses PascalCase nested keys (shutdown.BlockTime, etc.). // These are optional (not in reference.conf), so @Setter(NONE) prevents ConfigBeanFactory @@ -66,7 +63,7 @@ public boolean isDiscoveryPersist() { } public String getDiscoveryExternalIp() { - return externalIP; + return discovery.getExternal().getIp(); } private int inactiveThreshold = 600; @@ -148,6 +145,14 @@ public static class DiscoveryConfig { private boolean enable = false; private boolean persist = false; + private ExternalConfig external = new ExternalConfig(); + + @Getter + @Setter + public static class ExternalConfig { + + private String ip = ""; + } } @Getter @@ -314,11 +319,6 @@ public static NodeConfig fromConfig(Config config) { nc.maxConnectionsWithSameIp = section.getInt("maxActiveNodesWithSameIp"); } - nc.externalIP = getString(section, "discovery.external.ip", ""); - if ("null".equalsIgnoreCase(nc.externalIP)) { - nc.externalIP = ""; - } - // Legacy key fallback: node.fullNodeAllowShieldedTransaction -> allowShieldedTransactionApi. if (section.hasPath("allowShieldedTransactionApi")) { nc.allowShieldedTransactionApi = @@ -449,13 +449,19 @@ private static String getString(Config config, String path, String defaultValue) /** * "isOpenFullTcpDisconnect" config key has an "is" prefix that the JavaBean Introspector - * strips from boolean getter names, so the derived property is "openFullTcpDisconnect" + * strips from boolean getter names, so the derived property is "openFullTcpDisconnect". + * "discovery.external.ip" may be HOCON null or the string "null"; both normalize to "". */ private static Config normalizeNonStandardKeys(Config section) { if (section.hasPath("isOpenFullTcpDisconnect")) { section = section.withValue("openFullTcpDisconnect", section.getValue("isOpenFullTcpDisconnect")); } + String externalIpPath = "discovery.external.ip"; + if (section.getIsNull(externalIpPath) + || "null".equalsIgnoreCase(section.getString(externalIpPath))) { + section = section.withValue(externalIpPath, ConfigValueFactory.fromAnyRef("")); + } return section; } From 99dcd91acb383c039172f3dd9bc2b3b1bd0a36c0 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Wed, 13 May 2026 12:35:23 +0800 Subject: [PATCH 04/10] optimize trustNodeAddr --- .../src/main/java/org/tron/core/config/args/NodeConfig.java | 2 ++ framework/src/main/java/org/tron/core/config/args/Args.java | 5 +---- framework/src/main/java/org/tron/program/FullNode.java | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/common/src/main/java/org/tron/core/config/args/NodeConfig.java b/common/src/main/java/org/tron/core/config/args/NodeConfig.java index c2523dc2a97..82619726b7e 100644 --- a/common/src/main/java/org/tron/core/config/args/NodeConfig.java +++ b/common/src/main/java/org/tron/core/config/args/NodeConfig.java @@ -418,10 +418,12 @@ private void postProcess() { agreeNodeCount = MAX_ACTIVE_WITNESS_NUM; } + // dynamicConfigCheckInterval: minimum 600 if (dynamicConfig.checkInterval <= 0) { dynamicConfig.checkInterval = 600; } + // maxTrxCacheSize: minimum 2000 if (maxTrxCacheSize < 2000) { maxTrxCacheSize = 2000; } diff --git a/framework/src/main/java/org/tron/core/config/args/Args.java b/framework/src/main/java/org/tron/core/config/args/Args.java index b8c700ce303..8d8e2500c9f 100644 --- a/framework/src/main/java/org/tron/core/config/args/Args.java +++ b/framework/src/main/java/org/tron/core/config/args/Args.java @@ -610,10 +610,7 @@ private static void applyNodeConfig(NodeConfig nc) { PARAMETER.maxHttpConnectNumber = nc.getMaxHttpConnectNumber(); PARAMETER.netMaxTrxPerSecond = nc.getNetMaxTrxPerSecond(); - if (StringUtils.isEmpty(PARAMETER.trustNodeAddr)) { - String trustNode = nc.getTrustNode(); - PARAMETER.trustNodeAddr = StringUtils.isEmpty(trustNode) ? null : trustNode; - } + PARAMETER.trustNodeAddr = nc.getTrustNode(); PARAMETER.validateSignThreadNum = nc.getValidateSignThreadNum(); PARAMETER.walletExtensionApi = nc.isWalletExtensionApi(); diff --git a/framework/src/main/java/org/tron/program/FullNode.java b/framework/src/main/java/org/tron/program/FullNode.java index 308cb9a1c69..96b9f73d577 100644 --- a/framework/src/main/java/org/tron/program/FullNode.java +++ b/framework/src/main/java/org/tron/program/FullNode.java @@ -1,8 +1,8 @@ package org.tron.program; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.util.ObjectUtils; import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; import org.tron.common.application.TronApplicationContext; @@ -35,7 +35,7 @@ public static void main(String[] args) { } if (parameter.isSolidityNode()) { logger.info("Solidity node is running."); - if (ObjectUtils.isEmpty(parameter.getTrustNodeAddr())) { + if (StringUtils.isEmpty(parameter.getTrustNodeAddr())) { throw new TronError(new IllegalArgumentException("Trust node is not set."), TronError.ErrCode.SOLID_NODE_INIT); } From e15cbbf7b50132ad1edd99bfe6f8d7d82641aa52 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Wed, 13 May 2026 14:06:37 +0800 Subject: [PATCH 05/10] fix the bug of VmConfigTest --- .../tron/core/config/args/VmConfigTest.java | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/common/src/test/java/org/tron/core/config/args/VmConfigTest.java b/common/src/test/java/org/tron/core/config/args/VmConfigTest.java index 7eae1ddf937..6e3da7953f8 100644 --- a/common/src/test/java/org/tron/core/config/args/VmConfigTest.java +++ b/common/src/test/java/org/tron/core/config/args/VmConfigTest.java @@ -90,8 +90,8 @@ public void testEstimateEnergyMaxRetryBoundaryValues() { } // =========================================================================== - // Constant-call timeout (issue #6681). The validation rule: any positive - // value that fits VM deadline conversion is accepted, but zero/negative is + // Constant-call timeout (issue #6681). The validation rule: any zero or positive + // value that fits VM deadline conversion is accepted, but negative is // rejected ONLY when the operator explicitly set the property in their // config. Absence keeps the in-Java default (0L = "share the // block-processing deadline"). @@ -107,6 +107,8 @@ public void testConstantCallTimeoutDefaultWhenAbsent() { @Test public void testConstantCallTimeoutAcceptsAnyPositiveValue() { + assertEquals(0L, VmConfig.fromConfig( + withRef("vm { constantCallTimeoutMs = 0 }")).getConstantCallTimeoutMs()); assertEquals(1L, VmConfig.fromConfig( withRef("vm { constantCallTimeoutMs = 1 }")).getConstantCallTimeoutMs()); assertEquals(50L, VmConfig.fromConfig( @@ -117,19 +119,6 @@ public void testConstantCallTimeoutAcceptsAnyPositiveValue() { withRef("vm { constantCallTimeoutMs = 5000 }")).getConstantCallTimeoutMs()); } - @Test - public void testConstantCallTimeoutZeroRejectedWhenExplicitlyConfigured() { - // Operator wrote `= 0` in config -> treated as a misconfiguration even - // though it equals the in-Java default. Forces an explicit positive value. - try { - VmConfig.fromConfig(withRef("vm { constantCallTimeoutMs = 0 }")); - org.junit.Assert.fail("expected IllegalArgumentException for explicit 0"); - } catch (IllegalArgumentException ex) { - org.junit.Assert.assertTrue(ex.getMessage(), - ex.getMessage().contains("constantCallTimeoutMs")); - } - } - @Test public void testConstantCallTimeoutNegativeRejected() { try { From 16494de0e378c59a4a0f469ee7016922cddf3ac4 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Wed, 13 May 2026 15:56:22 +0800 Subject: [PATCH 06/10] remove the comment of trustNode in config --- codecov.yml | 38 ------------------- common/src/main/resources/reference.conf | 2 - .../tron/core/config/args/NodeConfigTest.java | 2 - 3 files changed, 42 deletions(-) delete mode 100644 codecov.yml diff --git a/codecov.yml b/codecov.yml deleted file mode 100644 index 1b46f3fa8db..00000000000 --- a/codecov.yml +++ /dev/null @@ -1,38 +0,0 @@ -# DEPRECATED: Codecov integration is no longer active. -# Coverage is now handled by JaCoCo + madrapps/jacoco-report in pr-build.yml. -# This file is retained for reference only and can be safely deleted. - -# Post a Codecov comment on pull requests. If don't need comment, use comment: false, else use following -comment: false -#comment: -# # Show coverage diff, flags table, and changed files in the PR comment -# layout: "diff, flags, files" -# # Update existing comment if present, otherwise create a new one -# behavior: default -# # Post a comment even when coverage numbers do not change -# require_changes: false -# # Do not require a base report before posting the comment -# require_base: false -# # Require the PR head commit to have a coverage report -# require_head: true -# # Show both project coverage and patch coverage in the PR comment -# hide_project_coverage: false - -codecov: - # Do not wait for all CI checks to pass before sending notifications - require_ci_to_pass: false - notify: - wait_for_ci: false - -coverage: - status: - project: # PR coverage/project UI - default: - # Compare against the base branch automatically - target: auto - # Allow a small coverage drop tolerance - threshold: 0.02% -# patch: off - patch: # PR coverage/patch UI - default: - target: 60% diff --git a/common/src/main/resources/reference.conf b/common/src/main/resources/reference.conf index 184f22868ed..f37326155d5 100644 --- a/common/src/main/resources/reference.conf +++ b/common/src/main/resources/reference.conf @@ -164,8 +164,6 @@ node.metrics = { node { # Trust node for solidity node (example: "127.0.0.1:50051"). - # Empty string here = "not configured"; Args.java bridge converts "" → null so the - # runtime behavior matches develop (trustNodeAddr is null unless user sets the key). trustNode = "" # Expose extension api to public or not diff --git a/common/src/test/java/org/tron/core/config/args/NodeConfigTest.java b/common/src/test/java/org/tron/core/config/args/NodeConfigTest.java index d4fbc05e730..bbc2d2475ee 100644 --- a/common/src/test/java/org/tron/core/config/args/NodeConfigTest.java +++ b/common/src/test/java/org/tron/core/config/args/NodeConfigTest.java @@ -245,8 +245,6 @@ public void testValidContractProtoThreadsExplicitPreserved() { @Test public void testTrustNodeNotDefaultedByReferenceConf() { - // reference.conf intentionally omits `node.trustNode` so that empty configs - // preserve develop's behavior (trustNodeAddr stays null in the Args bridge). NodeConfig nc = NodeConfig.fromConfig(withRef()); assertTrue(nc.getTrustNode() == null || nc.getTrustNode().isEmpty()); } From b2254678b101608e84ea0d02dcd79193f9df51e9 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Wed, 13 May 2026 17:41:54 +0800 Subject: [PATCH 07/10] delete withoutPath(topicDefaults) for EventConfig --- .../src/main/java/org/tron/core/config/args/EventConfig.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/common/src/main/java/org/tron/core/config/args/EventConfig.java b/common/src/main/java/org/tron/core/config/args/EventConfig.java index 4df10ea3e7e..f4378682cc3 100644 --- a/common/src/main/java/org/tron/core/config/args/EventConfig.java +++ b/common/src/main/java/org/tron/core/config/args/EventConfig.java @@ -84,8 +84,9 @@ public static EventConfig fromConfig(Config config) { String nativeKey = "native"; String topicsKey = "topics"; - Config bindable = section.withoutPath(nativeKey).withoutPath(topicsKey) - .withoutPath("topicDefaults"); + // remove two keys to construct EventConfig because they cannot be bind automatically, + // we can bind them manually later + Config bindable = section.withoutPath(nativeKey).withoutPath(topicsKey); EventConfig ec = ConfigBeanFactory.create(bindable, EventConfig.class); // "native" sub-section: bind via ConfigBeanFactory when present, use defaults otherwise From 84775dfff5d9c7d625ba8187ab86c2ee4676a0eb Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Wed, 13 May 2026 18:25:10 +0800 Subject: [PATCH 08/10] update the comment of constantCallTimeoutMs --- common/src/main/resources/reference.conf | 2 +- framework/src/main/resources/config.conf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/src/main/resources/reference.conf b/common/src/main/resources/reference.conf index f37326155d5..0864f4d5126 100644 --- a/common/src/main/resources/reference.conf +++ b/common/src/main/resources/reference.conf @@ -699,7 +699,7 @@ vm = { # Max retry time for executing transaction in estimating energy estimateEnergyMaxRetry = 3 - # Specify constant call timeout + # Max TVM execution time (ms) for constant calls. 0 means no effect constantCallTimeoutMs = 0 } diff --git a/framework/src/main/resources/config.conf b/framework/src/main/resources/config.conf index d6d3ab236a6..0686890f030 100644 --- a/framework/src/main/resources/config.conf +++ b/framework/src/main/resources/config.conf @@ -750,7 +750,7 @@ vm = { # Omit the property entirely to keep the default behaviour of sharing the # block-processing deadline. Migration note: if previously running --debug # to extend constant calls, switch to this option (--debug also extends - # block-processing, which is unsafe; see issue #6266). + # block-processing, which is unsafe; see issue #6266). Default: 0. # constantCallTimeoutMs = 100 } From 59ea298f5fd3de28b09b18a737f726838204023d Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Thu, 14 May 2026 11:50:19 +0800 Subject: [PATCH 09/10] update testcase --- .../tron/core/config/args/VmConfigTest.java | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/common/src/test/java/org/tron/core/config/args/VmConfigTest.java b/common/src/test/java/org/tron/core/config/args/VmConfigTest.java index 6e3da7953f8..99015a8c012 100644 --- a/common/src/test/java/org/tron/core/config/args/VmConfigTest.java +++ b/common/src/test/java/org/tron/core/config/args/VmConfigTest.java @@ -2,10 +2,12 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import com.typesafe.config.Config; import com.typesafe.config.ConfigFactory; +import org.junit.Assert; import org.junit.Test; public class VmConfigTest { @@ -99,7 +101,7 @@ public void testEstimateEnergyMaxRetryBoundaryValues() { @Test public void testConstantCallTimeoutDefaultWhenAbsent() { - // No path in the config, no entry in reference.conf -> default 0L kept, + // reference.conf default is 0; absence of a user override keeps that default; // no validation triggered. VmConfig vm = VmConfig.fromConfig(withRef()); assertEquals(0L, vm.getConstantCallTimeoutMs()); @@ -121,24 +123,18 @@ public void testConstantCallTimeoutAcceptsAnyPositiveValue() { @Test public void testConstantCallTimeoutNegativeRejected() { - try { + IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> { VmConfig.fromConfig(withRef("vm { constantCallTimeoutMs = -1 }")); - org.junit.Assert.fail("expected IllegalArgumentException for negative ms"); - } catch (IllegalArgumentException ex) { - org.junit.Assert.assertTrue(ex.getMessage(), - ex.getMessage().contains("constantCallTimeoutMs")); - } + }); + Assert.assertTrue(thrown.getMessage().contains("constantCallTimeoutMs")); } @Test public void testConstantCallTimeoutOverflowRejected() { long value = Long.MAX_VALUE / 1000 + 1L; - try { + IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> { VmConfig.fromConfig(withRef("vm { constantCallTimeoutMs = " + value + " }")); - org.junit.Assert.fail("expected IllegalArgumentException for overflowing ms"); - } catch (IllegalArgumentException ex) { - org.junit.Assert.assertTrue(ex.getMessage(), - ex.getMessage().contains("deadline conversion")); - } + }); + Assert.assertTrue(thrown.getMessage().contains("deadline conversion")); } } From 10eb9f0468132608e8828dae8c089dd20442abfd Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Thu, 14 May 2026 12:09:12 +0800 Subject: [PATCH 10/10] update EventConfigTest --- .../java/org/tron/core/config/args/EventConfigTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/common/src/test/java/org/tron/core/config/args/EventConfigTest.java b/common/src/test/java/org/tron/core/config/args/EventConfigTest.java index 361d9f48581..ca0cbefaddd 100644 --- a/common/src/test/java/org/tron/core/config/args/EventConfigTest.java +++ b/common/src/test/java/org/tron/core/config/args/EventConfigTest.java @@ -79,4 +79,11 @@ public void testFilter() { assertEquals(2, ec.getFilter().getContractAddress().size()); assertEquals(1, ec.getFilter().getContractTopic().size()); } + + @Test + public void testTopicsEmptyList() { + EventConfig ec = EventConfig.fromConfig(withRef( + "event.subscribe.topics = []")); + assertTrue(ec.getTopics().isEmpty()); + } }