From 69874c2050bc765fe53f2ce71eed2143b40b3881 Mon Sep 17 00:00:00 2001 From: "M. J. Fromberger" Date: Thu, 14 Apr 2022 06:20:49 -0700 Subject: [PATCH] confix: convert tx-index.indexer from string to array (#8342) The format of this config value was changed in v0.35. - Move plan to its own file (for ease of reading). - Convert indexer string to an array if not already done. --- scripts/confix/confix.go | 182 ------------------------------- scripts/confix/plan.go | 225 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 225 insertions(+), 182 deletions(-) create mode 100644 scripts/confix/plan.go diff --git a/scripts/confix/confix.go b/scripts/confix/confix.go index 7a1f22670..6677f0b49 100644 --- a/scripts/confix/confix.go +++ b/scripts/confix/confix.go @@ -12,11 +12,9 @@ import ( "log" "os" "path/filepath" - "strings" "github.com/creachadair/atomicfile" "github.com/creachadair/tomledit" - "github.com/creachadair/tomledit/parser" "github.com/creachadair/tomledit/transform" "github.com/spf13/viper" "github.com/tendermint/tendermint/config" @@ -78,186 +76,6 @@ func main() { } } -var plan = transform.Plan{ - { - // Since https://github.com/tendermint/tendermint/pull/5777. - Desc: "Rename everything from snake_case to kebab-case", - T: transform.SnakeToKebab(), - }, - { - // [fastsync] renamed in https://github.com/tendermint/tendermint/pull/6896. - // [blocksync] removed in https://github.com/tendermint/tendermint/pull/7159. - Desc: "Remove [fastsync] and [blocksync] sections", - T: transform.Func(func(_ context.Context, doc *tomledit.Document) error { - doc.First("fast-sync").Remove() - transform.FindTable(doc, "fastsync").Remove() - transform.FindTable(doc, "blocksync").Remove() - return nil - }), - ErrorOK: true, - }, - { - // Since https://github.com/tendermint/tendermint/pull/6241. - Desc: `Add top-level mode setting (default "full")`, - T: transform.EnsureKey(nil, &parser.KeyValue{ - Block: parser.Comments{"Mode of Node: full | validator | seed"}, - Name: parser.Key{"mode"}, - Value: parser.MustValue(`"full"`), - }), - ErrorOK: true, - }, - { - // Since https://github.com/tendermint/tendermint/pull/7121. - Desc: "Remove gRPC settings from the [rpc] section", - T: transform.Func(func(_ context.Context, doc *tomledit.Document) error { - doc.First("rpc", "grpc-laddr").Remove() - doc.First("rpc", "grpc-max-open-connections").Remove() - return nil - }), - }, - { - // Since https://github.com/tendermint/tendermint/pull/8217. - Desc: "Remove per-node consensus timeouts (converted to consensus parameters)", - T: transform.Remove( - parser.Key{"consensus", "skip-timeout-commit"}, - parser.Key{"consensus", "timeout-commit"}, - parser.Key{"consensus", "timeout-precommit"}, - parser.Key{"consensus", "timeout-precommit-delta"}, - parser.Key{"consensus", "timeout-prevote"}, - parser.Key{"consensus", "timeout-prevote-delta"}, - parser.Key{"consensus", "timeout-propose"}, - parser.Key{"consensus", "timeout-propose-delta"}, - ), - ErrorOK: true, - }, - { - // Removed wal-dir: https://github.com/tendermint/tendermint/pull/6396. - // Removed version: https://github.com/tendermint/tendermint/pull/7171. - Desc: "Remove vestigial mempool.wal-dir settings", - T: transform.Remove( - parser.Key{"mempool", "wal-dir"}, - parser.Key{"mempool", "version"}, - ), - ErrorOK: true, - }, - { - // Since https://github.com/tendermint/tendermint/pull/6323. - Desc: "Add new [p2p] queue-type setting", - T: transform.EnsureKey(parser.Key{"p2p"}, &parser.KeyValue{ - Block: parser.Comments{"Select the p2p internal queue"}, - Name: parser.Key{"queue-type"}, - Value: parser.MustValue(`"priority"`), - }), - ErrorOK: true, - }, - { - // Since https://github.com/tendermint/tendermint/pull/6353. - Desc: "Add [p2p] connection count and rate limit settings", - T: transform.Func(func(_ context.Context, doc *tomledit.Document) error { - tab := transform.FindTable(doc, "p2p") - if tab == nil { - return errors.New("p2p table not found") - } - transform.InsertMapping(tab.Section, &parser.KeyValue{ - Block: parser.Comments{"Maximum number of connections (inbound and outbound)."}, - Name: parser.Key{"max-connections"}, - Value: parser.MustValue("64"), - }, false) - transform.InsertMapping(tab.Section, &parser.KeyValue{ - Block: parser.Comments{ - "Rate limits the number of incoming connection attempts per IP address.", - }, - Name: parser.Key{"max-incoming-connection-attempts"}, - Value: parser.MustValue("100"), - }, false) - return nil - }), - }, - { - // Added "chunk-fetchers" https://github.com/tendermint/tendermint/pull/6566. - // This value was backported into v0.34.11 (modulo casing). - // Renamed to "fetchers" https://github.com/tendermint/tendermint/pull/6587. - Desc: "Rename statesync.chunk-fetchers to statesync.fetchers", - T: transform.Func(func(ctx context.Context, doc *tomledit.Document) error { - // If the key already exists, rename it preserving its value. - if found := doc.First("statesync", "chunk-fetchers"); found != nil { - found.KeyValue.Name = parser.Key{"fetchers"} - return nil - } - - // Otherwise, add it. - return transform.EnsureKey(parser.Key{"statesync"}, &parser.KeyValue{ - Block: parser.Comments{ - "The number of concurrent chunk and block fetchers to run (default: 4).", - }, - Name: parser.Key{"fetchers"}, - Value: parser.MustValue("4"), - })(ctx, doc) - }), - }, - { - // Since https://github.com/tendermint/tendermint/pull/6807. - // Backported into v0.34.13 (modulo casing). - Desc: "Add statesync.use-p2p setting", - T: transform.EnsureKey(parser.Key{"statesync"}, &parser.KeyValue{ - Block: parser.Comments{ - "# State sync uses light client verification to verify state. This can be done either through the", - "# P2P layer or RPC layer. Set this to true to use the P2P layer. If false (default), RPC layer", - "# will be used.", - }, - Name: parser.Key{"use-p2p"}, - Value: parser.MustValue("false"), - }), - }, - { - // Since https://github.com/tendermint/tendermint/pull/6462. - Desc: "Move priv-validator settings under [priv-validator]", - T: transform.Func(func(_ context.Context, doc *tomledit.Document) error { - const pvPrefix = "priv-validator-" - - var found []*tomledit.Entry - doc.Scan(func(key parser.Key, e *tomledit.Entry) bool { - if e.IsSection() && !e.IsGlobal() { - return false // no more candidates - } else if len(key) == 1 && strings.HasPrefix(key[0], pvPrefix) { - found = append(found, e) - } - return true - }) - if len(found) == 0 { - return nil // nothing to do - } - - // Now that we know we have work to do, find the target table. - var sec *tomledit.Section - if dst := transform.FindTable(doc, "priv-validator"); dst == nil { - // If the table doesn't exist, create it. Old config files - // probably will not have it, so plug in the comment too. - sec = &tomledit.Section{ - Heading: &parser.Heading{ - Block: parser.Comments{ - "#######################################################", - "### Priv Validator Configuration ###", - "#######################################################", - }, - Name: parser.Key{"priv-validator"}, - }, - } - doc.Sections = append(doc.Sections, sec) - } else { - sec = dst.Section - } - - for _, e := range found { - e.Remove() - e.Name = parser.Key{strings.TrimPrefix(e.Name[0], pvPrefix)} - sec.Items = append(sec.Items, e.KeyValue) - } - return nil - }), - }, -} - // ApplyFixes transforms doc and reports whether it succeeded. func ApplyFixes(ctx context.Context, doc *tomledit.Document) error { // Check what version of Tendermint might have created this config file, as diff --git a/scripts/confix/plan.go b/scripts/confix/plan.go new file mode 100644 index 000000000..653bca9fd --- /dev/null +++ b/scripts/confix/plan.go @@ -0,0 +1,225 @@ +package main + +import ( + "context" + "errors" + "fmt" + "strings" + + "github.com/creachadair/tomledit" + "github.com/creachadair/tomledit/parser" + "github.com/creachadair/tomledit/transform" +) + +// The plan is the sequence of transformation steps that should be applied, in +// the given order, to convert a configuration file to be compatible with the +// current version of the config grammar. +// +// Transformation steps are specific to the target config version. For this +// reason, you must exercise caution when backporting changes to this script +// into older releases. +var plan = transform.Plan{ + { + // Since https://github.com/tendermint/tendermint/pull/5777. + Desc: "Rename everything from snake_case to kebab-case", + T: transform.SnakeToKebab(), + }, + { + // [fastsync] renamed in https://github.com/tendermint/tendermint/pull/6896. + // [blocksync] removed in https://github.com/tendermint/tendermint/pull/7159. + Desc: "Remove [fastsync] and [blocksync] sections", + T: transform.Func(func(_ context.Context, doc *tomledit.Document) error { + doc.First("fast-sync").Remove() + transform.FindTable(doc, "fastsync").Remove() + transform.FindTable(doc, "blocksync").Remove() + return nil + }), + ErrorOK: true, + }, + { + // Since https://github.com/tendermint/tendermint/pull/6241. + Desc: `Add top-level mode setting (default "full")`, + T: transform.EnsureKey(nil, &parser.KeyValue{ + Block: parser.Comments{"Mode of Node: full | validator | seed"}, + Name: parser.Key{"mode"}, + Value: parser.MustValue(`"full"`), + }), + ErrorOK: true, + }, + { + // Since https://github.com/tendermint/tendermint/pull/7121. + Desc: "Remove gRPC settings from the [rpc] section", + T: transform.Func(func(_ context.Context, doc *tomledit.Document) error { + doc.First("rpc", "grpc-laddr").Remove() + doc.First("rpc", "grpc-max-open-connections").Remove() + return nil + }), + }, + { + // Since https://github.com/tendermint/tendermint/pull/8217. + Desc: "Remove per-node consensus timeouts (converted to consensus parameters)", + T: transform.Remove( + parser.Key{"consensus", "skip-timeout-commit"}, + parser.Key{"consensus", "timeout-commit"}, + parser.Key{"consensus", "timeout-precommit"}, + parser.Key{"consensus", "timeout-precommit-delta"}, + parser.Key{"consensus", "timeout-prevote"}, + parser.Key{"consensus", "timeout-prevote-delta"}, + parser.Key{"consensus", "timeout-propose"}, + parser.Key{"consensus", "timeout-propose-delta"}, + ), + ErrorOK: true, + }, + { + // Removed wal-dir: https://github.com/tendermint/tendermint/pull/6396. + // Removed version: https://github.com/tendermint/tendermint/pull/7171. + Desc: "Remove vestigial mempool.wal-dir settings", + T: transform.Remove( + parser.Key{"mempool", "wal-dir"}, + parser.Key{"mempool", "version"}, + ), + ErrorOK: true, + }, + { + // Since https://github.com/tendermint/tendermint/pull/6323. + Desc: "Add new [p2p] queue-type setting", + T: transform.EnsureKey(parser.Key{"p2p"}, &parser.KeyValue{ + Block: parser.Comments{"Select the p2p internal queue"}, + Name: parser.Key{"queue-type"}, + Value: parser.MustValue(`"priority"`), + }), + ErrorOK: true, + }, + { + // Since https://github.com/tendermint/tendermint/pull/6353. + Desc: "Add [p2p] connection count and rate limit settings", + T: transform.Func(func(_ context.Context, doc *tomledit.Document) error { + tab := transform.FindTable(doc, "p2p") + if tab == nil { + return errors.New("p2p table not found") + } + transform.InsertMapping(tab.Section, &parser.KeyValue{ + Block: parser.Comments{"Maximum number of connections (inbound and outbound)."}, + Name: parser.Key{"max-connections"}, + Value: parser.MustValue("64"), + }, false) + transform.InsertMapping(tab.Section, &parser.KeyValue{ + Block: parser.Comments{ + "Rate limits the number of incoming connection attempts per IP address.", + }, + Name: parser.Key{"max-incoming-connection-attempts"}, + Value: parser.MustValue("100"), + }, false) + return nil + }), + }, + { + // Added "chunk-fetchers" https://github.com/tendermint/tendermint/pull/6566. + // This value was backported into v0.34.11 (modulo casing). + // Renamed to "fetchers" https://github.com/tendermint/tendermint/pull/6587. + Desc: "Rename statesync.chunk-fetchers to statesync.fetchers", + T: transform.Func(func(ctx context.Context, doc *tomledit.Document) error { + // If the key already exists, rename it preserving its value. + if found := doc.First("statesync", "chunk-fetchers"); found != nil { + found.KeyValue.Name = parser.Key{"fetchers"} + return nil + } + + // Otherwise, add it. + return transform.EnsureKey(parser.Key{"statesync"}, &parser.KeyValue{ + Block: parser.Comments{ + "The number of concurrent chunk and block fetchers to run (default: 4).", + }, + Name: parser.Key{"fetchers"}, + Value: parser.MustValue("4"), + })(ctx, doc) + }), + }, + { + // Since https://github.com/tendermint/tendermint/pull/6807. + // Backported into v0.34.13 (modulo casing). + Desc: "Add statesync.use-p2p setting", + T: transform.EnsureKey(parser.Key{"statesync"}, &parser.KeyValue{ + Block: parser.Comments{ + "# State sync uses light client verification to verify state. This can be done either through the", + "# P2P layer or RPC layer. Set this to true to use the P2P layer. If false (default), RPC layer", + "# will be used.", + }, + Name: parser.Key{"use-p2p"}, + Value: parser.MustValue("false"), + }), + }, + { + // Since https://github.com/tendermint/tendermint/pull/6462. + Desc: "Move priv-validator settings under [priv-validator]", + T: transform.Func(func(_ context.Context, doc *tomledit.Document) error { + const pvPrefix = "priv-validator-" + + var found []*tomledit.Entry + doc.Global.Scan(func(key parser.Key, e *tomledit.Entry) bool { + if len(key) == 1 && strings.HasPrefix(key[0], pvPrefix) { + found = append(found, e) + } + return true + }) + if len(found) == 0 { + return nil // nothing to do + } + + // Now that we know we have work to do, find the target table. + var sec *tomledit.Section + if dst := transform.FindTable(doc, "priv-validator"); dst == nil { + // If the table doesn't exist, create it. Old config files + // probably will not have it, so plug in the comment too. + sec = &tomledit.Section{ + Heading: &parser.Heading{ + Block: parser.Comments{ + "#######################################################", + "### Priv Validator Configuration ###", + "#######################################################", + }, + Name: parser.Key{"priv-validator"}, + }, + } + doc.Sections = append(doc.Sections, sec) + } else { + sec = dst.Section + } + + for _, e := range found { + e.Remove() + e.Name = parser.Key{strings.TrimPrefix(e.Name[0], pvPrefix)} + sec.Items = append(sec.Items, e.KeyValue) + } + return nil + }), + }, + { + // Since https://github.com/tendermint/tendermint/pull/6411. + Desc: "Convert tx-index.indexer from a string to a list of strings", + T: transform.Func(func(ctx context.Context, doc *tomledit.Document) error { + idx := doc.First("tx-index", "indexer") + if idx == nil { + // No previous indexer setting: Default to ["null"] per #8222. + return transform.EnsureKey(parser.Key{"tx-index"}, &parser.KeyValue{ + Block: parser.Comments{"The backend database list to back the indexer."}, + Name: parser.Key{"indexer"}, + Value: parser.MustValue(`["null"]`), + })(ctx, doc) + } + + // Versions prior to v0.35 had a string value here, v0.35 and onward + // use an array of strings. + switch idx.KeyValue.Value.X.(type) { + case parser.Array: + // OK, this is already up-to-date. + return nil + case parser.Token: + // Wrap the value in a single-element array. + idx.KeyValue.Value.X = parser.Array{idx.KeyValue.Value} + return nil + } + return fmt.Errorf("unrecognized value: %v", idx.KeyValue) + }), + }, +}