github.com/okex/exchain@v1.8.0/libs/tendermint/config/toml.go (about)

     1  package config
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"path/filepath"
     8  	"text/template"
     9  
    10  	tmos "github.com/okex/exchain/libs/tendermint/libs/os"
    11  )
    12  
    13  // DefaultDirPerm is the default permissions used when creating directories.
    14  const DefaultDirPerm = 0700
    15  
    16  var configTemplate *template.Template
    17  
    18  func init() {
    19  	var err error
    20  	if configTemplate, err = template.New("configFileTemplate").Parse(defaultConfigTemplate); err != nil {
    21  		panic(err)
    22  	}
    23  }
    24  
    25  /****** these are for production settings ***********/
    26  
    27  // EnsureRoot creates the root, config, and data directories if they don't exist,
    28  // and panics if it fails.
    29  func EnsureRoot(rootDir string) {
    30  	if err := tmos.EnsureDir(rootDir, DefaultDirPerm); err != nil {
    31  		panic(err.Error())
    32  	}
    33  	if err := tmos.EnsureDir(filepath.Join(rootDir, defaultConfigDir), DefaultDirPerm); err != nil {
    34  		panic(err.Error())
    35  	}
    36  	if err := tmos.EnsureDir(filepath.Join(rootDir, defaultDataDir), DefaultDirPerm); err != nil {
    37  		panic(err.Error())
    38  	}
    39  
    40  	configFilePath := filepath.Join(rootDir, defaultConfigFilePath)
    41  
    42  	// Write default config file if missing.
    43  	if !tmos.FileExists(configFilePath) {
    44  		writeDefaultConfigFile(configFilePath)
    45  	}
    46  }
    47  
    48  // XXX: this func should probably be called by cmd/tendermint/commands/init.go
    49  // alongside the writing of the genesis.json and priv_validator.json
    50  func writeDefaultConfigFile(configFilePath string) {
    51  	WriteConfigFile(configFilePath, DefaultConfig())
    52  }
    53  
    54  // WriteConfigFile renders config using the template and writes it to configFilePath.
    55  func WriteConfigFile(configFilePath string, config *Config) {
    56  	var buffer bytes.Buffer
    57  
    58  	if err := configTemplate.Execute(&buffer, config); err != nil {
    59  		panic(err)
    60  	}
    61  
    62  	tmos.MustWriteFile(configFilePath, buffer.Bytes(), 0644)
    63  }
    64  
    65  // Note: any changes to the comments/variables/mapstructure
    66  // must be reflected in the appropriate struct in config/config.go
    67  const defaultConfigTemplate = `# This is a TOML config file.
    68  # For more information, see https://github.com/toml-lang/toml
    69  
    70  # NOTE: Any path below can be absolute (e.g. "/var/myawesomeapp/data") or
    71  # relative to the home directory (e.g. "data"). The home directory is
    72  # "$HOME/.tendermint" by default, but could be changed via $TMHOME env variable
    73  # or --home cmd flag.
    74  
    75  ##### main base config options #####
    76  
    77  # TCP or UNIX socket address of the ABCI application,
    78  # or the name of an ABCI application compiled in with the Tendermint binary
    79  proxy_app = "{{ .BaseConfig.ProxyApp }}"
    80  
    81  # A custom human readable name for this node
    82  moniker = "{{ .BaseConfig.Moniker }}"
    83  
    84  # If this node is many blocks behind the tip of the chain, FastSync
    85  # allows them to catchup quickly by downloading blocks in parallel
    86  # and verifying their commits
    87  fast_sync = {{ .BaseConfig.FastSyncMode }}
    88  
    89  # AutoFastSync allows this node switches from consensus mode to fast-sync mode automatically
    90  # when it is many blocks behind the tip of the chain.
    91  auto_fast_sync = {{ .BaseConfig.AutoFastSync }}
    92  
    93  # Database backend: goleveldb | cleveldb | boltdb | rocksdb
    94  # * goleveldb (github.com/syndtr/goleveldb - most popular implementation)
    95  #   - pure go
    96  #   - stable
    97  # * cleveldb (uses levigo wrapper)
    98  #   - fast
    99  #   - requires gcc
   100  #   - use cleveldb build tag (go build -tags cleveldb)
   101  # * boltdb (uses etcd's fork of bolt - github.com/etcd-io/bbolt)
   102  #   - EXPERIMENTAL
   103  #   - may be faster is some use-cases (random reads - indexer)
   104  #   - use boltdb build tag (go build -tags boltdb)
   105  # * rocksdb (uses github.com/tecbot/gorocksdb)
   106  #   - EXPERIMENTAL
   107  #   - requires gcc
   108  #   - use rocksdb build tag (go build -tags rocksdb)
   109  db_backend = "{{ .BaseConfig.DBBackend }}"
   110  
   111  # Database directory
   112  db_dir = "{{ js .BaseConfig.DBPath }}"
   113  
   114  # Output level for logging, including package level options
   115  log_level = "{{ .BaseConfig.LogLevel }}"
   116  
   117  # Output format: 'plain' (colored text) or 'json'
   118  log_format = "{{ .BaseConfig.LogFormat }}"
   119  
   120  ##### additional base config options #####
   121  
   122  # Path to the JSON file containing the initial validator set and other meta data
   123  genesis_file = "{{ js .BaseConfig.Genesis }}"
   124  
   125  # Path to the JSON file containing the private key to use as a validator in the consensus protocol
   126  priv_validator_key_file = "{{ js .BaseConfig.PrivValidatorKey }}"
   127  
   128  # Path to the JSON file containing the last sign state of a validator
   129  priv_validator_state_file = "{{ js .BaseConfig.PrivValidatorState }}"
   130  
   131  # TCP or UNIX socket address for Tendermint to listen on for
   132  # connections from an external PrivValidator process
   133  priv_validator_laddr = "{{ .BaseConfig.PrivValidatorListenAddr }}"
   134  
   135  # Path to the JSON file containing the private key to use for node authentication in the p2p protocol
   136  node_key_file = "{{ js .BaseConfig.NodeKey }}"
   137  
   138  # Mechanism to connect to the ABCI application: socket | grpc
   139  abci = "{{ .BaseConfig.ABCI }}"
   140  
   141  # TCP or UNIX socket address for the profiling server to listen on
   142  prof_laddr = "{{ .BaseConfig.ProfListenAddress }}"
   143  
   144  # If true, query the ABCI app on connecting to a new peer
   145  # so the app can decide if we should keep the connection or not
   146  filter_peers = {{ .BaseConfig.FilterPeers }}
   147  
   148  ##### advanced configuration options #####
   149  
   150  ##### rpc server configuration options #####
   151  [rpc]
   152  
   153  # TCP or UNIX socket address for the RPC server to listen on
   154  laddr = "{{ .RPC.ListenAddress }}"
   155  
   156  # A list of origins a cross-domain request can be executed from
   157  # Default value '[]' disables cors support
   158  # Use '["*"]' to allow any origin
   159  cors_allowed_origins = [{{ range .RPC.CORSAllowedOrigins }}{{ printf "%q, " . }}{{end}}]
   160  
   161  # A list of methods the client is allowed to use with cross-domain requests
   162  cors_allowed_methods = [{{ range .RPC.CORSAllowedMethods }}{{ printf "%q, " . }}{{end}}]
   163  
   164  # A list of non simple headers the client is allowed to use with cross-domain requests
   165  cors_allowed_headers = [{{ range .RPC.CORSAllowedHeaders }}{{ printf "%q, " . }}{{end}}]
   166  
   167  # TCP or UNIX socket address for the gRPC server to listen on
   168  # NOTE: This server only supports /broadcast_tx_commit
   169  grpc_laddr = "{{ .RPC.GRPCListenAddress }}"
   170  
   171  # Maximum number of simultaneous connections.
   172  # Does not include RPC (HTTP&WebSocket) connections. See max_open_connections
   173  # If you want to accept a larger number than the default, make sure
   174  # you increase your OS limits.
   175  # 0 - unlimited.
   176  # Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files}
   177  # 1024 - 40 - 10 - 50 = 924 = ~900
   178  grpc_max_open_connections = {{ .RPC.GRPCMaxOpenConnections }}
   179  
   180  # Activate unsafe RPC commands like /dial_seeds and /unsafe_flush_mempool
   181  unsafe = {{ .RPC.Unsafe }}
   182  
   183  # Maximum number of simultaneous connections (including WebSocket).
   184  # Does not include gRPC connections. See grpc_max_open_connections
   185  # If you want to accept a larger number than the default, make sure
   186  # you increase your OS limits.
   187  # 0 - unlimited.
   188  # Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files}
   189  # 1024 - 40 - 10 - 50 = 924 = ~900
   190  max_open_connections = {{ .RPC.MaxOpenConnections }}
   191  
   192  # Maximum number of unique clientIDs that can /subscribe
   193  # If you're using /broadcast_tx_commit, set to the estimated maximum number
   194  # of broadcast_tx_commit calls per block.
   195  max_subscription_clients = {{ .RPC.MaxSubscriptionClients }}
   196  
   197  # Maximum number of unique queries a given client can /subscribe to
   198  # If you're using GRPC (or Local RPC client) and /broadcast_tx_commit, set to
   199  # the estimated # maximum number of broadcast_tx_commit calls per block.
   200  max_subscriptions_per_client = {{ .RPC.MaxSubscriptionsPerClient }}
   201  
   202  # How long to wait for a tx to be committed during /broadcast_tx_commit.
   203  # WARNING: Using a value larger than 10s will result in increasing the
   204  # global HTTP write timeout, which applies to all connections and endpoints.
   205  # See https://github.com/tendermint/tendermint/issues/3435
   206  timeout_broadcast_tx_commit = "{{ .RPC.TimeoutBroadcastTxCommit }}"
   207  
   208  # Maximum size of request body, in bytes
   209  max_body_bytes = {{ .RPC.MaxBodyBytes }}
   210  
   211  # Maximum size of request header, in bytes
   212  max_header_bytes = {{ .RPC.MaxHeaderBytes }}
   213  
   214  # The path to a file containing certificate that is used to create the HTTPS server.
   215  # Migth be either absolute path or path related to tendermint's config directory.
   216  # If the certificate is signed by a certificate authority,
   217  # the certFile should be the concatenation of the server's certificate, any intermediates,
   218  # and the CA's certificate.
   219  # NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server.
   220  # Otherwise, HTTP server is run.
   221  tls_cert_file = "{{ .RPC.TLSCertFile }}"
   222  
   223  # The path to a file containing matching private key that is used to create the HTTPS server.
   224  # Migth be either absolute path or path related to tendermint's config directory.
   225  # NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server.
   226  # Otherwise, HTTP server is run.
   227  tls_key_file = "{{ .RPC.TLSKeyFile }}"
   228  
   229  ##### peer to peer configuration options #####
   230  [p2p]
   231  
   232  # Address to listen for incoming connections
   233  laddr = "{{ .P2P.ListenAddress }}"
   234  
   235  # Address to advertise to peers for them to dial
   236  # If empty, will use the same port as the laddr,
   237  # and will introspect on the listener or use UPnP
   238  # to figure out the address.
   239  external_address = "{{ .P2P.ExternalAddress }}"
   240  
   241  # Comma separated list of seed nodes to connect to
   242  seeds = "{{ .P2P.Seeds }}"
   243  
   244  # Comma separated list of nodes to keep persistent connections to
   245  persistent_peers = "{{ .P2P.PersistentPeers }}"
   246  
   247  # UPNP port forwarding
   248  upnp = {{ .P2P.UPNP }}
   249  
   250  # Path to address book
   251  addr_book_file = "{{ js .P2P.AddrBook }}"
   252  
   253  # Set true for strict address routability rules
   254  # Set false for private or local networks
   255  addr_book_strict = {{ .P2P.AddrBookStrict }}
   256  
   257  # Maximum number of inbound peers
   258  max_num_inbound_peers = {{ .P2P.MaxNumInboundPeers }}
   259  
   260  # Maximum number of outbound peers to connect to, excluding persistent peers
   261  max_num_outbound_peers = {{ .P2P.MaxNumOutboundPeers }}
   262  
   263  # List of node IDs, to which a connection will be (re)established ignoring any existing limits
   264  unconditional_peer_ids = "{{ .P2P.UnconditionalPeerIDs }}"
   265  
   266  # Maximum pause when redialing a persistent peer (if zero, exponential backoff is used)
   267  persistent_peers_max_dial_period = "{{ .P2P.PersistentPeersMaxDialPeriod }}"
   268  
   269  # Time to wait before flushing messages out on the connection
   270  flush_throttle_timeout = "{{ .P2P.FlushThrottleTimeout }}"
   271  
   272  # Maximum size of a message packet payload, in bytes
   273  max_packet_msg_payload_size = {{ .P2P.MaxPacketMsgPayloadSize }}
   274  
   275  # Rate at which packets can be sent, in bytes/second
   276  send_rate = {{ .P2P.SendRate }}
   277  
   278  # Rate at which packets can be received, in bytes/second
   279  recv_rate = {{ .P2P.RecvRate }}
   280  
   281  # Set true to enable the peer-exchange reactor
   282  pex = {{ .P2P.PexReactor }}
   283  
   284  # Seed mode, in which node constantly crawls the network and looks for
   285  # peers. If another node asks it for addresses, it responds and disconnects.
   286  #
   287  # Does not work if the peer-exchange reactor is disabled.
   288  seed_mode = {{ .P2P.SeedMode }}
   289  
   290  # Comma separated list of peer IDs to keep private (will not be gossiped to other peers)
   291  private_peer_ids = "{{ .P2P.PrivatePeerIDs }}"
   292  
   293  # Toggle to disable guard against peers connecting from the same ip.
   294  allow_duplicate_ip = {{ .P2P.AllowDuplicateIP }}
   295  
   296  # Peer connection configuration.
   297  handshake_timeout = "{{ .P2P.HandshakeTimeout }}"
   298  dial_timeout = "{{ .P2P.DialTimeout }}"
   299  
   300  ##### mempool configuration options #####
   301  [mempool]
   302  
   303  recheck = {{ .Mempool.Recheck }}
   304  force_recheck_gap = {{ .Mempool.ForceRecheckGap }}
   305  broadcast = {{ .Mempool.Broadcast }}
   306  
   307  # Maximum number of transactions in the mempool
   308  size = {{ .Mempool.Size }}
   309  
   310  # Limit the total size of all txs in the mempool.
   311  # This only accounts for raw transactions (e.g. given 1MB transactions and
   312  # max_txs_bytes=5MB, mempool will only accept 5 transactions).
   313  max_txs_bytes = {{ .Mempool.MaxTxsBytes }}
   314  
   315  # Size of the cache (used to filter transactions we saw earlier) in transactions
   316  cache_size = {{ .Mempool.CacheSize }}
   317  
   318  # Maximum size of a single transaction.
   319  # NOTE: the max size of a tx transmitted over the network is {max_tx_bytes} + {amino overhead}.
   320  max_tx_bytes = {{ .Mempool.MaxTxBytes }}
   321  
   322  # Limit the max number of txs in the a block.
   323  max_tx_num_per_block = {{ .Mempool.MaxTxNumPerBlock }}
   324  
   325  # Enable sort txs in mempool by gas price.
   326  sort_tx_by_gp = {{ .Mempool.SortTxByGp }}
   327  
   328  # Minimum price bump percentage to replace an already existing transaction (nonce)
   329  tx_price_bump = {{ .Mempool.TxPriceBump }}
   330  
   331  # Node key whitelist used in mempool to reduce CPU and Memory tradeoff 
   332  node_key_whitelist = [{{ range .Mempool.NodeKeyWhitelist }}{{ printf "%q, " . }}{{end}}]
   333  
   334  ##### fast sync configuration options #####
   335  [fastsync]
   336  
   337  # Fast Sync version to use:
   338  #   1) "v0" (default) - the legacy fast sync implementation
   339  #   2) "v1" - refactor of v0 version for better testability
   340  #   3) "v2" - refactor of v1 version for better usability
   341  version = "{{ .FastSync.Version }}"
   342  
   343  ##### consensus configuration options #####
   344  [consensus]
   345  
   346  wal_file = "{{ js .Consensus.WalPath }}"
   347  
   348  timeout_propose = "{{ .Consensus.TimeoutPropose }}"
   349  timeout_propose_delta = "{{ .Consensus.TimeoutProposeDelta }}"
   350  timeout_prevote = "{{ .Consensus.TimeoutPrevote }}"
   351  timeout_prevote_delta = "{{ .Consensus.TimeoutPrevoteDelta }}"
   352  timeout_precommit = "{{ .Consensus.TimeoutPrecommit }}"
   353  timeout_precommit_delta = "{{ .Consensus.TimeoutPrecommitDelta }}"
   354  timeout_commit = "{{ .Consensus.TimeoutCommit }}"
   355  waiting = "{{ .Consensus.Waiting }}"
   356  
   357  # Make progress as soon as we have all the precommits (as if TimeoutCommit = 0)
   358  skip_timeout_commit = {{ .Consensus.SkipTimeoutCommit }}
   359  
   360  # EmptyBlocks mode and possible interval between empty blocks
   361  create_empty_blocks = {{ .Consensus.CreateEmptyBlocks }}
   362  create_empty_blocks_interval = "{{ .Consensus.CreateEmptyBlocksInterval }}"
   363  
   364  # Reactor sleep duration parameters
   365  peer_gossip_sleep_duration = "{{ .Consensus.PeerGossipSleepDuration }}"
   366  peer_query_maj23_sleep_duration = "{{ .Consensus.PeerQueryMaj23SleepDuration }}"
   367  
   368  ##### transactions indexer configuration options #####
   369  [tx_index]
   370  
   371  # What indexer to use for transactions
   372  #
   373  # Options:
   374  #   1) "null"
   375  #   2) "kv" (default) - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend).
   376  indexer = "{{ .TxIndex.Indexer }}"
   377  
   378  # Comma-separated list of compositeKeys to index (by default the only key is "tx.hash")
   379  # Remember that Event has the following structure: type.key
   380  # type: [
   381  #  key: value,
   382  #  ...
   383  # ]
   384  #
   385  # You can also index transactions by height by adding "tx.height" key here.
   386  #
   387  # It's recommended to index only a subset of keys due to possible memory
   388  # bloat. This is, of course, depends on the indexer's DB and the volume of
   389  # transactions.
   390  index_keys = "{{ .TxIndex.IndexKeys }}"
   391  
   392  # When set to true, tells indexer to index all compositeKeys (predefined keys:
   393  # "tx.hash", "tx.height" and all keys from DeliverTx responses).
   394  #
   395  # Note this may be not desirable (see the comment above). IndexKeys has a
   396  # precedence over IndexAllKeys (i.e. when given both, IndexKeys will be
   397  # indexed).
   398  index_all_keys = {{ .TxIndex.IndexAllKeys }}
   399  
   400  ##### instrumentation configuration options #####
   401  [instrumentation]
   402  
   403  # When true, Prometheus metrics are served under /metrics on
   404  # PrometheusListenAddr.
   405  # Check out the documentation for the list of available metrics.
   406  prometheus = {{ .Instrumentation.Prometheus }}
   407  
   408  # Address to listen for Prometheus collector(s) connections
   409  prometheus_listen_addr = "{{ .Instrumentation.PrometheusListenAddr }}"
   410  
   411  # Maximum number of simultaneous connections.
   412  # If you want to accept a larger number than the default, make sure
   413  # you increase your OS limits.
   414  # 0 - unlimited.
   415  max_open_connections = {{ .Instrumentation.MaxOpenConnections }}
   416  
   417  # Instrumentation namespace
   418  namespace = "{{ .Instrumentation.Namespace }}"
   419  
   420  # Log file
   421  log_file = "{{ js .BaseConfig.LogFile }}"
   422  
   423  # Log stdout
   424  log_stdout = "{{ .BaseConfig.LogStdout }}"
   425  `
   426  
   427  /****** these are for test settings ***********/
   428  
   429  func ResetTestRoot(testName string) *Config {
   430  	return ResetTestRootWithChainID(testName, "")
   431  }
   432  
   433  func ResetTestRootWithChainID(testName string, chainID string) *Config {
   434  	// create a unique, concurrency-safe test directory under os.TempDir()
   435  	rootDir, err := ioutil.TempDir("", fmt.Sprintf("%s-%s_", chainID, testName))
   436  	if err != nil {
   437  		panic(err)
   438  	}
   439  	// ensure config and data subdirs are created
   440  	if err := tmos.EnsureDir(filepath.Join(rootDir, defaultConfigDir), DefaultDirPerm); err != nil {
   441  		panic(err)
   442  	}
   443  	if err := tmos.EnsureDir(filepath.Join(rootDir, defaultDataDir), DefaultDirPerm); err != nil {
   444  		panic(err)
   445  	}
   446  
   447  	baseConfig := DefaultBaseConfig()
   448  	configFilePath := filepath.Join(rootDir, defaultConfigFilePath)
   449  	genesisFilePath := filepath.Join(rootDir, baseConfig.Genesis)
   450  	privKeyFilePath := filepath.Join(rootDir, baseConfig.PrivValidatorKey)
   451  	privStateFilePath := filepath.Join(rootDir, baseConfig.PrivValidatorState)
   452  
   453  	// Write default config file if missing.
   454  	if !tmos.FileExists(configFilePath) {
   455  		writeDefaultConfigFile(configFilePath)
   456  	}
   457  	if !tmos.FileExists(genesisFilePath) {
   458  		if chainID == "" {
   459  			chainID = "tendermint_test"
   460  		}
   461  		testGenesis := fmt.Sprintf(testGenesisFmt, chainID)
   462  		tmos.MustWriteFile(genesisFilePath, []byte(testGenesis), 0644)
   463  	}
   464  	// we always overwrite the priv val
   465  	tmos.MustWriteFile(privKeyFilePath, []byte(testPrivValidatorKey), 0644)
   466  	tmos.MustWriteFile(privStateFilePath, []byte(testPrivValidatorState), 0644)
   467  
   468  	config := TestConfig().SetRoot(rootDir)
   469  	return config
   470  }
   471  
   472  var testGenesisFmt = `{
   473    "genesis_time": "2018-10-10T08:20:13.695936996Z",
   474    "chain_id": "%s",
   475    "consensus_params": {
   476  	"block": {
   477  		"max_bytes": "22020096",
   478  		"max_gas": "-1",
   479  		"time_iota_ms": "10"
   480  	},
   481  	"evidence": {
   482  		"max_age_num_blocks": "100000",
   483  		"max_age_duration": "172800000000000",
   484  		"max_num": 50
   485  	},
   486  	"validator": {
   487  		"pub_key_types": [
   488  			"ed25519"
   489  		]
   490  	},
   491  	"version": {}
   492    },
   493    "validators": [
   494      {
   495        "pub_key": {
   496          "type": "tendermint/PubKeyEd25519",
   497          "value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="
   498        },
   499        "power": "10",
   500        "name": ""
   501      }
   502    ],
   503    "app_hash": ""
   504  }`
   505  
   506  var testPrivValidatorKey = `{
   507    "address": "A3258DCBF45DCA0DF052981870F2D1441A36D145",
   508    "pub_key": {
   509      "type": "tendermint/PubKeyEd25519",
   510      "value": "AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="
   511    },
   512    "priv_key": {
   513      "type": "tendermint/PrivKeyEd25519",
   514      "value": "EVkqJO/jIXp3rkASXfh9YnyToYXRXhBr6g9cQVxPFnQBP/5povV4HTjvsy530kybxKHwEi85iU8YL0qQhSYVoQ=="
   515    }
   516  }`
   517  
   518  var testPrivValidatorState = `{
   519    "height": "0",
   520    "round": "0",
   521    "step": 0
   522  }`