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  }