github.com/devwanda/aphelion-staking@v0.33.9/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/devwanda/aphelion-staking/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  # Database backend: goleveldb | cleveldb | boltdb | rocksdb
    90  # * goleveldb (github.com/syndtr/goleveldb - most popular implementation)
    91  #   - pure go
    92  #   - stable
    93  # * cleveldb (uses levigo wrapper)
    94  #   - fast
    95  #   - requires gcc
    96  #   - use cleveldb build tag (go build -tags cleveldb)
    97  # * boltdb (uses etcd's fork of bolt - github.com/etcd-io/bbolt)
    98  #   - EXPERIMENTAL
    99  #   - may be faster is some use-cases (random reads - indexer)
   100  #   - use boltdb build tag (go build -tags boltdb)
   101  # * rocksdb (uses github.com/tecbot/gorocksdb)
   102  #   - EXPERIMENTAL
   103  #   - requires gcc
   104  #   - use rocksdb build tag (go build -tags rocksdb)
   105  db_backend = "{{ .BaseConfig.DBBackend }}"
   106  
   107  # Database directory
   108  db_dir = "{{ js .BaseConfig.DBPath }}"
   109  
   110  # Output level for logging, including package level options
   111  log_level = "{{ .BaseConfig.LogLevel }}"
   112  
   113  # Output format: 'plain' (colored text) or 'json'
   114  log_format = "{{ .BaseConfig.LogFormat }}"
   115  
   116  ##### additional base config options #####
   117  
   118  # Path to the JSON file containing the initial validator set and other meta data
   119  genesis_file = "{{ js .BaseConfig.Genesis }}"
   120  
   121  # Path to the JSON file containing the private key to use as a validator in the consensus protocol
   122  priv_validator_key_file = "{{ js .BaseConfig.PrivValidatorKey }}"
   123  
   124  # Path to the JSON file containing the last sign state of a validator
   125  priv_validator_state_file = "{{ js .BaseConfig.PrivValidatorState }}"
   126  
   127  # TCP or UNIX socket address for Tendermint to listen on for
   128  # connections from an external PrivValidator process
   129  priv_validator_laddr = "{{ .BaseConfig.PrivValidatorListenAddr }}"
   130  
   131  # Path to the JSON file containing the private key to use for node authentication in the p2p protocol
   132  node_key_file = "{{ js .BaseConfig.NodeKey }}"
   133  
   134  # Mechanism to connect to the ABCI application: socket | grpc
   135  abci = "{{ .BaseConfig.ABCI }}"
   136  
   137  # TCP or UNIX socket address for the profiling server to listen on
   138  prof_laddr = "{{ .BaseConfig.ProfListenAddress }}"
   139  
   140  # If true, query the ABCI app on connecting to a new peer
   141  # so the app can decide if we should keep the connection or not
   142  filter_peers = {{ .BaseConfig.FilterPeers }}
   143  
   144  ##### advanced configuration options #####
   145  
   146  ##### rpc server configuration options #####
   147  [rpc]
   148  
   149  # TCP or UNIX socket address for the RPC server to listen on
   150  laddr = "{{ .RPC.ListenAddress }}"
   151  
   152  # A list of origins a cross-domain request can be executed from
   153  # Default value '[]' disables cors support
   154  # Use '["*"]' to allow any origin
   155  cors_allowed_origins = [{{ range .RPC.CORSAllowedOrigins }}{{ printf "%q, " . }}{{end}}]
   156  
   157  # A list of methods the client is allowed to use with cross-domain requests
   158  cors_allowed_methods = [{{ range .RPC.CORSAllowedMethods }}{{ printf "%q, " . }}{{end}}]
   159  
   160  # A list of non simple headers the client is allowed to use with cross-domain requests
   161  cors_allowed_headers = [{{ range .RPC.CORSAllowedHeaders }}{{ printf "%q, " . }}{{end}}]
   162  
   163  # TCP or UNIX socket address for the gRPC server to listen on
   164  # NOTE: This server only supports /broadcast_tx_commit
   165  grpc_laddr = "{{ .RPC.GRPCListenAddress }}"
   166  
   167  # Maximum number of simultaneous connections.
   168  # Does not include RPC (HTTP&WebSocket) connections. See max_open_connections
   169  # If you want to accept a larger number than the default, make sure
   170  # you increase your OS limits.
   171  # 0 - unlimited.
   172  # Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files}
   173  # 1024 - 40 - 10 - 50 = 924 = ~900
   174  grpc_max_open_connections = {{ .RPC.GRPCMaxOpenConnections }}
   175  
   176  # Activate unsafe RPC commands like /dial_seeds and /unsafe_flush_mempool
   177  unsafe = {{ .RPC.Unsafe }}
   178  
   179  # Maximum number of simultaneous connections (including WebSocket).
   180  # Does not include gRPC connections. See grpc_max_open_connections
   181  # If you want to accept a larger number than the default, make sure
   182  # you increase your OS limits.
   183  # 0 - unlimited.
   184  # Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files}
   185  # 1024 - 40 - 10 - 50 = 924 = ~900
   186  max_open_connections = {{ .RPC.MaxOpenConnections }}
   187  
   188  # Maximum number of unique clientIDs that can /subscribe
   189  # If you're using /broadcast_tx_commit, set to the estimated maximum number
   190  # of broadcast_tx_commit calls per block.
   191  max_subscription_clients = {{ .RPC.MaxSubscriptionClients }}
   192  
   193  # Maximum number of unique queries a given client can /subscribe to
   194  # If you're using GRPC (or Local RPC client) and /broadcast_tx_commit, set to
   195  # the estimated # maximum number of broadcast_tx_commit calls per block.
   196  max_subscriptions_per_client = {{ .RPC.MaxSubscriptionsPerClient }}
   197  
   198  # How long to wait for a tx to be committed during /broadcast_tx_commit.
   199  # WARNING: Using a value larger than 10s will result in increasing the
   200  # global HTTP write timeout, which applies to all connections and endpoints.
   201  # See https://github.com/devwanda/aphelion-staking/issues/3435
   202  timeout_broadcast_tx_commit = "{{ .RPC.TimeoutBroadcastTxCommit }}"
   203  
   204  # Maximum size of request body, in bytes
   205  max_body_bytes = {{ .RPC.MaxBodyBytes }}
   206  
   207  # Maximum size of request header, in bytes
   208  max_header_bytes = {{ .RPC.MaxHeaderBytes }}
   209  
   210  # The path to a file containing certificate that is used to create the HTTPS server.
   211  # Migth be either absolute path or path related to tendermint's config directory.
   212  # If the certificate is signed by a certificate authority,
   213  # the certFile should be the concatenation of the server's certificate, any intermediates,
   214  # and the CA's certificate.
   215  # NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server.
   216  # Otherwise, HTTP server is run.
   217  tls_cert_file = "{{ .RPC.TLSCertFile }}"
   218  
   219  # The path to a file containing matching private key that is used to create the HTTPS server.
   220  # Migth be either absolute path or path related to tendermint's config directory.
   221  # NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server.
   222  # Otherwise, HTTP server is run.
   223  tls_key_file = "{{ .RPC.TLSKeyFile }}"
   224  
   225  ##### peer to peer configuration options #####
   226  [p2p]
   227  
   228  # Address to listen for incoming connections
   229  laddr = "{{ .P2P.ListenAddress }}"
   230  
   231  # Address to advertise to peers for them to dial
   232  # If empty, will use the same port as the laddr,
   233  # and will introspect on the listener or use UPnP
   234  # to figure out the address.
   235  external_address = "{{ .P2P.ExternalAddress }}"
   236  
   237  # Comma separated list of seed nodes to connect to
   238  seeds = "{{ .P2P.Seeds }}"
   239  
   240  # Comma separated list of nodes to keep persistent connections to
   241  persistent_peers = "{{ .P2P.PersistentPeers }}"
   242  
   243  # UPNP port forwarding
   244  upnp = {{ .P2P.UPNP }}
   245  
   246  # Path to address book
   247  addr_book_file = "{{ js .P2P.AddrBook }}"
   248  
   249  # Set true for strict address routability rules
   250  # Set false for private or local networks
   251  addr_book_strict = {{ .P2P.AddrBookStrict }}
   252  
   253  # Maximum number of inbound peers
   254  max_num_inbound_peers = {{ .P2P.MaxNumInboundPeers }}
   255  
   256  # Maximum number of outbound peers to connect to, excluding persistent peers
   257  max_num_outbound_peers = {{ .P2P.MaxNumOutboundPeers }}
   258  
   259  # List of node IDs, to which a connection will be (re)established ignoring any existing limits
   260  unconditional_peer_ids = "{{ .P2P.UnconditionalPeerIDs }}"
   261  
   262  # Maximum pause when redialing a persistent peer (if zero, exponential backoff is used)
   263  persistent_peers_max_dial_period = "{{ .P2P.PersistentPeersMaxDialPeriod }}"
   264  
   265  # Time to wait before flushing messages out on the connection
   266  flush_throttle_timeout = "{{ .P2P.FlushThrottleTimeout }}"
   267  
   268  # Maximum size of a message packet payload, in bytes
   269  max_packet_msg_payload_size = {{ .P2P.MaxPacketMsgPayloadSize }}
   270  
   271  # Rate at which packets can be sent, in bytes/second
   272  send_rate = {{ .P2P.SendRate }}
   273  
   274  # Rate at which packets can be received, in bytes/second
   275  recv_rate = {{ .P2P.RecvRate }}
   276  
   277  # Set true to enable the peer-exchange reactor
   278  pex = {{ .P2P.PexReactor }}
   279  
   280  # Seed mode, in which node constantly crawls the network and looks for
   281  # peers. If another node asks it for addresses, it responds and disconnects.
   282  #
   283  # Does not work if the peer-exchange reactor is disabled.
   284  seed_mode = {{ .P2P.SeedMode }}
   285  
   286  # Comma separated list of peer IDs to keep private (will not be gossiped to other peers)
   287  private_peer_ids = "{{ .P2P.PrivatePeerIDs }}"
   288  
   289  # Toggle to disable guard against peers connecting from the same ip.
   290  allow_duplicate_ip = {{ .P2P.AllowDuplicateIP }}
   291  
   292  # Peer connection configuration.
   293  handshake_timeout = "{{ .P2P.HandshakeTimeout }}"
   294  dial_timeout = "{{ .P2P.DialTimeout }}"
   295  
   296  ##### mempool configuration options #####
   297  [mempool]
   298  
   299  recheck = {{ .Mempool.Recheck }}
   300  broadcast = {{ .Mempool.Broadcast }}
   301  wal_dir = "{{ js .Mempool.WalPath }}"
   302  
   303  # Maximum number of transactions in the mempool
   304  size = {{ .Mempool.Size }}
   305  
   306  # Limit the total size of all txs in the mempool.
   307  # This only accounts for raw transactions (e.g. given 1MB transactions and
   308  # max_txs_bytes=5MB, mempool will only accept 5 transactions).
   309  max_txs_bytes = {{ .Mempool.MaxTxsBytes }}
   310  
   311  # Size of the cache (used to filter transactions we saw earlier) in transactions
   312  cache_size = {{ .Mempool.CacheSize }}
   313  
   314  # Maximum size of a single transaction.
   315  # NOTE: the max size of a tx transmitted over the network is {max_tx_bytes} + {amino overhead}.
   316  max_tx_bytes = {{ .Mempool.MaxTxBytes }}
   317  
   318  ##### fast sync configuration options #####
   319  [fastsync]
   320  
   321  # Fast Sync version to use:
   322  #   1) "v0" (default) - the legacy fast sync implementation
   323  #   2) "v1" - refactor of v0 version for better testability
   324  #   3) "v2" - refactor of v1 version for better usability
   325  version = "{{ .FastSync.Version }}"
   326  
   327  ##### consensus configuration options #####
   328  [consensus]
   329  
   330  wal_file = "{{ js .Consensus.WalPath }}"
   331  
   332  timeout_propose = "{{ .Consensus.TimeoutPropose }}"
   333  timeout_propose_delta = "{{ .Consensus.TimeoutProposeDelta }}"
   334  timeout_prevote = "{{ .Consensus.TimeoutPrevote }}"
   335  timeout_prevote_delta = "{{ .Consensus.TimeoutPrevoteDelta }}"
   336  timeout_precommit = "{{ .Consensus.TimeoutPrecommit }}"
   337  timeout_precommit_delta = "{{ .Consensus.TimeoutPrecommitDelta }}"
   338  timeout_commit = "{{ .Consensus.TimeoutCommit }}"
   339  
   340  # Make progress as soon as we have all the precommits (as if TimeoutCommit = 0)
   341  skip_timeout_commit = {{ .Consensus.SkipTimeoutCommit }}
   342  
   343  # EmptyBlocks mode and possible interval between empty blocks
   344  create_empty_blocks = {{ .Consensus.CreateEmptyBlocks }}
   345  create_empty_blocks_interval = "{{ .Consensus.CreateEmptyBlocksInterval }}"
   346  
   347  # Reactor sleep duration parameters
   348  peer_gossip_sleep_duration = "{{ .Consensus.PeerGossipSleepDuration }}"
   349  peer_query_maj23_sleep_duration = "{{ .Consensus.PeerQueryMaj23SleepDuration }}"
   350  
   351  ##### transactions indexer configuration options #####
   352  [tx_index]
   353  
   354  # What indexer to use for transactions
   355  #
   356  # Options:
   357  #   1) "null"
   358  #   2) "kv" (default) - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend).
   359  indexer = "{{ .TxIndex.Indexer }}"
   360  
   361  # Comma-separated list of compositeKeys to index (by default the only key is "tx.hash")
   362  # Remember that Event has the following structure: type.key
   363  # type: [
   364  #  key: value,
   365  #  ...
   366  # ]
   367  #
   368  # You can also index transactions by height by adding "tx.height" key here.
   369  #
   370  # It's recommended to index only a subset of keys due to possible memory
   371  # bloat. This is, of course, depends on the indexer's DB and the volume of
   372  # transactions.
   373  index_keys = "{{ .TxIndex.IndexKeys }}"
   374  
   375  # When set to true, tells indexer to index all compositeKeys (predefined keys:
   376  # "tx.hash", "tx.height" and all keys from DeliverTx responses).
   377  #
   378  # Note this may be not desirable (see the comment above). IndexKeys has a
   379  # precedence over IndexAllKeys (i.e. when given both, IndexKeys will be
   380  # indexed).
   381  index_all_keys = {{ .TxIndex.IndexAllKeys }}
   382  
   383  ##### instrumentation configuration options #####
   384  [instrumentation]
   385  
   386  # When true, Prometheus metrics are served under /metrics on
   387  # PrometheusListenAddr.
   388  # Check out the documentation for the list of available metrics.
   389  prometheus = {{ .Instrumentation.Prometheus }}
   390  
   391  # Address to listen for Prometheus collector(s) connections
   392  prometheus_listen_addr = "{{ .Instrumentation.PrometheusListenAddr }}"
   393  
   394  # Maximum number of simultaneous connections.
   395  # If you want to accept a larger number than the default, make sure
   396  # you increase your OS limits.
   397  # 0 - unlimited.
   398  max_open_connections = {{ .Instrumentation.MaxOpenConnections }}
   399  
   400  # Instrumentation namespace
   401  namespace = "{{ .Instrumentation.Namespace }}"
   402  `
   403  
   404  /****** these are for test settings ***********/
   405  
   406  func ResetTestRoot(testName string) *Config {
   407  	return ResetTestRootWithChainID(testName, "")
   408  }
   409  
   410  func ResetTestRootWithChainID(testName string, chainID string) *Config {
   411  	// create a unique, concurrency-safe test directory under os.TempDir()
   412  	rootDir, err := ioutil.TempDir("", fmt.Sprintf("%s-%s_", chainID, testName))
   413  	if err != nil {
   414  		panic(err)
   415  	}
   416  	// ensure config and data subdirs are created
   417  	if err := tmos.EnsureDir(filepath.Join(rootDir, defaultConfigDir), DefaultDirPerm); err != nil {
   418  		panic(err)
   419  	}
   420  	if err := tmos.EnsureDir(filepath.Join(rootDir, defaultDataDir), DefaultDirPerm); err != nil {
   421  		panic(err)
   422  	}
   423  
   424  	baseConfig := DefaultBaseConfig()
   425  	configFilePath := filepath.Join(rootDir, defaultConfigFilePath)
   426  	genesisFilePath := filepath.Join(rootDir, baseConfig.Genesis)
   427  	privKeyFilePath := filepath.Join(rootDir, baseConfig.PrivValidatorKey)
   428  	privStateFilePath := filepath.Join(rootDir, baseConfig.PrivValidatorState)
   429  
   430  	// Write default config file if missing.
   431  	if !tmos.FileExists(configFilePath) {
   432  		writeDefaultConfigFile(configFilePath)
   433  	}
   434  	if !tmos.FileExists(genesisFilePath) {
   435  		if chainID == "" {
   436  			chainID = "tendermint_test"
   437  		}
   438  		testGenesis := fmt.Sprintf(testGenesisFmt, chainID)
   439  		tmos.MustWriteFile(genesisFilePath, []byte(testGenesis), 0644)
   440  	}
   441  	// we always overwrite the priv val
   442  	tmos.MustWriteFile(privKeyFilePath, []byte(testPrivValidatorKey), 0644)
   443  	tmos.MustWriteFile(privStateFilePath, []byte(testPrivValidatorState), 0644)
   444  
   445  	config := TestConfig().SetRoot(rootDir)
   446  	return config
   447  }
   448  
   449  var testGenesisFmt = `{
   450    "genesis_time": "2018-10-10T08:20:13.695936996Z",
   451    "chain_id": "%s",
   452    "validators": [
   453      {
   454        "pub_key": {
   455          "type": "tendermint/PubKeyEd25519",
   456          "value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="
   457        },
   458        "power": "10",
   459        "name": ""
   460      }
   461    ],
   462    "app_hash": ""
   463  }`
   464  
   465  var testPrivValidatorKey = `{
   466    "address": "A3258DCBF45DCA0DF052981870F2D1441A36D145",
   467    "pub_key": {
   468      "type": "tendermint/PubKeyEd25519",
   469      "value": "AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="
   470    },
   471    "priv_key": {
   472      "type": "tendermint/PrivKeyEd25519",
   473      "value": "EVkqJO/jIXp3rkASXfh9YnyToYXRXhBr6g9cQVxPFnQBP/5povV4HTjvsy530kybxKHwEi85iU8YL0qQhSYVoQ=="
   474    }
   475  }`
   476  
   477  var testPrivValidatorState = `{
   478    "height": "0",
   479    "round": "0",
   480    "step": 0
   481  }`