diff --git a/cmd/kvd/main.go b/cmd/kvd/main.go index 4bd9f3fa..cbfe5091 100644 --- a/cmd/kvd/main.go +++ b/cmd/kvd/main.go @@ -6,6 +6,8 @@ package main import ( "encoding/json" "io" + "os" + "path/filepath" "github.com/cosmos/cosmos-sdk/baseapp" @@ -44,6 +46,9 @@ func main() { server.AddCommands(ctx, cdc, rootCmd, appInit, appCreator, appExporter) + // Add custom init command + rootCmd.AddCommand(initTestnetCmd()) + // handle envs and add some flags and stuff executor := cli.PrepareBaseCmd(rootCmd, "KV", app.DefaultNodeHome) @@ -62,3 +67,79 @@ func exportAppStateAndTMValidators(logger log.Logger, db dbm.DB, traceStore io.W tempApp := app.NewKavaApp(logger, db, traceStore) return tempApp.ExportAppStateAndValidators() } + +func initTestnetCmd() *cobra.Command { + flagChainID := "chain-id" + cmd := &cobra.Command{ + Use: "init-testnet-helper", + Short: "Setup genesis and config to join testnet.", + Long: "Copy the genesis.json and config.toml files from the testnets folder into the default config directories.", + RunE: func(cmd *cobra.Command, args []string) error { + testnetVersion := viper.GetString(flagChainID) + genesisFileName := "genesis.json" + configFileName := "config.toml" + configPath := "config" + testnetsPath := os.ExpandEnv("$GOPATH/src/github.com/kava-labs/kava/testnets/") + + // Copy genesis file from testnet folder to config directories + // Copied to .kvcli to enable automatic reading of chain-id + genesis := filepath.Join(testnetsPath, testnetVersion, genesisFileName) + err := copyFile(genesis, filepath.Join(app.DefaultNodeHome, configPath, genesisFileName)) + if err != nil { + return err + } + err = copyFile(genesis, filepath.Join(app.DefaultCLIHome, configPath, genesisFileName)) + if err != nil { + return err + } + // Copy config file from testnet folder to config directories + // Custom config file specifies seeds and altered ports + config := filepath.Join(testnetsPath, testnetVersion, configFileName) + err = copyFile(config, filepath.Join(app.DefaultNodeHome, configPath, configFileName)) + if err != nil { + return err + } + err = copyFile(config, filepath.Join(app.DefaultCLIHome, configPath, configFileName)) + if err != nil { + return err + } + return nil + }, + } + cmd.Flags().String(flagChainID, "", "testnet chain-id, cannot be left blank") + return cmd +} + +func copyFile(src string, dst string) error { + // read in source file + in, err := os.Open(src) + if err != nil { + return err + } + defer in.Close() + + // create destination file (and any necessary directories)(overwriting if it exists already) + path := filepath.Dir(dst) + err = os.MkdirAll(path, os.ModePerm) + if err != nil { + return err + } + out, err := os.Create(dst) + if err != nil { + return err + } + defer func() { + cerr := out.Close() + if err == nil { + err = cerr + } + }() + + // copy file contents + if _, err = io.Copy(out, in); err != nil { + return err + } + // write to disk + err = out.Sync() + return err +} diff --git a/testnets/kava-test-3/config.toml b/testnets/kava-test-3/config.toml new file mode 100644 index 00000000..1fc71230 --- /dev/null +++ b/testnets/kava-test-3/config.toml @@ -0,0 +1,207 @@ +# This is a TOML config file. +# For more information, see https://github.com/toml-lang/toml + +##### main base config options ##### + +# TCP or UNIX socket address of the ABCI application, +# or the name of an ABCI application compiled in with the Tendermint binary +proxy_app = "tcp://127.0.0.1:17128" + +# A custom human readable name for this node +moniker = "validator" + +# If this node is many blocks behind the tip of the chain, FastSync +# allows them to catchup quickly by downloading blocks in parallel +# and verifying their commits +fast_sync = true + +# Database backend: leveldb | memdb +db_backend = "leveldb" + +# Database directory +db_path = "data" + +# Output level for logging, including package level options +log_level = "main:info,state:info,*:error" + +##### additional base config options ##### + +# Path to the JSON file containing the initial validator set and other meta data +genesis_file = "config/genesis.json" + +# Path to the JSON file containing the private key to use as a validator in the consensus protocol +priv_validator_file = "config/priv_validator.json" + +# Path to the JSON file containing the private key to use for node authentication in the p2p protocol +node_key_file = "config/node_key.json" + +# Mechanism to connect to the ABCI application: socket | grpc +abci = "socket" + +# TCP or UNIX socket address for the profiling server to listen on +prof_laddr = "localhost:6060" + +# If true, query the ABCI app on connecting to a new peer +# so the app can decide if we should keep the connection or not +filter_peers = false + +##### advanced configuration options ##### + +##### rpc server configuration options ##### +[rpc] + +# TCP or UNIX socket address for the RPC server to listen on +laddr = "tcp://0.0.0.0:17127" + +# TCP or UNIX socket address for the gRPC server to listen on +# NOTE: This server only supports /broadcast_tx_commit +grpc_laddr = "" + +# Maximum number of simultaneous connections. +# Does not include RPC (HTTP&WebSocket) connections. See max_open_connections +# If you want to accept more significant number than the default, make sure +# you increase your OS limits. +# 0 - unlimited. +grpc_max_open_connections = 900 + +# Activate unsafe RPC commands like /dial_seeds and /unsafe_flush_mempool +unsafe = false + +# Maximum number of simultaneous connections (including WebSocket). +# Does not include gRPC connections. See grpc_max_open_connections +# If you want to accept more significant number than the default, make sure +# you increase your OS limits. +# 0 - unlimited. +max_open_connections = 900 + +##### peer to peer configuration options ##### +[p2p] + +# Address to listen for incoming connections +laddr = "tcp://0.0.0.0:17126" + +# Address to advertise to peers for them to dial +# If empty, will use the same port as the laddr, +# and will introspect on the listener or use UPnP +# to figure out the address. +external_address = "" + +# Comma separated list of seed nodes to connect to +seeds = "" + +# Comma separated list of nodes to keep persistent connections to +persistent_peers = "" + +# UPNP port forwarding +upnp = false + +# Path to address book +addr_book_file = "config/addrbook.json" + +# Set true for strict address routability rules +addr_book_strict = true + +# Time to wait before flushing messages out on the connection, in ms +flush_throttle_timeout = 100 + +# Maximum number of peers to connect to +max_num_peers = 50 + +# Maximum size of a message packet payload, in bytes +max_packet_msg_payload_size = 1024 + +# Rate at which packets can be sent, in bytes/second +send_rate = 5120000 + +# Rate at which packets can be received, in bytes/second +recv_rate = 5120000 + +# Set true to enable the peer-exchange reactor +pex = true + +# Seed mode, in which node constantly crawls the network and looks for +# peers. If another node asks it for addresses, it responds and disconnects. +# +# Does not work if the peer-exchange reactor is disabled. +seed_mode = false + +# Comma separated list of peer IDs to keep private (will not be gossiped to other peers) +private_peer_ids = "" + +##### mempool configuration options ##### +[mempool] + +recheck = true +recheck_empty = true +broadcast = true +wal_dir = "data/mempool.wal" + +# size of the mempool +size = 100000 + +# size of the cache (used to filter transactions we saw earlier) +cache_size = 100000 + +##### consensus configuration options ##### +[consensus] + +wal_file = "data/cs.wal/wal" + +# All timeouts are in milliseconds +timeout_propose = 3000 +timeout_propose_delta = 500 +timeout_prevote = 1000 +timeout_prevote_delta = 500 +timeout_precommit = 1000 +timeout_precommit_delta = 500 +timeout_commit = 5000 + +# Make progress as soon as we have all the precommits (as if TimeoutCommit = 0) +skip_timeout_commit = false + +# EmptyBlocks mode and possible interval between empty blocks in seconds +create_empty_blocks = true +create_empty_blocks_interval = 0 + +# Reactor sleep duration parameters are in milliseconds +peer_gossip_sleep_duration = 100 +peer_query_maj23_sleep_duration = 2000 + +##### transactions indexer configuration options ##### +[tx_index] + +# What indexer to use for transactions +# +# Options: +# 1) "null" (default) +# 2) "kv" - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend). +indexer = "kv" + +# Comma-separated list of tags to index (by default the only tag is tx hash) +# +# It's recommended to index only a subset of tags due to possible memory +# bloat. This is, of course, depends on the indexer's DB and the volume of +# transactions. +index_tags = "" + +# When set to true, tells indexer to index all tags. Note this may be not +# desirable (see the comment above). IndexTags has a precedence over +# IndexAllTags (i.e. when given both, IndexTags will be indexed). +index_all_tags = true + +##### instrumentation configuration options ##### +[instrumentation] + +# When true, Prometheus metrics are served under /metrics on +# PrometheusListenAddr. +# Check out the documentation for the list of available metrics. +prometheus = false + +# Address to listen for Prometheus collector(s) connections +prometheus_listen_addr = ":26660" + +# Maximum number of simultaneous connections. +# If you want to accept more significant number than the default, make sure +# you increase your OS limits. +# 0 - unlimited. +max_open_connections = 3 diff --git a/testnets/kava-test-3/genesis.json b/testnets/kava-test-3/genesis.json new file mode 100644 index 00000000..f0e529f9 --- /dev/null +++ b/testnets/kava-test-3/genesis.json @@ -0,0 +1,99 @@ +{ + "genesis_time": "2018-10-02T22:07:14.081536126Z", + "chain_id": "kava-test-3", + "consensus_params": { + "block_size_params": { + "max_bytes": "22020096", + "max_txs": "10000", + "max_gas": "-1" + }, + "tx_size_params": { + "max_bytes": "10240", + "max_gas": "-1" + }, + "block_gossip_params": { + "block_part_size_bytes": "65536" + }, + "evidence_params": { + "max_age": "100000" + } + }, + "validators": [ + { + "pub_key": { + "type": "tendermint/PubKeyEd25519", + "value": "tvYvH9rTsYcu8Yu/D1xa/4hCC+iMu3hPmaQzjXY4ooo=" + }, + "power": "1000", + "name": "" + } + ], + "app_hash": "", + "app_state": { + "accounts": [ + { + "address": "kaccaddr1hearejlx77u0uhqc2xnznnnzvyf0yctep4zq3t", + "coins": [ + { + "denom": "KVA", + "amount": "99000" + } + ] + } + ], + "stake": { + "pool": { + "loose_tokens": "100000", + "bonded_tokens": "0", + "inflation_last_time": "1970-01-01T00:00:00Z", + "inflation": "7/100", + "date_last_commission_reset": "0", + "prev_bonded_shares": "0" + }, + "params": { + "inflation_rate_change": "13/100", + "inflation_max": "1/5", + "inflation_min": "7/100", + "goal_bonded": "67/100", + "unbonding_time": "300000000000", + "max_validators": 100, + "bond_denom": "KVA" + }, + "validators": [ + { + "owner": "kaccaddr1hearejlx77u0uhqc2xnznnnzvyf0yctep4zq3t", + "pub_key": { + "type": "tendermint/PubKeyEd25519", + "value": "tvYvH9rTsYcu8Yu/D1xa/4hCC+iMu3hPmaQzjXY4ooo=" + }, + "revoked": false, + "status": 0, + "tokens": "1000", + "delegator_shares": "1000", + "description": { + "moniker": "validator", + "identity": "", + "website": "", + "details": "" + }, + "bond_height": "0", + "bond_intra_tx_counter": 0, + "proposer_reward_pool": [], + "commission": "0", + "commission_max": "0", + "commission_change_rate": "0", + "commission_change_today": "0", + "prev_bonded_tokens": "0" + } + ], + "bonds": [ + { + "delegator_addr": "kaccaddr1hearejlx77u0uhqc2xnznnnzvyf0yctep4zq3t", + "validator_addr": "kaccaddr1hearejlx77u0uhqc2xnznnnzvyf0yctep4zq3t", + "shares": "1000", + "height": "0" + } + ] + } + } +} \ No newline at end of file