-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
Software Versions
Version : develop branch (commit 13b68eac0)
Expected behaviour
CLI flags should take priority over config file values. This is the standard convention (CLI > config file > default) and is already correctly implemented for 9 other parameters (e.g. --storage-db-directory, --trust-node) using the Optional pattern.
java -jar FullNode.jar --rpc-thread 16
# Expected: rpcThreadNum = 16Actual behaviour
For 13 parameters, Args.setParam(Config) unconditionally overwrites the CLI value with the config file value. The CLI flags are silently ignored.
# config.conf contains: node.rpc.thread = 8
java -jar FullNode.jar --rpc-thread 16
# Actual: rpcThreadNum = 8 (CLI value lost)Root cause — unconditional assignment in Args.setParam():
PARAMETER.rpcThreadNum = config.hasPath(ConfigKey.NODE_RPC_THREAD)
? config.getInt(ConfigKey.NODE_RPC_THREAD)
: Runtime.getRuntime().availableProcessors() / 2;
// JCommander-set value of 16 is overwritten to 8Frequency
100% — every time a config file key exists for any of the 13 affected parameters.
Steps to reproduce the behaviour
- Set
node.rpc.thread = 8inconfig.conf - Start node with
java -jar FullNode.jar -c config.conf --rpc-thread 16 - Observe that
rpcThreadNumis 8, not 16
Any of the following 13 parameters can reproduce the same issue:
| # | CLI Flag | Field | Config Key |
|---|---|---|---|
| 1 | --support-constant |
supportConstant |
vm.supportConstant |
| 2 | --max-energy-limit-for-constant |
maxEnergyLimitForConstant |
vm.maxEnergyLimitForConstant |
| 3 | --lru-cache-size |
lruCacheSize |
vm.lruCacheSize |
| 4 | --min-time-ratio |
minTimeRatio |
vm.minTimeRatio |
| 5 | --max-time-ratio |
maxTimeRatio |
vm.maxTimeRatio |
| 6 | --long-running-time |
longRunningTime |
vm.longRunningTime |
| 7 | --save-internaltx |
saveInternalTx |
vm.saveInternalTx |
| 8 | --save-featured-internaltx |
saveFeaturedInternalTx |
vm.saveFeaturedInternalTx |
| 9 | --max-connect-number |
maxHttpConnectNumber |
node.maxHttpConnectNumber |
| 10 | --rpc-thread |
rpcThreadNum |
node.rpc.thread |
| 11 | --solidity-thread |
solidityThreads |
node.solidity.threads |
| 12 | --validate-sign-thread |
validateSignThreadNum |
node.validateSignThreadNum |
| 13 | --history-balance-lookup |
historyBalanceLookup |
storage.balance.history.lookup |
Backtrace
Not applicable — no crash or exception. The bug is silent incorrect behavior.
Below is the full findings of all 34 @Parameter CLI flags in CommonParameter and additional findings.
full findings: all 34 CLI parameters by category
Category 1: Startup parameters (6) — No issue
Only control startup flow, no config file overlap.
| CLI Flag | Field | Description |
|---|---|---|
-c, --config |
shellConfFileName |
Config file path |
-d, --output-directory |
outputDirectory |
Data directory |
--log-config |
logbackPath |
Log config file |
-h, --help |
help |
Print help and exit |
-v, --version |
version |
Print version and exit |
--password |
password |
Witness password |
Category 2: CLI-only parameters (10) — No issue
Only set by CLI, setParam(Config) does not override.
| CLI Flag | Field | Description |
|---|---|---|
-w, --witness |
witness |
Witness mode |
-p, --private-key |
privateKey |
Witness private key |
--witness-address |
witnessAddress |
Witness address |
--debug |
debug |
TVM debug mode |
--fast-forward |
fastForward |
Fast forward mode |
--solidity |
solidityNode |
Solidity node mode |
--keystore-factory |
keystoreFactory |
KeystoreFactory mode |
--p2p-disable |
p2pDisable |
Disable P2P module |
--es |
eventSubscribe |
Enable event subscription |
--contract-parse-enable |
contractParseEnable |
Contract parse switch |
Category 3: CLI + Config, CLI priority (9) — Correct
Uses Optional pattern, CLI value takes priority when present.
| CLI Flag | Field | Config Key |
|---|---|---|
--storage-db-directory |
storageDbDirectory |
storage.db.directory |
--storage-db-engine |
storageDbEngine |
storage.db.engine |
--storage-db-synchronous |
storageDbSynchronous |
storage.db.synchronous |
--storage-index-directory |
storageIndexDirectory |
storage.index.directory |
--storage-index-switch |
storageIndexSwitch |
storage.index.switch |
--storage-transactionHistory-switch |
storageTransactionHistorySwitch |
storage.transactionHistory.switch |
--trust-node |
trustNodeAddr |
node.trustNode |
--save-cancel-all-unfreeze-v2-details |
saveCancelAllUnfreezeV2Details |
vm.saveCancelAllUnfreezeV2Details |
--seed-nodes |
seedNodes |
seed.node.ip.list |
Category 4: CLI + Config, config overwrites CLI (13) — BUG
See "Steps to reproduce" section above for full list.
Other issues found during investigation
clearParam() misses 9 fields
clearParam() is used for test state reset, but the following fields are not cleared, which may cause test pollution:
maxEnergyLimitForConstant,lruCacheSizeallowDelegateOptimization,unfreezeDelayDaysallowDynamicEnergy,dynamicEnergyThreshold,dynamicEnergyIncreaseFactor,dynamicEnergyMaxFactorsaveCancelAllUnfreezeV2Details
Inconsistent default value patterns
Two patterns coexist in Args.setParam():
- Pattern A (ternary): default value explicit —
config.hasPath(key) ? config.get(key) : defaultValue - Pattern B (if-block, no else): default value hidden in
CommonParameterfield declaration
Mixing both increases maintenance burden. Suggest unifying to Pattern A.
CommonParameter overloaded
780 lines, ~150 fields, mixing CLI parameters, config file values, and runtime objects. Long-term suggestion: split into domain-specific classes (RpcConfig, StorageConfig, VmConfig, etc.).
Suggested improvement roadmap
Industry comparison
| Project | CLI/Config Overlap | Strategy | Priority Rule |
|---|---|---|---|
| Nginx | Nearly none | CLI for startup ops only; all business config in file | CLI > config |
| Hadoop | Full overlap | All items overridable via -D key=value; multi-layer XML merge |
CLI > site XML > default XML |
| Kubernetes | Heavy → deprecating CLI | Migrating to config file; CLI flags marked deprecated | CLI > config file |
java-tron's current situation is most similar to early Kubernetes.
Short-term (current release): Fix the priority bug
if (PARAMETER.rpcThreadNum <= 0) {
PARAMETER.rpcThreadNum = config.hasPath(ConfigKey.NODE_RPC_THREAD)
? config.getInt(ConfigKey.NODE_RPC_THREAD)
: Runtime.getRuntime().availableProcessors() / 2;
}Mid-term (next release): Deprecate overlapping CLI flags
@Deprecated // Use node.rpc.thread in config.conf instead
@Parameter(names = {"--rpc-thread"}, description = "[DEPRECATED] Num of gRPC thread")
public int rpcThreadNum;Long-term (future release): Converge to Nginx model
Only keep ~8 startup-class CLI parameters (-c, -d, -w, -p, -h, -v, --password, --log-config). All other runtime parameters managed exclusively by config file.