From 4718aa7ec20e2ef70dff7fb72095d357f3725a80 Mon Sep 17 00:00:00 2001 From: Augustus <14297860+augustbleeds@users.noreply.github.com> Date: Thu, 23 May 2024 17:06:37 -0400 Subject: [PATCH] BCI-1426: Add GasPriceSubunits Data Source Pipeline (#13200) * initial * incorporate gasPriceSubunits data source * update deps * add in data source * comment * update plugin config * add changeset * update chainlink-common & chainlink-feeds * lint fixes * lint --------- Co-authored-by: Bolek <1416262+bolekk@users.noreply.github.com> --- .changeset/sharp-plums-punch.md | 5 +++ .tool-versions | 2 +- contracts/foundry-lib/forge-std | 2 +- .../features/ocr2/features_ocr2_test.go | 11 ++++- core/scripts/go.mod | 4 +- core/scripts/go.sum | 8 ++-- core/services/feeds/service_test.go | 16 +++++++ core/services/job/orm.go | 28 +++++++++---- core/services/ocr2/database_test.go | 7 +++- .../ocr2/plugins/median/config/config.go | 19 ++++++++- .../ocr2/plugins/median/config/config_test.go | 9 ++-- core/services/ocr2/plugins/median/services.go | 18 ++++++-- core/services/ocr2/validate/validate_test.go | 4 +- go.mod | 4 +- go.sum | 8 ++-- integration-tests/go.mod | 4 +- integration-tests/go.sum | 8 ++-- integration-tests/load/go.mod | 4 +- integration-tests/load/go.sum | 8 ++-- plugins/medianpoc/plugin.go | 42 +++++++++++++++++-- 20 files changed, 161 insertions(+), 50 deletions(-) create mode 100644 .changeset/sharp-plums-punch.md diff --git a/.changeset/sharp-plums-punch.md b/.changeset/sharp-plums-punch.md new file mode 100644 index 00000000000..b5186ecf065 --- /dev/null +++ b/.changeset/sharp-plums-punch.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +Add option to include GasPriceSubunits pipeline to include gasPriceSubunits in median ocr2 transmission (only to be used with Starknet chain for now) #added #nops #updated diff --git a/.tool-versions b/.tool-versions index 492db47bbd0..ebf563134eb 100644 --- a/.tool-versions +++ b/.tool-versions @@ -2,7 +2,7 @@ golang 1.21.7 mockery 2.42.2 nodejs 20.13.1 pnpm 8.15.8 -postgres 14.11 +postgres 15.1 helm 3.10.3 zig 0.11.0 golangci-lint 1.55.2 diff --git a/contracts/foundry-lib/forge-std b/contracts/foundry-lib/forge-std index bb4ceea94d6..f73c73d2018 160000 --- a/contracts/foundry-lib/forge-std +++ b/contracts/foundry-lib/forge-std @@ -1 +1 @@ -Subproject commit bb4ceea94d6f10eeb5b41dc2391c6c8bf8e734ef +Subproject commit f73c73d2018eb6a111f35e4dae7b4f27401e9421 diff --git a/core/internal/features/ocr2/features_ocr2_test.go b/core/internal/features/ocr2/features_ocr2_test.go index fab9d34b4b1..9b950f487bf 100644 --- a/core/internal/features/ocr2/features_ocr2_test.go +++ b/core/internal/features/ocr2/features_ocr2_test.go @@ -309,8 +309,9 @@ fromBlock = %d })) t.Cleanup(servers[s].Close) u, _ := url.Parse(servers[i].URL) + bridgeName := fmt.Sprintf("bridge%d", i) require.NoError(t, apps[i].BridgeORM().CreateBridgeType(testutils.Context(t), &bridges.BridgeType{ - Name: bridges.BridgeName(fmt.Sprintf("bridge%d", i)), + Name: bridges.BridgeName(bridgeName), URL: models.WebURL(*u), })) @@ -488,9 +489,15 @@ juelsPerFeeCoinSource = """ answer1 [type=median index=0]; """ +gasPriceSource = """ + // data source + dsp [type=bridge name="%s"]; + dsp_parse [type=jsonparse path="data"]; + dsp -> dsp_parse; +""" [pluginConfig.juelsPerFeeCoinCache] updateInterval = "1m" -`, ocrContractAddress, kbs[i].ID(), transmitters[i], fmt.Sprintf("bridge%d", i), i, slowServers[i].URL, i, blockBeforeConfig.Number().Int64(), chainReaderSpec, fmt.Sprintf("bridge%d", i), i, slowServers[i].URL, i), nil) +`, ocrContractAddress, kbs[i].ID(), transmitters[i], bridgeName, i, slowServers[i].URL, i, blockBeforeConfig.Number().Int64(), chainReaderSpec, bridgeName, i, slowServers[i].URL, i, bridgeName), nil) require.NoError(t, err) err = apps[i].AddJobV2(testutils.Context(t), &ocrJob) require.NoError(t, err) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index cea4ca21242..01101b5f1b5 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -21,7 +21,7 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chainlink-automation v1.0.3 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240521015506-6a2cfa12f801 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240522203001-10ea0211efd7 github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240419185742-fd3cab206b2c @@ -258,7 +258,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.10 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240508101745-af1ed7bc8a69 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 // indirect - github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab // indirect + github.com/smartcontractkit/chainlink-feeds v0.0.0-20240522213638-159fb2d99917 // indirect github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240523174813-45db170c1ccc // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240508155030-1024f2b55c69 // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index cde855e2d2f..92e4debab99 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1185,14 +1185,14 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.3 h1:h/ijT0NiyV06VxYVgcNfsE3+8OEzT3Q0Z9au0z1BPWs= github.com/smartcontractkit/chainlink-automation v1.0.3/go.mod h1:RjboV0Qd7YP+To+OrzHGXaxUxoSONveCoAK2TQ1INLU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240521015506-6a2cfa12f801 h1:PP7nqhCc4NTp9xBJ5/d6wYLl61UQpMaDdqU+8SgEkJM= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240521015506-6a2cfa12f801/go.mod h1:s+68EchlrXqHKRW3JJgZLEARvzMSKRI5+cE5Zx7pVJA= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240522203001-10ea0211efd7 h1:od+11B83s0mQwAMPP3lhtb0nYz63pIKpJEKddfFpu/M= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240522203001-10ea0211efd7/go.mod h1:cFHRblGbGn/rFYOOGsNbtLicMc1+5YdN0KoebYr93pk= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240508101745-af1ed7bc8a69 h1:Sec/GpBpUVaTEax1kSHlTvkzF/+d3w5roAQXaj5+SLA= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240508101745-af1ed7bc8a69/go.mod h1:ZQKf+0OLzCLYIisH/OdOIQuFRI6bDuw+jPBTATyHfFM= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540/go.mod h1:sjAmX8K2kbQhvDarZE1ZZgDgmHJ50s0BBc/66vKY2ek= -github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab h1:Ct1oUlyn03HDUVdFHJqtRGRUujMqdoMzvf/Cjhe30Ag= -github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab/go.mod h1:RPUY7r8GxgzXxS1ijtU1P/fpJomOXztXgUbEziNmbCA= +github.com/smartcontractkit/chainlink-feeds v0.0.0-20240522213638-159fb2d99917 h1:MD80ZRCTvxxJ8PBmhtrKoTnky8cVNYrCrIBLVRbrOM0= +github.com/smartcontractkit/chainlink-feeds v0.0.0-20240522213638-159fb2d99917/go.mod h1:jwVxhctE6BgLOSSsVq9wbREpZ8Ev34H+UBxeUhESZRs= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240523174813-45db170c1ccc h1:ZqgatXFWsJR/hkvm2mKAta6ivXZqTw7542Iz9ucoOq0= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240523174813-45db170c1ccc/go.mod h1:sR0dMjjpvvEpX3qH8DPRANauPkbO9jgUUGYK95xjLRU= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240508155030-1024f2b55c69 h1:ssh/w3oXWu+C6bE88GuFRC1+0Bx/4ihsbc80XMLrl2k= diff --git a/core/services/feeds/service_test.go b/core/services/feeds/service_test.go index b8cd590a402..ea25fb05756 100644 --- a/core/services/feeds/service_test.go +++ b/core/services/feeds/service_test.go @@ -125,6 +125,13 @@ ds1_multiply [type=multiply times=1.23]; ds1 -> ds1_parse -> ds1_multiply -> answer1; answer1 [type=median index=0]; """ +gasPriceSubunitsSource = """ +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] updateInterval = "1m" ` @@ -1108,6 +1115,7 @@ 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]; +# omit gasPriceSubunitsSource intentionally """ ` @@ -2423,6 +2431,13 @@ ds1_multiply [type=multiply times=1.23]; ds1 -> ds1_parse -> ds1_multiply -> answer1; answer1 [type=median index=0]; """ +gasPriceSubunitsSource = """ +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] updateInterval = "30s" ` @@ -2454,6 +2469,7 @@ ds1_multiply [type=multiply times=1.23]; ds1 -> ds1_parse -> ds1_multiply -> answer1; answer1 [type=median index=0]; """ +# intentionally do not set gasPriceSubunitsSource for this pipeline example to cover case when none is set [pluginConfig.juelsPerFeeCoinCache] updateInterval = "20m" ` diff --git a/core/services/job/orm.go b/core/services/job/orm.go index 71a4ebebb1e..58b84851749 100644 --- a/core/services/job/orm.go +++ b/core/services/job/orm.go @@ -280,16 +280,28 @@ func (o *orm) CreateJob(ctx context.Context, jb *Job) error { if jb.OCR2OracleSpec.PluginType == types.Median { var cfg medianconfig.PluginConfig - err2 := json.Unmarshal(jb.OCR2OracleSpec.PluginConfig.Bytes(), &cfg) - if err2 != nil { - return errors.Wrap(err2, "failed to parse plugin config") + + validatePipeline := func(p string) error { + pipeline, pipelineErr := pipeline.Parse(p) + if pipelineErr != nil { + return pipelineErr + } + return tx.AssertBridgesExist(ctx, *pipeline) } - feePipeline, err2 := pipeline.Parse(cfg.JuelsPerFeeCoinPipeline) - if err2 != nil { - return err2 + + errUnmarshal := json.Unmarshal(jb.OCR2OracleSpec.PluginConfig.Bytes(), &cfg) + if errUnmarshal != nil { + return errors.Wrap(errUnmarshal, "failed to parse plugin config") } - if err2 = tx.AssertBridgesExist(ctx, *feePipeline); err2 != nil { - return err2 + + if errFeePipeline := validatePipeline(cfg.JuelsPerFeeCoinPipeline); errFeePipeline != nil { + return errFeePipeline + } + + if cfg.HasGasPriceSubunitsPipeline() { + if errGasPipeline := validatePipeline(cfg.GasPriceSubunitsPipeline); errGasPipeline != nil { + return errGasPipeline + } } } diff --git a/core/services/ocr2/database_test.go b/core/services/ocr2/database_test.go index 3d3eec22a6d..7e6b492a2db 100644 --- a/core/services/ocr2/database_test.go +++ b/core/services/ocr2/database_test.go @@ -34,7 +34,12 @@ func MustInsertOCROracleSpec(t *testing.T, db *sqlx.DB, transmitterAddress types ds1_multiply [type=multiply times=1.23]; ds1 -> ds1_parse -> ds1_multiply -> answer1; answer1 [type=median index=0];` - config := medianconfig.PluginConfig{JuelsPerFeeCoinPipeline: mockJuelsPerFeeCoinSource} + mockGasPriceSubunitsSource := `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];` + config := medianconfig.PluginConfig{JuelsPerFeeCoinPipeline: mockJuelsPerFeeCoinSource, GasPriceSubunitsPipeline: mockGasPriceSubunitsSource} jsonConfig, err := json.Marshal(config) require.NoError(t, err) diff --git a/core/services/ocr2/plugins/median/config/config.go b/core/services/ocr2/plugins/median/config/config.go index 310662ef6c0..9674ae73ebd 100644 --- a/core/services/ocr2/plugins/median/config/config.go +++ b/core/services/ocr2/plugins/median/config/config.go @@ -4,6 +4,7 @@ package config import ( + "strings" "time" "github.com/pkg/errors" @@ -13,8 +14,11 @@ import ( ) // The PluginConfig struct contains the custom arguments needed for the Median plugin. +// To avoid a catastrophic libocr codec error, you must make sure that either all nodes in the same DON +// (1) have no GasPriceSubunitsPipeline or all nodes in the same DON (2) have a GasPriceSubunitsPipeline type PluginConfig struct { - JuelsPerFeeCoinPipeline string `json:"juelsPerFeeCoinSource"` + GasPriceSubunitsPipeline string `json:"gasPriceSubunitsSource"` + JuelsPerFeeCoinPipeline string `json:"juelsPerFeeCoinSource"` // JuelsPerFeeCoinCache is disabled when nil JuelsPerFeeCoinCache *JuelsPerFeeCoinCache `json:"juelsPerFeeCoinCache"` } @@ -26,7 +30,7 @@ type JuelsPerFeeCoinCache struct { } // ValidatePluginConfig validates the arguments for the Median plugin. -func ValidatePluginConfig(config PluginConfig) error { +func (config *PluginConfig) ValidatePluginConfig() error { if _, err := pipeline.Parse(config.JuelsPerFeeCoinPipeline); err != nil { return errors.Wrap(err, "invalid juelsPerFeeCoinSource pipeline") } @@ -41,5 +45,16 @@ func ValidatePluginConfig(config PluginConfig) error { } } + // Gas price pipeline is optional + if !config.HasGasPriceSubunitsPipeline() { + return nil + } else if _, err := pipeline.Parse(config.GasPriceSubunitsPipeline); err != nil { + return errors.Wrap(err, "invalid gasPriceSubunitsSource pipeline") + } + return nil } + +func (config *PluginConfig) HasGasPriceSubunitsPipeline() bool { + return strings.TrimSpace(config.GasPriceSubunitsPipeline) != "" +} diff --git a/core/services/ocr2/plugins/median/config/config_test.go b/core/services/ocr2/plugins/median/config/config_test.go index e54b59215bd..544258eebcf 100644 --- a/core/services/ocr2/plugins/median/config/config_test.go +++ b/core/services/ocr2/plugins/median/config/config_test.go @@ -25,7 +25,8 @@ func TestValidatePluginConfig(t *testing.T) { {"foo pipeline", "foo", models.Interval(time.Minute), fmt.Errorf("invalid juelsPerFeeCoinSource pipeline: UnmarshalTaskFromMap: unknown task type: \"\"")}, } { t.Run(tc.name, func(t *testing.T) { - assert.EqualError(t, ValidatePluginConfig(PluginConfig{JuelsPerFeeCoinPipeline: tc.pipeline}), tc.expectedError.Error()) + pc := PluginConfig{JuelsPerFeeCoinPipeline: tc.pipeline} + assert.EqualError(t, pc.ValidatePluginConfig(), tc.expectedError.Error()) }) } }) @@ -36,7 +37,8 @@ func TestValidatePluginConfig(t *testing.T) { {"cache duration above maximum", `ds1 [type=bridge name=voter_turnout];`, models.Interval(time.Minute*20 + time.Second), fmt.Errorf("juelsPerFeeCoinSourceCache update interval: 20m1s is above 20 minute maximum")}, } { t.Run(tc.name, func(t *testing.T) { - assert.EqualError(t, ValidatePluginConfig(PluginConfig{JuelsPerFeeCoinPipeline: tc.pipeline, JuelsPerFeeCoinCache: &JuelsPerFeeCoinCache{UpdateInterval: tc.cacheDuration}}), tc.expectedError.Error()) + pc := PluginConfig{JuelsPerFeeCoinPipeline: tc.pipeline, JuelsPerFeeCoinCache: &JuelsPerFeeCoinCache{UpdateInterval: tc.cacheDuration}} + assert.EqualError(t, pc.ValidatePluginConfig(), tc.expectedError.Error()) }) } }) @@ -48,7 +50,8 @@ func TestValidatePluginConfig(t *testing.T) { {"valid duration and valid pipeline", `ds1 [type=bridge name=voter_turnout];`, models.Interval(time.Minute * 20), nil}, } { t.Run(s.name, func(t *testing.T) { - assert.Nil(t, ValidatePluginConfig(PluginConfig{JuelsPerFeeCoinPipeline: s.pipeline})) + pc := PluginConfig{JuelsPerFeeCoinPipeline: s.pipeline} + assert.Nil(t, pc.ValidatePluginConfig()) }) } }) diff --git a/core/services/ocr2/plugins/median/services.go b/core/services/ocr2/plugins/median/services.go index e2b8da13407..897531b82fb 100644 --- a/core/services/ocr2/plugins/median/services.go +++ b/core/services/ocr2/plugins/median/services.go @@ -7,6 +7,7 @@ import ( "fmt" "time" + libocr_median "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median" libocr "github.com/smartcontractkit/libocr/offchainreporting2plus" "github.com/smartcontractkit/chainlink-common/pkg/loop" @@ -69,7 +70,7 @@ func NewMedianServices(ctx context.Context, if err != nil { return } - err = config.ValidatePluginConfig(pluginConfig) + err = pluginConfig.ValidatePluginConfig() if err != nil { return } @@ -136,6 +137,17 @@ func NewMedianServices(ctx context.Context, srvs = append(srvs, juelsPerFeeCoinSourceCache) } + var gasPriceSubunitsDataSource libocr_median.DataSource + if pluginConfig.HasGasPriceSubunitsPipeline() { + gasPriceSubunitsDataSource = ocrcommon.NewInMemoryDataSource(pipelineRunner, jb, pipeline.Spec{ + ID: jb.ID, + DotDagSource: pluginConfig.GasPriceSubunitsPipeline, + CreatedAt: time.Now(), + }, lggr) + } else { + gasPriceSubunitsDataSource = &median.ZeroDataSource{} + } + if cmdName := env.MedianPlugin.Cmd.Get(); cmdName != "" { // use unique logger names so we can use it to register a loop medianLggr := lggr.Named("Median").Named(spec.ContractID).Named(spec.GetID()) @@ -155,11 +167,11 @@ func NewMedianServices(ctx context.Context, abort() return } - median := loop.NewMedianService(lggr, telem, cmdFn, medianProvider, dataSource, juelsPerFeeCoinSource, errorLog) + median := loop.NewMedianService(lggr, telem, cmdFn, medianProvider, dataSource, juelsPerFeeCoinSource, gasPriceSubunitsDataSource, errorLog) argsNoPlugin.ReportingPluginFactory = median srvs = append(srvs, median) } else { - argsNoPlugin.ReportingPluginFactory, err = median.NewPlugin(lggr).NewMedianFactory(ctx, medianProvider, dataSource, juelsPerFeeCoinSource, errorLog) + argsNoPlugin.ReportingPluginFactory, err = median.NewPlugin(lggr).NewMedianFactory(ctx, medianProvider, dataSource, juelsPerFeeCoinSource, gasPriceSubunitsDataSource, errorLog) if err != nil { err = fmt.Errorf("failed to create median factory: %w", err) abort() diff --git a/core/services/ocr2/validate/validate_test.go b/core/services/ocr2/validate/validate_test.go index 05881187ba4..da896bf4a92 100644 --- a/core/services/ocr2/validate/validate_test.go +++ b/core/services/ocr2/validate/validate_test.go @@ -71,7 +71,7 @@ answer1 [type=median index=0]; 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)) + require.NoError(t, pc.ValidatePluginConfig()) var oss validate.OCR2OnchainSigningStrategy require.NoError(t, json.Unmarshal(r.OnchainSigningStrategy.Bytes(), &oss)) }, @@ -901,7 +901,7 @@ UpdateInterval="1m" 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)) + require.NoError(t, pc.ValidatePluginConfig()) }, }, } diff --git a/go.mod b/go.mod index 9ce8d98b91d..42bdc2b4e79 100644 --- a/go.mod +++ b/go.mod @@ -72,10 +72,10 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chain-selectors v1.0.10 github.com/smartcontractkit/chainlink-automation v1.0.3 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240521015506-6a2cfa12f801 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240522203001-10ea0211efd7 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240508101745-af1ed7bc8a69 github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 - github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab + github.com/smartcontractkit/chainlink-feeds v0.0.0-20240522213638-159fb2d99917 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240523174813-45db170c1ccc github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240508155030-1024f2b55c69 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 diff --git a/go.sum b/go.sum index a41f19e2cb1..37edaa1161e 100644 --- a/go.sum +++ b/go.sum @@ -1171,14 +1171,14 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.3 h1:h/ijT0NiyV06VxYVgcNfsE3+8OEzT3Q0Z9au0z1BPWs= github.com/smartcontractkit/chainlink-automation v1.0.3/go.mod h1:RjboV0Qd7YP+To+OrzHGXaxUxoSONveCoAK2TQ1INLU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240521015506-6a2cfa12f801 h1:PP7nqhCc4NTp9xBJ5/d6wYLl61UQpMaDdqU+8SgEkJM= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240521015506-6a2cfa12f801/go.mod h1:s+68EchlrXqHKRW3JJgZLEARvzMSKRI5+cE5Zx7pVJA= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240522203001-10ea0211efd7 h1:od+11B83s0mQwAMPP3lhtb0nYz63pIKpJEKddfFpu/M= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240522203001-10ea0211efd7/go.mod h1:cFHRblGbGn/rFYOOGsNbtLicMc1+5YdN0KoebYr93pk= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240508101745-af1ed7bc8a69 h1:Sec/GpBpUVaTEax1kSHlTvkzF/+d3w5roAQXaj5+SLA= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240508101745-af1ed7bc8a69/go.mod h1:ZQKf+0OLzCLYIisH/OdOIQuFRI6bDuw+jPBTATyHfFM= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540/go.mod h1:sjAmX8K2kbQhvDarZE1ZZgDgmHJ50s0BBc/66vKY2ek= -github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab h1:Ct1oUlyn03HDUVdFHJqtRGRUujMqdoMzvf/Cjhe30Ag= -github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab/go.mod h1:RPUY7r8GxgzXxS1ijtU1P/fpJomOXztXgUbEziNmbCA= +github.com/smartcontractkit/chainlink-feeds v0.0.0-20240522213638-159fb2d99917 h1:MD80ZRCTvxxJ8PBmhtrKoTnky8cVNYrCrIBLVRbrOM0= +github.com/smartcontractkit/chainlink-feeds v0.0.0-20240522213638-159fb2d99917/go.mod h1:jwVxhctE6BgLOSSsVq9wbREpZ8Ev34H+UBxeUhESZRs= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240523174813-45db170c1ccc h1:ZqgatXFWsJR/hkvm2mKAta6ivXZqTw7542Iz9ucoOq0= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240523174813-45db170c1ccc/go.mod h1:sR0dMjjpvvEpX3qH8DPRANauPkbO9jgUUGYK95xjLRU= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240508155030-1024f2b55c69 h1:ssh/w3oXWu+C6bE88GuFRC1+0Bx/4ihsbc80XMLrl2k= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 9442426eeb3..469809937e5 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -27,7 +27,7 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.3 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240521015506-6a2cfa12f801 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240522203001-10ea0211efd7 github.com/smartcontractkit/chainlink-testing-framework v1.28.15 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 @@ -375,7 +375,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.10 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240508101745-af1ed7bc8a69 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 // indirect - github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab // indirect + github.com/smartcontractkit/chainlink-feeds v0.0.0-20240522213638-159fb2d99917 // indirect github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240523174813-45db170c1ccc // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240508155030-1024f2b55c69 // indirect github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240328204215-ac91f55f1449 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 477edf4ab53..650dfb4ed4e 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1512,14 +1512,14 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.3 h1:h/ijT0NiyV06VxYVgcNfsE3+8OEzT3Q0Z9au0z1BPWs= github.com/smartcontractkit/chainlink-automation v1.0.3/go.mod h1:RjboV0Qd7YP+To+OrzHGXaxUxoSONveCoAK2TQ1INLU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240521015506-6a2cfa12f801 h1:PP7nqhCc4NTp9xBJ5/d6wYLl61UQpMaDdqU+8SgEkJM= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240521015506-6a2cfa12f801/go.mod h1:s+68EchlrXqHKRW3JJgZLEARvzMSKRI5+cE5Zx7pVJA= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240522203001-10ea0211efd7 h1:od+11B83s0mQwAMPP3lhtb0nYz63pIKpJEKddfFpu/M= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240522203001-10ea0211efd7/go.mod h1:cFHRblGbGn/rFYOOGsNbtLicMc1+5YdN0KoebYr93pk= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240508101745-af1ed7bc8a69 h1:Sec/GpBpUVaTEax1kSHlTvkzF/+d3w5roAQXaj5+SLA= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240508101745-af1ed7bc8a69/go.mod h1:ZQKf+0OLzCLYIisH/OdOIQuFRI6bDuw+jPBTATyHfFM= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540/go.mod h1:sjAmX8K2kbQhvDarZE1ZZgDgmHJ50s0BBc/66vKY2ek= -github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab h1:Ct1oUlyn03HDUVdFHJqtRGRUujMqdoMzvf/Cjhe30Ag= -github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab/go.mod h1:RPUY7r8GxgzXxS1ijtU1P/fpJomOXztXgUbEziNmbCA= +github.com/smartcontractkit/chainlink-feeds v0.0.0-20240522213638-159fb2d99917 h1:MD80ZRCTvxxJ8PBmhtrKoTnky8cVNYrCrIBLVRbrOM0= +github.com/smartcontractkit/chainlink-feeds v0.0.0-20240522213638-159fb2d99917/go.mod h1:jwVxhctE6BgLOSSsVq9wbREpZ8Ev34H+UBxeUhESZRs= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240523174813-45db170c1ccc h1:ZqgatXFWsJR/hkvm2mKAta6ivXZqTw7542Iz9ucoOq0= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240523174813-45db170c1ccc/go.mod h1:sR0dMjjpvvEpX3qH8DPRANauPkbO9jgUUGYK95xjLRU= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240508155030-1024f2b55c69 h1:ssh/w3oXWu+C6bE88GuFRC1+0Bx/4ihsbc80XMLrl2k= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 395199f599b..192b741fe37 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.30.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.3 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240521015506-6a2cfa12f801 + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240522203001-10ea0211efd7 github.com/smartcontractkit/chainlink-testing-framework v1.28.15 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 @@ -368,7 +368,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.10 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240508101745-af1ed7bc8a69 // indirect github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 // indirect - github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab // indirect + github.com/smartcontractkit/chainlink-feeds v0.0.0-20240522213638-159fb2d99917 // indirect github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240523174813-45db170c1ccc // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240508155030-1024f2b55c69 // indirect github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240328204215-ac91f55f1449 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 95624177f68..265b577f868 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1502,14 +1502,14 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.3 h1:h/ijT0NiyV06VxYVgcNfsE3+8OEzT3Q0Z9au0z1BPWs= github.com/smartcontractkit/chainlink-automation v1.0.3/go.mod h1:RjboV0Qd7YP+To+OrzHGXaxUxoSONveCoAK2TQ1INLU= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240521015506-6a2cfa12f801 h1:PP7nqhCc4NTp9xBJ5/d6wYLl61UQpMaDdqU+8SgEkJM= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240521015506-6a2cfa12f801/go.mod h1:s+68EchlrXqHKRW3JJgZLEARvzMSKRI5+cE5Zx7pVJA= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240522203001-10ea0211efd7 h1:od+11B83s0mQwAMPP3lhtb0nYz63pIKpJEKddfFpu/M= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240522203001-10ea0211efd7/go.mod h1:cFHRblGbGn/rFYOOGsNbtLicMc1+5YdN0KoebYr93pk= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240508101745-af1ed7bc8a69 h1:Sec/GpBpUVaTEax1kSHlTvkzF/+d3w5roAQXaj5+SLA= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240508101745-af1ed7bc8a69/go.mod h1:ZQKf+0OLzCLYIisH/OdOIQuFRI6bDuw+jPBTATyHfFM= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540/go.mod h1:sjAmX8K2kbQhvDarZE1ZZgDgmHJ50s0BBc/66vKY2ek= -github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab h1:Ct1oUlyn03HDUVdFHJqtRGRUujMqdoMzvf/Cjhe30Ag= -github.com/smartcontractkit/chainlink-feeds v0.0.0-20240422130241-13c17a91b2ab/go.mod h1:RPUY7r8GxgzXxS1ijtU1P/fpJomOXztXgUbEziNmbCA= +github.com/smartcontractkit/chainlink-feeds v0.0.0-20240522213638-159fb2d99917 h1:MD80ZRCTvxxJ8PBmhtrKoTnky8cVNYrCrIBLVRbrOM0= +github.com/smartcontractkit/chainlink-feeds v0.0.0-20240522213638-159fb2d99917/go.mod h1:jwVxhctE6BgLOSSsVq9wbREpZ8Ev34H+UBxeUhESZRs= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240523174813-45db170c1ccc h1:ZqgatXFWsJR/hkvm2mKAta6ivXZqTw7542Iz9ucoOq0= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240523174813-45db170c1ccc/go.mod h1:sR0dMjjpvvEpX3qH8DPRANauPkbO9jgUUGYK95xjLRU= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240508155030-1024f2b55c69 h1:ssh/w3oXWu+C6bE88GuFRC1+0Bx/4ihsbc80XMLrl2k= diff --git a/plugins/medianpoc/plugin.go b/plugins/medianpoc/plugin.go index bbd9d437e3a..41580afe499 100644 --- a/plugins/medianpoc/plugin.go +++ b/plugins/medianpoc/plugin.go @@ -3,6 +3,7 @@ package medianpoc import ( "context" "encoding/json" + "errors" "fmt" "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median" @@ -30,6 +31,14 @@ type Plugin struct { reportingplugins.MedianProviderServer } +type PipelineNotFoundError struct { + Key string +} + +func (e *PipelineNotFoundError) Error() string { + return fmt.Sprintf("no pipeline found for %s", e.Key) +} + func (p *Plugin) NewValidationService(ctx context.Context) (core.ValidationService, error) { s := &reportingPluginValidationService{lggr: p.Logger} p.SubService(s) @@ -55,7 +64,7 @@ func (j jsonConfig) getPipeline(key string) (string, error) { return v.Spec, nil } } - return "", fmt.Errorf("no pipeline found for %s", key) + return "", &PipelineNotFoundError{key} } func (p *Plugin) NewReportingPluginFactory( @@ -103,12 +112,39 @@ func (p *Plugin) newFactory(ctx context.Context, config core.ReportingPluginServ spec: jfp, lggr: p.Logger, } + + var gds median.DataSource + gp, err := jc.getPipeline("gasPriceSubunitsPipeline") + + var pnf *PipelineNotFoundError + pipelineNotFound := errors.As(err, &pnf) + if !pipelineNotFound && err != nil { + return nil, err + } + + // We omit gas price in observation to maintain backwards compatibility in libocr (with older nodes). + // Once all chainlink nodes have updated to libocr version >= fd3cab206b2c + // the IncludeGasPriceSubunitsInObservation field can be removed + + var includeGasPriceSubunitsInObservation bool + if pipelineNotFound { + gds = &ZeroDataSource{} + includeGasPriceSubunitsInObservation = false + } else { + gds = &DataSource{ + pipelineRunner: pipelineRunner, + spec: gp, + lggr: p.Logger, + } + includeGasPriceSubunitsInObservation = true + } + factory := &median.NumericalMedianFactory{ ContractTransmitter: provider.MedianContract(), DataSource: ds, JuelsPerFeeCoinDataSource: jds, - GasPriceSubunitsDataSource: &ZeroDataSource{}, - IncludeGasPriceSubunitsInObservation: false, + GasPriceSubunitsDataSource: gds, + IncludeGasPriceSubunitsInObservation: includeGasPriceSubunitsInObservation, Logger: logger.NewOCRWrapper( p.Logger, true,