diff --git a/config/config.go b/config/config.go index 5e14f884553..0ebacc89b3a 100644 --- a/config/config.go +++ b/config/config.go @@ -1350,8 +1350,7 @@ func (c *Config) CheckOrderManagerConfig() { c.OrderManager.RespectOrderHistoryLimits = convert.BoolPtr(true) } if c.OrderManager.ActivelyTrackFuturesPositions && c.OrderManager.FuturesTrackingSeekDuration >= 0 { - // one isn't likely to have a perpetual futures order open - // for longer than a year + // one isn't likely to have a perpetual futures order open for longer than a year c.OrderManager.FuturesTrackingSeekDuration = -time.Hour * 24 * 365 } } diff --git a/config/versions/v4.go b/config/versions/v4.go new file mode 100644 index 00000000000..283c21a0e3b --- /dev/null +++ b/config/versions/v4.go @@ -0,0 +1,47 @@ +package versions + +import ( + "context" + "errors" + + "github.com/buger/jsonparser" +) + +// Version4 implements ConfigVersion +type Version4 struct { +} + +func init() { + Manager.registerVersion(4, &Version4{}) +} + +// defaultConfig contains the stateless V4 representation of orderbookManager +// Note: Do not be tempted to an constant for Duration. Whilst defaults are still written to config, we need to manage default upgrades discretely +var defaultConfig = []byte(`{ + "enabled": true, + "verbose": false, + "activelyTrackFuturesPositions": true, + "futuresTrackingSeekDuration": 31536000000000000, + "respectOrderHistoryLimits": true, + "cancelOrdersOnShutdown": false + }`) + +// UpgradeConfig sets OrderManager config to defaults if it doesn't exist, and sets respectOrderHistoryLimits to true if it doesn't exist +func (v *Version4) UpgradeConfig(_ context.Context, e []byte) ([]byte, error) { + _, _, _, err := jsonparser.Get(e, "orderManager") //nolint:dogsled // Ignored return values really not needed + switch { + case errors.Is(err, jsonparser.KeyPathNotFoundError): + return jsonparser.Set(e, defaultConfig, "orderManager") + case err == nil: + _, err = jsonparser.GetBoolean(e, "orderManager", "respectOrderHistoryLimits") + if errors.Is(err, jsonparser.KeyPathNotFoundError) { + return jsonparser.Set(e, []byte(`true`), "orderManager", "respectOrderHistoryLimits") + } + } + return e, err +} + +// DowngradeConfig doesn't need to do anything for this version, since it's a lossy downgrade +func (v *Version4) DowngradeConfig(_ context.Context, e []byte) ([]byte, error) { + return e, nil +} diff --git a/config/versions/v4_test.go b/config/versions/v4_test.go new file mode 100644 index 00000000000..1ec59f24fdd --- /dev/null +++ b/config/versions/v4_test.go @@ -0,0 +1,36 @@ +package versions + +import ( + "bytes" + "context" + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestVersion4Upgrade(t *testing.T) { + t.Parallel() + + out, err := new(Version4).UpgradeConfig(context.Background(), []byte(`{}`)) + require.NoError(t, err) + b := new(bytes.Buffer) + require.NoError(t, json.Compact(b, out), "json.Compact must not error") + exp := `{"orderManager":{"enabled":true,"verbose":false,"activelyTrackFuturesPositions":true,"futuresTrackingSeekDuration":31536000000000000,"respectOrderHistoryLimits":true,"cancelOrdersOnShutdown":false}}` + require.Equal(t, exp, b.String()) + + in := []byte(`{"orderManager":{"enabled":false,"verbose":true,"activelyTrackFuturesPositions":true,"futuresTrackingSeekDuration":3600000,"cancelOrdersOnShutdown":false}}`) + out, err = new(Version4).UpgradeConfig(context.Background(), in) + require.NoError(t, err) + exp = `{"orderManager":{"enabled":false,"verbose":true,"activelyTrackFuturesPositions":true,"futuresTrackingSeekDuration":3600000,"cancelOrdersOnShutdown":false,"respectOrderHistoryLimits":true}}` + require.Equal(t, exp, string(out)) +} + +func TestVersion4Downgrade(t *testing.T) { + t.Parallel() + in := []byte(`{"orderManager":{"enabled":false,"verbose":true}}`) + out, err := new(Version4).DowngradeConfig(context.Background(), in) + require.NoError(t, err) + assert.Equal(t, string(in), string(out), "Downgrade should not touch the config") +}