github.com/klaytn/klaytn@v1.12.1/cmd/utils/flaggroup.go (about) 1 // Copyright 2020 The klaytn Authors 2 // This file is part of the klaytn library. 3 // 4 // The klaytn library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The klaytn library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the klaytn library. If not, see <http://www.gnu.org/licenses/>. 16 17 package utils 18 19 import ( 20 "sort" 21 22 "github.com/klaytn/klaytn/api/debug" 23 "github.com/urfave/cli/v2" 24 ) 25 26 const uncategorized = "MISC" // Uncategorized flags will belong to this group 27 28 // FlagGroup is a collection of flags belonging to a single topic. 29 type FlagGroup struct { 30 Name string 31 Flags []cli.Flag 32 } 33 34 // TODO-Klaytn: consider changing the type of FlagGroups to map 35 // FlagGroups categorizes flags into groups to print structured help. 36 var FlagGroups = []FlagGroup{ 37 { 38 Name: "KLAY", 39 Flags: []cli.Flag{ 40 NtpDisableFlag, 41 NtpServerFlag, 42 DbTypeFlag, 43 DataDirFlag, 44 ChainDataDirFlag, 45 IdentityFlag, 46 SyncModeFlag, 47 GCModeFlag, 48 SrvTypeFlag, 49 ExtraDataFlag, 50 ConfigFileFlag, 51 OverwriteGenesisFlag, 52 StartBlockNumberFlag, 53 BlockGenerationIntervalFlag, 54 BlockGenerationTimeLimitFlag, 55 OpcodeComputationCostLimitFlag, 56 }, 57 }, 58 { 59 Name: "ACCOUNT", 60 Flags: []cli.Flag{ 61 UnlockedAccountFlag, 62 PasswordFileFlag, 63 LightKDFFlag, 64 KeyStoreDirFlag, 65 }, 66 }, 67 { 68 Name: "TXPOOL", 69 Flags: []cli.Flag{ 70 TxPoolNoLocalsFlag, 71 TxPoolAllowLocalAnchorTxFlag, 72 TxPoolDenyRemoteTxFlag, 73 TxPoolJournalFlag, 74 TxPoolJournalIntervalFlag, 75 TxPoolPriceLimitFlag, 76 TxPoolPriceBumpFlag, 77 TxPoolExecSlotsAccountFlag, 78 TxPoolExecSlotsAllFlag, 79 TxPoolNonExecSlotsAccountFlag, 80 TxPoolNonExecSlotsAllFlag, 81 TxPoolLifetimeFlag, 82 TxPoolKeepLocalsFlag, 83 TxResendIntervalFlag, 84 TxResendCountFlag, 85 TxResendUseLegacyFlag, 86 }, 87 }, 88 { 89 Name: "DATABASE", 90 Flags: []cli.Flag{ 91 LevelDBCacheSizeFlag, 92 SingleDBFlag, 93 NumStateTrieShardsFlag, 94 LevelDBCompressionTypeFlag, 95 LevelDBNoBufferPoolFlag, 96 RocksDBSecondaryFlag, 97 RocksDBCacheSizeFlag, 98 RocksDBDumpMallocStatFlag, 99 RocksDBCompressionTypeFlag, 100 RocksDBBottommostCompressionTypeFlag, 101 RocksDBFilterPolicyFlag, 102 RocksDBDisableMetricsFlag, 103 RocksDBMaxOpenFilesFlag, 104 RocksDBCacheIndexAndFilterFlag, 105 DynamoDBTableNameFlag, 106 DynamoDBRegionFlag, 107 DynamoDBIsProvisionedFlag, 108 DynamoDBReadCapacityFlag, 109 DynamoDBWriteCapacityFlag, 110 DynamoDBReadOnlyFlag, 111 NoParallelDBWriteFlag, 112 SenderTxHashIndexingFlag, 113 DBNoPerformanceMetricsFlag, 114 }, 115 }, 116 { 117 Name: "DATABASE SYNCER", 118 Flags: []cli.Flag{ 119 EnableDBSyncerFlag, 120 DBHostFlag, 121 DBPortFlag, 122 DBNameFlag, 123 DBUserFlag, 124 DBPasswordFlag, 125 EnabledLogModeFlag, 126 MaxIdleConnsFlag, 127 MaxOpenConnsFlag, 128 ConnMaxLifeTimeFlag, 129 BlockSyncChannelSizeFlag, 130 DBSyncerModeFlag, 131 GenQueryThreadFlag, 132 InsertThreadFlag, 133 BulkInsertSizeFlag, 134 EventModeFlag, 135 MaxBlockDiffFlag, 136 }, 137 }, 138 { 139 Name: "CHAINDATAFETCHER", 140 Flags: []cli.Flag{ 141 EnableChainDataFetcherFlag, 142 ChainDataFetcherMode, 143 ChainDataFetcherNoDefault, 144 ChainDataFetcherNumHandlers, 145 ChainDataFetcherJobChannelSize, 146 ChainDataFetcherChainEventSizeFlag, 147 ChainDataFetcherMaxProcessingDataSize, 148 ChainDataFetcherKASDBHostFlag, 149 ChainDataFetcherKASDBPortFlag, 150 ChainDataFetcherKASDBNameFlag, 151 ChainDataFetcherKASDBUserFlag, 152 ChainDataFetcherKASDBPasswordFlag, 153 ChainDataFetcherKASCacheUse, 154 ChainDataFetcherKASCacheURLFlag, 155 ChainDataFetcherKASXChainIdFlag, 156 ChainDataFetcherKASBasicAuthParamFlag, 157 ChainDataFetcherKafkaBrokersFlag, 158 ChainDataFetcherKafkaTopicEnvironmentFlag, 159 ChainDataFetcherKafkaTopicResourceFlag, 160 ChainDataFetcherKafkaReplicasFlag, 161 ChainDataFetcherKafkaPartitionsFlag, 162 ChainDataFetcherKafkaMaxMessageBytesFlag, 163 ChainDataFetcherKafkaSegmentSizeBytesFlag, 164 ChainDataFetcherKafkaRequiredAcksFlag, 165 ChainDataFetcherKafkaMessageVersionFlag, 166 ChainDataFetcherKafkaProducerIdFlag, 167 }, 168 }, 169 { 170 Name: "DATABASE MIGRATION", 171 Flags: []cli.Flag{ 172 DstDbTypeFlag, 173 DstDataDirFlag, 174 DstSingleDBFlag, 175 DstLevelDBCompressionTypeFlag, 176 DstLevelDBCacheSizeFlag, 177 DstNumStateTrieShardsFlag, 178 DstDynamoDBTableNameFlag, 179 DstDynamoDBRegionFlag, 180 DstDynamoDBIsProvisionedFlag, 181 DstDynamoDBReadCapacityFlag, 182 DstDynamoDBWriteCapacityFlag, 183 DstRocksDBSecondaryFlag, 184 DstRocksDBCacheSizeFlag, 185 DstRocksDBDumpMallocStatFlag, 186 DstRocksDBCompressionTypeFlag, 187 DstRocksDBBottommostCompressionTypeFlag, 188 DstRocksDBFilterPolicyFlag, 189 DstRocksDBDisableMetricsFlag, 190 DstRocksDBMaxOpenFilesFlag, 191 DstRocksDBCacheIndexAndFilterFlag, 192 }, 193 }, 194 { 195 Name: "STATE", 196 Flags: []cli.Flag{ 197 TrieMemoryCacheSizeFlag, 198 TrieBlockIntervalFlag, 199 TriesInMemoryFlag, 200 LivePruningFlag, 201 LivePruningRetentionFlag, 202 }, 203 }, 204 { 205 Name: "CACHE", 206 Flags: []cli.Flag{ 207 CacheTypeFlag, 208 CacheScaleFlag, 209 CacheUsageLevelFlag, 210 MemorySizeFlag, 211 TrieNodeCacheTypeFlag, 212 NumFetcherPrefetchWorkerFlag, 213 UseSnapshotForPrefetchFlag, 214 TrieNodeCacheLimitFlag, 215 TrieNodeCacheSavePeriodFlag, 216 TrieNodeCacheRedisEndpointsFlag, 217 TrieNodeCacheRedisClusterFlag, 218 TrieNodeCacheRedisPublishBlockFlag, 219 TrieNodeCacheRedisSubscribeBlockFlag, 220 }, 221 }, 222 { 223 Name: "CONSENSUS", 224 Flags: []cli.Flag{ 225 ServiceChainSignerFlag, 226 RewardbaseFlag, 227 }, 228 }, 229 { 230 Name: "NETWORKING", 231 Flags: []cli.Flag{ 232 BootnodesFlag, 233 ListenPortFlag, 234 SubListenPortFlag, 235 MultiChannelUseFlag, 236 MaxConnectionsFlag, 237 MaxPendingPeersFlag, 238 TargetGasLimitFlag, 239 NATFlag, 240 NoDiscoverFlag, 241 RWTimerWaitTimeFlag, 242 RWTimerIntervalFlag, 243 NetrestrictFlag, 244 NodeKeyFileFlag, 245 NodeKeyHexFlag, 246 NetworkIdFlag, 247 BaobabFlag, 248 CypressFlag, 249 }, 250 }, 251 { 252 Name: "METRICS", 253 Flags: []cli.Flag{ 254 MetricsEnabledFlag, 255 PrometheusExporterFlag, 256 PrometheusExporterPortFlag, 257 }, 258 }, 259 { 260 Name: "VIRTUAL MACHINE", 261 Flags: []cli.Flag{ 262 VMEnableDebugFlag, 263 VMLogTargetFlag, 264 VMTraceInternalTxFlag, 265 VMOpDebugFlag, 266 }, 267 }, 268 { 269 Name: "API AND CONSOLE", 270 Flags: []cli.Flag{ 271 RPCEnabledFlag, 272 HeavyDebugRequestLimitFlag, 273 StateRegenerationTimeLimitFlag, 274 RPCListenAddrFlag, 275 RPCPortFlag, 276 RPCCORSDomainFlag, 277 RPCVirtualHostsFlag, 278 RPCApiFlag, 279 RPCGlobalGasCap, 280 RPCGlobalEVMTimeoutFlag, 281 RPCGlobalEthTxFeeCapFlag, 282 RPCConcurrencyLimit, 283 RPCNonEthCompatibleFlag, 284 RPCExecutionTimeoutFlag, 285 RPCIdleTimeoutFlag, 286 RPCReadTimeout, 287 RPCWriteTimeoutFlag, 288 RPCUpstreamArchiveENFlag, 289 UnsafeDebugDisableFlag, 290 IPCDisabledFlag, 291 IPCPathFlag, 292 WSEnabledFlag, 293 WSListenAddrFlag, 294 WSPortFlag, 295 WSApiFlag, 296 WSAllowedOriginsFlag, 297 WSMaxConnections, 298 WSMaxSubscriptionPerConn, 299 WSReadDeadLine, 300 WSWriteDeadLine, 301 GRPCEnabledFlag, 302 GRPCListenAddrFlag, 303 GRPCPortFlag, 304 JSpathFlag, 305 ExecFlag, 306 PreloadJSFlag, 307 MaxRequestContentLengthFlag, 308 APIFilterGetLogsDeadlineFlag, 309 APIFilterGetLogsMaxItemsFlag, 310 }, 311 }, 312 { 313 Name: "LOGGING AND DEBUGGING", 314 Flags: debug.Flags, 315 }, 316 { 317 Name: "SERVICECHAIN", 318 Flags: []cli.Flag{ 319 ChildChainIndexingFlag, 320 MainBridgeFlag, 321 MainBridgeListenPortFlag, 322 SubBridgeFlag, 323 SubBridgeListenPortFlag, 324 AnchoringPeriodFlag, 325 SentChainTxsLimit, 326 ParentChainIDFlag, 327 VTRecoveryFlag, 328 VTRecoveryIntervalFlag, 329 ServiceChainAnchoringFlag, 330 ServiceChainNewAccountFlag, 331 ServiceChainParentOperatorTxGasLimitFlag, 332 ServiceChainChildOperatorTxGasLimitFlag, 333 KASServiceChainAnchorFlag, 334 KASServiceChainAnchorPeriodFlag, 335 KASServiceChainAnchorUrlFlag, 336 KASServiceChainAnchorOperatorFlag, 337 KASServiceChainAccessKeyFlag, 338 KASServiceChainSecretKeyFlag, 339 KASServiceChainXChainIdFlag, 340 KASServiceChainAnchorRequestTimeoutFlag, 341 }, 342 }, 343 { 344 Name: "MISC", 345 Flags: []cli.Flag{ 346 GenKeyFlag, 347 WriteAddressFlag, 348 AutoRestartFlag, 349 RestartTimeOutFlag, 350 DaemonPathFlag, 351 KESNodeTypeServiceFlag, 352 SnapshotFlag, 353 SnapshotCacheSizeFlag, 354 SnapshotAsyncGen, 355 DocRootFlag, 356 }, 357 }, 358 } 359 360 // CategorizeFlags classifies each flag into pre-defined flagGroups. 361 func CategorizeFlags(flags []cli.Flag) []FlagGroup { 362 flagGroupsMap := make(map[string][]cli.Flag) 363 isFlagAdded := make(map[string]bool) // Check duplicated flags 364 365 // Find its group for each flag 366 for _, flag := range flags { 367 if isFlagAdded[flag.Names()[0]] { 368 logger.Debug("a flag is added in the help description more than one time", "flag", flag.Names()[0]) 369 continue 370 } 371 372 // Find a group of the flag. If a flag doesn't belong to any groups, categorize it as a MISC flag 373 group := flagCategory(flag, FlagGroups) 374 flagGroupsMap[group] = append(flagGroupsMap[group], flag) 375 isFlagAdded[flag.Names()[0]] = true 376 } 377 378 // Convert flagGroupsMap to a slice of FlagGroup 379 flagGroups := []FlagGroup{} 380 for group, flags := range flagGroupsMap { 381 flagGroups = append(flagGroups, FlagGroup{Name: group, Flags: flags}) 382 } 383 384 // Sort flagGroups in ascending order of name 385 sortFlagGroup(flagGroups, uncategorized) 386 387 return flagGroups 388 } 389 390 // sortFlagGroup sorts a slice of FlagGroup in ascending order of name, 391 // but an uncategorized group is exceptionally placed at the end. 392 func sortFlagGroup(flagGroups []FlagGroup, uncategorized string) []FlagGroup { 393 sort.Slice(flagGroups, func(i, j int) bool { 394 if flagGroups[i].Name == uncategorized { 395 return false 396 } 397 if flagGroups[j].Name == uncategorized { 398 return true 399 } 400 return flagGroups[i].Name < flagGroups[j].Name 401 }) 402 403 // Sort flags in each group i ascending order of flag name. 404 for _, group := range flagGroups { 405 sort.Slice(group.Flags, func(i, j int) bool { 406 return group.Flags[i].Names()[0] < group.Flags[j].Names()[0] 407 }) 408 } 409 410 return flagGroups 411 } 412 413 // flagCategory returns belonged group of the given flag. 414 func flagCategory(flag cli.Flag, fg []FlagGroup) string { 415 for _, category := range fg { 416 for _, flg := range category.Flags { 417 if flg.Names()[0] == flag.Names()[0] { 418 return category.Name 419 } 420 } 421 } 422 return uncategorized 423 }