github.com/klaytn/klaytn@v1.10.2/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 "gopkg.in/urfave/cli.v1" 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 KeyStoreDirFlag, 45 IdentityFlag, 46 SyncModeFlag, 47 GCModeFlag, 48 LightKDFFlag, 49 SrvTypeFlag, 50 ExtraDataFlag, 51 ConfigFileFlag, 52 OverwriteGenesisFlag, 53 StartBlockNumberFlag, 54 BlockGenerationIntervalFlag, 55 BlockGenerationTimeLimitFlag, 56 OpcodeComputationCostLimitFlag, 57 }, 58 }, 59 { 60 Name: "ACCOUNT", 61 Flags: []cli.Flag{ 62 UnlockedAccountFlag, 63 PasswordFileFlag, 64 }, 65 }, 66 { 67 Name: "TXPOOL", 68 Flags: []cli.Flag{ 69 TxPoolNoLocalsFlag, 70 TxPoolAllowLocalAnchorTxFlag, 71 TxPoolDenyRemoteTxFlag, 72 TxPoolJournalFlag, 73 TxPoolJournalIntervalFlag, 74 TxPoolPriceLimitFlag, 75 TxPoolPriceBumpFlag, 76 TxPoolExecSlotsAccountFlag, 77 TxPoolExecSlotsAllFlag, 78 TxPoolNonExecSlotsAccountFlag, 79 TxPoolNonExecSlotsAllFlag, 80 TxPoolLifetimeFlag, 81 TxPoolKeepLocalsFlag, 82 TxResendIntervalFlag, 83 TxResendCountFlag, 84 TxResendUseLegacyFlag, 85 }, 86 }, 87 { 88 Name: "DATABASE", 89 Flags: []cli.Flag{ 90 LevelDBCacheSizeFlag, 91 SingleDBFlag, 92 NumStateTrieShardsFlag, 93 LevelDBCompressionTypeFlag, 94 LevelDBNoBufferPoolFlag, 95 DynamoDBTableNameFlag, 96 DynamoDBRegionFlag, 97 DynamoDBIsProvisionedFlag, 98 DynamoDBReadCapacityFlag, 99 DynamoDBWriteCapacityFlag, 100 NoParallelDBWriteFlag, 101 SenderTxHashIndexingFlag, 102 DBNoPerformanceMetricsFlag, 103 }, 104 }, 105 { 106 Name: "DATABASE SYNCER", 107 Flags: []cli.Flag{ 108 EnableDBSyncerFlag, 109 DBHostFlag, 110 DBPortFlag, 111 DBNameFlag, 112 DBUserFlag, 113 DBPasswordFlag, 114 EnabledLogModeFlag, 115 MaxIdleConnsFlag, 116 MaxOpenConnsFlag, 117 ConnMaxLifeTimeFlag, 118 BlockSyncChannelSizeFlag, 119 DBSyncerModeFlag, 120 GenQueryThreadFlag, 121 InsertThreadFlag, 122 BulkInsertSizeFlag, 123 EventModeFlag, 124 MaxBlockDiffFlag, 125 }, 126 }, 127 { 128 Name: "CHAINDATAFETCHER", 129 Flags: []cli.Flag{ 130 EnableChainDataFetcherFlag, 131 ChainDataFetcherMode, 132 ChainDataFetcherNoDefault, 133 ChainDataFetcherNumHandlers, 134 ChainDataFetcherJobChannelSize, 135 ChainDataFetcherChainEventSizeFlag, 136 ChainDataFetcherMaxProcessingDataSize, 137 ChainDataFetcherKASDBHostFlag, 138 ChainDataFetcherKASDBPortFlag, 139 ChainDataFetcherKASDBNameFlag, 140 ChainDataFetcherKASDBUserFlag, 141 ChainDataFetcherKASDBPasswordFlag, 142 ChainDataFetcherKASCacheUse, 143 ChainDataFetcherKASCacheURLFlag, 144 ChainDataFetcherKASXChainIdFlag, 145 ChainDataFetcherKASBasicAuthParamFlag, 146 ChainDataFetcherKafkaBrokersFlag, 147 ChainDataFetcherKafkaTopicEnvironmentFlag, 148 ChainDataFetcherKafkaTopicResourceFlag, 149 ChainDataFetcherKafkaReplicasFlag, 150 ChainDataFetcherKafkaPartitionsFlag, 151 ChainDataFetcherKafkaMaxMessageBytesFlag, 152 ChainDataFetcherKafkaSegmentSizeBytesFlag, 153 ChainDataFetcherKafkaRequiredAcksFlag, 154 ChainDataFetcherKafkaMessageVersionFlag, 155 ChainDataFetcherKafkaProducerIdFlag, 156 }, 157 }, 158 { 159 Name: "DATABASE MIGRATION", 160 Flags: []cli.Flag{ 161 DstDbTypeFlag, 162 DstDataDirFlag, 163 DstSingleDBFlag, 164 DstLevelDBCompressionTypeFlag, 165 DstNumStateTrieShardsFlag, 166 DstDynamoDBTableNameFlag, 167 DstDynamoDBRegionFlag, 168 DstDynamoDBIsProvisionedFlag, 169 DstDynamoDBReadCapacityFlag, 170 DstDynamoDBWriteCapacityFlag, 171 }, 172 }, 173 { 174 Name: "STATE", 175 Flags: []cli.Flag{ 176 TrieMemoryCacheSizeFlag, 177 TrieBlockIntervalFlag, 178 TriesInMemoryFlag, 179 }, 180 }, 181 { 182 Name: "CACHE", 183 Flags: []cli.Flag{ 184 CacheTypeFlag, 185 CacheScaleFlag, 186 CacheUsageLevelFlag, 187 MemorySizeFlag, 188 TrieNodeCacheTypeFlag, 189 NumFetcherPrefetchWorkerFlag, 190 UseSnapshotForPrefetchFlag, 191 TrieNodeCacheLimitFlag, 192 TrieNodeCacheSavePeriodFlag, 193 TrieNodeCacheRedisEndpointsFlag, 194 TrieNodeCacheRedisClusterFlag, 195 TrieNodeCacheRedisPublishBlockFlag, 196 TrieNodeCacheRedisSubscribeBlockFlag, 197 }, 198 }, 199 { 200 Name: "CONSENSUS", 201 Flags: []cli.Flag{ 202 ServiceChainSignerFlag, 203 RewardbaseFlag, 204 }, 205 }, 206 { 207 Name: "NETWORKING", 208 Flags: []cli.Flag{ 209 BootnodesFlag, 210 ListenPortFlag, 211 SubListenPortFlag, 212 MultiChannelUseFlag, 213 MaxConnectionsFlag, 214 MaxPendingPeersFlag, 215 TargetGasLimitFlag, 216 NATFlag, 217 NoDiscoverFlag, 218 RWTimerWaitTimeFlag, 219 RWTimerIntervalFlag, 220 NetrestrictFlag, 221 NodeKeyFileFlag, 222 NodeKeyHexFlag, 223 NetworkIdFlag, 224 BaobabFlag, 225 CypressFlag, 226 }, 227 }, 228 { 229 Name: "METRICS", 230 Flags: []cli.Flag{ 231 MetricsEnabledFlag, 232 PrometheusExporterFlag, 233 PrometheusExporterPortFlag, 234 }, 235 }, 236 { 237 Name: "VIRTUAL MACHINE", 238 Flags: []cli.Flag{ 239 VMEnableDebugFlag, 240 VMLogTargetFlag, 241 VMTraceInternalTxFlag, 242 }, 243 }, 244 { 245 Name: "API AND CONSOLE", 246 Flags: []cli.Flag{ 247 RPCEnabledFlag, 248 RPCListenAddrFlag, 249 RPCPortFlag, 250 RPCCORSDomainFlag, 251 RPCVirtualHostsFlag, 252 RPCApiFlag, 253 RPCGlobalGasCap, 254 RPCGlobalEVMTimeoutFlag, 255 RPCGlobalEthTxFeeCapFlag, 256 RPCConcurrencyLimit, 257 RPCNonEthCompatibleFlag, 258 UnsafeDebugDisableFlag, 259 IPCDisabledFlag, 260 IPCPathFlag, 261 WSEnabledFlag, 262 WSListenAddrFlag, 263 WSPortFlag, 264 WSApiFlag, 265 WSAllowedOriginsFlag, 266 GRPCEnabledFlag, 267 GRPCListenAddrFlag, 268 GRPCPortFlag, 269 JSpathFlag, 270 ExecFlag, 271 PreloadJSFlag, 272 MaxRequestContentLengthFlag, 273 APIFilterGetLogsDeadlineFlag, 274 APIFilterGetLogsMaxItemsFlag, 275 }, 276 }, 277 { 278 Name: "LOGGING AND DEBUGGING", 279 Flags: debug.Flags, 280 }, 281 { 282 Name: "SERVICECHAIN", 283 Flags: []cli.Flag{ 284 ChildChainIndexingFlag, 285 MainBridgeFlag, 286 MainBridgeListenPortFlag, 287 SubBridgeFlag, 288 SubBridgeListenPortFlag, 289 AnchoringPeriodFlag, 290 SentChainTxsLimit, 291 ParentChainIDFlag, 292 VTRecoveryFlag, 293 VTRecoveryIntervalFlag, 294 ServiceChainAnchoringFlag, 295 ServiceChainNewAccountFlag, 296 ServiceChainParentOperatorTxGasLimitFlag, 297 ServiceChainChildOperatorTxGasLimitFlag, 298 KASServiceChainAnchorFlag, 299 KASServiceChainAnchorPeriodFlag, 300 KASServiceChainAnchorUrlFlag, 301 KASServiceChainAnchorOperatorFlag, 302 KASServiceChainAccessKeyFlag, 303 KASServiceChainSecretKeyFlag, 304 KASServiceChainXChainIdFlag, 305 KASServiceChainAnchorRequestTimeoutFlag, 306 }, 307 }, 308 { 309 Name: "MISC", 310 Flags: []cli.Flag{ 311 GenKeyFlag, 312 WriteAddressFlag, 313 AutoRestartFlag, 314 RestartTimeOutFlag, 315 DaemonPathFlag, 316 KESNodeTypeServiceFlag, 317 SnapshotFlag, 318 SnapshotCacheSizeFlag, 319 SnapshotAsyncGen, 320 }, 321 }, 322 } 323 324 // CategorizeFlags classifies each flag into pre-defined flagGroups. 325 func CategorizeFlags(flags []cli.Flag) []FlagGroup { 326 flagGroupsMap := make(map[string][]cli.Flag) 327 isFlagAdded := make(map[string]bool) // Check duplicated flags 328 329 // Find its group for each flag 330 for _, flag := range flags { 331 if isFlagAdded[flag.GetName()] { 332 logger.Debug("a flag is added in the help description more than one time", "flag", flag.GetName()) 333 continue 334 } 335 336 // Find a group of the flag. If a flag doesn't belong to any groups, categorize it as a MISC flag 337 group := flagCategory(flag, FlagGroups) 338 flagGroupsMap[group] = append(flagGroupsMap[group], flag) 339 isFlagAdded[flag.GetName()] = true 340 } 341 342 // Convert flagGroupsMap to a slice of FlagGroup 343 flagGroups := []FlagGroup{} 344 for group, flags := range flagGroupsMap { 345 flagGroups = append(flagGroups, FlagGroup{Name: group, Flags: flags}) 346 } 347 348 // Sort flagGroups in ascending order of name 349 sortFlagGroup(flagGroups, uncategorized) 350 351 return flagGroups 352 } 353 354 // sortFlagGroup sorts a slice of FlagGroup in ascending order of name, 355 // but an uncategorized group is exceptionally placed at the end. 356 func sortFlagGroup(flagGroups []FlagGroup, uncategorized string) []FlagGroup { 357 sort.Slice(flagGroups, func(i, j int) bool { 358 if flagGroups[i].Name == uncategorized { 359 return false 360 } 361 if flagGroups[j].Name == uncategorized { 362 return true 363 } 364 return flagGroups[i].Name < flagGroups[j].Name 365 }) 366 367 // Sort flags in each group i ascending order of flag name. 368 for _, group := range flagGroups { 369 sort.Slice(group.Flags, func(i, j int) bool { 370 return group.Flags[i].GetName() < group.Flags[j].GetName() 371 }) 372 } 373 374 return flagGroups 375 } 376 377 // flagCategory returns belonged group of the given flag. 378 func flagCategory(flag cli.Flag, fg []FlagGroup) string { 379 for _, category := range fg { 380 for _, flg := range category.Flags { 381 if flg.GetName() == flag.GetName() { 382 return category.Name 383 } 384 } 385 } 386 return uncategorized 387 }