Skip to content
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

[BCF-2261] Break up config/v2 #9697

Merged
merged 7 commits into from
Jul 10, 2023
Merged

Conversation

cedric-cordenier
Copy link
Contributor

@cedric-cordenier cedric-cordenier commented Jun 22, 2023

This PR is a proposal to break up the config/v2 package. Before this PR, the package combined multiple responsibilities, namely:

  • providing an API to validate structs, via Validate(interface{}).
  • providing utilities for dealing with TOML structs, eg. a unified DecodeTOML method.
  • the concrete struct types for non-chain-specific config.
  • providing an API to deal with env variables.
  • providing a toolset to deal with automated doc generation for config settings.

This PR breaks up these responsibilities so that the config/v2 package (renamed config/toml) is only responsible for defining the structs for the non-chain-specific config.

  • Move config/env.go into its own package: config/env.
  • Move config utilities relating to TOML, ValidateConfig, into utils/configutils.
  • Rename config/v2 -> config/toml. This package now only contains the TOML structs for the base config.
  • Move config/v2/docs -> config/docs.
  • Stop an import cycle by placing the integration tests which verify defaults are correctly extracted for chain-specific configs into a separate docs_test package.

@github-actions
Copy link
Contributor

I see that you haven't updated any CHANGELOG files. Would it make sense to do so?

@cedric-cordenier cedric-cordenier force-pushed the bcf-2261-rename-config-v2 branch 5 times, most recently from 42de976 to e22764a Compare June 23, 2023 11:44
@cedric-cordenier cedric-cordenier changed the title Bcf 2261 rename config v2 [BCF-2261] Break up config/v2 Jun 23, 2023
@cedric-cordenier cedric-cordenier marked this pull request as ready for review June 23, 2023 12:37
@@ -23,7 +21,7 @@ type Validated interface {

// Validate returns any errors from calling Validated.ValidateConfig on cfg and any nested types that implement Validated.
func Validate(cfg interface{}) (err error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about a more specific name if this is going to live in a general utils package?

Suggested change
func Validate(cfg interface{}) (err error) {
func ValidateConfig(cfg interface{}) (err error) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If anything, I would suggest making it less, rather than more, specific. That way this can be used generally to validate any struct.

eg.

func Validate(s interface{}) error {
...
}

type Validated interface {
     IsValid() error
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But isn't the code hyper-specific to toml config? I'm concerned about moving any pieces over to utils:

Move config utilities relating to TOML, ValidateConfig, into utils.

It would not be appropriate to use most (all?) of these as-is from other parts of the system - TOML especially, since we use a different module here than for job specs, for example. I think they need to remain config scoped, at least by name, but package separation seems cleaner.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm... yes, fair point. How about a configutils package containing DecodeTOML, ValidateConfig and the various errors that might be emitted from ValidateConfig() functions?

What I want to achieve with this is to break the dependency between config/v2 and evmconfig/v2, since previously evmconfig/v2 would depend on config/v2, and this caused some import cycles, by moving the common parts out to a separate package.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, in the future LOOP Plugins will be responsible for validating their own config, so we will want to move these generic pieces over to chainlink-relay to be available for other repos. With that in mind, I think it would be simplest to keep a specialized package in the meantime.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm... yes, fair point. How about a configutils package containing DecodeTOML, ValidateConfig and the various errors that might be emitted from ValidateConfig() functions?

Yeah I think that would work 👍

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a minimal package config in chainlink-relay with copies of some error types:
https://github.com/smartcontractkit/chainlink-relay/tree/main/pkg/config

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood! Would you like me to move these pieces to chainlink-relay and import them here? Or should I just stick to putting them in configutils for now?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a local package is fine for now. We can move it later when we move the chain family types for LOOPs.

@cedric-cordenier cedric-cordenier force-pushed the bcf-2261-rename-config-v2 branch 3 times, most recently from 5427476 to 3486897 Compare June 23, 2023 15:00
@@ -17,37 +17,37 @@ import (

"github.com/smartcontractkit/chainlink/v2/core/chains"
"github.com/smartcontractkit/chainlink/v2/core/chains/cosmos/types"
v2 "github.com/smartcontractkit/chainlink/v2/core/config/v2"
"github.com/smartcontractkit/chainlink/v2/core/utils/configutils"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit/ I think it would be more idiomatic to name the package just config to avoid repeating utils:

Suggested change
"github.com/smartcontractkit/chainlink/v2/core/utils/configutils"
"github.com/smartcontractkit/chainlink/v2/core/utils/config"

Can still name the imports when there are collisions 🤷

Suggested change
"github.com/smartcontractkit/chainlink/v2/core/utils/configutils"
configutils "github.com/smartcontractkit/chainlink/v2/core/utils/config"

@@ -38,12 +38,12 @@ var (
//go:embed example-secrets.toml
exampleSecrets string

docsTOML = coreTOML + chainsEVMTOML + chainsCosmosTOML + chainsSolanaTOML + chainsStarknetTOML
DocsTOML = CoreDefaultsTOML + chainsEVMTOML + chainsCosmosTOML + chainsSolanaTOML + chainsStarknetTOML
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any way to avoid exporting these vars? Ideally they would be co-located with their usage. IIRC there was an obstacle to using an internal/ directory when I first implemented this, but that may have changed.

core/config/env/env.go Outdated Show resolved Hide resolved
@cedric-cordenier cedric-cordenier force-pushed the bcf-2261-rename-config-v2 branch 2 times, most recently from eb283c4 to 2642950 Compare June 23, 2023 17:13
)

func CoreDefaults() (c toml.Core) {
if (defaults == toml.Core{}) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jmank88 Let me know what you think of this change; instinctively I think it's an anti-pattern to have packages implement init, so I made the instantiation of defaults lazy. This shouldn't change any behaviour since CoreDefaults is still one of the very first calls made at startup.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is this an improvement over an init func? A sync.Once would be more efficient than a mutex, but with the init you don't need to synchronize at all.

core/config/docs/docs.go Outdated Show resolved Hide resolved
@cedric-cordenier
Copy link
Contributor Author

@jmank88 I've removed my changes to CoreDefault and added the init back in. Your comment about that seems to have disappeared, but my thinking here wasn't primarily about efficiency, it was primarily about the principle of least surprise and avoiding side effects when a package is imported.

core/config/env/env.go Outdated Show resolved Hide resolved
jmank88
jmank88 previously approved these changes Jul 10, 2023
@cl-sonarqube-production
Copy link

@cedric-cordenier cedric-cordenier added this pull request to the merge queue Jul 10, 2023
Merged via the queue into develop with commit cef1712 Jul 10, 2023
95 checks passed
@cedric-cordenier cedric-cordenier deleted the bcf-2261-rename-config-v2 branch July 10, 2023 15:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants