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

fix: network commands check for latest config version before build #2922

Merged
merged 10 commits into from
Oct 18, 2022
Merged
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
- Fix config file migration to void leaving end of file content chunks
- Change session print loop to block until all events are handled.
- Handle "No records were found in keyring" message when checking keys.
- [#2922](https://github.com/ignite/cli/pull/2922) Network commands check for latest config version before building the chain binary.

## [`v0.24.1`](https://github.com/ignite/cli/releases/tag/v0.24.1)

Expand Down
16 changes: 16 additions & 0 deletions ignite/chainconfig/chainconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package chainconfig

import (
"fmt"
"io"
"os"
"path/filepath"
"strings"
Expand Down Expand Up @@ -87,3 +88,18 @@ func LocateDefault(root string) (path string, err error) {

return "", ErrConfigNotFound
}

// CheckVersion checks that the config version is the latest
// and if not a VersionError is returned.
func CheckVersion(configFile io.Reader) error {
version, err := ReadConfigVersion(configFile)
if err != nil {
return err
}

if version != LatestVersion {
return VersionError{version}
}

return nil
}
38 changes: 38 additions & 0 deletions ignite/chainconfig/chainconfig_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package chainconfig_test

import (
"bytes"
"fmt"
"testing"

"github.com/stretchr/testify/require"

"github.com/ignite/cli/ignite/chainconfig"
"github.com/ignite/cli/ignite/chainconfig/config"
)

func TestCheckVersion(t *testing.T) {
// Arrange
cfg := bytes.NewBufferString(
fmt.Sprintf("version: %d", chainconfig.LatestVersion),
)

// Act
err := chainconfig.CheckVersion(cfg)

// Assert
require.NoError(t, err)
}

func TestCheckVersionWithOutdatedVersion(t *testing.T) {
// Arrange
cfg := bytes.NewBufferString("version: 0")
wantError := chainconfig.VersionError{}

// Act
err := chainconfig.CheckVersion(cfg)

// Assert
require.ErrorAs(t, err, &wantError)
require.Equal(t, wantError.Version, config.Version(0))
}
5 changes: 5 additions & 0 deletions ignite/chainconfig/config/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package config

import (
"fmt"
"io"

"github.com/imdario/mergo"
Expand All @@ -11,6 +12,10 @@ import (
// Version defines the type for the config version number.
type Version uint

func (v Version) String() string {
return fmt.Sprintf("v%d", v)
}

// Converter defines the interface required to migrate configurations to newer versions.
type Converter interface {
// Clone clones the config by returning a new copy of the current one.
Expand Down
15 changes: 12 additions & 3 deletions ignite/chainconfig/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type ValidationError struct {
Message string
}

func (e *ValidationError) Error() string {
func (e ValidationError) Error() string {
return fmt.Sprintf("config is not valid: %s", e.Message)
}

Expand All @@ -24,6 +24,15 @@ type UnsupportedVersionError struct {
Version config.Version
}

func (e *UnsupportedVersionError) Error() string {
return fmt.Sprintf("config version %d is not supported", e.Version)
func (e UnsupportedVersionError) Error() string {
return fmt.Sprintf("config version %s is not supported", e.Version)
}

// VersionError is returned when config version is not the latest.
type VersionError struct {
Version config.Version
}

func (e VersionError) Error() string {
return fmt.Sprintf("config version %s is required and the current version is %s", LatestVersion, e.Version)
}
23 changes: 23 additions & 0 deletions ignite/services/network/networkchain/networkchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"

"github.com/ignite/cli/ignite/chainconfig"
sperrors "github.com/ignite/cli/ignite/errors"
"github.com/ignite/cli/ignite/pkg/cache"
"github.com/ignite/cli/ignite/pkg/chaincmd"
Expand Down Expand Up @@ -279,8 +280,30 @@ func (c Chain) NodeID(ctx context.Context) (string, error) {
return nodeID, nil
}

// CheckConfigVersion checks that the config version is the latest.
func (c Chain) CheckConfigVersion() error {
configPath := c.chain.ConfigPath()
if configPath == "" {
return chainconfig.ErrConfigNotFound
}

file, err := os.Open(configPath)
if err != nil {
return err
}

defer file.Close()

return chainconfig.CheckVersion(file)
}

// Build builds chain sources, also checks if source was already built
func (c *Chain) Build(ctx context.Context, cacheStorage cache.Storage) (binaryName string, err error) {
// Check that the config version is the latest before building the binary
if err = c.CheckConfigVersion(); err != nil {
return
}

// if chain was already published and has launch id check binary cache
if c.launchID != 0 {
if binaryName, err = c.chain.Binary(); err != nil {
Expand Down
6 changes: 5 additions & 1 deletion integration/network/network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,12 @@ func TestNetworkPublish(t *testing.T) {
step.Exec(
envtest.IgniteApp,
"network", "chain", "publish",
"https://github.com/lubtd/planet",
"https://github.com/ignite/example",
"--local",
// The hash is used to be sure the test uses the right config
// version. Hash value must be updated to the latest when the
// config version in the repository is updated to a new version.
"--hash", "b8b2cc2876c982dd4a049ed16b9a6099eca000aa",
),
step.Stdout(&b),
)),
Expand Down