From ca8518f8dc0d3d17d73b6cbc6dc2aef0d3bad166 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrej=20Buko=C5=A1ek?= Date: Tue, 21 Jan 2025 21:30:43 +0100 Subject: [PATCH] go/oasis-node/cmd: Remove config migrate command All users have migrated from the old config format, so this command is no longer necessary. --- .changelog/6009.trivial.md | 4 + go/oasis-node/cmd/config/config.go | 20 - go/oasis-node/cmd/config/migrate/migrate.go | 844 ------------------ .../cmd/config/migrate/migrate_test.go | 841 ----------------- go/oasis-node/cmd/root.go | 2 - 5 files changed, 4 insertions(+), 1707 deletions(-) create mode 100644 .changelog/6009.trivial.md delete mode 100644 go/oasis-node/cmd/config/config.go delete mode 100644 go/oasis-node/cmd/config/migrate/migrate.go delete mode 100644 go/oasis-node/cmd/config/migrate/migrate_test.go diff --git a/.changelog/6009.trivial.md b/.changelog/6009.trivial.md new file mode 100644 index 00000000000..93f76c19caf --- /dev/null +++ b/.changelog/6009.trivial.md @@ -0,0 +1,4 @@ +go/oasis-node/cmd: Remove config migrate command + +All users have migrated from the old config format, so this command +is no longer necessary. diff --git a/go/oasis-node/cmd/config/config.go b/go/oasis-node/cmd/config/config.go deleted file mode 100644 index 5c8ac01e3aa..00000000000 --- a/go/oasis-node/cmd/config/config.go +++ /dev/null @@ -1,20 +0,0 @@ -// Package config implements various configuration-related sub-commands. -package config - -import ( - "github.com/spf13/cobra" - - "github.com/oasisprotocol/oasis-core/go/oasis-node/cmd/config/migrate" -) - -var configCmd = &cobra.Command{ - Use: "config", - Short: "config utilities", -} - -// Register registers the config sub-command and all of it's children. -func Register(parentCmd *cobra.Command) { - migrate.Register(configCmd) - - parentCmd.AddCommand(configCmd) -} diff --git a/go/oasis-node/cmd/config/migrate/migrate.go b/go/oasis-node/cmd/config/migrate/migrate.go deleted file mode 100644 index 283aec4042b..00000000000 --- a/go/oasis-node/cmd/config/migrate/migrate.go +++ /dev/null @@ -1,844 +0,0 @@ -// Package migrate implements the migrate command. -// nolint: gocyclo,revive,govet,goconst -package migrate - -import ( - "bytes" - "fmt" - "io" - "net/url" - "os" - "runtime" - "strings" - "sync" - - "github.com/spf13/cobra" - flag "github.com/spf13/pflag" - "github.com/spf13/viper" - "gopkg.in/yaml.v3" - - "github.com/oasisprotocol/oasis-core/go/common/logging" - "github.com/oasisprotocol/oasis-core/go/config" - cmdCommon "github.com/oasisprotocol/oasis-core/go/oasis-node/cmd/common" -) - -const ( - cfgIn = "in" - cfgOut = "out" -) - -var ( - migrateCmd = &cobra.Command{ - Use: "migrate", - Short: "migrate YAML config file into new format", - Run: doMigrateConfig, - } - - migrateFlags = flag.NewFlagSet("", flag.ContinueOnError) - - logger = logging.GetLogger("cmd/config/migrate") - - // This is a bit of a kludge to allow running the command from unit tests - // multiple times without getting a "logging: already initialized" error. - initOnce sync.Once -) - -// Recursively prune maps that are empty. -func pruneEmptyMaps(m map[string]interface{}) { - for k, v := range m { - if vMap, isMap := v.(map[string]interface{}); isMap { - pruneEmptyMaps(vMap) - if len(vMap) == 0 { - delete(m, k) - } - } - } -} - -// Translate known P2P addresses from the old format into the new. -func translateKnownP2P(in []string) ([]string, uint) { - // Old format is the Tendermint P2P address, which we can't translate - // automatically because it is hashed. - // New format is the node's P2P public key. - // However, we know both the old and new addresses of Oasis public - // seed nodes for the testnet and mainnet, so we can at least translate - // those. - - known := map[string]string{ - // Mainnet seed node. - "E27F6B7A350B4CC2B48A6CBE94B0A02B0DCB0BF3@35.199.49.168:26656": "H6u9MtuoWRKn5DKSgarj/dzr2Z9BsjuRHgRAoXITOcU=@35.199.49.168:26656", - // Testnet seed node. - "53572F689E5BACDD3C6527E6594EC49C8F3093F6@34.86.165.6:26656": "HcDFrTp/MqRHtju5bCx6TIhIMd6X/0ZQ3lUG73q5898=@34.86.165.6:26656", - // Old Testnet seed node. - "05EAC99BB37F6DAAD4B13386FF5E087ACBDDC450@34.86.165.6:26656": "HcDFrTp/MqRHtju5bCx6TIhIMd6X/0ZQ3lUG73q5898=@34.86.165.6:26656", - } - - var numUnknown uint - - out := []string{} - for _, p2pOld := range in { - var p2pNew string - - if knownNew, isKnown := known[p2pOld]; isKnown { - // New address is known, use it. - p2pNew = knownNew - } else { - // New address is not known, make sure the user replaces the ID. - s := strings.Split(p2pOld, "@") - addr := s[len(s)-1] - p2pNew = fmt.Sprintf("INSERT_P2P_PUBKEY_HERE@%s", addr) - numUnknown++ - } - - out = append(out, p2pNew) - } - - return out, numUnknown -} - -// Wrapper for the above function that simplifies logging. -func convertP2P(i interface{}, oldS string, newS string) []string { - if i == nil { - return []string{} - } - - // Go can't convert interface{} into []string in one go, so we have to - // do it in two steps. - in1, ok := i.([]interface{}) - if !ok { - logger.Error("P2P address list in input file is malformed", "section", oldS, "expected", "[]interface{}", "got", fmt.Sprintf("%T", i)) - os.Exit(1) - } - - if len(in1) == 0 { - return []string{} - } - - in := make([]string, len(in1)) - for idx, ii := range in1 { - if s, ok := ii.(string); ok { - in[idx] = s - } else { - logger.Error("P2P address list in input file is malformed", "section", oldS, "expected", "string", "got", fmt.Sprintf("%T", ii)) - os.Exit(1) - } - } - - out, numUnknown := translateKnownP2P(in) - - if numUnknown == uint(len(in)) { - logger.Error(fmt.Sprintf("%s is now %s, but instead of Tendermint P2P addresses we now use P2P public keys here, so manual migration of all addresses is required -- replace INSERT_P2P_PUBKEY_HERE with the P2P public key of the node (use 'oasis-node control status' to get its P2P public key)", oldS, newS)) - } else if numUnknown > 0 { - logger.Error(fmt.Sprintf("%s is now %s, but instead of Tendermint P2P addresses we now use P2P public keys here, so manual migration of some addresses is required -- replace INSERT_P2P_PUBKEY_HERE with the P2P public key of the node (use 'oasis-node control status' to get its P2P public key)", oldS, newS)) - } else { - logger.Warn(fmt.Sprintf("%s is now %s, but instead of Tendermint P2P addresses we now use P2P public keys here, however, all the addresses in this section of your config file have known translation mappings and were automatically translated for you", oldS, newS)) - } - - return out -} - -// AppendLibp2pAddrs appends the corresponding libp2p seed node address (which -// differs only in the port number) for each Tendermint seed node address. -func appendLibp2pAddrs(in []string) []string { - out := []string{} - for _, addr := range in { - out = append(out, addr) - - idxOfColon := strings.Index(addr, ":") - if idxOfColon != -1 { - entry := addr[0:idxOfColon] - p2pRT := entry + ":9200" - out = append(out, p2pRT) - } - } - return out -} - -func doMigrateConfig(cmd *cobra.Command, args []string) { - initOnce.Do(func() { - config.GlobalConfig.Common.Log.Level["default"] = "info" - if err := cmdCommon.Init(); err != nil { - cmdCommon.EarlyLogAndExit(err) - } - }) - - // Perform some sanity checks on the input and output file names. - cfgInFileName := viper.GetString(cfgIn) - cfgOutFileName := viper.GetString(cfgOut) - - if len(cfgInFileName) == 0 { - logger.Error("input file name missing, use the --in flag to specify it") - os.Exit(1) - } - if len(cfgOutFileName) == 0 { - logger.Error("output file name missing, use the --out flag to specify it") - os.Exit(1) - } - if cfgInFileName == cfgOutFileName { - logger.Error("input and output file names must be different") - os.Exit(1) - } - - // Start with a blank config that we will populate as we convert the old one. - // - // NOTE: We don't use config.DefaultConfig() here on purpose, since the - // input config file might contain some environment variable substitutions - // and would fail to parse as the appropriate type from the structs when - // saving it later. - // Additionally, we don't want to write any settings that weren't also - // present in the old config file to keep the new config file pretty. - newCfg := make(map[string]interface{}) - - logger.Info("loading input config file", "file_name", cfgInFileName) - - // Load input config file. - oldCfgRaw, err := os.ReadFile(cfgInFileName) - if err != nil { - logger.Error("failed to read input file", "file_name", cfgInFileName, "err", err) - os.Exit(1) - } - - // Parse old config into map. - oldCfg := make(map[string]interface{}) - err = yaml.Unmarshal(oldCfgRaw, &oldCfg) - if err != nil { - logger.Error("failed to parse input file", "file_name", cfgInFileName, "err", err) - os.Exit(1) - } - - logger.Info("input config file loaded successfully", "file_name", cfgInFileName) - - // Helper for making sub-maps. - mkSubMap := func(root map[string]interface{}, name string) { - if _, ok := root[name]; !ok { - root[name] = make(map[string]interface{}) - } - } - - // Helper for casting into maps (we're going to be doing that a lot). - m := func(i interface{}) map[string]interface{} { - if i == nil { - return make(map[string]interface{}) - } - - ret, ok := i.(map[string]interface{}) - if !ok { - var from string - _, file, line, ok := runtime.Caller(1) - if ok { - from = fmt.Sprintf("%s:%d", file, line) - } else { - from = "unknown" - } - logger.Error("invalid input file format", "from", from) - os.Exit(1) - } - return ret - } - - // Convert known keys into new format section by section... - logger.Info("config file migration has started") - - nodeMode := "client" - consensus, ok := oldCfg["consensus"] - if ok { - if validator, ok := m(consensus)["validator"]; ok { - mkSubMap(newCfg, "consensus") - m(newCfg["consensus"])["validator"] = validator - delete(m(consensus), "validator") - } - - if tendermint, ok := m(consensus)["tendermint"]; ok { - if mode, ok := m(tendermint)["mode"]; ok { - logger.Warn("consensus.tendermint.mode has been deprecated in favor of using the global node mode") - if mode == "archive" { - logger.Warn("node mode set to archive") - nodeMode = "archive" - } else if mode == "seed" { - logger.Warn("node mode set to seed") - nodeMode = "seed" - } - delete(m(tendermint), "mode") - } - - if len(m(tendermint)) > 0 { - logger.Info("consensus.tendermint.* is now consensus.*") - mkSubMap(newCfg, "consensus") - for k, v := range m(tendermint) { - if k == "core" { - if la, ok := m(v)["listen_address"]; ok { - logger.Info("consensus.tendermint.core.listen_address is now consensus.listen_address") - m(newCfg["consensus"])["listen_address"] = la - delete(m(m(tendermint)["core"]), "listen_address") - } - if ea, ok := m(v)["external_address"]; ok { - logger.Info("consensus.tendermint.core.external_address is now consensus.external_address") - m(newCfg["consensus"])["external_address"] = ea - delete(m(m(tendermint)["core"]), "external_address") - } - } else if k == "log" { - if dbg, ok := m(v)["debug"]; ok { - logger.Info("consensus.tendermint.log.debug is now consensus.log_debug") - m(newCfg["consensus"])["log_debug"] = dbg - delete(m(m(tendermint)["log"]), "debug") - } - } else if k == "light_client" { - if tp, ok := m(v)["trust_period"]; ok { - logger.Info("consensus.tendermint.light_client.trust_period is now consensus.state_sync.trust_period") - mkSubMap(m(newCfg["consensus"]), "state_sync") - m(m(newCfg["consensus"])["state_sync"])["trust_period"] = tp - delete(m(m(tendermint)["light_client"]), "trust_period") - } - } else if k == "seed" { - if dbg, ok := m(v)["debug"]; ok { - if dabfg, ok := m(dbg)["disable_addr_book_from_genesis"]; ok { - logger.Info("consensus.tendermint.seed.debug.disable_addr_book_from_genesis is now consensus.debug.disable_addr_book_from_genesis") - mkSubMap(m(newCfg["consensus"]), "debug") - m(m(newCfg["consensus"])["debug"])["disable_addr_book_from_genesis"] = dabfg - delete(m(m(m(tendermint)["seed"])["debug"]), "disable_addr_book_from_genesis") - } - } - } else if k == "state_sync" { - if _, ok = m(v)["consensus_node"]; ok { - logger.Info("consensus.state_sync.consensus_node is no longer needed") - delete(m(v), "consensus_node") - } - m(newCfg["consensus"])["state_sync"] = v - delete(m(tendermint), "state_sync") - } else if k == "sentry" { - if upaddr, ok := m(v)["upstream_address"]; ok { - m(newCfg["consensus"])["sentry_upstream_addresses"] = convertP2P(upaddr, "consensus.tendermint.sentry.upstream_address", "consensus.sentry_upstream_addresses") - delete(m(m(tendermint)["sentry"]), "upstream_address") - } - } else if k == "upgrade" { - if sd, ok := m(v)["stop_delay"]; ok { - logger.Info("consensus.tendermint.upgrade.stop_delay is now consensus.upgrade_stop_delay") - m(newCfg["consensus"])["upgrade_stop_delay"] = sd - delete(m(m(tendermint)["upgrade"]), "stop_delay") - } - } else if k == "supplementarysanity" { - logger.Info("consensus.tendermint.supplementarysanity.* is now consensus.supplementary_sanity.*") - m(newCfg["consensus"])["supplementary_sanity"] = v - delete(m(tendermint), k) - } else if k == "p2p" { - mkSubMap(m(newCfg["consensus"]), "p2p") - for pk, pv := range m(v) { - if pk == "persistent_peer" { - m(m(newCfg["consensus"])["p2p"])["persistent_peers"] = convertP2P(pv, "consensus.tendermint.p2p.persistent_peer", "consensus.p2p.persistent_peers") - delete(m(m(tendermint)["p2p"]), pk) - continue - } else if pk == "unconditional_peer" || pk == "unconditional_peer_ids" { - m(m(newCfg["consensus"])["p2p"])["unconditional_peers"] = convertP2P(pv, fmt.Sprintf("consensus.tendermint.p2p.%s", pk), "consensus.p2p.unconditional_peers") - delete(m(m(tendermint)["p2p"]), pk) - continue - } else if pk == "seed" { - mkSubMap(newCfg, "p2p") - m(newCfg["p2p"])["seeds"] = appendLibp2pAddrs(convertP2P(pv, "consensus.tendermint.p2p.seed", "p2p.seeds")) - delete(m(m(tendermint)["p2p"]), pk) - continue - } - m(m(newCfg["consensus"])["p2p"])[pk] = pv - delete(m(m(tendermint)["p2p"]), pk) - } - } else if k == "abci" { - if prune, ok := m(v)["prune"]; ok { - logger.Info("consensus.tendermint.abci.prune.* is now consensus.prune.*") - m(newCfg["consensus"])["prune"] = prune - delete(m(m(tendermint)["abci"]), "prune") - } - } else if k == "db" { - logger.Info("consensus.db.* is no longer needed") - delete(m(tendermint), "db") - } else { - m(newCfg["consensus"])[k] = v - delete(m(tendermint), k) - } - } - } - } - } - - runtime, ok := oldCfg["runtime"] - if ok { - if mode, ok := m(runtime)["mode"]; ok { - logger.Warn("runtime.mode has been deprecated in favor of using the global node mode") - if modeStr, ok := mode.(string); ok { - if modeStr != "none" && modeStr != nodeMode { - nodeMode = modeStr - logger.Warn("node mode set to runtime.mode", "mode", nodeMode) - } - delete(m(runtime), "mode") - } else { - logger.Error("runtime.mode has invalid type (string expected)") - } - } - - if sandbox, ok := m(runtime)["sandbox"]; ok { - if binary, ok := m(sandbox)["binary"]; ok { - logger.Info("runtime.sandbox.binary is now runtime.sandbox_binary") - mkSubMap(newCfg, "runtime") - m(newCfg["runtime"])["sandbox_binary"] = binary - delete(m(sandbox), "binary") - } else { - logger.Warn("input has invalid entries under runtime.sandbox") - } - } - - if sgx, ok := m(runtime)["sgx"]; ok { - if loader, ok := m(sgx)["loader"]; ok { - logger.Info("runtime.sgx.loader is now runtime.sgx_loader") - mkSubMap(newCfg, "runtime") - m(newCfg["runtime"])["sgx_loader"] = loader - delete(m(sgx), "loader") - } else { - logger.Warn("input has invalid entries under runtime.sgx") - } - } - - if history, ok := m(runtime)["history"]; ok { - if pruner, ok := m(history)["pruner"]; ok { - logger.Info("runtime.history.pruner is now runtime.prune") - mkSubMap(newCfg, "runtime") - m(newCfg["runtime"])["prune"] = m(pruner) - delete(m(history), "pruner") - } else { - logger.Warn("input has invalid entries under runtime.history") - } - } - - if provisioner, ok := m(runtime)["provisioner"]; ok { - mkSubMap(newCfg, "runtime") - m(newCfg["runtime"])["provisioner"] = provisioner - delete(m(runtime), "provisioner") - } - - if paths, ok := m(runtime)["paths"]; ok { - mkSubMap(newCfg, "runtime") - m(newCfg["runtime"])["paths"] = paths - delete(m(runtime), "paths") - } - - if environment, ok := m(runtime)["environment"]; ok { - mkSubMap(newCfg, "runtime") - m(newCfg["runtime"])["environment"] = environment - delete(m(runtime), "environment") - } - - if cfg, ok := m(runtime)["config"]; ok { - mkSubMap(newCfg, "config") - m(newCfg["runtime"])["config"] = cfg - delete(m(runtime), "config") - } - } - - worker, ok := oldCfg["worker"] - if ok { - if client, ok := m(worker)["client"]; ok { - if _, ok := m(client)["port"]; ok { - logger.Warn("worker.client.port has been deprecated as it is no longer required") - delete(m(client), "port") - } - } - - if registration, ok := m(worker)["registration"]; ok { - if _, ok := m(registration)["force_register"]; ok { - logger.Warn("worker.registration.force_register has been deprecated, use the 'oasis-node control clear-deregister' command instead") - delete(m(registration), "force_register") - } - - // Copy the remaining keys. - if len(m(registration)) > 0 { - logger.Info("worker.registration.* is now registration.*") - mkSubMap(newCfg, "registration") - for k, v := range m(registration) { - m(newCfg["registration"])[k] = v - delete(m(registration), k) - } - } - } - - if tx_pool, ok := m(worker)["tx_pool"]; ok { - logger.Info("worker.tx_pool.* is now runtime.tx_pool.*") - mkSubMap(newCfg, "runtime") - mkSubMap(m(newCfg["runtime"]), "tx_pool") - for k, v := range m(tx_pool) { - m(m(newCfg["runtime"])["tx_pool"])[k] = v - delete(m(tx_pool), k) - } - } - - if sentry, ok := m(worker)["sentry"]; ok { - logger.Info("worker.sentry.* is now sentry.*") - mkSubMap(newCfg, "sentry") - for k, v := range m(sentry) { - if k == "addresses" { - logger.Info("worker.sentry.addresses is now runtime.sentry_addresses") - mkSubMap(newCfg, "runtime") - m(newCfg["runtime"])["sentry_addresses"] = v - delete(m(sentry), "addresses") - } else if k == "control" { - mkSubMap(m(newCfg["sentry"]), "control") - if port, ok := m(v)["port"]; ok { - m(m(newCfg["sentry"])["control"])["port"] = port - } - if ap, ok := m(v)["authorized_pubkey"]; ok { - logger.Info("worker.sentry.control.authorized_pubkey is now sentry.control.authorized_pubkeys") - m(m(newCfg["sentry"])["control"])["authorized_pubkeys"] = ap - } - delete(m(sentry), "control") - } else { - m(newCfg["sentry"])[k] = v - delete(m(sentry), k) - } - } - } - - if keymanager, ok := m(worker)["keymanager"]; ok { - logger.Info("worker.keymanager.* is now keymanager.*") - mkSubMap(newCfg, "keymanager") - for k, v := range m(keymanager) { - if k == "runtime" { - if id, ok := m(v)["id"]; ok { - logger.Info("worker.keymanager.runtime.id is now keymanager.runtime_id") - m(newCfg["keymanager"])["runtime_id"] = id - delete(m(m(keymanager)["runtime"]), "id") - } else { - logger.Warn("worker.keymanager.runtime is malformed (missing 'id' field)") - } - } else { - m(newCfg["keymanager"])[k] = v - delete(m(keymanager), k) - } - } - } - - if storage, ok := m(worker)["storage"]; ok { - logger.Info("worker.storage.* is now storage.*") - mkSubMap(newCfg, "storage") - for k, v := range m(storage) { - if k == "public_rpc" { - if enabled, ok := m(v)["enabled"]; ok { - logger.Info("worker.storage.public_rpc.enabled is now storage.public_rpc_enabled") - m(newCfg["storage"])["public_rpc_enabled"] = enabled - delete(m(m(storage)["public_rpc"]), "enabled") - } else { - logger.Warn("worker.storage.public_rpc is malformed (missing 'enabled' field)") - } - } else if k == "checkpoint_sync" { - if disabled, ok := m(v)["disabled"]; ok { - logger.Info("worker.storage.checkpoint_sync.disabled is now storage.checkpoint_sync_disabled") - m(newCfg["storage"])["checkpoint_sync_disabled"] = disabled - delete(m(m(storage)["checkpoint_sync"]), "disabled") - } else { - logger.Warn("worker.storage.checkpoint_sync is malformed (missing 'disabled' field)") - } - } else { - m(newCfg["storage"])[k] = v - delete(m(storage), k) - } - } - } - - if p2p, ok := m(worker)["p2p"]; ok { - if port, ok := m(p2p)["port"]; ok { - logger.Info("worker.p2p.port is now p2p.port") - mkSubMap(newCfg, "p2p") - m(newCfg["p2p"])["port"] = port - delete(m(p2p), "port") - } - - if addresses, ok := m(p2p)["addresses"]; ok { - logger.Info("worker.p2p.addresses is now p2p.registration.addresses") - mkSubMap(newCfg, "p2p") - mkSubMap(m(newCfg["p2p"]), "registration") - m(m(newCfg["p2p"])["registration"])["addresses"] = addresses - delete(m(p2p), "addresses") - } - - // Migrate gossipsub config. - for _, k := range []string{ - "peer_outbound_queue_size", - "validate_queue_size", - "validate_concurrency", - "validate_throttle", - } { - if v, ok := m(p2p)[k]; ok { - logger.Info(fmt.Sprintf("worker.p2p.%s is now p2p.gossipsub.%s", k, k)) - mkSubMap(newCfg, "p2p") - mkSubMap(m(newCfg["p2p"]), "gossipsub") - m(m(newCfg["p2p"])["gossipsub"])[k] = v - delete(m(p2p), k) - } - } - - // Migrate connection manager config. - for _, k := range []string{ - "max_num_peers", - "peer_grace_period", - "persistent_peers", - } { - if v, ok := m(p2p)[k]; ok { - logger.Info(fmt.Sprintf("worker.p2p.%s is now p2p.connection_manager.%s", k, k)) - mkSubMap(newCfg, "p2p") - mkSubMap(m(newCfg["p2p"]), "connection_manager") - m(m(newCfg["p2p"])["connection_manager"])[k] = v - delete(m(p2p), k) - } - } - - if blocked_peers, ok := m(p2p)["blocked_peers"]; ok { - logger.Info("worker.p2p.blocked_peers is now p2p.connection_gater.blocked_peers") - mkSubMap(newCfg, "p2p") - mkSubMap(m(newCfg["p2p"]), "connection_gater") - m(m(newCfg["p2p"])["connection_gater"])["blocked_peers"] = blocked_peers - delete(m(p2p), "blocked_peers") - } - - if connectedness_low_water, ok := m(p2p)["connectedness_low_water"]; ok { - logger.Info("worker.p2p.connectedness_low_water is now p2p.peer_manager.connectedness_low_water") - mkSubMap(newCfg, "p2p") - mkSubMap(m(newCfg["p2p"]), "peer_manager") - m(m(newCfg["p2p"])["peer_manager"])["connectedness_low_water"] = connectedness_low_water - delete(m(p2p), "connectedness_low_water") - } - } - } - - datadir, ok := oldCfg["datadir"] - if ok { - logger.Info("datadir is now common.data_dir") - mkSubMap(newCfg, "common") - m(newCfg["common"])["data_dir"] = datadir - delete(oldCfg, "datadir") - } - - log, ok := oldCfg["log"] - if ok { - logger.Info("log.* is now common.log.*") - mkSubMap(newCfg, "common") - mkSubMap(m(newCfg["common"]), "log") - mLog := m(m(newCfg["common"])["log"]) - - if file, ok := m(log)["file"]; ok { - mLog["file"] = file - delete(m(log), "file") - } - - if format, ok := m(log)["format"]; ok { - mLog["format"] = format - delete(m(log), "format") - } - - if level, ok := m(log)["level"]; ok { - if mLevel, isMap := level.(map[string]interface{}); isMap { - // Copy the map. - mkSubMap(mLog, "level") - for k, v := range mLevel { - // Also replace any occurrences of 'tendermint' with - // 'cometbft' in the keys. - newK := strings.Replace(k, "tendermint", "cometbft", -1) - m(mLog["level"])[newK] = v - } - } else { - if sLevel, isString := level.(string); isString { - // If only a single level is given instead of the map, - // convert it into a map with only the default level. - mkSubMap(mLog, "level") - m(mLog["level"])["default"] = sLevel - } else { - logger.Warn("log.level is malformed, ignoring") - } - } - delete(m(log), "level") - } - } - - debug, ok := oldCfg["debug"] - if ok { - logger.Info("debug.* is now common.debug.*") - mkSubMap(newCfg, "common") - mkSubMap(m(newCfg["common"]), "debug") - mDebug := m(m(newCfg["common"])["debug"]) - - if rlimit, ok := m(debug)["rlimit"]; ok { - mDebug["rlimit"] = rlimit - delete(m(debug), "rlimit") - } - - if allow_root, ok := m(debug)["allow_root"]; ok { - mDebug["allow_root"] = allow_root - delete(m(debug), "allow_root") - } - - if socketPath, ok := m(m(m(debug)["grpc"])["internal"])["socket_path"]; ok { - m(newCfg["common"])["internal_socket_path"] = socketPath - delete(m(debug), "grpc") - } - } - - pprof, ok := oldCfg["pprof"] - if ok { - if bind, ok := m(pprof)["bind"]; ok { - logger.Info("pprof.bind is now pprof.bind_address") - mkSubMap(newCfg, "pprof") - m(newCfg["pprof"])["bind_address"] = bind - delete(m(pprof), "bind") - } - } - - ias, ok := oldCfg["ias"] - if ok { - mkSubMap(newCfg, "ias") - mIAS := m(newCfg["ias"]) - - if proxy, ok := m(ias)["proxy"]; ok { - if address, ok := m(proxy)["address"]; ok { - logger.Info("ias.proxy.address is now ias.proxy_addresses") - mIAS["proxy_addresses"] = address - delete(m(proxy), "address") - } - } - - if debug, ok := m(ias)["debug"]; ok { - if skip_verify, ok := m(debug)["skip_verify"]; ok { - logger.Info("ias.debug.skip_verify is now ias.debug_skip_verify") - mIAS["debug_skip_verify"] = skip_verify - delete(m(debug), "skip_verify") - } - } - } - - genesis, ok := oldCfg["genesis"] - if ok { - mkSubMap(newCfg, "genesis") - mGen := m(newCfg["genesis"]) - - if file, ok := m(genesis)["file"]; ok { - mGen["file"] = file - delete(m(genesis), "file") - } - } - - metrics, ok := oldCfg["metrics"] - if ok { - mkSubMap(newCfg, "metrics") - newCfg["metrics"] = metrics - delete(oldCfg, "metrics") - } - - // If we deleted any keys, make sure we don't retain empty structures. - pruneEmptyMaps(oldCfg) - // Also prune new config. - pruneEmptyMaps(newCfg) - - // If a node has `consensus.validator` set to true and it does not have any runtimes configured, - // the new `mode` should be set to `validator`. - var isValidator bool - if newValidator, ok := m(newCfg["consensus"])["validator"]; ok { - isValidator, _ = newValidator.(bool) - if _, hasRuntimes := m(newCfg["runtime"])["paths"]; !hasRuntimes && isValidator { - nodeMode = "validator" - delete(m(newCfg["consensus"]), "validator") - } - } - // If node is a validator, it now requires external P2P addresses to have set. - if isValidator { - // Set P2P port if not set. - if _, ok := m(newCfg["p2p"])["port"]; !ok { - m(newCfg["p2p"])["port"] = 9200 - } - // Set P2P registration addresses if not set. - if _, ok := m(m(newCfg["p2p"])["registration"])["addresses"]; !ok { - mkSubMap(m(newCfg["p2p"]), "registration") - - // Parse host from consensus.external_address. - ea := m(newCfg["consensus"])["external_address"] - if eaStr, ok := ea.(string); ok { - url, err := url.Parse(eaStr) - if err != nil { - logger.Error("failed to parse URI from consensus.external_address", "err", err) - os.Exit(1) - } - m(m(newCfg["p2p"])["registration"])["addresses"] = []string{url.Hostname() + ":" + fmt.Sprintf("%d", m(newCfg["p2p"])["port"])} - } else { - logger.Warn("consensus.external_address missing, not configuring p2p.registration.addresses parameter", "address", ea) - } - } else { - logger.Warn("p2p.registration.addresses is already set, make sure the address port matches p2p.port") - } - - } - if isValidator && (m(newCfg["p2p"])["port"] == nil || m(m(newCfg["p2p"])["registration"])["addresses"] == nil) { - logger.Warn("node is a validator but p2p.port or p2p.registration.addresses are not set") - } - - // Check for options that are only available on the command-line. - if _, ok = oldCfg["debug"]; ok { - logger.Warn("note that some debug.* options are from now on only available on the command-line") - } - if _, ok = oldCfg["grpc"]; ok { - logger.Warn("note that grpc.* options are from now on only available on the command-line") - } - - logger.Info("config file migration completed") - - // Print sections remaining in map (if any). - if len(oldCfg) > 0 { - remaining, grr := yaml.Marshal(&oldCfg) - if grr != nil { - logger.Error("failed to marshal remaining sections from input file", "err", grr) - os.Exit(1) - } - - fmt.Printf("Ignored unknown sections from input file, please review manually:\n%s\n", remaining) - } - - logger.Info("saving migrated config file", "file_name", cfgOutFileName) - - // Save new config to file. - newCfgRaw, err := yaml.Marshal(&newCfg) - if err != nil { - logger.Error("failed to convert migrated config file into YAML", "err", err) - os.Exit(1) - } - // Prepend the node mode at the very beginning. - newCfgRaw = append([]byte(fmt.Sprintf("mode: %s\n", nodeMode)), newCfgRaw...) - if err = os.WriteFile(cfgOutFileName, newCfgRaw, 0o600); err != nil { - logger.Error("failed to write migrated config file", "file_name", cfgOutFileName, "err", err) - os.Exit(1) - } - - logger.Info("migrated config file saved successfully", "file_name", cfgOutFileName) - - // Validate new config. - logger.Info("validating migrated config file") - newCfgStruct := config.DefaultConfig() - dec := yaml.NewDecoder(bytes.NewReader(newCfgRaw)) - dec.KnownFields(true) - err = dec.Decode(&newCfgStruct) - if err != nil && err != io.EOF { - logger.Error("failed to parse config file after migration (this might be normal if you're using environment variable substitutions in your original config file)", "err", err) - os.Exit(1) - } - err = newCfgStruct.Validate() - if err != nil { - logger.Error("failed to validate migrated config file (this might be normal if you're using environment variable substitutions in your original config file)", "err", err) - os.Exit(1) - } else { - logger.Info("validation of the migrated config file completed successfully") - } - - logger.Info("migration completed successfully", "new_config_file_name", cfgOutFileName) -} - -// Register registers the migrate-config sub-command. -func Register(parentCmd *cobra.Command) { - migrateCmd.PersistentFlags().AddFlagSet(migrateFlags) - parentCmd.AddCommand(migrateCmd) -} - -func init() { - migrateFlags.String(cfgIn, "config.yaml", "path to input config file") - migrateFlags.String(cfgOut, "config_new.yaml", "path to output config file") - _ = viper.BindPFlags(migrateFlags) -} diff --git a/go/oasis-node/cmd/config/migrate/migrate_test.go b/go/oasis-node/cmd/config/migrate/migrate_test.go deleted file mode 100644 index 95ac4bf3b1c..00000000000 --- a/go/oasis-node/cmd/config/migrate/migrate_test.go +++ /dev/null @@ -1,841 +0,0 @@ -package migrate - -import ( - "os" - "path/filepath" - "testing" - "time" - - "github.com/spf13/viper" - "github.com/stretchr/testify/require" - "gopkg.in/yaml.v3" - - "github.com/oasisprotocol/oasis-core/go/config" - rtConfig "github.com/oasisprotocol/oasis-core/go/runtime/config" -) - -// Simple test configuration file. -const testSimpleConfigRaw = ` -datadir: /node/data - -log: - level: - default: debug - tendermint: debug - tendermint/context: error - format: JSON - -genesis: - file: /node/etc/genesis.json - -consensus: - tendermint: - p2p: - seed: - - "E27F6B7A350B4CC2B48A6CBE94B0A02B0DCB0BF3@35.199.49.168:26656" - -runtime: - mode: client - paths: - - /node/runtime/cipher-paratime-2.6.2.orc - - /node/runtime/emerald-paratime-10.0.0.orc - - /node/runtime/sapphire-paratime-0.4.0.orc - -worker: - storage: - checkpointer: - enabled: true -` - -// Test configuration file with as many options as possible. -// Note that this configuration isn't meant to actually work, -// we're just testing the parsing. -const testComplexConfigRaw = ` -datadir: /storage/node - -# Logging. -log: - file: /storage/node/log.txt - level: - default: debug - tendermint: warn - tendermint/context: error - format: JSON - -# Genesis. -genesis: - file: /storage/node/genesis.json - -# Worker configuration. -worker: - p2p: - port: 9002 - peer_outbound_queue_size: 42 - validate_queue_size: 43 - validate_concurrency: 44 - validate_throttle: 45 - max_num_peers: 46 - peer_grace_period: 47s - connectedness_low_water: 48 - persistent_peers: - - "foo@1.2.3.4:4321" - blocked_peers: - - "1.2.3.4" - - registration: - entity: /storage/node/entity/entity.json - - tx_pool: - schedule_max_tx_pool_size: 10000 - - storage: - backend: "badger" - checkpoint_sync: - disabled: true - checkpointer: - enabled: true - -# IAS configuration. -ias: - proxy: - address: - - "qwerty@1.2.3.4:4321" - -# Consensus backend. -consensus: - validator: true - - # Tendermint backend configuration. - tendermint: - abci: - prune: - strategy: keep_n - num_kept: 86400 - core: - listen_address: tcp://0.0.0.0:26656 - external_address: tcp://4.3.2.1:26656 - debug: - addr_book_lenient: false - sentry: - upstream_address: - - "asdf@1.2.3.4:5678" - mode: full - db: - backend: badger - - # Validators behind sentry nodes should set sentries as persistent peers. - p2p: - # Seed node setup. - seed: - - "53572F689E5BACDD3C6527E6594EC49C8F3093F6@34.86.165.6:26656" - - persistent_peer: - - "asdf@1.2.3.4:5678" - - unconditional_peer: - - "53572F689E5BACDD3C6527E6594EC49C8F3093F6@34.86.165.6:26656" - - disable_peer_exchange: true - - state_sync: - enabled: false - trust_height: 4692334 - trust_hash: "2d9dd35e7254a6c5c87f49d0646ee359f06f460b72278ad3ac17130bd9a7ec19" - consensus_node: - - "xAMjfJDcUFUcwgZGEQuOdux8gAdc+IFEqccB2LHdGjU=@34.86.145.181:9001" - - "DbYomffhISzQ4Nd6O2RX0PBPzbt0U8996IjH4oifOPM=@35.221.19.64:9001" - - -runtime: - mode: "client" - environment: sgx - provisioner: sandboxed - - history: - pruner: - strategy: keep_last - - sgx: - loader: /oasis/bin/oasis-core-runtime-loader - - paths: - - /oasis/runtimes/sapphire-paratime.orc - - /oasis/runtimes/sapphire-paratime-previous.orc - - config: - "000000000000000000000000000000000000000000000000f80306c9858e7279": {"allow_expensive_queries": true} - -# Profiling. -pprof: - bind: 0.0.0.0:6666 - -# Metrics. -metrics: - mode: pull - address: 0.0.0.0:9101 - job_name: node-mainnet - interval: 10s - labels: - instance: asdf-instance-0 -` - -// Keymanager test configuration file. -const testKMConfigRaw = ` -datadir: /km/data - -log: - level: debug - format: JSON - -genesis: - file: /km/etc/genesis.json - -worker: - p2p: - port: 1234 - addresses: - - "4.3.2.1:26656" - registration: - entity: /km/etc/entity/entity.json - keymanager: - runtime: - id: "4000000000000000000000000000000000000000000000004a1a53dff2ae482d" - private_peer_pub_keys: - - "asdf" - - "ghij" - - "klmn" - -ias: - proxy: - address: - - "foo@1.2.3.4:5678" - -consensus: - validator: false - tendermint: - mode: full - core: - listen_address: tcp://0.0.0.0:26656 - external_address: tcp://4.3.2.1:26656 - p2p: - seed: - - "asdf@1.2.3.4:26656" - -runtime: - mode: "keymanager" - environment: sgx - provisioner: sandboxed - sgx: - loader: /km/bin/oasis-core-runtime-loader - paths: - - /km/runtimes/keymanager.orc -` - -// Validator node. -const testValidatorConfigRaw = ` -datadir: /node/data - -log: - level: - default: info - tendermint: info - tendermint/context: error - format: JSON - -genesis: - file: /node/etc/genesis.json - -consensus: - validator: true - - tendermint: - p2p: - # List of seed nodes to connect to. - # NOTE: You can add additional seed nodes to this list if you want. - seed: - - "E27F6B7A350B4CC2B48A6CBE94B0A02B0DCB0BF3@35.199.49.168:26656" - -worker: - registration: - # In order for the node to register itself, the entity.json of the entity - # used to provision the node must be available on the node. - entity: /node/entity/entity.json -` - -// Validator node with external address set and no P2P address. -const testValidatorConfig2Raw = ` -datadir: /node/data - -log: - level: - default: info - tendermint: info - tendermint/context: error - format: JSON - -genesis: - file: /node/etc/genesis.json - -consensus: - validator: true - - tendermint: - p2p: - # List of seed nodes to connect to. - # NOTE: You can add additional seed nodes to this list if you want. - seed: - - "E27F6B7A350B4CC2B48A6CBE94B0A02B0DCB0BF3@35.199.49.168:26656" - core: - external_address: tcp://4.3.2.1:26656 - -worker: - registration: - # In order for the node to register itself, the entity.json of the entity - # used to provision the node must be available on the node. - entity: /node/entity/entity.json -` - -// Non-validator node from docs test configuration file. -const testDocsNonValidatorConfigRaw = ` -datadir: /node/data - -log: - level: - default: info - tendermint: info - tendermint/context: error - format: JSON - -genesis: - file: /node/etc/genesis.json - -consensus: - tendermint: - p2p: - # List of seed nodes to connect to. - # NOTE: You can add additional seed nodes to this list if you want. - seed: - - "E27F6B7A350B4CC2B48A6CBE94B0A02B0DCB0BF3@35.199.49.168:26656" -` - -// Seed node from docs test configuration file. -const testDocsSeedConfigRaw = ` -datadir: /node/data - -log: - level: - default: info - tendermint: info - tendermint/context: error - format: JSON - -genesis: - file: /node/etc/genesis.json - -consensus: - tendermint: - mode: seed -` - -// Archive node from docs test configuration file. -const testDocsArchiveConfigRaw = ` -datadir: /node/data - -log: - level: - default: info - tendermint: info - tendermint/context: error - format: JSON - -genesis: - file: /node/etc/genesis.json - -consensus: - tendermint: - mode: archive -` - -// ParaTime node from docs test configuration file. -const testDocsParaTimeConfigRaw = ` -datadir: /node/data - -log: - level: - default: info - tendermint: info - tendermint/context: error - format: JSON - -genesis: - file: /node/etc/genesis.json - -consensus: - tendermint: - core: - listen_address: tcp://0.0.0.0:26656 - - # The external IP that is used when registering this node to the network. - # NOTE: If you are using the Sentry node setup, this option should be - # omitted. - external_address: tcp://1.2.3.4:26656 - - p2p: - # List of seed nodes to connect to. - # NOTE: You can add additional seed nodes to this list if you want. - seed: - - "E27F6B7A350B4CC2B48A6CBE94B0A02B0DCB0BF3@35.199.49.168:26656" - -runtime: - mode: compute - paths: - # Paths to ParaTime bundles for all of the supported ParaTimes. - - /node/runtimes/test.orc - - # The following section is required for ParaTimes which are running inside the - # Intel SGX Trusted Execution Environment. - sgx: - loader: /node/bin/oasis-core-runtime-loader - -worker: - registration: - # In order for the node to register itself, the entity.json of the entity - # used to provision the node must be available on the node. - entity: /node/entity/entity.json - - p2p: - # External P2P configuration. - port: 30002 - addresses: - # The external IP that is used when registering this node to the network. - - "1.2.3.4:30002" - -# The following section is required for ParaTimes which are running inside the -# Intel SGX Trusted Execution Environment. -ias: - proxy: - address: - # List of IAS proxies to connect to. - # NOTE: You can add additional IAS proxies to this list if you want. - - "asdf@5.4.3.2:1234" -` - -// ParaTime client node from docs test configuration file. -const testDocsParaTimeClientConfigRaw = ` -datadir: /node/data - -log: - level: - default: info - tendermint: info - tendermint/context: error - format: JSON - -genesis: - file: /node/etc/genesis.json - -consensus: - tendermint: - p2p: - # List of seed nodes to connect to. - # NOTE: You can add additional seed nodes to this list if you want. - seed: - - "E27F6B7A350B4CC2B48A6CBE94B0A02B0DCB0BF3@35.199.49.168:26656" - -runtime: - mode: client - paths: - # Paths to ParaTime bundles for all of the supported ParaTimes. - - "/node/runtimes/test.orc" -` - -// Sentry node from docs test configuration file. -const testDocsSentryConfigRaw = ` -datadir: /serverdir/node - -log: - level: - default: debug - tendermint: warn - tendermint/context: error - format: JSON - -genesis: - file: /serverdir/etc/genesis.json - -worker: - sentry: - enabled: true - control: - port: 9009 - authorized_pubkey: - - asdf - -consensus: - tendermint: - abci: - prune: - strategy: keep_n - # Keep ~1 hour of data since block production is ~1 block every 6 seconds. - # (3600/6 = 600) - num_kept: 600 - core: - listen_address: tcp://0.0.0.0:26656 - external_address: tcp://6.7.8.9:26656 - - p2p: - seed: - - "E27F6B7A350B4CC2B48A6CBE94B0A02B0DCB0BF3@35.199.49.168:26656" - - sentry: - upstream_address: - - "asdf@1.2.3.4:26656" -` - -// Simple config with internal socket override. -const testInternalSocketOverrideConfigRaw = ` -debug: - dont_blame_oasis: true - grpc: - internal: - socket_path: /node/custom-internal.sock - -datadir: /node/data - -log: - level: - default: debug - tendermint: debug - tendermint/context: error - format: JSON - -genesis: - file: /node/etc/genesis.json - -consensus: - tendermint: - p2p: - seed: - - "E27F6B7A350B4CC2B48A6CBE94B0A02B0DCB0BF3@35.199.49.168:26656" - -runtime: - mode: client - paths: - - /node/runtime/cipher-paratime-2.6.2.orc - - /node/runtime/emerald-paratime-10.0.0.orc - - /node/runtime/sapphire-paratime-0.4.0.orc - -worker: - storage: - checkpointer: - enabled: true -` - -func prepareTest(require *require.Assertions, configIn string) config.Config { - // Prepare temporary directory and populate it with the test config file. - tempDir, err := os.MkdirTemp("", "oasis-node-config_migrate_test_") - require.NoError(err, "failed to create temp dir") - defer os.RemoveAll(tempDir) - - inFile := filepath.Join(tempDir, "config.yaml") - outFile := filepath.Join(tempDir, "config_new.yaml") - - err = os.WriteFile(inFile, []byte(configIn), 0o600) - require.NoError(err, "failed to write test config file") - - // Run the migration command. - cmd := migrateCmd - viper.Set(cfgIn, inFile) - viper.Set(cfgOut, outFile) - require.NoError(cmd.Execute(), "migration failed") - - // Parse migrated config file. - newConfigRaw, err := os.ReadFile(outFile) - require.NoError(err, "failed to read migrated config file") - - newConfig := config.DefaultConfig() - err = yaml.Unmarshal(newConfigRaw, &newConfig) - require.NoError(err, "failed to unmarshal migrated config file") - - err = newConfig.Validate() - require.NoError(err, "failed to validate migrated config file") - - return newConfig -} - -func TestConfigMigrationSimple(t *testing.T) { - require := require.New(t) - newConfig := prepareTest(require, testSimpleConfigRaw) - - // Now check if the config struct fields actually match the original state. - require.Equal(newConfig.Mode, config.ModeClient) - require.Equal(newConfig.Common.DataDir, "/node/data") - require.Equal(newConfig.Common.Log.Format, "JSON") - require.Equal(newConfig.Common.Log.Level["default"], "debug") - require.Equal(newConfig.Common.Log.Level["cometbft"], "debug") - require.Equal(newConfig.Common.Log.Level["cometbft/context"], "error") - require.Equal(newConfig.Genesis.File, "/node/etc/genesis.json") - require.Equal(newConfig.P2P.Seeds[0], "H6u9MtuoWRKn5DKSgarj/dzr2Z9BsjuRHgRAoXITOcU=@35.199.49.168:26656") - require.Equal(newConfig.P2P.Seeds[1], "H6u9MtuoWRKn5DKSgarj/dzr2Z9BsjuRHgRAoXITOcU=@35.199.49.168:9200") - require.Equal(newConfig.Runtime.Paths[0], "/node/runtime/cipher-paratime-2.6.2.orc") - require.Equal(newConfig.Runtime.Paths[1], "/node/runtime/emerald-paratime-10.0.0.orc") - require.Equal(newConfig.Runtime.Paths[2], "/node/runtime/sapphire-paratime-0.4.0.orc") - require.Equal(newConfig.Storage.Checkpointer.Enabled, true) -} - -func TestConfigMigrationComplex(t *testing.T) { - require := require.New(t) - newConfig := prepareTest(require, testComplexConfigRaw) - - // Now check if the config struct fields actually match the original state. - require.Equal(newConfig.Mode, config.ModeClient) - require.Equal(newConfig.Common.DataDir, "/storage/node") - require.Equal(newConfig.Common.Log.File, "/storage/node/log.txt") - require.Equal(newConfig.Common.Log.Format, "JSON") - require.Equal(newConfig.Common.Log.Level["default"], "debug") - require.Equal(newConfig.Common.Log.Level["cometbft"], "warn") - require.Equal(newConfig.Common.Log.Level["cometbft/context"], "error") - require.Equal(newConfig.Genesis.File, "/storage/node/genesis.json") - require.Equal(newConfig.P2P.Port, uint16(9002)) - require.Equal(newConfig.P2P.Seeds[0], "HcDFrTp/MqRHtju5bCx6TIhIMd6X/0ZQ3lUG73q5898=@34.86.165.6:26656") - require.Equal(newConfig.P2P.Seeds[1], "HcDFrTp/MqRHtju5bCx6TIhIMd6X/0ZQ3lUG73q5898=@34.86.165.6:9200") - require.Equal(newConfig.P2P.Gossipsub.PeerOutboundQueueSize, 42) - require.Equal(newConfig.P2P.Gossipsub.ValidateQueueSize, 43) - require.Equal(newConfig.P2P.Gossipsub.ValidateConcurrency, 44) - require.Equal(newConfig.P2P.Gossipsub.ValidateThrottle, 45) - require.Equal(newConfig.P2P.ConnectionManager.MaxNumPeers, 46) - require.Equal(newConfig.P2P.ConnectionManager.PeerGracePeriod, 47*time.Second) - require.Equal(newConfig.P2P.ConnectionManager.PersistentPeers[0], "foo@1.2.3.4:4321") - require.Equal(newConfig.P2P.ConnectionGater.BlockedPeerIPs[0], "1.2.3.4") - require.Equal(newConfig.P2P.PeerManager.ConnectednessLowWater, 48.0) - require.Equal(newConfig.Consensus.P2P.PersistentPeer[0], "INSERT_P2P_PUBKEY_HERE@1.2.3.4:5678") - require.Equal(newConfig.Consensus.P2P.UnconditionalPeer[0], "HcDFrTp/MqRHtju5bCx6TIhIMd6X/0ZQ3lUG73q5898=@34.86.165.6:26656") - require.Equal(newConfig.Consensus.SentryUpstreamAddresses[0], "INSERT_P2P_PUBKEY_HERE@1.2.3.4:5678") - require.Equal(newConfig.IAS.ProxyAddresses, []string{"qwerty@1.2.3.4:4321"}) - require.Equal(newConfig.Pprof.BindAddress, "0.0.0.0:6666") - require.Equal(newConfig.Runtime.Environment, rtConfig.RuntimeEnvironmentSGX) - require.Equal(newConfig.Runtime.Provisioner, rtConfig.RuntimeProvisionerSandboxed) - require.Equal(newConfig.Runtime.Prune.Strategy, "keep_last") - require.Equal(newConfig.Runtime.SGXLoader, "/oasis/bin/oasis-core-runtime-loader") - require.Equal(newConfig.Runtime.Paths[0], "/oasis/runtimes/sapphire-paratime.orc") - require.Equal(newConfig.Runtime.Paths[1], "/oasis/runtimes/sapphire-paratime-previous.orc") - _, hasConfigKey := newConfig.Runtime.RuntimeConfig["000000000000000000000000000000000000000000000000f80306c9858e7279"] - require.Equal(hasConfigKey, true) - require.Equal(newConfig.Runtime.TxPool.MaxPoolSize, uint64(10000)) - require.Equal(newConfig.Consensus.ListenAddress, "tcp://0.0.0.0:26656") - require.Equal(newConfig.Consensus.ExternalAddress, "tcp://4.3.2.1:26656") - require.Equal(newConfig.Consensus.Validator, true) - require.Equal(newConfig.Consensus.P2P.DisablePeerExchange, true) - require.Equal(newConfig.Consensus.Prune.Strategy, "keep_n") - require.Equal(newConfig.Consensus.Prune.NumKept, uint64(86400)) - require.Equal(newConfig.Consensus.StateSync.Enabled, false) - require.Equal(newConfig.Consensus.StateSync.TrustPeriod, 30*24*time.Hour) - require.Equal(newConfig.Consensus.StateSync.TrustHeight, uint64(4692334)) - require.Equal(newConfig.Consensus.StateSync.TrustHash, "2d9dd35e7254a6c5c87f49d0646ee359f06f460b72278ad3ac17130bd9a7ec19") - require.Equal(newConfig.Storage.Backend, "badger") - require.Equal(newConfig.Storage.CheckpointSyncDisabled, true) - require.Equal(newConfig.Storage.Checkpointer.Enabled, true) - require.Equal(newConfig.Registration.Entity, "/storage/node/entity/entity.json") - require.Equal(newConfig.Metrics.Mode, "pull") - require.Equal(newConfig.Metrics.Address, "0.0.0.0:9101") - require.Equal(newConfig.Metrics.JobName, "node-mainnet") - require.Equal(newConfig.Metrics.Interval, 10*time.Second) - require.Equal(newConfig.Metrics.Labels["instance"], "asdf-instance-0") -} - -func TestConfigMigrationKM(t *testing.T) { - require := require.New(t) - newConfig := prepareTest(require, testKMConfigRaw) - - // Now check if the config struct fields actually match the original state. - require.Equal(newConfig.Mode, config.ModeKeyManager) - require.Equal(newConfig.Common.DataDir, "/km/data") - require.Equal(newConfig.Common.Log.Format, "JSON") - require.Equal(newConfig.Common.Log.Level["default"], "debug") - require.Equal(newConfig.Genesis.File, "/km/etc/genesis.json") - require.Equal(newConfig.P2P.Port, uint16(1234)) - require.Equal(newConfig.P2P.Seeds[0], "INSERT_P2P_PUBKEY_HERE@1.2.3.4:26656") - require.Equal(newConfig.P2P.Seeds[1], "INSERT_P2P_PUBKEY_HERE@1.2.3.4:9200") - require.Equal(newConfig.P2P.Registration.Addresses[0], "4.3.2.1:26656") - require.Equal(newConfig.Registration.Entity, "/km/etc/entity/entity.json") - require.Equal(newConfig.IAS.ProxyAddresses, []string{"foo@1.2.3.4:5678"}) - require.Equal(newConfig.Runtime.Environment, rtConfig.RuntimeEnvironmentSGX) - require.Equal(newConfig.Runtime.Provisioner, rtConfig.RuntimeProvisionerSandboxed) - require.Equal(newConfig.Runtime.SGXLoader, "/km/bin/oasis-core-runtime-loader") - require.Equal(newConfig.Runtime.Paths[0], "/km/runtimes/keymanager.orc") - require.Equal(newConfig.Consensus.ListenAddress, "tcp://0.0.0.0:26656") - require.Equal(newConfig.Consensus.ExternalAddress, "tcp://4.3.2.1:26656") - require.Equal(newConfig.Consensus.Validator, false) -} - -func TestConfigMigrationValidator(t *testing.T) { - require := require.New(t) - newConfig := prepareTest(require, testValidatorConfigRaw) - - // Now check if the config struct fields actually match the original state. - require.Equal(newConfig.Mode, config.ModeValidator) - require.Equal(newConfig.Common.DataDir, "/node/data") - require.Equal(newConfig.Common.Log.Format, "JSON") - require.Equal(newConfig.Common.Log.Level["default"], "info") - require.Equal(newConfig.Common.Log.Level["cometbft"], "info") - require.Equal(newConfig.Common.Log.Level["cometbft/context"], "error") - require.Equal(newConfig.Genesis.File, "/node/etc/genesis.json") - require.Equal(newConfig.P2P.Seeds[0], "H6u9MtuoWRKn5DKSgarj/dzr2Z9BsjuRHgRAoXITOcU=@35.199.49.168:26656") - require.Equal(newConfig.P2P.Seeds[1], "H6u9MtuoWRKn5DKSgarj/dzr2Z9BsjuRHgRAoXITOcU=@35.199.49.168:9200") - require.Equal(newConfig.Consensus.Validator, false) -} - -func TestConfigMigrationValidator2(t *testing.T) { - require := require.New(t) - newConfig := prepareTest(require, testValidatorConfig2Raw) - - // Now check if the config struct fields actually match the original state. - require.Equal(newConfig.Mode, config.ModeValidator) - require.Equal(newConfig.Common.DataDir, "/node/data") - require.Equal(newConfig.Common.Log.Format, "JSON") - require.Equal(newConfig.Common.Log.Level["default"], "info") - require.Equal(newConfig.Common.Log.Level["cometbft"], "info") - require.Equal(newConfig.Common.Log.Level["cometbft/context"], "error") - require.Equal(newConfig.Genesis.File, "/node/etc/genesis.json") - require.Equal(newConfig.P2P.Seeds[0], "H6u9MtuoWRKn5DKSgarj/dzr2Z9BsjuRHgRAoXITOcU=@35.199.49.168:26656") - require.Equal(newConfig.P2P.Seeds[1], "H6u9MtuoWRKn5DKSgarj/dzr2Z9BsjuRHgRAoXITOcU=@35.199.49.168:9200") - require.Equal(newConfig.Consensus.Validator, false) - require.Equal(newConfig.Consensus.ExternalAddress, "tcp://4.3.2.1:26656") - require.Equal(newConfig.P2P.Port, uint16(9200)) - require.Equal(len(newConfig.P2P.Registration.Addresses), 1) - require.Equal(newConfig.P2P.Registration.Addresses[0], "4.3.2.1:9200") -} - -func TestConfigMigrationDocsNonValidator(t *testing.T) { - require := require.New(t) - newConfig := prepareTest(require, testDocsNonValidatorConfigRaw) - - // Now check if the config struct fields actually match the original state. - require.Equal(newConfig.Mode, config.ModeClient) - require.Equal(newConfig.Common.DataDir, "/node/data") - require.Equal(newConfig.Common.Log.Format, "JSON") - require.Equal(newConfig.Common.Log.Level["default"], "info") - require.Equal(newConfig.Common.Log.Level["cometbft"], "info") - require.Equal(newConfig.Common.Log.Level["cometbft/context"], "error") - require.Equal(newConfig.Genesis.File, "/node/etc/genesis.json") - require.Equal(newConfig.P2P.Seeds[0], "H6u9MtuoWRKn5DKSgarj/dzr2Z9BsjuRHgRAoXITOcU=@35.199.49.168:26656") - require.Equal(newConfig.P2P.Seeds[1], "H6u9MtuoWRKn5DKSgarj/dzr2Z9BsjuRHgRAoXITOcU=@35.199.49.168:9200") - require.Equal(newConfig.Consensus.Validator, false) -} - -func TestConfigMigrationDocsSeed(t *testing.T) { - require := require.New(t) - newConfig := prepareTest(require, testDocsSeedConfigRaw) - - // Now check if the config struct fields actually match the original state. - require.Equal(newConfig.Mode, config.ModeSeed) - require.Equal(newConfig.Common.DataDir, "/node/data") - require.Equal(newConfig.Common.Log.Format, "JSON") - require.Equal(newConfig.Common.Log.Level["default"], "info") - require.Equal(newConfig.Common.Log.Level["cometbft"], "info") - require.Equal(newConfig.Common.Log.Level["cometbft/context"], "error") - require.Equal(newConfig.Genesis.File, "/node/etc/genesis.json") - require.Equal(newConfig.Consensus.Validator, false) -} - -func TestConfigMigrationDocsArchive(t *testing.T) { - require := require.New(t) - newConfig := prepareTest(require, testDocsArchiveConfigRaw) - - // Now check if the config struct fields actually match the original state. - require.Equal(newConfig.Mode, config.ModeArchive) - require.Equal(newConfig.Common.DataDir, "/node/data") - require.Equal(newConfig.Common.Log.Format, "JSON") - require.Equal(newConfig.Common.Log.Level["default"], "info") - require.Equal(newConfig.Common.Log.Level["cometbft"], "info") - require.Equal(newConfig.Common.Log.Level["cometbft/context"], "error") - require.Equal(newConfig.Genesis.File, "/node/etc/genesis.json") - require.Equal(newConfig.Consensus.Validator, false) -} - -func TestConfigMigrationDocsParaTime(t *testing.T) { - require := require.New(t) - newConfig := prepareTest(require, testDocsParaTimeConfigRaw) - - // Now check if the config struct fields actually match the original state. - require.Equal(newConfig.Mode, config.ModeCompute) - require.Equal(newConfig.Common.DataDir, "/node/data") - require.Equal(newConfig.Common.Log.Format, "JSON") - require.Equal(newConfig.Common.Log.Level["default"], "info") - require.Equal(newConfig.Common.Log.Level["cometbft"], "info") - require.Equal(newConfig.Common.Log.Level["cometbft/context"], "error") - require.Equal(newConfig.Genesis.File, "/node/etc/genesis.json") - require.Equal(newConfig.P2P.Port, uint16(30002)) - require.Equal(newConfig.P2P.Registration.Addresses[0], "1.2.3.4:30002") - require.Equal(newConfig.P2P.Seeds[0], "H6u9MtuoWRKn5DKSgarj/dzr2Z9BsjuRHgRAoXITOcU=@35.199.49.168:26656") - require.Equal(newConfig.P2P.Seeds[1], "H6u9MtuoWRKn5DKSgarj/dzr2Z9BsjuRHgRAoXITOcU=@35.199.49.168:9200") - require.Equal(newConfig.Registration.Entity, "/node/entity/entity.json") - require.Equal(newConfig.IAS.ProxyAddresses, []string{"asdf@5.4.3.2:1234"}) - require.Equal(newConfig.Runtime.SGXLoader, "/node/bin/oasis-core-runtime-loader") - require.Equal(newConfig.Runtime.Paths[0], "/node/runtimes/test.orc") - require.Equal(newConfig.Consensus.ListenAddress, "tcp://0.0.0.0:26656") - require.Equal(newConfig.Consensus.ExternalAddress, "tcp://1.2.3.4:26656") - require.Equal(newConfig.Consensus.Validator, false) -} - -func TestConfigMigrationDocsParaTimeClient(t *testing.T) { - require := require.New(t) - newConfig := prepareTest(require, testDocsParaTimeClientConfigRaw) - - // Now check if the config struct fields actually match the original state. - require.Equal(newConfig.Mode, config.ModeClient) - require.Equal(newConfig.Common.DataDir, "/node/data") - require.Equal(newConfig.Common.Log.Format, "JSON") - require.Equal(newConfig.Common.Log.Level["default"], "info") - require.Equal(newConfig.Common.Log.Level["cometbft"], "info") - require.Equal(newConfig.Common.Log.Level["cometbft/context"], "error") - require.Equal(newConfig.Genesis.File, "/node/etc/genesis.json") - require.Equal(newConfig.P2P.Seeds[0], "H6u9MtuoWRKn5DKSgarj/dzr2Z9BsjuRHgRAoXITOcU=@35.199.49.168:26656") - require.Equal(newConfig.P2P.Seeds[1], "H6u9MtuoWRKn5DKSgarj/dzr2Z9BsjuRHgRAoXITOcU=@35.199.49.168:9200") - require.Equal(newConfig.Runtime.Paths[0], "/node/runtimes/test.orc") -} - -func TestConfigMigrationDocsSentry(t *testing.T) { - require := require.New(t) - newConfig := prepareTest(require, testDocsSentryConfigRaw) - - // Now check if the config struct fields actually match the original state. - require.Equal(newConfig.Mode, config.ModeClient) - require.Equal(newConfig.Common.DataDir, "/serverdir/node") - require.Equal(newConfig.Common.Log.Format, "JSON") - require.Equal(newConfig.Common.Log.Level["default"], "debug") - require.Equal(newConfig.Common.Log.Level["cometbft"], "warn") - require.Equal(newConfig.Common.Log.Level["cometbft/context"], "error") - require.Equal(newConfig.Genesis.File, "/serverdir/etc/genesis.json") - require.Equal(newConfig.Consensus.ListenAddress, "tcp://0.0.0.0:26656") - require.Equal(newConfig.Consensus.ExternalAddress, "tcp://6.7.8.9:26656") - require.Equal(newConfig.Consensus.Prune.Strategy, "keep_n") - require.Equal(newConfig.Consensus.Prune.NumKept, uint64(600)) - require.Equal(newConfig.Sentry.Enabled, true) - require.Equal(newConfig.Sentry.Control.Port, uint16(9009)) - require.Equal(newConfig.Sentry.Control.AuthorizedPubkeys[0], "asdf") - require.Equal(newConfig.P2P.Seeds[0], "H6u9MtuoWRKn5DKSgarj/dzr2Z9BsjuRHgRAoXITOcU=@35.199.49.168:26656") - require.Equal(newConfig.P2P.Seeds[1], "H6u9MtuoWRKn5DKSgarj/dzr2Z9BsjuRHgRAoXITOcU=@35.199.49.168:9200") - require.Equal(newConfig.Consensus.SentryUpstreamAddresses[0], "INSERT_P2P_PUBKEY_HERE@1.2.3.4:26656") -} - -func TestConfigMigrationSocketOverride(t *testing.T) { - require := require.New(t) - newConfig := prepareTest(require, testInternalSocketOverrideConfigRaw) - - // Now check if the config struct fields actually match the original state. - require.Equal(newConfig.Mode, config.ModeClient) - require.Equal(newConfig.Common.DataDir, "/node/data") - require.Equal(newConfig.Common.Log.Format, "JSON") - require.Equal(newConfig.Common.Log.Level["default"], "debug") - require.Equal(newConfig.Common.Log.Level["cometbft"], "debug") - require.Equal(newConfig.Common.Log.Level["cometbft/context"], "error") - require.Equal(newConfig.Genesis.File, "/node/etc/genesis.json") - require.Equal(newConfig.P2P.Seeds[0], "H6u9MtuoWRKn5DKSgarj/dzr2Z9BsjuRHgRAoXITOcU=@35.199.49.168:26656") - require.Equal(newConfig.P2P.Seeds[1], "H6u9MtuoWRKn5DKSgarj/dzr2Z9BsjuRHgRAoXITOcU=@35.199.49.168:9200") - require.Equal(newConfig.Runtime.Paths[0], "/node/runtime/cipher-paratime-2.6.2.orc") - require.Equal(newConfig.Runtime.Paths[1], "/node/runtime/emerald-paratime-10.0.0.orc") - require.Equal(newConfig.Runtime.Paths[2], "/node/runtime/sapphire-paratime-0.4.0.orc") - require.Equal(newConfig.Storage.Checkpointer.Enabled, true) - require.Equal(newConfig.Common.InternalSocketPath, "/node/custom-internal.sock") -} diff --git a/go/oasis-node/cmd/root.go b/go/oasis-node/cmd/root.go index 728511cd4ec..902066b4428 100644 --- a/go/oasis-node/cmd/root.go +++ b/go/oasis-node/cmd/root.go @@ -8,7 +8,6 @@ import ( "github.com/oasisprotocol/oasis-core/go/common/version" cmdCommon "github.com/oasisprotocol/oasis-core/go/oasis-node/cmd/common" - "github.com/oasisprotocol/oasis-core/go/oasis-node/cmd/config" "github.com/oasisprotocol/oasis-core/go/oasis-node/cmd/consensus" "github.com/oasisprotocol/oasis-core/go/oasis-node/cmd/control" "github.com/oasisprotocol/oasis-core/go/oasis-node/cmd/debug" @@ -86,7 +85,6 @@ func init() { storage.Register, consensus.Register, node.Register, - config.Register, } { v(rootCmd) }