diff --git a/.changeset/warm-impalas-return.md b/.changeset/warm-impalas-return.md new file mode 100644 index 00000000000..167d831692c --- /dev/null +++ b/.changeset/warm-impalas-return.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +#added JuelsPerFeeCoinCache is enabled by default for OCR2 jobs, added `Disable` field under [pluginConfig.JuelsPerFeeCoinCache] tag to disable this feature (e.g. Disable=true) diff --git a/core/services/ocr2/plugins/median/config/config.go b/core/services/ocr2/plugins/median/config/config.go index 9cfda641552..310662ef6c0 100644 --- a/core/services/ocr2/plugins/median/config/config.go +++ b/core/services/ocr2/plugins/median/config/config.go @@ -20,6 +20,7 @@ type PluginConfig struct { } type JuelsPerFeeCoinCache struct { + Disable bool `json:"disable"` UpdateInterval models.Interval `json:"updateInterval"` StalenessAlertThreshold models.Interval `json:"stalenessAlertThreshold"` } diff --git a/core/services/ocr2/plugins/median/services.go b/core/services/ocr2/plugins/median/services.go index 779ea4f346c..e2b8da13407 100644 --- a/core/services/ocr2/plugins/median/services.go +++ b/core/services/ocr2/plugins/median/services.go @@ -12,7 +12,6 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/loop" "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-feeds/median" - "github.com/smartcontractkit/chainlink/v2/core/config/env" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services" @@ -127,9 +126,9 @@ func NewMedianServices(ctx context.Context, CreatedAt: time.Now(), }, lggr) - if pluginConfig.JuelsPerFeeCoinCache != nil { + if pluginConfig.JuelsPerFeeCoinCache == nil || (pluginConfig.JuelsPerFeeCoinCache != nil && !pluginConfig.JuelsPerFeeCoinCache.Disable) { lggr.Infof("juelsPerFeeCoin data source caching is enabled") - juelsPerFeeCoinSourceCache, err2 := ocrcommon.NewInMemoryDataSourceCache(juelsPerFeeCoinSource, kvStore, *pluginConfig.JuelsPerFeeCoinCache) + juelsPerFeeCoinSourceCache, err2 := ocrcommon.NewInMemoryDataSourceCache(juelsPerFeeCoinSource, kvStore, pluginConfig.JuelsPerFeeCoinCache) if err2 != nil { return nil, err2 } diff --git a/core/services/ocr2/validate/validate_test.go b/core/services/ocr2/validate/validate_test.go index 305a727d030..fad5a36e51f 100644 --- a/core/services/ocr2/validate/validate_test.go +++ b/core/services/ocr2/validate/validate_test.go @@ -693,6 +693,47 @@ Command="some random command" require.Error(t, err) require.ErrorContains(t, err, "failed to find binary") }, + }, { + name: "minimal OCR2 oracle spec with JuelsPerFeeCoinCache", + toml: ` +type = "offchainreporting2" +pluginType = "median" +schemaVersion = 1 +relay = "evm" +contractID = "0x613a38AC1659769640aaE063C651F48E0250454C" +observationSource = """ +ds1 [type=bridge name=voter_turnout]; +ds1_parse [type=jsonparse path="one,two"]; +ds1_multiply [type=multiply times=1.23]; +ds1 -> ds1_parse -> ds1_multiply -> answer1; +answer1 [type=median index=0]; +""" +[relayConfig] +chainID = 1337 +[pluginConfig] +juelsPerFeeCoinSource = """ +ds1 [type=bridge name=voter_turnout]; +ds1_parse [type=jsonparse path="one,two"]; +ds1_multiply [type=multiply times=1.23]; +ds1 -> ds1_parse -> ds1_multiply -> answer1; +answer1 [type=median index=0]; +""" +[pluginConfig.JuelsPerFeeCoinCache] +Disable=false +UpdateInterval="1m" +`, + assertion: func(t *testing.T, os job.Job, err error) { + require.NoError(t, err) + b, err := jsonapi.Marshal(os.OCR2OracleSpec) + require.NoError(t, err) + var r job.OCR2OracleSpec + err = jsonapi.Unmarshal(b, &r) + require.NoError(t, err) + assert.Equal(t, "median", string(r.PluginType)) + var pc medianconfig.PluginConfig + require.NoError(t, json.Unmarshal(r.PluginConfig.Bytes(), &pc)) + require.NoError(t, medianconfig.ValidatePluginConfig(pc)) + }, }, } diff --git a/core/services/ocrcommon/data_source.go b/core/services/ocrcommon/data_source.go index 9ca111dea68..cb544e01639 100644 --- a/core/services/ocrcommon/data_source.go +++ b/core/services/ocrcommon/data_source.go @@ -113,18 +113,23 @@ type DataSourceCacheService interface { median.DataSource } -func NewInMemoryDataSourceCache(ds median.DataSource, kvStore job.KVStore, cacheCfg config.JuelsPerFeeCoinCache) (DataSourceCacheService, error) { +func NewInMemoryDataSourceCache(ds median.DataSource, kvStore job.KVStore, cacheCfg *config.JuelsPerFeeCoinCache) (DataSourceCacheService, error) { inMemoryDS, ok := ds.(*inMemoryDataSource) if !ok { return nil, errors.Errorf("unsupported data source type: %T, only inMemoryDataSource supported", ds) } - - updateInterval, stalenessAlertThreshold := cacheCfg.UpdateInterval.Duration(), cacheCfg.StalenessAlertThreshold.Duration() - if updateInterval == 0 { + var updateInterval, stalenessAlertThreshold time.Duration + if cacheCfg == nil { updateInterval = defaultUpdateInterval - } - if stalenessAlertThreshold == 0 { stalenessAlertThreshold = defaultStalenessAlertThreshold + } else { + updateInterval, stalenessAlertThreshold = cacheCfg.UpdateInterval.Duration(), cacheCfg.StalenessAlertThreshold.Duration() + if updateInterval == 0 { + updateInterval = defaultUpdateInterval + } + if stalenessAlertThreshold == 0 { + stalenessAlertThreshold = defaultStalenessAlertThreshold + } } dsCache := &inMemoryDataSourceCache{ diff --git a/core/services/ocrcommon/data_source_test.go b/core/services/ocrcommon/data_source_test.go index 05ba0f4aa42..a62852eaced 100644 --- a/core/services/ocrcommon/data_source_test.go +++ b/core/services/ocrcommon/data_source_test.go @@ -80,7 +80,7 @@ func Test_CachedInMemoryDataSourceErrHandling(t *testing.T) { mockKVStore := mocks.KVStore{} mockKVStore.On("Store", mock.Anything, mock.Anything, mock.Anything).Return(nil) mockKVStore.On("Get", mock.Anything, mock.Anything).Return(nil, nil) - dsCache, err := ocrcommon.NewInMemoryDataSourceCache(ds, &mockKVStore, config.JuelsPerFeeCoinCache{UpdateInterval: models.Interval(time.Second * 2)}) + dsCache, err := ocrcommon.NewInMemoryDataSourceCache(ds, &mockKVStore, &config.JuelsPerFeeCoinCache{UpdateInterval: models.Interval(time.Second * 2)}) require.NoError(t, err) servicetest.Run(t, dsCache) @@ -114,7 +114,7 @@ func Test_CachedInMemoryDataSourceErrHandling(t *testing.T) { mockKVStore.On("Get", mock.Anything, mock.Anything).Return(result, nil) // set updater to a long time so that it doesn't log errors after the test is done - dsCache, err := ocrcommon.NewInMemoryDataSourceCache(ds, &mockKVStore, config.JuelsPerFeeCoinCache{UpdateInterval: models.Interval(time.Hour * 100)}) + dsCache, err := ocrcommon.NewInMemoryDataSourceCache(ds, &mockKVStore, &config.JuelsPerFeeCoinCache{UpdateInterval: models.Interval(time.Hour * 100)}) require.NoError(t, err) changeResultValue(runner, "-1", true, false) servicetest.Run(t, dsCache) @@ -133,7 +133,7 @@ func Test_CachedInMemoryDataSourceErrHandling(t *testing.T) { mockKVStore.On("Get", mock.Anything, mock.Anything).Return(nil, assert.AnError) // set updater to a long time so that it doesn't log errors after the test is done - dsCache, err := ocrcommon.NewInMemoryDataSourceCache(ds, &mockKVStore, config.JuelsPerFeeCoinCache{UpdateInterval: models.Interval(time.Hour * 100)}) + dsCache, err := ocrcommon.NewInMemoryDataSourceCache(ds, &mockKVStore, &config.JuelsPerFeeCoinCache{UpdateInterval: models.Interval(time.Hour * 100)}) require.NoError(t, err) changeResultValue(runner, "-1", true, false) servicetest.Run(t, dsCache)