-
Notifications
You must be signed in to change notification settings - Fork 117
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[TRA-721] Enforce sidecar versions (#2491)
- Loading branch information
Showing
9 changed files
with
281 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package client | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"cosmossdk.io/log" | ||
"github.com/hashicorp/go-version" | ||
|
||
oracleclient "github.com/skip-mev/connect/v2/service/clients/oracle" | ||
"github.com/skip-mev/connect/v2/service/servers/oracle/types" | ||
) | ||
|
||
// SidecarVersionChecker is a lightweight process run in a goroutine by the slinky client. | ||
// Its purpose is to query the running sidecar version and check if it is at least a minimum | ||
// acceptable version. | ||
type SidecarVersionChecker interface { | ||
Start(ctx context.Context) error | ||
Stop() | ||
CheckSidecarVersion(context.Context) error | ||
} | ||
|
||
// SidecarVersionCheckerImpl implements the SidecarVersionChecker interface. | ||
type SidecarVersionCheckerImpl struct { | ||
slinky oracleclient.OracleClient | ||
logger log.Logger | ||
} | ||
|
||
func NewSidecarVersionChecker(slinky oracleclient.OracleClient, logger log.Logger) SidecarVersionChecker { | ||
return &SidecarVersionCheckerImpl{ | ||
slinky: slinky, | ||
logger: logger, | ||
} | ||
} | ||
|
||
// Start initializes the underlying connections of the SidecarVersionChecker. | ||
func (s *SidecarVersionCheckerImpl) Start( | ||
ctx context.Context) error { | ||
return s.slinky.Start(ctx) | ||
} | ||
|
||
// Stop closes all existing connections. | ||
func (s *SidecarVersionCheckerImpl) Stop() { | ||
_ = s.slinky.Stop() | ||
} | ||
|
||
func (s *SidecarVersionCheckerImpl) CheckSidecarVersion(ctx context.Context) error { | ||
// Retrieve sidecar version via gRPC | ||
slinkyResponse, err := s.slinky.Version(ctx, &types.QueryVersionRequest{}) | ||
if err != nil { | ||
return err | ||
} | ||
current, err := version.NewVersion(slinkyResponse.Version) | ||
if err != nil { | ||
return fmt.Errorf("failed to parse current version: %w", err) | ||
} | ||
|
||
minimum, err := version.NewVersion(MinSidecarVersion) | ||
if err != nil { | ||
return fmt.Errorf("failed to parse minimum version: %w", err) | ||
} | ||
|
||
// Compare versions | ||
if current.LessThan(minimum) { | ||
return fmt.Errorf("Sidecar version %s is less than minimum required version %s. "+ | ||
"The node will shut down soon", current, minimum) | ||
} | ||
|
||
// Version is acceptable | ||
s.logger.Info("Sidecar version check passed", "version", current) | ||
return nil | ||
} |
62 changes: 62 additions & 0 deletions
62
protocol/daemons/slinky/client/sidecar_version_checker_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package client_test | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
|
||
"cosmossdk.io/log" | ||
"github.com/stretchr/testify/mock" | ||
"github.com/stretchr/testify/require" | ||
|
||
"github.com/dydxprotocol/v4-chain/protocol/daemons/slinky/client" | ||
"github.com/dydxprotocol/v4-chain/protocol/mocks" | ||
"github.com/skip-mev/connect/v2/service/servers/oracle/types" | ||
) | ||
|
||
func TestSidecarVersionChecker(t *testing.T) { | ||
logger := log.NewTestLogger(t) | ||
var fetcher client.SidecarVersionChecker | ||
|
||
t.Run("Checks sidecar version passes", func(t *testing.T) { | ||
slinky := mocks.NewOracleClient(t) | ||
slinky.On("Stop").Return(nil) | ||
slinky.On("Start", mock.Anything).Return(nil).Once() | ||
slinky.On("Version", mock.Anything, mock.Anything). | ||
Return(&types.QueryVersionResponse{ | ||
Version: client.MinSidecarVersion, | ||
}, nil) | ||
fetcher = client.NewSidecarVersionChecker(slinky, logger) | ||
require.NoError(t, fetcher.Start(context.Background())) | ||
require.NoError(t, fetcher.CheckSidecarVersion(context.Background())) | ||
fetcher.Stop() | ||
}) | ||
|
||
t.Run("Checks sidecar version less than minimum version", func(t *testing.T) { | ||
slinky := mocks.NewOracleClient(t) | ||
slinky.On("Stop").Return(nil) | ||
slinky.On("Start", mock.Anything).Return(nil).Once() | ||
slinky.On("Version", mock.Anything, mock.Anything). | ||
Return(&types.QueryVersionResponse{ | ||
Version: "v0.0.0", | ||
}, nil) | ||
fetcher = client.NewSidecarVersionChecker(slinky, logger) | ||
require.NoError(t, fetcher.Start(context.Background())) | ||
require.ErrorContains(t, fetcher.CheckSidecarVersion(context.Background()), | ||
"Sidecar version 0.0.0 is less than minimum required version") | ||
fetcher.Stop() | ||
}) | ||
|
||
t.Run("Checks sidecar version incorrectly formatted", func(t *testing.T) { | ||
slinky := mocks.NewOracleClient(t) | ||
slinky.On("Stop").Return(nil) | ||
slinky.On("Start", mock.Anything).Return(nil).Once() | ||
slinky.On("Version", mock.Anything, mock.Anything). | ||
Return(&types.QueryVersionResponse{ | ||
Version: "a.b.c", | ||
}, nil) | ||
fetcher = client.NewSidecarVersionChecker(slinky, logger) | ||
require.NoError(t, fetcher.Start(context.Background())) | ||
require.ErrorContains(t, fetcher.CheckSidecarVersion(context.Background()), "Malformed version: a.b.c") | ||
fetcher.Stop() | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.