-
Notifications
You must be signed in to change notification settings - Fork 555
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
introduce a migration system for the config file #2470
Comments
config.yml
Hey, great to hear that! Can you please check out the participation rules, and show interest on a thread by sharing your past experiences in Go and other work? https://discord.com/channels/893126937067802685/946155736289910894/948148181114421318 Thank you. 🙏 |
Hey Vincent @vinbrucelu! Nice to see you around here! You have been assigned to this issue, we're eager to see your solution! 🎊 |
I plan to implement this bounty in multiple steps. |
@ilgooz The step 1 has been accomplished in the PR I opened.
|
I am not sure how we are going to deal with the fields: Accounts, Faucet and Build in the v0 version. @ilgooz Could you give me more description on them? |
I did not find any existing definitions for the following structs in cosmos/cosmos-sdk: genesis, app, client and config. The only thing I found is there is a struct defined for GenesisDoc in tendermint/tendermint, which looks like:
However, they are used to parsed the json. We have to change it in order to parse them in yaml format. |
We can in-fact leave defining structs for Genesis and other similar ones to the last. This is a bit fragile and their structure may change between version. If there are no reliable ways of handling them defined in the Tendermint Core, or SDK we may even give up on the idea of defining structs. |
@ilgooz I have got a few questions regarding the default value for the Config.
In v1, they will be saved in the validator. However, we support a list of validators in the config, do we save the default information for RPC, P2P, etc in the first item of validator in the list? What if there are multiple validators? Do we fill in the default values of RPC, P2P, etc for each of them? And, how do we merge the default values into the v1.config? I found out that the lib "github.com/imdario/mergo" is unable to merge the structs in the array. See the issue: darccio/mergo#209 To resolve this issue, I propose to add a method called "fill_default()" method in the config, we can call it each time parsing the config yaml. It can fill in the values of faucet, build and the RPC, P2P... information. OR... We still leverage the the lib "github.com/imdario/mergo" to do the merge work, but merge the list of validator separately and set the list back to the config. Please share me your thought. Thx. |
I think we should auto fill the these addresses in the struct only when they don't present in the config.yml. For each validator, we can add the port numbers in incremental fashion. For ex. user might configure some of the addresses for the first validator and all addresses in the second validator. In this scenario, we only should fill the missing addresses in the first one. If there was other missing ones in the second validator, we also would have to fill them by incrementing the relevant port numbers by one (relative to the validator defined just before). But as you see this is something that should be computed after parsing the config.yml. So we cannot just set a default config struct somewhere like we used to do for v0 with the
I think this is irrelevant now because of the behaviour in the first answer.
I guess this is pretty similar to what I was describing? If not, please elaborate. 👍 Thank you! |
Thx, only one thing to clarify: |
Yes
You're right. This is specially the case for the grpc/grpc_web, rpc/p2p ones. In this case, what if we do not increment the last digit by one but increment the one that before that? For ex:
|
@ilgooz So far, the pkg chainconfig has been refactored into the structure, that implemented the migration system. Config yamls at lower versions are able to migrate to the next version or the latest version. Config interface is added. both v0 and v1 funstion at this time. V1 is now defined and able to use. V1 config is defined as in the design. V0 is able to converted to v1. Test cases are added to verify the migration. Will see if there are more needed, and clean up as well. The migration from v0 to v1 is done automatically. Next I will add the support in the "ignite chain" commands and subcommands to interact with users. It is pretty close to ending phase of this bounty. |
Under the v0 version, we can call directly
There is only one validator, and there is no issue. In v1, we will have multiple validators, containing multiple clients, KeyringBackend, etc, across multiple validators. The same question for Or what I described above is in the scope of #2473? And, how can I find the structure for gentx? How to install the CLI to run "marsd gentx -h"? |
I have defined the struct for gentx, and retrieve the fields from it in IssueGentx. |
The blockchain app config file were updated twice, once by the stargate plugin and then again by the chain init. This changeset updated the app's config only once. The stargate plugin is the one that updates them. The changeset also solves the issue where come of the addresses that must have the protocol prefix were ovewritten with an address without prefix because the host config value was removed (#2470), so now addresses are defined in the app and config sections.
* Separate the struct definitions of the chainconfig from the parser * Move the struct Config into v0 package * Add and implement the interface Config * Parse the yaml based on the version * Move the filed Build into the common struct * Create the interface for validator * Change the parameter for parse * Add the conversion * Replace v0 with v1 after parsing * Fix the getInit for v1 * Update the parser and the validator * Replace v0 with v1 in env * Change the template * Fixes the issue with the GetHost interface * Add the method to increment the port number * Move FaucetHost to the common package * Remove the default() in config * Type the Version * Refactor the function Parse * Add the test to verify the Parse with migration * Clean up the interface of Config * Update the subcommands for ignite chain * Add tests on the ConfigYaml an some comments * Add the struct defining Gentx * Remove the getters in BaseConfig * Fix the function ConvertLatest * Remove all getters * refactor createValidatorFromConfig * Refactor the common pkg * Change FillValidatorsDefaults and add tests * a * chore: remove empty file * refactor: simplify file names * refactor: improve tests layout * refactor: add `config` package to `chainconfig` This change resolves a cyclic import issue * refactor: rename `Config` interface to `Converter` * chore: change testdata to give BaseConfig precedence * refactor: rename `Config.ConfigVersion` to `Config.Version` The interface's `Version()` method was also renamed to `GetVersion()`. * chore: code cleanup for consistency * chore: remove unused `BaseConfig.AccountByName` method * refactor: move `ListAccounts()` into `BaseConfig` * refactor: rename `ErrCouldntLocateConfig` to `ErrConfigNotFound` * chore: fix docstrings and broken test * refactor: improve v0 to v1 conversion * feat: add `xnet` package * refactor: improve `v1` config implementation - Simplify `Validator` to remove many getter methods - Removed some global variables - Improve unit tests - Add more unit tests - Remove unit tests that were not useful * refactor: remove global and rename var `Migration` to `Versions` * refactor: add default config function to `config` Also added `SetDefaults` to be able to initialize configs during conversion to default values. * refactor: change `ConvertLatest` to return `*v1.Config` This function must always return the latest config. * refactor: move `ErrConfigNotFound` to `errors.go` Also changed `UnsupportedVersionError` to contain the version number instead of an error message. * fix: change v1 `ConvertNext` to assign 1 to the version * test: add `TestConvertV0ToV1` to `v0` convert tests Also removed the `TestConvertNext`. * test: change `v0` testdata to only return a v0 config with values * fix: various fixes related to the refactor * fix: parsing and migration now work using interfaces * refactor: change migration cmd verifier The verifier now stops the command when the config migration is not made. * fix: change config validation to validate "validators" * chore: change `Seek` calls to use a constant argument * refactor: change to use standard reader/writers instead of seeker * test: add test for `MigrateLatest` * test: move testdata config files inside its corresponding version The config files and `GetConfig()` functions for each version not live inside the `v0` and `v1` package. * refactor: rewrite `Parse()` tests * fix: changed `v1` set defaults for don't ovewrite existing values * chore: add more values to testdata config files * test: add `TestParseWithUnknownVersion` test * chore: remove `GetConfigV0` from `v0` testdata Test must use `v0testdata.GetConfig()` instead. * test: rewrite `v0` clone test * fix: change imports from "ignite-hq" to "ignite" * fix: change integration tests to work with the new config * chore: update changelog * chore: fix integration test argument for `IsAppServed` * test: fix broken integration tests * chore(pkg/xnet): add `MustIncreasePortBy` to simplify tests * refactor: use struct to manage config's server addresses Map type causes a lot of trouble and extra casting and checks when the Cosmos SDK or Tendermint config values for the server addresses are read or modified so instead of that this changeset uses a struct. We can't use Cosmos SDK ot Tendermint config structs because if any of there configs gets updated it could break the migrations. The changeset also fixes the default address values that were encoded to the YAML config. These values no longer appear if they are the default ones. * chore: minor corrections * chore: remove unneeded `SetDefaults` call * fix: change init chain to support merging YAML generated maps The contributed implementation was removing some fields which was not correct; Now those config fields are saved during init. It seems that the map fields were being removed to avoid an issue with maps containing interface{} key types instead of string. This change fixes it by saving all the config values and by adding support for YAML generated maps thought a transformer implementation. * refactor: remove merge transformer in favor of a custom map type The mergo transformer didn't work properly so it was replaced with a custom map type that implements the yaml.Unmarshaller interface to convert the map keys to strings right after they are decoded. * refactor: change chain's init to update app config files only once The blockchain app config file were updated twice, once by the stargate plugin and then again by the chain init. This changeset updated the app's config only once. The stargate plugin is the one that updates them. The changeset also solves the issue where come of the addresses that must have the protocol prefix were ovewritten with an address without prefix because the host config value was removed (#2470), so now addresses are defined in the app and config sections. * test: fix broken integration test * refactor: trigger config migration verifier from a pre run handler * refactor: change config migration cmd handler to use `cliui` package * refactor: add a type alias for the latest config version * ci: fix typo * chore: rename variables to follow standard * refactor: change `addGitChangesVerifier` to a cmd pre run handler * refactor: add confirmation before migrating config in unclean state A confirmation is shown now before migrating the confir file to the latest version if the app repository has uncommitted changes. * fix: change config clonning to copy using mergo package * chore: replace deprecated call to ReadFile * chore: fix formatting * tests: change `IsAppServed` to receive the API address * fix: change `pkg/yaml` to convert keys in slice of map This is required to make sure the values read from YAML files can be merged and serialized to other formats like JSON. * tests: fix broken network publish integration test * chore: add `gitChangesConfirmPreRunHandler` to `ts-client` cmd * test: fix broken TS client bank module integration test Co-authored-by: vinbrucelu <[email protected]> Co-authored-by: İlker G. Öztürk <[email protected]> Co-authored-by: Alex Johnson <[email protected]>
* Separate the struct definitions of the chainconfig from the parser * Move the struct Config into v0 package * Add and implement the interface Config * Parse the yaml based on the version * Move the filed Build into the common struct * Create the interface for validator * Change the parameter for parse * Add the conversion * Replace v0 with v1 after parsing * Fix the getInit for v1 * Update the parser and the validator * Replace v0 with v1 in env * Change the template * Fixes the issue with the GetHost interface * Add the method to increment the port number * Move FaucetHost to the common package * Remove the default() in config * Type the Version * Refactor the function Parse * Add the test to verify the Parse with migration * Clean up the interface of Config * Update the subcommands for ignite chain * Add tests on the ConfigYaml an some comments * Add the struct defining Gentx * Remove the getters in BaseConfig * Fix the function ConvertLatest * Remove all getters * refactor createValidatorFromConfig * Refactor the common pkg * Change FillValidatorsDefaults and add tests * a * chore: remove empty file * refactor: simplify file names * refactor: improve tests layout * refactor: add `config` package to `chainconfig` This change resolves a cyclic import issue * refactor: rename `Config` interface to `Converter` * chore: change testdata to give BaseConfig precedence * refactor: rename `Config.ConfigVersion` to `Config.Version` The interface's `Version()` method was also renamed to `GetVersion()`. * chore: code cleanup for consistency * chore: remove unused `BaseConfig.AccountByName` method * refactor: move `ListAccounts()` into `BaseConfig` * refactor: rename `ErrCouldntLocateConfig` to `ErrConfigNotFound` * chore: fix docstrings and broken test * refactor: improve v0 to v1 conversion * feat: add `xnet` package * refactor: improve `v1` config implementation - Simplify `Validator` to remove many getter methods - Removed some global variables - Improve unit tests - Add more unit tests - Remove unit tests that were not useful * refactor: remove global and rename var `Migration` to `Versions` * refactor: add default config function to `config` Also added `SetDefaults` to be able to initialize configs during conversion to default values. * refactor: change `ConvertLatest` to return `*v1.Config` This function must always return the latest config. * refactor: move `ErrConfigNotFound` to `errors.go` Also changed `UnsupportedVersionError` to contain the version number instead of an error message. * fix: change v1 `ConvertNext` to assign 1 to the version * test: add `TestConvertV0ToV1` to `v0` convert tests Also removed the `TestConvertNext`. * test: change `v0` testdata to only return a v0 config with values * fix: various fixes related to the refactor * fix: parsing and migration now work using interfaces * refactor: change migration cmd verifier The verifier now stops the command when the config migration is not made. * fix: change config validation to validate "validators" * chore: change `Seek` calls to use a constant argument * refactor: change to use standard reader/writers instead of seeker * test: add test for `MigrateLatest` * test: move testdata config files inside its corresponding version The config files and `GetConfig()` functions for each version not live inside the `v0` and `v1` package. * refactor: rewrite `Parse()` tests * fix: changed `v1` set defaults for don't ovewrite existing values * chore: add more values to testdata config files * test: add `TestParseWithUnknownVersion` test * chore: remove `GetConfigV0` from `v0` testdata Test must use `v0testdata.GetConfig()` instead. * test: rewrite `v0` clone test * fix: change imports from "ignite-hq" to "ignite" * fix: change integration tests to work with the new config * chore: update changelog * chore: fix integration test argument for `IsAppServed` * test: fix broken integration tests * chore(pkg/xnet): add `MustIncreasePortBy` to simplify tests * refactor: use struct to manage config's server addresses Map type causes a lot of trouble and extra casting and checks when the Cosmos SDK or Tendermint config values for the server addresses are read or modified so instead of that this changeset uses a struct. We can't use Cosmos SDK ot Tendermint config structs because if any of there configs gets updated it could break the migrations. The changeset also fixes the default address values that were encoded to the YAML config. These values no longer appear if they are the default ones. * chore: minor corrections * chore: remove unneeded `SetDefaults` call * fix: change init chain to support merging YAML generated maps The contributed implementation was removing some fields which was not correct; Now those config fields are saved during init. It seems that the map fields were being removed to avoid an issue with maps containing interface{} key types instead of string. This change fixes it by saving all the config values and by adding support for YAML generated maps thought a transformer implementation. * refactor: remove merge transformer in favor of a custom map type The mergo transformer didn't work properly so it was replaced with a custom map type that implements the yaml.Unmarshaller interface to convert the map keys to strings right after they are decoded. * refactor: change chain's init to update app config files only once The blockchain app config file were updated twice, once by the stargate plugin and then again by the chain init. This changeset updated the app's config only once. The stargate plugin is the one that updates them. The changeset also solves the issue where come of the addresses that must have the protocol prefix were ovewritten with an address without prefix because the host config value was removed (ignite#2470), so now addresses are defined in the app and config sections. * test: fix broken integration test * refactor: trigger config migration verifier from a pre run handler * refactor: change config migration cmd handler to use `cliui` package * refactor: add a type alias for the latest config version * ci: fix typo * chore: rename variables to follow standard * refactor: change `addGitChangesVerifier` to a cmd pre run handler * refactor: add confirmation before migrating config in unclean state A confirmation is shown now before migrating the confir file to the latest version if the app repository has uncommitted changes. * fix: change config clonning to copy using mergo package * chore: replace deprecated call to ReadFile * chore: fix formatting * tests: change `IsAppServed` to receive the API address * fix: change `pkg/yaml` to convert keys in slice of map This is required to make sure the values read from YAML files can be merged and serialized to other formats like JSON. * tests: fix broken network publish integration test * chore: add `gitChangesConfirmPreRunHandler` to `ts-client` cmd * test: fix broken TS client bank module integration test Co-authored-by: vinbrucelu <[email protected]> Co-authored-by: İlker G. Öztürk <[email protected]> Co-authored-by: Alex Johnson <[email protected]>
Learn more about the bounty on Ignite's Discord.
The parser for
config.yml
can be found at ignite/chainconfig.1-
version
fieldThere wasn't a version field in the config file (AKA
config.yml
). We should introduce a top levelversion
field to define the version of the config file.E.g.:
version: 0
,version: 1
.And assume that version is
0
if noversion
field presents.2- migration system
Introduce a migration system into
chainconfig
package to upgrade a chain's config file version to the latest version and do the necessary migrations to apply to the latest format to chain's config file.Migration system should define
Config
struct for each version in their respective packages.E.g.:
In the
chainconfig/config.go
:Config
interface or generic.ConvertNext(Config) (Config, error)
function to convert a Config to the next version of Config.ConvertLatest(Config) (Config, error)
function to convert a Config to the latest version of Config.3- automatic migrations
Hook to all sub commands (e.g.:
addGitChangesVerifier
see 1, see 2) underignite chain
command set. Use the config file path given by the flag or if it's empty usechainconfig.LocateDefault
to determine the path of the config file.Check the version of the config file and check if it can upgraded to latest. If so, prompt a confirmation to user to get confirmation on overwriting the existing config file with the newer format. Inform about the new version number.
Also prompt confirmation if there are any uncommitted changes to get confirmation. Same as how
addGitChangesVerifier
used forignite scaffold
command set.Add a
--yes
,-y
flag toignite chain
command set, If this flag is provided, no need for prompting confirmation both for migration and uncommitted changes.4- define the migration rules for
version 1
version 1:
To summarize the changes in the config file:
1-
validator
field is deprecated and converted to an array withvalidators
name.2-
init
field is deprecated but fields inside theinit
field moved to validator info (items insidevalidators
).3- introducing
gentx
field to validator info to make it possible customizing gentxs.4-
host
field is deprecated with all its sub fields, now you need to usevalidators[].app
andvalidators[].config
to configure addresses.5- previously we were using
map[string]interface{}
to represent genesis, app, client, config. Now we need to use the existing structs for these fromcosmos/cosmos-sdk
or define ourselves if they do not exists.update templates:
Update the config.yml template to scaffold
version: 1
of the config with the new format.Refactor and add tests
Refactor the
configchain
pkg if it's needed.Please add unit tests for your additions.
Also add tests for converting these real chain's config files to v1:
Let us know
Please review the design choices above and take them as suggestions and nothing as final. Let us know if it can be improved or you have other ideas.
The text was updated successfully, but these errors were encountered: