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  }