Skip to content

Commit 0dd5139

Browse files
authored
refactor(config,protocol,ci): optimize config binding (#6762)
1 parent 5f7eeca commit 0dd5139

20 files changed

Lines changed: 224 additions & 445 deletions

File tree

codecov.yml

Lines changed: 0 additions & 38 deletions
This file was deleted.

common/src/main/java/org/tron/common/parameter/CommonParameter.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
import org.tron.common.logsfilter.FilterQuery;
1515
import org.tron.common.setting.RocksDbSettings;
1616
import org.tron.core.Constant;
17-
import org.tron.core.config.args.Overlay;
1817
import org.tron.core.config.args.SeedNode;
1918
import org.tron.core.config.args.Storage;
2019
import org.tron.p2p.P2pConfig;
@@ -435,8 +434,6 @@ public class CommonParameter {
435434
@Getter
436435
public Storage storage;
437436
@Getter
438-
public Overlay overlay;
439-
@Getter
440437
public SeedNode seedNode;
441438
@Getter
442439
public EventPluginConfig eventPluginConfig;

common/src/main/java/org/tron/core/config/args/CommitteeConfig.java

Lines changed: 61 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.typesafe.config.Config;
44
import com.typesafe.config.ConfigBeanFactory;
5+
import com.typesafe.config.ConfigValue;
56
import lombok.Getter;
67
import lombok.Setter;
78
import lombok.extern.slf4j.Slf4j;
@@ -35,29 +36,10 @@ public class CommitteeConfig {
3536
private long allowProtoFilterNum = 0;
3637
private long allowAccountStateRoot = 0;
3738
private long changedDelegation = 0;
38-
// NON-STANDARD NAMING: "allowPBFT" and "pBFTExpireNum" in config.conf contain
39-
// consecutive uppercase letters ("PBFT"), which violates JavaBean naming convention.
40-
// ConfigBeanFactory derives config keys from setter names using JavaBean rules:
41-
// setPBFTExpireNum -> property "PBFTExpireNum" (capital P, per JavaBean spec)
42-
// but config.conf uses "pBFTExpireNum" (lowercase p) -> mismatch -> binding fails.
43-
//
44-
// These two fields are excluded from auto-binding and handled manually in fromConfig().
45-
// TODO: Rename config keys to standard camelCase (allowPbft, pbftExpireNum) when
46-
// PBFT feature is enabled and a breaking config change is acceptable.
47-
@Getter(lombok.AccessLevel.NONE)
48-
@Setter(lombok.AccessLevel.NONE)
49-
private long allowPBFT = 0;
50-
@Getter(lombok.AccessLevel.NONE)
51-
@Setter(lombok.AccessLevel.NONE)
52-
private long pBFTExpireNum = 20;
53-
54-
// Only getters are exposed. No public setters — ConfigBeanFactory scans public
55-
// setters via reflection and would derive key "PBFTExpireNum" / "AllowPBFT"
56-
// (JavaBean uppercase rule), which does not match config keys "pBFTExpireNum"
57-
// / "allowPBFT" and would throw. Values are assigned to fields directly in
58-
// fromConfig() below.
59-
public long getAllowPBFT() { return allowPBFT; }
60-
public long getPBFTExpireNum() { return pBFTExpireNum; }
39+
// "allowPBFT" / "pBFTExpireNum" in config.conf use non-standard casing; they are
40+
// remapped to standard camelCase by normalizeNonStandardKeys() before binding.
41+
private long allowPbft = 0;
42+
private long pbftExpireNum = 20;
6143
private long allowTvmFreeze = 0;
6244
private long allowTvmVote = 0;
6345
private long allowTvmLondon = 0;
@@ -85,32 +67,30 @@ public class CommitteeConfig {
8567
private long dynamicEnergyMaxFactor = 0;
8668

8769
// proposalExpireTime is NOT a committee field — it's in block.* and handled by BlockConfig
88-
8970
// Defaults come from reference.conf (loaded globally via Configuration.java)
90-
91-
/**
92-
* Create CommitteeConfig from the "committee" section of the application config.
93-
*
94-
* Note: allowPBFT and pBFTExpireNum have non-standard JavaBean naming (consecutive
95-
* uppercase letters) which causes ConfigBeanFactory key mismatch. These two fields
96-
* are excluded from automatic binding and handled manually after.
97-
*/
98-
private static final String PBFT_EXPIRE_NUM_KEY = "pBFTExpireNum";
99-
private static final String ALLOW_PBFT_KEY = "allowPBFT";
100-
10171
public static CommitteeConfig fromConfig(Config config) {
102-
Config section = config.getConfig("committee");
103-
72+
Config section = normalizeNonStandardKeys(config.getConfig("committee"));
10473
CommitteeConfig cc = ConfigBeanFactory.create(section, CommitteeConfig.class);
105-
// Ensure the manually-named fields get the right values from the original keys
106-
cc.allowPBFT = section.hasPath(ALLOW_PBFT_KEY) ? section.getLong(ALLOW_PBFT_KEY) : 0;
107-
cc.pBFTExpireNum = section.hasPath(PBFT_EXPIRE_NUM_KEY)
108-
? section.getLong(PBFT_EXPIRE_NUM_KEY) : 20;
109-
11074
cc.postProcess();
11175
return cc;
11276
}
11377

78+
// "allowPBFT" and "pBFTExpireNum" use non-standard casing that JavaBean Introspector
79+
// cannot derive correctly (setPBFTExpireNum -> property "PBFTExpireNum", not "pBFTExpireNum").
80+
// Remap them to standard camelCase keys so ConfigBeanFactory binds them normally.
81+
// Config is immutable; withValue() returns a new object.
82+
private static Config normalizeNonStandardKeys(Config section) {
83+
if (section.hasPath("allowPBFT")) {
84+
ConfigValue v = section.getValue("allowPBFT");
85+
section = section.withValue("allowPbft", v); // rename allowPBFT -> allowPbft
86+
}
87+
if (section.hasPath("pBFTExpireNum")) {
88+
ConfigValue v = section.getValue("pBFTExpireNum");
89+
section = section.withValue("pbftExpireNum", v); // rename pBFTExpireNum -> pbftExpireNum
90+
}
91+
return section;
92+
}
93+
11494
private void postProcess() {
11595
// clamp unfreezeDelayDays to 0-365
11696
if (unfreezeDelayDays < 0) {
@@ -121,35 +101,61 @@ private void postProcess() {
121101
}
122102

123103
// clamp allowDelegateOptimization to 0-1
124-
if (allowDelegateOptimization < 0) { allowDelegateOptimization = 0; }
125-
if (allowDelegateOptimization > 1) { allowDelegateOptimization = 1; }
104+
if (allowDelegateOptimization < 0) {
105+
allowDelegateOptimization = 0;
106+
}
107+
if (allowDelegateOptimization > 1) {
108+
allowDelegateOptimization = 1;
109+
}
126110

127111
// clamp allowDynamicEnergy to 0-1
128-
if (allowDynamicEnergy < 0) { allowDynamicEnergy = 0; }
129-
if (allowDynamicEnergy > 1) { allowDynamicEnergy = 1; }
112+
if (allowDynamicEnergy < 0) {
113+
allowDynamicEnergy = 0;
114+
}
115+
if (allowDynamicEnergy > 1) {
116+
allowDynamicEnergy = 1;
117+
}
130118

131119
// clamp dynamicEnergyThreshold to 0-100_000_000_000_000_000
132-
if (dynamicEnergyThreshold < 0) { dynamicEnergyThreshold = 0; }
120+
if (dynamicEnergyThreshold < 0) {
121+
dynamicEnergyThreshold = 0;
122+
}
133123
if (dynamicEnergyThreshold > 100_000_000_000_000_000L) {
134124
dynamicEnergyThreshold = 100_000_000_000_000_000L;
135125
}
136126

137127
// clamp dynamicEnergyIncreaseFactor to 0-10_000
138-
if (dynamicEnergyIncreaseFactor < 0) { dynamicEnergyIncreaseFactor = 0; }
139-
if (dynamicEnergyIncreaseFactor > 10_000L) { dynamicEnergyIncreaseFactor = 10_000L; }
128+
if (dynamicEnergyIncreaseFactor < 0) {
129+
dynamicEnergyIncreaseFactor = 0;
130+
}
131+
if (dynamicEnergyIncreaseFactor > 10_000L) {
132+
dynamicEnergyIncreaseFactor = 10_000L;
133+
}
140134

141135
// clamp dynamicEnergyMaxFactor to 0-100_000
142-
if (dynamicEnergyMaxFactor < 0) { dynamicEnergyMaxFactor = 0; }
143-
if (dynamicEnergyMaxFactor > 100_000L) { dynamicEnergyMaxFactor = 100_000L; }
136+
if (dynamicEnergyMaxFactor < 0) {
137+
dynamicEnergyMaxFactor = 0;
138+
}
139+
if (dynamicEnergyMaxFactor > 100_000L) {
140+
dynamicEnergyMaxFactor = 100_000L;
141+
}
144142

145143
// clamp allowNewReward to 0-1 (must run BEFORE the cross-field check below,
146144
// which depends on allowNewReward != 1)
147-
if (allowNewReward < 0) { allowNewReward = 0; }
148-
if (allowNewReward > 1) { allowNewReward = 1; }
145+
if (allowNewReward < 0) {
146+
allowNewReward = 0;
147+
}
148+
if (allowNewReward > 1) {
149+
allowNewReward = 1;
150+
}
149151

150152
// clamp memoFee to 0-1_000_000_000
151-
if (memoFee < 0) { memoFee = 0; }
152-
if (memoFee > 1_000_000_000L) { memoFee = 1_000_000_000L; }
153+
if (memoFee < 0) {
154+
memoFee = 0;
155+
}
156+
if (memoFee > 1_000_000_000L) {
157+
memoFee = 1_000_000_000L;
158+
}
153159

154160
// cross-field: allowOldRewardOpt requires at least one reward/vote flag
155161
if (allowOldRewardOpt == 1 && allowNewRewardAlgorithm != 1

common/src/main/java/org/tron/core/config/args/EventConfig.java

Lines changed: 23 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,15 @@ public class EventConfig {
2525
private String server = "";
2626
private String dbconfig = "";
2727
private boolean contractParse = true;
28-
@Getter(lombok.AccessLevel.NONE)
28+
// "native" is a Java reserved word; config key cannot match field name directly.
29+
// @Setter(NONE) prevents ConfigBeanFactory from requiring a "nativeQueue" key.
2930
@Setter(lombok.AccessLevel.NONE)
3031
private NativeConfig nativeQueue = new NativeConfig();
3132

32-
public NativeConfig getNativeQueue() { return nativeQueue; }
33-
// Topics list has optional fields (ethCompatible, redundancy, solidified) that
34-
// not all items have. ConfigBeanFactory requires all bean fields to exist in config.
35-
// Excluded from auto-binding, read manually in fromConfig().
36-
@Getter(lombok.AccessLevel.NONE)
33+
// Topics list items have optional fields; excluded from auto-binding.
34+
// @Setter(NONE) prevents ConfigBeanFactory from requiring a "topics" key.
3735
@Setter(lombok.AccessLevel.NONE)
3836
private List<TopicConfig> topics = new ArrayList<>();
39-
40-
public List<TopicConfig> getTopics() { return topics; }
4137
private FilterConfig filter = new FilterConfig();
4238

4339
@Getter
@@ -70,62 +66,40 @@ public static class FilterConfig {
7066

7167
// Defaults come from reference.conf (loaded globally via Configuration.java)
7268

69+
// TopicConfig fields are optional per item; this fallback ensures all keys exist
70+
// for ConfigBeanFactory binding. Values must match TopicConfig field defaults.
71+
private static final Config TOPIC_DEFAULTS = ConfigFactory.parseString(
72+
"triggerName=\"\", enable=false, topic=\"\", "
73+
+ "solidified=false, ethCompatible=false, redundancy=false");
74+
7375
/**
7476
* Create EventConfig from the "event.subscribe" section of the application config.
7577
*
76-
* <p>Note: HOCON key "native" is a Java reserved word, so the bean field is named
77-
* "nativeQueue" but config key is "native". We handle this manually after binding.
78+
* <p>"native" is a Java reserved word, so the field is named "nativeQueue" and the
79+
* sub-section is read directly after binding. "topics" items may omit optional fields;
80+
* TOPIC_DEFAULTS provides fallback values so ConfigBeanFactory can bind each item.
7881
*/
7982
public static EventConfig fromConfig(Config config) {
8083
Config section = config.getConfig("event.subscribe");
8184

82-
// "native" is a Java reserved word, "topics" has optional fields per item —
83-
// strip both before binding, read manually
8485
String nativeKey = "native";
8586
String topicsKey = "topics";
86-
Config bindable = section.withoutPath(nativeKey).withoutPath(topicsKey)
87-
.withoutPath("topicDefaults");
87+
// remove two keys to construct EventConfig because they cannot be bind automatically,
88+
// we can bind them manually later
89+
Config bindable = section.withoutPath(nativeKey).withoutPath(topicsKey);
8890
EventConfig ec = ConfigBeanFactory.create(bindable, EventConfig.class);
8991

90-
// manually bind "native" sub-section
91-
Config nativeSection = section.hasPath(nativeKey)
92-
? section.getConfig(nativeKey) : ConfigFactory.empty();
93-
ec.nativeQueue = new NativeConfig();
94-
if (nativeSection.hasPath("useNativeQueue")) {
95-
ec.nativeQueue.useNativeQueue = nativeSection.getBoolean("useNativeQueue");
96-
}
97-
if (nativeSection.hasPath("bindport")) {
98-
ec.nativeQueue.bindport = nativeSection.getInt("bindport");
99-
}
100-
if (nativeSection.hasPath("sendqueuelength")) {
101-
ec.nativeQueue.sendqueuelength = nativeSection.getInt("sendqueuelength");
102-
}
92+
// "native" sub-section: bind via ConfigBeanFactory when present, use defaults otherwise
93+
ec.nativeQueue = section.hasPath(nativeKey)
94+
? ConfigBeanFactory.create(section.getConfig(nativeKey), NativeConfig.class)
95+
: new NativeConfig();
10396

104-
// manually bind topics — each item may have optional fields
97+
// topics: withFallback fills optional fields so ConfigBeanFactory can bind each item
10598
if (section.hasPath(topicsKey)) {
10699
ec.topics = new ArrayList<>();
107100
for (com.typesafe.config.ConfigObject obj : section.getObjectList(topicsKey)) {
108-
Config tc = obj.toConfig();
109-
TopicConfig topic = new TopicConfig();
110-
if (tc.hasPath("triggerName")) {
111-
topic.triggerName = tc.getString("triggerName");
112-
}
113-
if (tc.hasPath("enable")) {
114-
topic.enable = tc.getBoolean("enable");
115-
}
116-
if (tc.hasPath("topic")) {
117-
topic.topic = tc.getString("topic");
118-
}
119-
if (tc.hasPath("solidified")) {
120-
topic.solidified = tc.getBoolean("solidified");
121-
}
122-
if (tc.hasPath("ethCompatible")) {
123-
topic.ethCompatible = tc.getBoolean("ethCompatible");
124-
}
125-
if (tc.hasPath("redundancy")) {
126-
topic.redundancy = tc.getBoolean("redundancy");
127-
}
128-
ec.topics.add(topic);
101+
ec.topics.add(ConfigBeanFactory.create(
102+
obj.toConfig().withFallback(TOPIC_DEFAULTS), TopicConfig.class));
129103
}
130104
}
131105

0 commit comments

Comments
 (0)