From a4534e774e11655ef4f2fb5bd085b8a4f43da49f Mon Sep 17 00:00:00 2001 From: Vyzaldy Sanchez Date: Wed, 7 Jun 2023 13:33:09 -0400 Subject: [PATCH] Block range guarantees (#9022) * Support libocr in-protocol block range guarantees - Low latency oracle jobs now support in-protocol block range guarantees. This is necessary in order to produce reports with block number ranges that do not overlap. It can now be guaranteed at the protocol level, so we can use local state instead of relying on an unreliable round-trip to the Mercury server. * scripts go.mod * test * Update core/web/presenters/ocr_keys.go Co-authored-by: Jordan Krage * remove commented useless code * Remove panics' * imports * Bump libocr to go get github.com/smartcontractkit/libocr@232b0d24bb3cb25a3014b62d68027f61b996ecf4 * lint * bump libocr to 3c336ffb2acf2b4ef261f5f7d52e9a9628985207 * go get github.com/smartcontractkit/chainlink-relay@7a0cfc835c3fcead61b0c428667f93c90c0767bf * gomodtidy * Fix lint * fix merge conflict * libocr => 82b910bef5c1c95cc7a886091ccfc1895bde76f5 * no longer experimental * latest ocr2vrf * Fix conflicts * rename InitialValidFromBlockNumber to InitialBlockNumber --------- Co-authored-by: Sam Davies Co-authored-by: Jordan Krage --- .tool-versions | 2 +- README.md | 2 +- core/chains/evm/logpoller/log_poller.go | 1 + core/cmd/csa_keys_commands_test.go | 2 +- .../features/ocr2/features_ocr2_test.go | 22 +- .../chaincli/handler/keeper_deployer.go | 4 +- core/scripts/chaincli/handler/ocr2_config.go | 2 +- core/scripts/chaincli/handler/report.go | 2 +- .../functions/src/generate_ocr2_config_cmd.go | 4 +- core/scripts/go.mod | 10 +- core/scripts/go.sum | 20 +- core/scripts/mercury/mercury.go | 48 --- core/scripts/ocr2vrf/util.go | 4 +- .../keystore/keys/ocr2key/cosmos_keyring.go | 4 +- .../keys/ocr2key/cosmos_keyring_test.go | 2 +- .../keystore/keys/ocr2key/evm_keyring.go | 4 +- .../keystore/keys/ocr2key/evm_keyring_test.go | 2 +- .../keys/ocr2key/generic_key_bundle.go | 2 +- .../keystore/keys/ocr2key/key_bundle.go | 2 +- .../keystore/keys/ocr2key/offchain_keyring.go | 2 +- .../keystore/keys/ocr2key/solana_keyring.go | 4 +- .../keys/ocr2key/solana_keyring_test.go | 2 +- .../keystore/keys/starkkey/ocr2key.go | 4 +- .../keystore/keys/starkkey/ocr2key_test.go | 2 +- core/services/ocr2/database.go | 31 +- core/services/ocr2/database_test.go | 75 ++++- core/services/ocr2/delegate.go | 18 +- .../ocr2/plugins/dkg/persistence/db.go | 2 +- core/services/ocr2/plugins/dkg/plugin.go | 4 +- .../functions_integration_test.go | 2 +- .../integration_tests/internal/testutils.go | 4 +- .../services/ocr2/plugins/functions/plugin.go | 4 +- .../ocr2/plugins/functions/reporting.go | 2 +- .../ocr2/plugins/functions/reporting_test.go | 2 +- core/services/ocr2/plugins/median/plugin.go | 12 +- .../ocr2/plugins/mercury/config/config.go | 5 + .../ocr2/plugins/mercury/integration_test.go | 230 ++++++++------- core/services/ocr2/plugins/mercury/plugin.go | 18 +- .../plugins/ocr2keeper/integration_test.go | 4 +- .../ocr2vrf/coordinator/coordinator.go | 2 +- .../ocr2vrf/coordinator/coordinator_test.go | 2 +- .../internal/ocr2vrf_integration_test.go | 4 +- core/services/ocr2/plugins/plugin.go | 2 +- .../ocr2/plugins/promwrapper/factory.go | 2 +- .../ocr2/plugins/promwrapper/plugin.go | 2 +- .../ocr2/plugins/promwrapper/plugin_test.go | 2 +- core/services/ocr2/plugins/s4/plugin.go | 2 +- core/services/ocr2/plugins/s4/plugin_test.go | 2 +- core/services/ocr2/testhelpers/digest.go | 2 +- core/services/ocr2/validate/config.go | 2 +- core/services/ocr2/validate/validate.go | 2 +- core/services/ocrbootstrap/database.go | 2 +- core/services/ocrbootstrap/database_test.go | 2 +- core/services/ocrbootstrap/delegate.go | 2 +- core/services/ocrcommon/data_source.go | 2 +- core/services/ocrcommon/data_source_test.go | 2 +- core/services/ocrcommon/peer_wrapper.go | 2 +- core/services/ocrcommon/telemetry.go | 2 +- core/services/ocrcommon/telemetry_test.go | 2 +- core/services/relay/evm/address.go | 2 +- core/services/relay/evm/config_poller.go | 2 +- core/services/relay/evm/config_poller_test.go | 9 +- .../relay/evm/contract_transmitter.go | 4 +- core/services/relay/evm/evm.go | 6 +- core/services/relay/evm/functions.go | 2 +- core/services/relay/evm/median.go | 4 +- .../relay/evm/mercury/config_digest.go | 6 +- .../relay/evm/mercury/config_digest_test.go | 6 +- .../relay/evm/mercury/config_poller.go | 3 +- .../relay/evm/mercury/config_poller_test.go | 6 +- .../services/relay/evm/mercury/data_source.go | 124 +++++--- .../relay/evm/mercury/data_source_test.go | 274 +++++++++++++++++- .../relay/evm/mercury/helpers_test.go | 4 +- .../evm/mercury/offchain_config_digester.go | 12 +- .../mercury/offchain_config_digester_test.go | 2 +- core/services/relay/evm/mercury/queue.go | 3 +- core/services/relay/evm/mercury/queue_test.go | 2 +- .../evm/mercury/reportcodec/factories_test.go | 94 ++++++ .../evm/mercury/reportcodec/report_codec.go | 47 ++- .../mercury/reportcodec/report_codec_test.go | 66 +++-- .../services/relay/evm/mercury/transmitter.go | 83 +++--- .../relay/evm/mercury/transmitter_test.go | 135 ++------- core/services/relay/evm/mercury_provider.go | 2 +- core/services/relay/evm/ocr2keeper.go | 4 +- core/services/relay/evm/ocr2vrf.go | 6 +- core/services/relay/evm/request_round_db.go | 2 +- .../relay/evm/request_round_tracker.go | 2 +- .../relay/evm/request_round_tracker_test.go | 2 +- .../0177_add_ocr_protocol_state.sql | 12 + core/web/presenters/csa_key.go | 4 +- core/web/presenters/csa_key_test.go | 2 +- core/web/presenters/ocr_keys.go | 8 + core/web/resolver/csa_keys.go | 4 +- core/web/resolver/csa_keys_test.go | 6 +- docs/CHANGELOG.md | 5 + go.mod | 10 +- go.sum | 20 +- .../actions/automation_ocr_helpers.go | 9 +- integration-tests/actions/ocr2_helpers.go | 4 +- .../ocr2vrf_actions/ocr2vrf_config_helpers.go | 4 +- .../contracts/contract_models.go | 2 +- integration-tests/go.mod | 10 +- integration-tests/go.sum | 20 +- 103 files changed, 1057 insertions(+), 585 deletions(-) delete mode 100644 core/scripts/mercury/mercury.go create mode 100644 core/services/relay/evm/mercury/reportcodec/factories_test.go create mode 100644 core/store/migrate/migrations/0177_add_ocr_protocol_state.sql diff --git a/.tool-versions b/.tool-versions index f39d48fc983..33d3adb2849 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,6 +1,6 @@ golang 1.20.4 mockery 2.28.1 -nodejs 16.13.2 +nodejs 16.16.0 postgres 13.3 helm 3.10.3 zig 0.10.1 diff --git a/README.md b/README.md index 02ea5ebf25d..4de44bf802a 100644 --- a/README.md +++ b/README.md @@ -183,7 +183,7 @@ If you do end up modifying the migrations for the database, you will need to rer 7. Run tests: ```bash -go test -tags test ./… +go test -tags test ./... ``` #### Notes diff --git a/core/chains/evm/logpoller/log_poller.go b/core/chains/evm/logpoller/log_poller.go index 7f5d3b00244..135b02b7d91 100644 --- a/core/chains/evm/logpoller/log_poller.go +++ b/core/chains/evm/logpoller/log_poller.go @@ -309,6 +309,7 @@ func (lp *logPoller) Filter(from, to *big.Int, bh *common.Hash) ethereum.FilterQ // is already in progress, the replay will continue and ErrReplayInProgress will be returned. If the client needs a // guarantee that the replay is complete before proceeding, it should either avoid cancelling or retry until nil is returned func (lp *logPoller) Replay(ctx context.Context, fromBlock int64) error { + lp.lggr.Debugf("Replaying from block %d", fromBlock) latest, err := lp.ec.HeadByNumber(ctx, nil) if err != nil { return err diff --git a/core/cmd/csa_keys_commands_test.go b/core/cmd/csa_keys_commands_test.go index 07f5fb6def5..23749476ac8 100644 --- a/core/cmd/csa_keys_commands_test.go +++ b/core/cmd/csa_keys_commands_test.go @@ -65,7 +65,7 @@ func TestShell_ListCSAKeys(t *testing.T) { assert.Nil(t, client.ListCSAKeys(cltest.EmptyCLIContext())) require.Equal(t, 1, len(r.Renders)) keys := *r.Renders[0].(*cmd.CSAKeyPresenters) - assert.Equal(t, key.PublicKeyString(), keys[0].PubKey) + assert.Equal(t, fmt.Sprintf("csa_%s", key.PublicKeyString()), keys[0].PubKey) } func TestShell_CreateCSAKey(t *testing.T) { diff --git a/core/internal/features/ocr2/features_ocr2_test.go b/core/internal/features/ocr2/features_ocr2_test.go index 8cad6cb671b..f1f04c52acf 100644 --- a/core/internal/features/ocr2/features_ocr2_test.go +++ b/core/internal/features/ocr2/features_ocr2_test.go @@ -25,8 +25,8 @@ import ( "github.com/smartcontractkit/libocr/commontypes" "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" testoffchainaggregator2 "github.com/smartcontractkit/libocr/gethwrappers2/testocr2aggregator" - confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" - ocrtypes2 "github.com/smartcontractkit/libocr/offchainreporting2/types" + confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + ocrtypes2 "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/exp/maps" @@ -295,6 +295,7 @@ fromBlock = %d "0": {}, "10": {}, "20": {}, "30": {}, } for i := 0; i < 4; i++ { + s := i err = apps[i].Start(testutils.Context(t)) require.NoError(t, err) @@ -305,7 +306,9 @@ fromBlock = %d _, err := res.Write([]byte(`{"data":10}`)) require.NoError(t, err) })) - t.Cleanup(slowServers[i].Close) + t.Cleanup(func() { + slowServers[s].Close() + }) servers[i] = httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { b, err := io.ReadAll(req.Body) require.NoError(t, err) @@ -320,7 +323,9 @@ fromBlock = %d _, err = res.Write([]byte(`{"data":10}`)) require.NoError(t, err) })) - t.Cleanup(servers[i].Close) + t.Cleanup(func() { + servers[s].Close() + }) u, _ := url.Parse(servers[i].URL) require.NoError(t, apps[i].BridgeORM().CreateBridgeType(&bridges.BridgeType{ Name: bridges.BridgeName(fmt.Sprintf("bridge%d", i)), @@ -559,6 +564,7 @@ chainID = 1337 "0": {}, "10": {}, "20": {}, "30": {}, } for i := 0; i < 4; i++ { + s := i err = apps[i].Start(testutils.Context(t)) require.NoError(t, err) @@ -569,7 +575,9 @@ chainID = 1337 _, err := res.Write([]byte(`{"data":10}`)) require.NoError(t, err) })) - t.Cleanup(slowServers[i].Close) + t.Cleanup(func() { + slowServers[s].Close() + }) servers[i] = httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { b, err := io.ReadAll(req.Body) require.NoError(t, err) @@ -584,7 +592,9 @@ chainID = 1337 _, err = res.Write([]byte(`{"data":10}`)) require.NoError(t, err) })) - t.Cleanup(servers[i].Close) + t.Cleanup(func() { + servers[s].Close() + }) u, _ := url.Parse(servers[i].URL) require.NoError(t, apps[i].BridgeORM().CreateBridgeType(&bridges.BridgeType{ Name: bridges.BridgeName(fmt.Sprintf("bridge%d", i)), diff --git a/core/scripts/chaincli/handler/keeper_deployer.go b/core/scripts/chaincli/handler/keeper_deployer.go index 0890b6b953d..84d1ba45086 100644 --- a/core/scripts/chaincli/handler/keeper_deployer.go +++ b/core/scripts/chaincli/handler/keeper_deployer.go @@ -12,8 +12,8 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - ocr2config "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" - ocr2types "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocr2config "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/types" "github.com/umbracle/ethgo/abi" diff --git a/core/scripts/chaincli/handler/ocr2_config.go b/core/scripts/chaincli/handler/ocr2_config.go index de55d281642..3ad4b177c25 100644 --- a/core/scripts/chaincli/handler/ocr2_config.go +++ b/core/scripts/chaincli/handler/ocr2_config.go @@ -11,7 +11,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/olekukonko/tablewriter" - "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" + "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" plugintypes "github.com/smartcontractkit/ocr2keepers/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper2_0" diff --git a/core/scripts/chaincli/handler/report.go b/core/scripts/chaincli/handler/report.go index 36a8bcccedb..6ab0858730e 100644 --- a/core/scripts/chaincli/handler/report.go +++ b/core/scripts/chaincli/handler/report.go @@ -16,7 +16,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/rpc" "github.com/olekukonko/tablewriter" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/ocr2keepers/pkg/chain" plugintypes "github.com/smartcontractkit/ocr2keepers/pkg/types" diff --git a/core/scripts/functions/src/generate_ocr2_config_cmd.go b/core/scripts/functions/src/generate_ocr2_config_cmd.go index 3911115b8c9..f760d843a09 100644 --- a/core/scripts/functions/src/generate_ocr2_config_cmd.go +++ b/core/scripts/functions/src/generate_ocr2_config_cmd.go @@ -13,8 +13,8 @@ import ( "github.com/ethereum/go-ethereum/common" - "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" - "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" helpers "github.com/smartcontractkit/chainlink/core/scripts/common" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions/config" diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 501643ece62..158700c7e21 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -17,9 +17,9 @@ require ( github.com/pelletier/go-toml/v2 v2.0.8 github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 - github.com/smartcontractkit/libocr v0.0.0-20230525150148-a75f6e244bb3 - github.com/smartcontractkit/ocr2keepers v0.6.15 - github.com/smartcontractkit/ocr2vrf v0.0.0-20230605190626-969219bf1df9 + github.com/smartcontractkit/libocr v0.0.0-20230606215712-82b910bef5c1 + github.com/smartcontractkit/ocr2keepers v0.6.16-0.20230607110245-0809f2a4a41d + github.com/smartcontractkit/ocr2vrf v0.0.0-20230607140106-3de6d0aed120 github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb github.com/spf13/cobra v1.6.0 github.com/spf13/viper v1.14.0 @@ -286,10 +286,10 @@ require ( github.com/scylladb/go-reflectx v1.0.1 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.22.12 // indirect - github.com/sirupsen/logrus v1.9.0 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/caigo v0.0.0-20230530082629-53a5a4bdb25e // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230525203711-20bed74ac906 // indirect - github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230606192102-72eb65f16e5e // indirect + github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230606234201-cca3103bf8a6 // indirect github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230531071550-c058f7c3964f // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.0-20230601080524-3d8186742482 // indirect github.com/smartcontractkit/wsrpc v0.7.2 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index e9da8b0041a..1de2774c761 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1379,24 +1379,24 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartcontractkit/caigo v0.0.0-20230530082629-53a5a4bdb25e h1:XY8DncHICYQ1WDVpoXM7Tv3tztNHa1/DctDlSmqgU10= github.com/smartcontractkit/caigo v0.0.0-20230530082629-53a5a4bdb25e/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230525203711-20bed74ac906 h1:u7Lw7oqLEjADlJPJQnzlCLNSbj038QttaKY0lCa3V78= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230525203711-20bed74ac906/go.mod h1:MH+MRJaG4SZAbRq5g7//AFY9H9sg5+lLDQnm85aHP6A= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230606192102-72eb65f16e5e h1:wgVIpUakH0bwHVK2TnPxIXLU70X8iwyXzRvVVCtQHnE= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230606192102-72eb65f16e5e/go.mod h1:mCOS1RSmUcQwbxEChrNrOa2N/93rVU0WRP+JGfuPtPc= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230606234201-cca3103bf8a6 h1:dQG7RYxvMk9b/oJZ7sPDdm8oloFnH+YO6qLvto4Y7Nc= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230606234201-cca3103bf8a6/go.mod h1:MfZBUifutkv3aK7abyw5YmTJbqt8iFwcQDFikrxC/uI= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230531071550-c058f7c3964f h1:XtumoxAyCO4JnDbhUjD+BT3H3NohfpVG3IOLKWE5m+k= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230531071550-c058f7c3964f/go.mod h1:km46XAo6xebV4Q+WyRFfo3E2t80YqTkegJM4FEfo5/Y= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.0-20230601080524-3d8186742482 h1:ZblU/X27pIHAZ7c/37TZf7ykZ4jkfVUmvIcchyO2rnw= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.0-20230601080524-3d8186742482/go.mod h1:bQmQtng05ueHYaLRKtAr1/LCaUWvOaE5ch008u5yJ+M= -github.com/smartcontractkit/libocr v0.0.0-20230525150148-a75f6e244bb3 h1:/Gel/U5eIZ/BGGr25OrHaXiVDTAJ5DYX5+UlXp3q7Gg= -github.com/smartcontractkit/libocr v0.0.0-20230525150148-a75f6e244bb3/go.mod h1:5JnCHuYgmIP9ZyXzgAfI5Iwu0WxBtBKp+ApeT5o1Cjw= -github.com/smartcontractkit/ocr2keepers v0.6.15 h1:dFhg+qT+tc6b3G8N4qnAHuHe8N0m8CSA8g4YGSeTGPo= -github.com/smartcontractkit/ocr2keepers v0.6.15/go.mod h1:gqIksJFzdXFsHfGdCWm1uTxbwvAltgcwcaqIgAStC1A= -github.com/smartcontractkit/ocr2vrf v0.0.0-20230605190626-969219bf1df9 h1:qLzqm5g2fzkvaDRE3LB75t9a0BRo+5a8yabawoBxlMA= -github.com/smartcontractkit/ocr2vrf v0.0.0-20230605190626-969219bf1df9/go.mod h1:AZbOisIoA3cOUku8suZ+KWBnzbRiafmhi7UKiXoezrk= +github.com/smartcontractkit/libocr v0.0.0-20230606215712-82b910bef5c1 h1:caG9BWjnCxN/HPBA5ltDGadDraZAsjGIct4S8lh8D5c= +github.com/smartcontractkit/libocr v0.0.0-20230606215712-82b910bef5c1/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= +github.com/smartcontractkit/ocr2keepers v0.6.16-0.20230607110245-0809f2a4a41d h1:AVpFTCA9lyB0qdBP/kADxMka6QBHUtqL6PkeA7mtLK0= +github.com/smartcontractkit/ocr2keepers v0.6.16-0.20230607110245-0809f2a4a41d/go.mod h1:ueL+ADZm47x+UpfHAY9bd0soStL9YDwbUN265AJF788= +github.com/smartcontractkit/ocr2vrf v0.0.0-20230607140106-3de6d0aed120 h1:iG9aRJxfZRxlPNKPqbUioEHyfvHvp1B1V11Fo+BK4pc= +github.com/smartcontractkit/ocr2vrf v0.0.0-20230607140106-3de6d0aed120/go.mod h1:AT1OrDDOCd8vzmMsCnA70N+tZdq9AbdZAiAw+gQq260= github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb h1:OMaBUb4X9IFPLbGbCHsMU+kw/BPCrewaVwWGIBc0I4A= github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb/go.mod h1:HNUu4cJekUdsJbwRBCiOybtkPJEfGRELQPe2tkoDEyk= github.com/smartcontractkit/wsrpc v0.7.2 h1:iBXzMeg7vc5YoezIQBq896y25BARw7OKbhrb6vPbtRQ= diff --git a/core/scripts/mercury/mercury.go b/core/scripts/mercury/mercury.go deleted file mode 100644 index 9f3e57156e7..00000000000 --- a/core/scripts/mercury/mercury.go +++ /dev/null @@ -1,48 +0,0 @@ -package main - -import ( - "fmt" - "net/http" - "sync/atomic" - "time" -) - -var reportsCount uint64 - -func handleReports(w http.ResponseWriter, req *http.Request) { - if req.Method != "POST" { - fmt.Printf("%s is not supported\n", req.Method) - return - } - - atomic.AddUint64(&reportsCount, 1) - - // fmt.Println("POST /reports called") - - // b, err := io.ReadAll(req.Body) - // if err != nil { - // fmt.Println("error reading body", err) - // } - // fmt.Printf("RAW BINARY received body: 0x%x\n", b) - // fmt.Printf("STRING received body %s\n", b) -} - -func main() { - http.HandleFunc("/reports", handleReports) - - fmt.Println("running server on :3000") - go func() { - ticker := time.NewTicker(1 * time.Second) - for { - <-ticker.C - c := atomic.SwapUint64(&reportsCount, 0) - fmt.Printf("%s - POST /reports called %d times\n", time.Now().String(), c) - } - }() - - // nolint - err := http.ListenAndServe(":3000", nil) - if err != nil { - panic(err) - } -} diff --git a/core/scripts/ocr2vrf/util.go b/core/scripts/ocr2vrf/util.go index 78ff44d4899..9948ab619cc 100644 --- a/core/scripts/ocr2vrf/util.go +++ b/core/scripts/ocr2vrf/util.go @@ -14,8 +14,8 @@ import ( "github.com/ethereum/go-ethereum/common" gethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" - "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" - "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/ocr2vrf/altbn_128" "github.com/smartcontractkit/ocr2vrf/dkg" "github.com/smartcontractkit/ocr2vrf/ocr2vrf" diff --git a/core/services/keystore/keys/ocr2key/cosmos_keyring.go b/core/services/keystore/keys/ocr2key/cosmos_keyring.go index 20bdd445176..490fa0cbfcb 100644 --- a/core/services/keystore/keys/ocr2key/cosmos_keyring.go +++ b/core/services/keystore/keys/ocr2key/cosmos_keyring.go @@ -7,8 +7,8 @@ import ( "github.com/hdevalence/ed25519consensus" "github.com/pkg/errors" - "github.com/smartcontractkit/libocr/offchainreporting2/chains/evmutil" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "golang.org/x/crypto/blake2s" "github.com/smartcontractkit/chainlink/v2/core/utils" diff --git a/core/services/keystore/keys/ocr2key/cosmos_keyring_test.go b/core/services/keystore/keys/ocr2key/cosmos_keyring_test.go index 235f82ef125..283ba43a79a 100644 --- a/core/services/keystore/keys/ocr2key/cosmos_keyring_test.go +++ b/core/services/keystore/keys/ocr2key/cosmos_keyring_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/stretchr/testify/require" ) diff --git a/core/services/keystore/keys/ocr2key/evm_keyring.go b/core/services/keystore/keys/ocr2key/evm_keyring.go index 16da3afc60b..cc4076391b4 100644 --- a/core/services/keystore/keys/ocr2key/evm_keyring.go +++ b/core/services/keystore/keys/ocr2key/evm_keyring.go @@ -7,8 +7,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" - "github.com/smartcontractkit/libocr/offchainreporting2/chains/evmutil" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ) var _ ocrtypes.OnchainKeyring = &evmKeyring{} diff --git a/core/services/keystore/keys/ocr2key/evm_keyring_test.go b/core/services/keystore/keys/ocr2key/evm_keyring_test.go index 5a19c58359e..5400b0df6a0 100644 --- a/core/services/keystore/keys/ocr2key/evm_keyring_test.go +++ b/core/services/keystore/keys/ocr2key/evm_keyring_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ) func TestEVMKeyring_SignVerify(t *testing.T) { diff --git a/core/services/keystore/keys/ocr2key/generic_key_bundle.go b/core/services/keystore/keys/ocr2key/generic_key_bundle.go index 5fd8aa947b1..be401becfb3 100644 --- a/core/services/keystore/keys/ocr2key/generic_key_bundle.go +++ b/core/services/keystore/keys/ocr2key/generic_key_bundle.go @@ -9,7 +9,7 @@ import ( "io" "github.com/pkg/errors" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" "github.com/smartcontractkit/chainlink/v2/core/store/models" diff --git a/core/services/keystore/keys/ocr2key/key_bundle.go b/core/services/keystore/keys/ocr2key/key_bundle.go index 9dc809fa7e5..79d8ad70d52 100644 --- a/core/services/keystore/keys/ocr2key/key_bundle.go +++ b/core/services/keystore/keys/ocr2key/key_bundle.go @@ -7,7 +7,7 @@ import ( "io" "github.com/ethereum/go-ethereum/crypto/secp256k1" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/starkkey" diff --git a/core/services/keystore/keys/ocr2key/offchain_keyring.go b/core/services/keystore/keys/ocr2key/offchain_keyring.go index 75e5f5c103c..9e6d8f64e03 100644 --- a/core/services/keystore/keys/ocr2key/offchain_keyring.go +++ b/core/services/keystore/keys/ocr2key/offchain_keyring.go @@ -11,7 +11,7 @@ import ( "golang.org/x/crypto/curve25519" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ) var _ ocrtypes.OffchainKeyring = &OffchainKeyring{} diff --git a/core/services/keystore/keys/ocr2key/solana_keyring.go b/core/services/keystore/keys/ocr2key/solana_keyring.go index ea97653cc07..aebe33e1d19 100644 --- a/core/services/keystore/keys/ocr2key/solana_keyring.go +++ b/core/services/keystore/keys/ocr2key/solana_keyring.go @@ -7,8 +7,8 @@ import ( "io" "github.com/ethereum/go-ethereum/crypto" - "github.com/smartcontractkit/libocr/offchainreporting2/chains/evmutil" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ) var _ ocrtypes.OnchainKeyring = &solanaKeyring{} diff --git a/core/services/keystore/keys/ocr2key/solana_keyring_test.go b/core/services/keystore/keys/ocr2key/solana_keyring_test.go index c2ed2677d06..f42f2c5f694 100644 --- a/core/services/keystore/keys/ocr2key/solana_keyring_test.go +++ b/core/services/keystore/keys/ocr2key/solana_keyring_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ) func TestSolanaKeyring_Sign_Verify(t *testing.T) { diff --git a/core/services/keystore/keys/starkkey/ocr2key.go b/core/services/keystore/keys/starkkey/ocr2key.go index 5342b6f2b3e..b4647a09dda 100644 --- a/core/services/keystore/keys/starkkey/ocr2key.go +++ b/core/services/keystore/keys/starkkey/ocr2key.go @@ -8,8 +8,8 @@ import ( "github.com/pkg/errors" "github.com/smartcontractkit/caigo" - "github.com/smartcontractkit/libocr/offchainreporting2/chains/evmutil" - "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ) var _ types.OnchainKeyring = &OCR2Key{} diff --git a/core/services/keystore/keys/starkkey/ocr2key_test.go b/core/services/keystore/keys/starkkey/ocr2key_test.go index b2f21aafbcb..e2d20258463 100644 --- a/core/services/keystore/keys/starkkey/ocr2key_test.go +++ b/core/services/keystore/keys/starkkey/ocr2key_test.go @@ -8,7 +8,7 @@ import ( caigotypes "github.com/smartcontractkit/caigo/types" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/core/services/ocr2/database.go b/core/services/ocr2/database.go index 3669622b818..7dd31f97e84 100644 --- a/core/services/ocr2/database.go +++ b/core/services/ocr2/database.go @@ -9,7 +9,7 @@ import ( "github.com/lib/pq" "github.com/pkg/errors" ocrcommon "github.com/smartcontractkit/libocr/commontypes" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/sqlx" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -341,3 +341,32 @@ WHERE ocr2_oracle_spec_id = $1 AND time < $2 return } + +func (d *db) ReadProtocolState(ctx context.Context, configDigest ocrtypes.ConfigDigest, key string) (value []byte, err error) { + err = d.q.GetContext(ctx, &value, ` +SELECT value FROM ocr_protocol_states +WHERE config_digest = $1 AND key = $2; +`, configDigest, key) + + if errors.Is(err, sql.ErrNoRows) { + return nil, nil + } + + err = errors.Wrapf(err, "ReadProtocolState failed for job %d", d.oracleSpecID) + + return +} + +func (d *db) WriteProtocolState(ctx context.Context, configDigest ocrtypes.ConfigDigest, key string, value []byte) (err error) { + if value == nil { + _, err = d.q.ExecContext(ctx, `DELETE FROM ocr_protocol_states WHERE config_digest = $1 AND key = $2;`, configDigest, key) + } else { + _, err = d.q.ExecContext(ctx, ` +INSERT INTO ocr_protocol_states (config_digest, key, value) VALUES ($1, $2, $3) +ON CONFLICT (config_digest, key) DO UPDATE SET value = $3;`, configDigest, key, value) + } + + err = errors.Wrapf(err, "WriteProtocolState failed for job %d", d.oracleSpecID) + + return +} diff --git a/core/services/ocr2/database_test.go b/core/services/ocr2/database_test.go index 9834b331114..24bfbc73562 100644 --- a/core/services/ocr2/database_test.go +++ b/core/services/ocr2/database_test.go @@ -7,8 +7,9 @@ import ( medianconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/median/config" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/sqlx" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" @@ -414,3 +415,75 @@ func Test_DB_PendingTransmissions(t *testing.T) { require.Len(t, m, 1) }) } + +func Test_DB_ReadWriteProtocolState(t *testing.T) { + sqlDB := setupDB(t) + + cfg := configtest.NewTestGeneralConfig(t) + + lggr := logger.TestLogger(t) + db := ocr2.NewDB(sqlDB, 0, lggr, cfg.Database()) + cd1 := testhelpers.MakeConfigDigest(t) + cd2 := testhelpers.MakeConfigDigest(t) + ctx := testutils.Context(t) + + assertCount := func(expected int64) { + testutils.AssertCount(t, sqlDB, "ocr_protocol_states", expected) + } + + t.Run("stores and retrieves protocol state", func(t *testing.T) { + assertCount(0) + + err := db.WriteProtocolState(ctx, cd1, "key1", []byte{1}) + assert.NoError(t, err) + + assertCount(1) + + err = db.WriteProtocolState(ctx, cd2, "key1", []byte{2}) + assert.NoError(t, err) + + assertCount(2) + + err = db.WriteProtocolState(ctx, cd2, "key2", []byte{3}) + assert.NoError(t, err) + + assertCount(3) + + // should overwrite + err = db.WriteProtocolState(ctx, cd2, "key2", []byte{4}) + assert.NoError(t, err) + + val, err := db.ReadProtocolState(ctx, cd1, "key1") + assert.NoError(t, err) + assert.Equal(t, []byte{1}, val) + + val, err = db.ReadProtocolState(ctx, cd2, "key1") + assert.NoError(t, err) + assert.Equal(t, []byte{2}, val) + + val, err = db.ReadProtocolState(ctx, cd2, "key2") + assert.NoError(t, err) + assert.Equal(t, []byte{4}, val) + + // should write empty value + err = db.WriteProtocolState(ctx, cd1, "key1", []byte{}) + assert.NoError(t, err) + + val, err = db.ReadProtocolState(ctx, cd1, "key1") + assert.NoError(t, err) + assert.Equal(t, []byte{}, val) + + assertCount(3) + + // should delete value + err = db.WriteProtocolState(ctx, cd1, "key1", nil) + assert.NoError(t, err) + + assertCount(2) + + // trying to read missing value yields nil + val, err = db.ReadProtocolState(ctx, cd1, "key1") + assert.NoError(t, err) + assert.Nil(t, val) + }) +} diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index 1f949cc9085..2c819f5a116 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -10,8 +10,9 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" - libocr2 "github.com/smartcontractkit/libocr/offchainreporting2" - ocr2types "github.com/smartcontractkit/libocr/offchainreporting2/types" + + libocr2 "github.com/smartcontractkit/libocr/offchainreporting2plus" + ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg" "github.com/smartcontractkit/ocr2vrf/altbn_128" dkgpkg "github.com/smartcontractkit/ocr2vrf/dkg" @@ -20,6 +21,7 @@ import ( "github.com/smartcontractkit/chainlink-relay/pkg/loop" "github.com/smartcontractkit/chainlink-relay/pkg/types" + "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/chains/evm" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -273,6 +275,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { if err2 != nil { return nil, errors.Wrap(err2, "ServicesForSpec failed to get chainID") } + lggr = logger.Sugared(lggr.With("evmChainID", chainID)) chain, err2 := d.chainSet.Get(big.NewInt(chainID)) if err2 != nil { return nil, errors.Wrap(err2, "ServicesForSpec failed to get chainset") @@ -299,6 +302,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { } } spec.RelayConfig["effectiveTransmitterID"] = effectiveTransmitterID + lggr = logger.Sugared(lggr.With("transmitterID", transmitterID)) ocrDB := NewDB(d.db, spec.ID, lggr, d.cfg.Database()) peerWrapper := d.peerWrapper @@ -372,7 +376,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { return nil, errors.Wrap(err2, "ServicesForSpec failed to get chain") } - oracleArgsNoPlugin := libocr2.OracleArgs{ + oracleArgsNoPlugin := libocr2.MercuryOracleArgs{ BinaryNetworkEndpointFactory: peerWrapper.Peer2, V2Bootstrappers: bootstrapPeers, ContractTransmitter: mercuryProvider.ContractTransmitter(), @@ -387,7 +391,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { } chEnhancedTelem := make(chan ocrcommon.EnhancedTelemetryMercuryData, 100) - mercuryServices, err2 := mercury.NewServices(jb, mercuryProvider, d.pipelineRunner, runResults, lggr, oracleArgsNoPlugin, d.cfg.JobPipeline(), chEnhancedTelem, chain) + mercuryServices, err2 := mercury.NewServices(jb, mercuryProvider, d.pipelineRunner, runResults, lggr, oracleArgsNoPlugin, d.cfg.JobPipeline(), chEnhancedTelem, chain, mercuryProvider.ContractTransmitter()) if ocrcommon.ShouldCollectEnhancedTelemetryMercury(&jb) { enhancedTelemService := ocrcommon.NewEnhancedTelemetryService(&jb, chEnhancedTelem, make(chan struct{}), d.monitoringEndpointGen.GenMonitoringEndpoint(spec.FeedID.String(), synchronization.EnhancedEAMercury), lggr.Named("Enhanced Telemetry Mercury")) @@ -397,7 +401,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { return mercuryServices, err2 case job.Median: - oracleArgsNoPlugin := libocr2.OracleArgs{ + oracleArgsNoPlugin := libocr2.OCR2OracleArgs{ BinaryNetworkEndpointFactory: peerWrapper.Peer2, V2Bootstrappers: bootstrapPeers, Database: ocrDB, @@ -445,7 +449,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { return nil, err2 } noopMonitoringEndpoint := telemetry.NoopAgent{} - oracleArgsNoPlugin := libocr2.OracleArgs{ + oracleArgsNoPlugin := libocr2.OCR2OracleArgs{ BinaryNetworkEndpointFactory: peerWrapper.Peer2, V2Bootstrappers: bootstrapPeers, ContractTransmitter: dkgProvider.ContractTransmitter(), @@ -746,7 +750,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job) ([]job.ServiceCtx, error) { return nil, err2 } - sharedOracleArgs := libocr2.OracleArgs{ + sharedOracleArgs := libocr2.OCR2OracleArgs{ BinaryNetworkEndpointFactory: peerWrapper.Peer2, V2Bootstrappers: bootstrapPeers, ContractTransmitter: functionsProvider.ContractTransmitter(), diff --git a/core/services/ocr2/plugins/dkg/persistence/db.go b/core/services/ocr2/plugins/dkg/persistence/db.go index 794cc3c0c07..75fb3b391fa 100644 --- a/core/services/ocr2/plugins/dkg/persistence/db.go +++ b/core/services/ocr2/plugins/dkg/persistence/db.go @@ -12,7 +12,7 @@ import ( "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ocr2vrftypes "github.com/smartcontractkit/ocr2vrf/types" "github.com/smartcontractkit/ocr2vrf/types/hash" "github.com/smartcontractkit/sqlx" diff --git a/core/services/ocr2/plugins/dkg/plugin.go b/core/services/ocr2/plugins/dkg/plugin.go index 67b554eb9ff..540518b553c 100644 --- a/core/services/ocr2/plugins/dkg/plugin.go +++ b/core/services/ocr2/plugins/dkg/plugin.go @@ -8,7 +8,7 @@ import ( "github.com/pkg/errors" "github.com/smartcontractkit/libocr/commontypes" - libocr2 "github.com/smartcontractkit/libocr/offchainreporting2" + libocr2 "github.com/smartcontractkit/libocr/offchainreporting2plus" "github.com/smartcontractkit/ocr2vrf/altbn_128" "github.com/smartcontractkit/ocr2vrf/dkg" "github.com/smartcontractkit/sqlx" @@ -32,7 +32,7 @@ func NewDKGServices( dkgSignKs keystore.DKGSign, dkgEncryptKs keystore.DKGEncrypt, ethClient evmclient.Client, - oracleArgsNoPlugin libocr2.OracleArgs, + oracleArgsNoPlugin libocr2.OCR2OracleArgs, db *sqlx.DB, qConfig pg.QConfig, chainID *big.Int, diff --git a/core/services/ocr2/plugins/functions/integration_tests/functions_integration_test.go b/core/services/ocr2/plugins/functions/integration_tests/functions_integration_test.go index d799bbe2db9..0f6eaead783 100644 --- a/core/services/ocr2/plugins/functions/integration_tests/functions_integration_test.go +++ b/core/services/ocr2/plugins/functions/integration_tests/functions_integration_test.go @@ -10,7 +10,7 @@ import ( "github.com/onsi/gomega" "github.com/smartcontractkit/libocr/commontypes" - confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" + confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" diff --git a/core/services/ocr2/plugins/functions/integration_tests/internal/testutils.go b/core/services/ocr2/plugins/functions/integration_tests/internal/testutils.go index 3d203ae5e03..aba2abfa380 100644 --- a/core/services/ocr2/plugins/functions/integration_tests/internal/testutils.go +++ b/core/services/ocr2/plugins/functions/integration_tests/internal/testutils.go @@ -18,8 +18,8 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/smartcontractkit/libocr/commontypes" - confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" - ocrtypes2 "github.com/smartcontractkit/libocr/offchainreporting2/types" + confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + ocrtypes2 "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/v2/core/assets" diff --git a/core/services/ocr2/plugins/functions/plugin.go b/core/services/ocr2/plugins/functions/plugin.go index 1ab9f400a45..a2a22f1ec5a 100644 --- a/core/services/ocr2/plugins/functions/plugin.go +++ b/core/services/ocr2/plugins/functions/plugin.go @@ -11,7 +11,7 @@ import ( "golang.org/x/exp/slices" "github.com/smartcontractkit/libocr/commontypes" - libocr2 "github.com/smartcontractkit/libocr/offchainreporting2" + libocr2 "github.com/smartcontractkit/libocr/offchainreporting2plus" "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/chains/evm" @@ -48,7 +48,7 @@ const ( ) // Create all OCR2 plugin Oracles and all extra services needed to run a Functions job. -func NewFunctionsServices(sharedOracleArgs *libocr2.OracleArgs, conf *FunctionsServicesConfig) ([]job.ServiceCtx, error) { +func NewFunctionsServices(sharedOracleArgs *libocr2.OCR2OracleArgs, conf *FunctionsServicesConfig) ([]job.ServiceCtx, error) { pluginORM := functions.NewORM(conf.DB, conf.Lggr, conf.OCR2JobConfig, common.HexToAddress(conf.ContractID)) var pluginConfig config.PluginConfig diff --git a/core/services/ocr2/plugins/functions/reporting.go b/core/services/ocr2/plugins/functions/reporting.go index 7eb33c8da42..1e6e5c2f6ae 100644 --- a/core/services/ocr2/plugins/functions/reporting.go +++ b/core/services/ocr2/plugins/functions/reporting.go @@ -10,7 +10,7 @@ import ( "google.golang.org/protobuf/proto" "github.com/smartcontractkit/libocr/commontypes" - "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink/v2/core/services/functions" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions/config" diff --git a/core/services/ocr2/plugins/functions/reporting_test.go b/core/services/ocr2/plugins/functions/reporting_test.go index 6deb7c4b2fe..225d5f78d39 100644 --- a/core/services/ocr2/plugins/functions/reporting_test.go +++ b/core/services/ocr2/plugins/functions/reporting_test.go @@ -9,7 +9,7 @@ import ( "google.golang.org/protobuf/proto" "github.com/smartcontractkit/libocr/commontypes" - "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" diff --git a/core/services/ocr2/plugins/median/plugin.go b/core/services/ocr2/plugins/median/plugin.go index e0ecbc3558f..ea9a43795c4 100644 --- a/core/services/ocr2/plugins/median/plugin.go +++ b/core/services/ocr2/plugins/median/plugin.go @@ -6,14 +6,11 @@ import ( "fmt" "time" - libocr "github.com/smartcontractkit/libocr/offchainreporting2" - "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" - "github.com/smartcontractkit/chainlink-relay/pkg/loop" "github.com/smartcontractkit/chainlink-relay/pkg/types" - - "github.com/smartcontractkit/chainlink/v2/plugins" + "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median" + libocr "github.com/smartcontractkit/libocr/offchainreporting2plus" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" v2 "github.com/smartcontractkit/chainlink/v2/core/config/v2" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -23,6 +20,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/core/utils" + "github.com/smartcontractkit/chainlink/v2/plugins" ) type MedianConfig interface { @@ -54,7 +52,7 @@ func NewMedianServices(ctx context.Context, pipelineRunner pipeline.Runner, runResults chan pipeline.Run, lggr logger.Logger, - argsNoPlugin libocr.OracleArgs, + argsNoPlugin libocr.OCR2OracleArgs, cfg MedianConfig, chEnhancedTelem chan ocrcommon.EnhancedTelemetryData, errorLog loop.ErrorLog, diff --git a/core/services/ocr2/plugins/mercury/config/config.go b/core/services/ocr2/plugins/mercury/config/config.go index d0ebfb520b6..d342828129f 100644 --- a/core/services/ocr2/plugins/mercury/config/config.go +++ b/core/services/ocr2/plugins/mercury/config/config.go @@ -17,6 +17,11 @@ import ( type PluginConfig struct { RawServerURL string `json:"serverURL" toml:"serverURL"` ServerPubKey utils.PlainHexBytes `json:"serverPubKey" toml:"serverPubKey"` + // InitialBlockNumber allows to set a custom "validFromBlockNumber" for + // the first ever report in the case of a brand new feed, where the mercury + // server does not have any previous reports. For a brand new feed, this + // effectively sets the "first" validFromBlockNumber. + InitialBlockNumber int64 `json:"initialBlockNumber" toml:"initialBlockNumber"` } func ValidatePluginConfig(config PluginConfig) (merr error) { diff --git a/core/services/ocr2/plugins/mercury/integration_test.go b/core/services/ocr2/plugins/mercury/integration_test.go index 478161f40e9..aa19711b050 100644 --- a/core/services/ocr2/plugins/mercury/integration_test.go +++ b/core/services/ocr2/plugins/mercury/integration_test.go @@ -25,8 +25,8 @@ import ( "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/shopspring/decimal" "github.com/smartcontractkit/libocr/commontypes" - "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" - ocr2types "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/wsrpc" "github.com/smartcontractkit/wsrpc/credentials" "github.com/smartcontractkit/wsrpc/peer" @@ -78,6 +78,7 @@ func TestIntegration_Mercury(t *testing.T) { const n = 4 // number of nodes const fromBlock = 1 // cannot use zero, start from block 1 const multiplier = 100000000 + initialBlockNumber := int64(rand.Int31n(10)) testStartTimeStamp := uint32(time.Now().Unix()) // test vars @@ -119,7 +120,11 @@ func TestIntegration_Mercury(t *testing.T) { steve := testutils.MustNewSimTransactor(t) // config contract deployer and owner genesisData := core.GenesisAlloc{steve.From: {Balance: assets.Ether(1000).ToInt()}} backend := cltest.NewSimulatedBackend(t, genesisData, uint32(ethconfig.Defaults.Miner.GasCeil)) - backend.Commit() // ensure starting block number at least 1 + backend.Commit() // ensure starting block number at least 1 + // Ensure initialBlockNumber is at or below current block number + for i := 1; i < int(initialBlockNumber); i++ { + backend.Commit() + } stopMining := cltest.Mine(backend, 1*time.Second) // Should be greater than deltaRound since we cannot access old blocks on simulated blockchain t.Cleanup(stopMining) @@ -222,6 +227,7 @@ func TestIntegration_Mercury(t *testing.T) { feed.id, chainID, fromBlock, + initialBlockNumber, ) } } @@ -231,8 +237,7 @@ func TestIntegration_Mercury(t *testing.T) { onchainConfig, err := (relaymercury.StandardOnchainConfigCodec{}).Encode(c) require.NoError(t, err) - require.NoError(t, err) - signers, _, _, onchainConfig, offchainConfigVersion, offchainConfig, err := confighelper.ContractSetConfigArgsForTests( + signers, _, _, onchainConfig, offchainConfigVersion, offchainConfig, err := confighelper.ContractSetConfigArgsForTestsMercuryV02( 2*time.Second, // DeltaProgress 20*time.Second, // DeltaResend 100*time.Millisecond, // DeltaRound @@ -242,11 +247,7 @@ func TestIntegration_Mercury(t *testing.T) { []int{len(nodes)}, // S oracles, []byte{}, // reportingPluginConfig []byte, - 0, // Max duration query 250*time.Millisecond, // Max duration observation - 250*time.Millisecond, // MaxDurationReport - 250*time.Millisecond, // MaxDurationShouldAcceptFinalizedReport - 250*time.Millisecond, // MaxDurationShouldTransmitAcceptedReport int(f), // f onchainConfig, ) @@ -294,122 +295,130 @@ func TestIntegration_Mercury(t *testing.T) { backend.Commit() } - // Expect at least one report per feed from each oracle - seen := make(map[[32]byte]map[credentials.StaticSizedPublicKey]struct{}) - for i := range feeds { - // feedID will be deleted when all n oracles have reported - seen[feeds[i].id] = make(map[credentials.StaticSizedPublicKey]struct{}, n) - } - - for req := range reqs { - v := make(map[string]interface{}) - err := mercury.PayloadTypes.UnpackIntoMap(v, req.req.Payload) - require.NoError(t, err) - report, exists := v["report"] - if !exists { - t.Fatalf("expected payload %#v to contain 'report'", v) + t.Run("receives at least one report per feed from each oracle when EAs are at 100% reliability", func(t *testing.T) { + // Expect at least one report per feed from each oracle + seen := make(map[[32]byte]map[credentials.StaticSizedPublicKey]struct{}) + for i := range feeds { + // feedID will be deleted when all n oracles have reported + seen[feeds[i].id] = make(map[credentials.StaticSizedPublicKey]struct{}, n) } - reportElems := make(map[string]interface{}) - err = reportcodec.ReportTypes.UnpackIntoMap(reportElems, report.([]byte)) - require.NoError(t, err) - feedID := ([32]byte)(reportElems["feedId"].([32]uint8)) - feed, exists := feedM[feedID] - require.True(t, exists) + for req := range reqs { + v := make(map[string]interface{}) + err := mercury.PayloadTypes.UnpackIntoMap(v, req.req.Payload) + require.NoError(t, err) + report, exists := v["report"] + if !exists { + t.Fatalf("expected payload %#v to contain 'report'", v) + } + reportElems := make(map[string]interface{}) + err = reportcodec.ReportTypes.UnpackIntoMap(reportElems, report.([]byte)) + require.NoError(t, err) + + feedID := ([32]byte)(reportElems["feedId"].([32]uint8)) + feed, exists := feedM[feedID] + require.True(t, exists) - if _, exists := seen[feedID]; !exists { - continue // already saw all oracles for this feed - } + if _, exists := seen[feedID]; !exists { + continue // already saw all oracles for this feed + } - num, err := (&reportcodec.EVMReportCodec{}).CurrentBlockNumFromReport(ocr2types.Report(report.([]byte))) - require.NoError(t, err) - currentBlock, err := backend.BlockByNumber(testutils.Context(t), nil) - require.NoError(t, err) + num, err := (&reportcodec.EVMReportCodec{}).CurrentBlockNumFromReport(ocr2types.Report(report.([]byte))) + require.NoError(t, err) + currentBlock, err := backend.BlockByNumber(testutils.Context(t), nil) + require.NoError(t, err) - assert.GreaterOrEqual(t, currentBlock.Number().Int64(), num) - - expectedBm := feed.baseBenchmarkPrice - expectedBid := feed.baseBid - expectedAsk := feed.baseAsk - - assert.GreaterOrEqual(t, int(reportElems["observationsTimestamp"].(uint32)), int(testStartTimeStamp)) - assert.InDelta(t, expectedBm.Int64(), reportElems["benchmarkPrice"].(*big.Int).Int64(), 5000000) - assert.InDelta(t, expectedBid.Int64(), reportElems["bid"].(*big.Int).Int64(), 5000000) - assert.InDelta(t, expectedAsk.Int64(), reportElems["ask"].(*big.Int).Int64(), 5000000) - assert.GreaterOrEqual(t, int(currentBlock.Number().Int64()), int(reportElems["currentBlockNum"].(uint64))) - assert.NotEqual(t, common.Hash{}, common.Hash(reportElems["currentBlockHash"].([32]uint8))) - assert.GreaterOrEqual(t, currentBlock.Time(), reportElems["currentBlockTimestamp"].(uint64)) - assert.LessOrEqual(t, int(reportElems["validFromBlockNum"].(uint64)), int(reportElems["currentBlockNum"].(uint64))) - - t.Logf("oracle %x reported for feed %s (0x%x)", req.pk, feed.name, feed.id) - - seen[feedID][req.pk] = struct{}{} - if len(seen[feedID]) == n { - t.Logf("all oracles reported for feed %x (0x%x)", feed.name, feed.id) - delete(seen, feedID) - if len(seen) == 0 { - break // saw all oracles; success! + assert.GreaterOrEqual(t, currentBlock.Number().Int64(), num) + + expectedBm := feed.baseBenchmarkPrice + expectedBid := feed.baseBid + expectedAsk := feed.baseAsk + + assert.GreaterOrEqual(t, int(reportElems["observationsTimestamp"].(uint32)), int(testStartTimeStamp)) + assert.InDelta(t, expectedBm.Int64(), reportElems["benchmarkPrice"].(*big.Int).Int64(), 5000000) + assert.InDelta(t, expectedBid.Int64(), reportElems["bid"].(*big.Int).Int64(), 5000000) + assert.InDelta(t, expectedAsk.Int64(), reportElems["ask"].(*big.Int).Int64(), 5000000) + assert.GreaterOrEqual(t, int(currentBlock.Number().Int64()), int(reportElems["currentBlockNum"].(uint64))) + assert.GreaterOrEqual(t, currentBlock.Time(), reportElems["currentBlockTimestamp"].(uint64)) + assert.NotEqual(t, common.Hash{}, common.Hash(reportElems["currentBlockHash"].([32]uint8))) + assert.LessOrEqual(t, int(reportElems["validFromBlockNum"].(uint64)), int(reportElems["currentBlockNum"].(uint64))) + assert.LessOrEqual(t, initialBlockNumber, int64(reportElems["validFromBlockNum"].(uint64))) + + t.Logf("oracle %x reported for feed %s (0x%x)", req.pk, feed.name, feed.id) + + seen[feedID][req.pk] = struct{}{} + if len(seen[feedID]) == n { + t.Logf("all oracles reported for feed %x (0x%x)", feed.name, feed.id) + delete(seen, feedID) + if len(seen) == 0 { + break // saw all oracles; success! + } } } - } + }) - pError.Store(20) // 20% chance of EA error - for i := range feeds { - // feedID will be deleted when all n oracles have reported - seen[feeds[i].id] = make(map[credentials.StaticSizedPublicKey]struct{}, n) - } + t.Run("receives at least one report per feed from each oracle when EAs are at 80% reliability", func(t *testing.T) { + pError.Store(20) // 20% chance of EA error - for req := range reqs { - v := make(map[string]interface{}) - err := mercury.PayloadTypes.UnpackIntoMap(v, req.req.Payload) - require.NoError(t, err) - report, exists := v["report"] - if !exists { - t.Fatalf("expected payload %#v to contain 'report'", v) + // Expect at least one report per feed from each oracle + seen := make(map[[32]byte]map[credentials.StaticSizedPublicKey]struct{}) + for i := range feeds { + // feedID will be deleted when all n oracles have reported + seen[feeds[i].id] = make(map[credentials.StaticSizedPublicKey]struct{}, n) } - reportElems := make(map[string]interface{}) - err = reportcodec.ReportTypes.UnpackIntoMap(reportElems, report.([]byte)) - require.NoError(t, err) - feedID := ([32]byte)(reportElems["feedId"].([32]uint8)) - feed, exists := feedM[feedID] - require.True(t, exists) + for req := range reqs { + v := make(map[string]interface{}) + err := mercury.PayloadTypes.UnpackIntoMap(v, req.req.Payload) + require.NoError(t, err) + report, exists := v["report"] + if !exists { + t.Fatalf("expected payload %#v to contain 'report'", v) + } + reportElems := make(map[string]interface{}) + err = reportcodec.ReportTypes.UnpackIntoMap(reportElems, report.([]byte)) + require.NoError(t, err) + + feedID := ([32]byte)(reportElems["feedId"].([32]uint8)) + feed, exists := feedM[feedID] + require.True(t, exists) - if _, exists := seen[feedID]; !exists { - continue // already saw all oracles for this feed - } + if _, exists := seen[feedID]; !exists { + continue // already saw all oracles for this feed + } - num, err := (&reportcodec.EVMReportCodec{}).CurrentBlockNumFromReport(ocr2types.Report(report.([]byte))) - require.NoError(t, err) - currentBlock, err := backend.BlockByNumber(testutils.Context(t), nil) - require.NoError(t, err) + num, err := (&reportcodec.EVMReportCodec{}).CurrentBlockNumFromReport(ocr2types.Report(report.([]byte))) + require.NoError(t, err) + currentBlock, err := backend.BlockByNumber(testutils.Context(t), nil) + require.NoError(t, err) - assert.GreaterOrEqual(t, currentBlock.Number().Int64(), num) - - expectedBm := feed.baseBenchmarkPrice - expectedBid := feed.baseBid - expectedAsk := feed.baseAsk - - assert.GreaterOrEqual(t, int(reportElems["observationsTimestamp"].(uint32)), int(testStartTimeStamp)) - assert.InDelta(t, expectedBm.Int64(), reportElems["benchmarkPrice"].(*big.Int).Int64(), 5000000) - assert.InDelta(t, expectedBid.Int64(), reportElems["bid"].(*big.Int).Int64(), 5000000) - assert.InDelta(t, expectedAsk.Int64(), reportElems["ask"].(*big.Int).Int64(), 5000000) - assert.GreaterOrEqual(t, int(currentBlock.Number().Int64()), int(reportElems["currentBlockNum"].(uint64))) - assert.NotEqual(t, common.Hash{}, common.Hash(reportElems["currentBlockHash"].([32]uint8))) - assert.GreaterOrEqual(t, currentBlock.Time(), reportElems["currentBlockTimestamp"].(uint64)) - assert.LessOrEqual(t, int(reportElems["validFromBlockNum"].(uint64)), int(reportElems["currentBlockNum"].(uint64))) - - t.Logf("oracle %x reported for feed %s (0x%x)", req.pk, feed.name, feed.id) - - seen[feedID][req.pk] = struct{}{} - if len(seen[feedID]) == n { - t.Logf("all oracles reported for feed %x (0x%x)", feed.name, feed.id) - delete(seen, feedID) - if len(seen) == 0 { - break // saw all oracles; success! + assert.GreaterOrEqual(t, currentBlock.Number().Int64(), num) + + expectedBm := feed.baseBenchmarkPrice + expectedBid := feed.baseBid + expectedAsk := feed.baseAsk + + assert.GreaterOrEqual(t, int(reportElems["observationsTimestamp"].(uint32)), int(testStartTimeStamp)) + assert.InDelta(t, expectedBm.Int64(), reportElems["benchmarkPrice"].(*big.Int).Int64(), 5000000) + assert.InDelta(t, expectedBid.Int64(), reportElems["bid"].(*big.Int).Int64(), 5000000) + assert.InDelta(t, expectedAsk.Int64(), reportElems["ask"].(*big.Int).Int64(), 5000000) + assert.GreaterOrEqual(t, int(currentBlock.Number().Int64()), int(reportElems["currentBlockNum"].(uint64))) + assert.GreaterOrEqual(t, currentBlock.Time(), reportElems["currentBlockTimestamp"].(uint64)) + assert.NotEqual(t, common.Hash{}, common.Hash(reportElems["currentBlockHash"].([32]uint8))) + assert.LessOrEqual(t, int(reportElems["validFromBlockNum"].(uint64)), int(reportElems["currentBlockNum"].(uint64))) + + t.Logf("oracle %x reported for feed %s (0x%x)", req.pk, feed.name, feed.id) + + seen[feedID][req.pk] = struct{}{} + if len(seen[feedID]) == n { + t.Logf("all oracles reported for feed %x (0x%x)", feed.name, feed.id) + delete(seen, feedID) + if len(seen) == 0 { + break // saw all oracles; success! + } } } - } + }) } var _ pb.MercuryServer = &mercuryServer{} @@ -596,6 +605,7 @@ func addMercuryJob( feedID [32]byte, chainID *big.Int, fromBlock int, + initialBlockNumber int64, ) { node.AddJob(t, fmt.Sprintf(` type = "offchainreporting2" @@ -639,6 +649,7 @@ observationSource = """ [pluginConfig] serverURL = "%[8]s" serverPubKey = "%[9]x" +initialBlockNumber = %[15]d [relayConfig] chainID = %[12]d @@ -658,5 +669,6 @@ fromBlock = %[13]d chainID, fromBlock, feedName, + initialBlockNumber, )) } diff --git a/core/services/ocr2/plugins/mercury/plugin.go b/core/services/ocr2/plugins/mercury/plugin.go index 3112d82520d..10f67921153 100644 --- a/core/services/ocr2/plugins/mercury/plugin.go +++ b/core/services/ocr2/plugins/mercury/plugin.go @@ -2,17 +2,17 @@ package mercury import ( "encoding/json" - "math/big" "github.com/pkg/errors" - libocr2 "github.com/smartcontractkit/libocr/offchainreporting2" + + libocr2 "github.com/smartcontractkit/libocr/offchainreporting2plus" relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types" + "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/mercury/config" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/promwrapper" "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury" @@ -28,10 +28,11 @@ func NewServices( pipelineRunner pipeline.Runner, runResults chan pipeline.Run, lggr logger.Logger, - argsNoPlugin libocr2.OracleArgs, + argsNoPlugin libocr2.MercuryOracleArgs, cfg Config, chEnhancedTelem chan ocrcommon.EnhancedTelemetryMercuryData, chainHeadTracker mercury.ChainHeadTracker, + fetcher relaymercury.Fetcher, ) ([]job.ServiceCtx, error) { if jb.PipelineSpec == nil { return nil, errors.New("expected job to have a non-nil PipelineSpec") @@ -54,19 +55,14 @@ func NewServices( runResults, chEnhancedTelem, chainHeadTracker, + fetcher, ) - wrappedPluginFactory := relaymercury.NewFactory( + argsNoPlugin.MercuryPluginFactory = relaymercury.NewFactory( ds, lggr, ocr2Provider.OnchainConfigCodec(), ocr2Provider.ReportCodec(), - ocr2Provider.ContractTransmitter(), ) - chain, err := jb.OCR2OracleSpec.RelayConfig.EVMChainID() - if err != nil { - return nil, errors.Wrap(err, "get chainset") - } - argsNoPlugin.ReportingPluginFactory = promwrapper.NewPromFactory(wrappedPluginFactory, "Mercury", string(jb.OCR2OracleSpec.Relay), big.NewInt(chain)) oracle, err := libocr2.NewOracle(argsNoPlugin) if err != nil { return nil, errors.WithStack(err) diff --git a/core/services/ocr2/plugins/ocr2keeper/integration_test.go b/core/services/ocr2/plugins/ocr2keeper/integration_test.go index 14f830c7f44..d06d42213ff 100644 --- a/core/services/ocr2/plugins/ocr2keeper/integration_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/integration_test.go @@ -20,8 +20,8 @@ import ( "github.com/onsi/gomega" "github.com/pkg/errors" "github.com/smartcontractkit/libocr/commontypes" - "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" - ocrTypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + ocrTypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator.go b/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator.go index 59cc6cb40e5..ef6164f9e5d 100644 --- a/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator.go +++ b/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator.go @@ -18,7 +18,7 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "github.com/smartcontractkit/libocr/commontypes" - ocr2Types "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocr2Types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/ocr2vrf/dkg" ocr2vrftypes "github.com/smartcontractkit/ocr2vrf/types" "golang.org/x/exp/maps" diff --git a/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator_test.go b/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator_test.go index dde52318f6b..31b2ad79820 100644 --- a/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator_test.go +++ b/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator_test.go @@ -20,7 +20,7 @@ import ( "github.com/stretchr/testify/require" "github.com/smartcontractkit/libocr/commontypes" - ocr2Types "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocr2Types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/ocr2vrf/dkg" "github.com/smartcontractkit/ocr2vrf/ocr2vrf" ocr2vrftypes "github.com/smartcontractkit/ocr2vrf/types" diff --git a/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go b/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go index dd04f0c9f86..91a4669d922 100644 --- a/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go +++ b/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go @@ -22,8 +22,8 @@ import ( "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/onsi/gomega" "github.com/smartcontractkit/libocr/commontypes" - confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" - ocrtypes2 "github.com/smartcontractkit/libocr/offchainreporting2/types" + confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + ocrtypes2 "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/ocr2vrf/altbn_128" ocr2dkg "github.com/smartcontractkit/ocr2vrf/dkg" "github.com/smartcontractkit/ocr2vrf/ocr2vrf" diff --git a/core/services/ocr2/plugins/plugin.go b/core/services/ocr2/plugins/plugin.go index 8455aec83a9..bb1c66da958 100644 --- a/core/services/ocr2/plugins/plugin.go +++ b/core/services/ocr2/plugins/plugin.go @@ -1,7 +1,7 @@ package plugins import ( - ocr2types "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink/v2/core/services/job" ) diff --git a/core/services/ocr2/plugins/promwrapper/factory.go b/core/services/ocr2/plugins/promwrapper/factory.go index 84fc2283bbc..c3dffa55013 100644 --- a/core/services/ocr2/plugins/promwrapper/factory.go +++ b/core/services/ocr2/plugins/promwrapper/factory.go @@ -3,7 +3,7 @@ package promwrapper import ( "math/big" - "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ) var _ types.ReportingPluginFactory = &promFactory{} diff --git a/core/services/ocr2/plugins/promwrapper/plugin.go b/core/services/ocr2/plugins/promwrapper/plugin.go index 43053f68e50..a409b5ba86c 100644 --- a/core/services/ocr2/plugins/promwrapper/plugin.go +++ b/core/services/ocr2/plugins/promwrapper/plugin.go @@ -13,7 +13,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" - "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ) // Type assertions, buckets and labels. diff --git a/core/services/ocr2/plugins/promwrapper/plugin_test.go b/core/services/ocr2/plugins/promwrapper/plugin_test.go index a0833124648..5c12c18f852 100644 --- a/core/services/ocr2/plugins/promwrapper/plugin_test.go +++ b/core/services/ocr2/plugins/promwrapper/plugin_test.go @@ -8,7 +8,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" - "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" diff --git a/core/services/ocr2/plugins/s4/plugin.go b/core/services/ocr2/plugins/s4/plugin.go index 53bddea4163..c8d38b83ff3 100644 --- a/core/services/ocr2/plugins/s4/plugin.go +++ b/core/services/ocr2/plugins/s4/plugin.go @@ -9,7 +9,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/s4" "github.com/pkg/errors" - "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ) type plugin struct { diff --git a/core/services/ocr2/plugins/s4/plugin_test.go b/core/services/ocr2/plugins/s4/plugin_test.go index 35050abb151..9f996a411c0 100644 --- a/core/services/ocr2/plugins/s4/plugin_test.go +++ b/core/services/ocr2/plugins/s4/plugin_test.go @@ -17,7 +17,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/smartcontractkit/libocr/commontypes" - "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "google.golang.org/protobuf/proto" diff --git a/core/services/ocr2/testhelpers/digest.go b/core/services/ocr2/testhelpers/digest.go index 7d9b5783a50..a0a64152d27 100644 --- a/core/services/ocr2/testhelpers/digest.go +++ b/core/services/ocr2/testhelpers/digest.go @@ -4,7 +4,7 @@ import ( "math/rand" "testing" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ) // MakeConfigDigest makes config digest diff --git a/core/services/ocr2/validate/config.go b/core/services/ocr2/validate/config.go index b111e805226..31cd4ead2b7 100644 --- a/core/services/ocr2/validate/config.go +++ b/core/services/ocr2/validate/config.go @@ -3,7 +3,7 @@ package validate import ( "time" - "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink/v2/core/config" "github.com/smartcontractkit/chainlink/v2/core/services/job" diff --git a/core/services/ocr2/validate/validate.go b/core/services/ocr2/validate/validate.go index 9cb06e580ea..0e409bb678d 100644 --- a/core/services/ocr2/validate/validate.go +++ b/core/services/ocr2/validate/validate.go @@ -9,7 +9,7 @@ import ( "github.com/lib/pq" "github.com/pelletier/go-toml" pkgerrors "github.com/pkg/errors" - libocr2 "github.com/smartcontractkit/libocr/offchainreporting2" + libocr2 "github.com/smartcontractkit/libocr/offchainreporting2plus" "github.com/smartcontractkit/chainlink/v2/core/services/job" dkgconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/dkg/config" diff --git a/core/services/ocrbootstrap/database.go b/core/services/ocrbootstrap/database.go index 76700772f56..86ade39a05d 100644 --- a/core/services/ocrbootstrap/database.go +++ b/core/services/ocrbootstrap/database.go @@ -6,7 +6,7 @@ import ( "github.com/lib/pq" "github.com/pkg/errors" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink/v2/core/logger" ) diff --git a/core/services/ocrbootstrap/database_test.go b/core/services/ocrbootstrap/database_test.go index e2e7f0748af..2f160eff582 100644 --- a/core/services/ocrbootstrap/database_test.go +++ b/core/services/ocrbootstrap/database_test.go @@ -6,7 +6,7 @@ import ( "github.com/smartcontractkit/sqlx" "github.com/stretchr/testify/require" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" diff --git a/core/services/ocrbootstrap/delegate.go b/core/services/ocrbootstrap/delegate.go index c0e9623b756..4339df7e895 100644 --- a/core/services/ocrbootstrap/delegate.go +++ b/core/services/ocrbootstrap/delegate.go @@ -5,7 +5,7 @@ import ( "github.com/pkg/errors" - ocr "github.com/smartcontractkit/libocr/offchainreporting2" + ocr "github.com/smartcontractkit/libocr/offchainreporting2plus" "github.com/smartcontractkit/sqlx" "github.com/smartcontractkit/chainlink-relay/pkg/loop" diff --git a/core/services/ocrcommon/data_source.go b/core/services/ocrcommon/data_source.go index 183ced94673..03f5a33500b 100644 --- a/core/services/ocrcommon/data_source.go +++ b/core/services/ocrcommon/data_source.go @@ -9,7 +9,7 @@ import ( "github.com/pkg/errors" ocr1types "github.com/smartcontractkit/libocr/offchainreporting/types" "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median" - ocr2types "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/logger" diff --git a/core/services/ocrcommon/data_source_test.go b/core/services/ocrcommon/data_source_test.go index a1d2bc640ca..f40637cd999 100644 --- a/core/services/ocrcommon/data_source_test.go +++ b/core/services/ocrcommon/data_source_test.go @@ -6,7 +6,7 @@ import ( promtestutil "github.com/prometheus/client_golang/prometheus/testutil" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting/types" - "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/spf13/cast" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" diff --git a/core/services/ocrcommon/peer_wrapper.go b/core/services/ocrcommon/peer_wrapper.go index d8d66ba420c..f677448879a 100644 --- a/core/services/ocrcommon/peer_wrapper.go +++ b/core/services/ocrcommon/peer_wrapper.go @@ -17,7 +17,7 @@ import ( ocrnetworking "github.com/smartcontractkit/libocr/networking" ocrnetworkingtypes "github.com/smartcontractkit/libocr/networking/types" ocr1types "github.com/smartcontractkit/libocr/offchainreporting/types" - ocr2types "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "go.uber.org/multierr" "github.com/smartcontractkit/chainlink/v2/core/logger" diff --git a/core/services/ocrcommon/telemetry.go b/core/services/ocrcommon/telemetry.go index f014fdd3ea3..7a306249c38 100644 --- a/core/services/ocrcommon/telemetry.go +++ b/core/services/ocrcommon/telemetry.go @@ -7,7 +7,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/smartcontractkit/libocr/commontypes" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "google.golang.org/protobuf/proto" "github.com/smartcontractkit/chainlink/v2/core/logger" diff --git a/core/services/ocrcommon/telemetry_test.go b/core/services/ocrcommon/telemetry_test.go index 2af1543b19a..ed72d2a1309 100644 --- a/core/services/ocrcommon/telemetry_test.go +++ b/core/services/ocrcommon/telemetry_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/ethereum/go-ethereum/common" - "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" diff --git a/core/services/relay/evm/address.go b/core/services/relay/evm/address.go index 9a66478e946..1a3e93ed3ca 100644 --- a/core/services/relay/evm/address.go +++ b/core/services/relay/evm/address.go @@ -6,7 +6,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/pkg/errors" - "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ) func AccountToAddress(accounts []types.Account) (addresses []common.Address, err error) { diff --git a/core/services/relay/evm/config_poller.go b/core/services/relay/evm/config_poller.go index 217545de2b4..a6ef894eb9f 100644 --- a/core/services/relay/evm/config_poller.go +++ b/core/services/relay/evm/config_poller.go @@ -8,7 +8,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/logger" diff --git a/core/services/relay/evm/config_poller_test.go b/core/services/relay/evm/config_poller_test.go index ca652b3508b..724c303210b 100644 --- a/core/services/relay/evm/config_poller_test.go +++ b/core/services/relay/evm/config_poller_test.go @@ -11,13 +11,14 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/onsi/gomega" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" testoffchainaggregator2 "github.com/smartcontractkit/libocr/gethwrappers2/testocr2aggregator" - confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median" - ocrtypes2 "github.com/smartcontractkit/libocr/offchainreporting2/types" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + ocrtypes2 "github.com/smartcontractkit/libocr/offchainreporting2plus/types" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" diff --git a/core/services/relay/evm/contract_transmitter.go b/core/services/relay/evm/contract_transmitter.go index 97a1defa331..b589a12a4f2 100644 --- a/core/services/relay/evm/contract_transmitter.go +++ b/core/services/relay/evm/contract_transmitter.go @@ -11,8 +11,8 @@ import ( "github.com/ethereum/go-ethereum/common" gethcommon "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" - "github.com/smartcontractkit/libocr/offchainreporting2/chains/evmutil" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index 36febf268dd..cdba93a6dee 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -11,10 +11,10 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" - "github.com/smartcontractkit/libocr/offchainreporting2/chains/evmutil" "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median" "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median/evmreportcodec" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/sqlx" "go.uber.org/multierr" "golang.org/x/exp/maps" @@ -122,7 +122,7 @@ func (r *Relayer) NewMercuryProvider(rargs relaytypes.RelayArgs, pargs relaytype if err != nil { return nil, err } - transmitter := mercury.NewTransmitter(r.lggr, configWatcher.ContractConfigTracker(), client, privKey.PublicKey, *relayConfig.FeedID) + transmitter := mercury.NewTransmitter(r.lggr, configWatcher.ContractConfigTracker(), client, privKey.PublicKey, *relayConfig.FeedID, mercuryConfig.InitialBlockNumber) return NewMercuryProvider(configWatcher, transmitter, reportCodec, r.lggr), nil } diff --git a/core/services/relay/evm/functions.go b/core/services/relay/evm/functions.go index 77baf832254..d345c8e0d39 100644 --- a/core/services/relay/evm/functions.go +++ b/core/services/relay/evm/functions.go @@ -1,7 +1,7 @@ package evm import ( - "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm" "github.com/smartcontractkit/chainlink/v2/core/logger" diff --git a/core/services/relay/evm/median.go b/core/services/relay/evm/median.go index 4e737b8c74e..af22a07e38b 100644 --- a/core/services/relay/evm/median.go +++ b/core/services/relay/evm/median.go @@ -10,8 +10,8 @@ import ( "github.com/pkg/errors" "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median" - "github.com/smartcontractkit/libocr/offchainreporting2/types" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/sqlx" "github.com/smartcontractkit/chainlink/v2/core/chains/evm" diff --git a/core/services/relay/evm/mercury/config_digest.go b/core/services/relay/evm/mercury/config_digest.go index fc1e9229b83..ed99749ad49 100644 --- a/core/services/relay/evm/mercury/config_digest.go +++ b/core/services/relay/evm/mercury/config_digest.go @@ -9,7 +9,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" - "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/wsrpc/credentials" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mercury_exposed_verifier" @@ -62,9 +62,9 @@ func configDigest( // assertion panic("copy too little data") } - binary.BigEndian.PutUint16(configDigest[:2], uint16(ConfigDigestPrefixMercuryV02)) - // TODO: get rid of this check + binary.BigEndian.PutUint16(configDigest[:2], uint16(types.ConfigDigestPrefixMercuryV02)) if !(configDigest[0] == 0 || configDigest[1] == 6) { + // assertion panic("unexpected mismatch") } return configDigest diff --git a/core/services/relay/evm/mercury/config_digest_test.go b/core/services/relay/evm/mercury/config_digest_test.go index e4ced40df14..55d057f19f6 100644 --- a/core/services/relay/evm/mercury/config_digest_test.go +++ b/core/services/relay/evm/mercury/config_digest_test.go @@ -40,6 +40,7 @@ func TestConfigCalculationMatches(t *testing.T) { p := gopter.NewProperties(nil) p.Property("onchain/offchain config digests match", prop.ForAll( func( + feedID [32]byte, chainID uint64, contractAddress common.Address, configCount uint64, @@ -51,7 +52,7 @@ func TestConfigCalculationMatches(t *testing.T) { offchainConfig []byte, ) bool { golangDigest := configDigest( - sampleFeedID, + feedID, chainID, contractAddress, configCount, @@ -67,7 +68,7 @@ func TestConfigCalculationMatches(t *testing.T) { bigChainID.SetUint64(chainID) solidityDigest, err := eoa.ExposedConfigDigestFromConfigData(nil, - sampleFeedID, + feedID, bigChainID, contractAddress, configCount, @@ -81,6 +82,7 @@ func TestConfigCalculationMatches(t *testing.T) { require.NoError(t, err, "could not compute solidity version of config digest") return golangDigest == solidityDigest }, + GenHash(t), gen.UInt64(), GenAddress(t), gen.UInt64(), diff --git a/core/services/relay/evm/mercury/config_poller.go b/core/services/relay/evm/mercury/config_poller.go index 58f20a9c9ef..fd34e6e5bdf 100644 --- a/core/services/relay/evm/mercury/config_poller.go +++ b/core/services/relay/evm/mercury/config_poller.go @@ -9,7 +9,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mercury_verifier" @@ -126,6 +126,7 @@ func (lp *ConfigPoller) Replay(ctx context.Context, fromBlock int64) error { // LatestConfigDetails returns the latest config details from the logs func (lp *ConfigPoller) LatestConfigDetails(ctx context.Context) (changedInBlock uint64, configDigest ocrtypes.ConfigDigest, err error) { + lp.lggr.Debugw("LatestConfigDetails", "eventSig", FeedScopedConfigSet, "addr", lp.addr, "topicIndex", feedIdTopicIndex, "feedID", lp.feedId) logs, err := lp.destChainLogPoller.IndexedLogs(FeedScopedConfigSet, lp.addr, feedIdTopicIndex, []common.Hash{lp.feedId}, 1, pg.WithParentCtx(ctx)) if err != nil { return 0, ocrtypes.ConfigDigest{}, err diff --git a/core/services/relay/evm/mercury/config_poller_test.go b/core/services/relay/evm/mercury/config_poller_test.go index 39d6782da3c..2cae7fddc03 100644 --- a/core/services/relay/evm/mercury/config_poller_test.go +++ b/core/services/relay/evm/mercury/config_poller_test.go @@ -14,13 +14,13 @@ import ( "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/onsi/gomega" "github.com/pkg/errors" - confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" - ocrtypes2 "github.com/smartcontractkit/libocr/offchainreporting2/types" + confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + ocrtypes2 "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/umbracle/ethgo/abi" - "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" diff --git a/core/services/relay/evm/mercury/data_source.go b/core/services/relay/evm/mercury/data_source.go index 0227a318ead..a2ff98585f2 100644 --- a/core/services/relay/evm/mercury/data_source.go +++ b/core/services/relay/evm/mercury/data_source.go @@ -8,9 +8,11 @@ import ( "sync" pkgerrors "github.com/pkg/errors" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" + evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" httypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" @@ -27,8 +29,12 @@ type ChainHeadTracker interface { HeadTracker() httypes.HeadTracker } +type Runner interface { + ExecuteRun(ctx context.Context, spec pipeline.Spec, vars pipeline.Vars, l logger.Logger) (run pipeline.Run, trrs pipeline.TaskRunResults, err error) +} + type datasource struct { - pipelineRunner pipeline.Runner + pipelineRunner Runner jb job.Job spec pipeline.Spec lggr logger.Logger @@ -38,50 +44,78 @@ type datasource struct { chEnhancedTelem chan<- ocrcommon.EnhancedTelemetryMercuryData chainHeadTracker ChainHeadTracker + fetcher relaymercury.Fetcher } var _ relaymercury.DataSource = &datasource{} -func NewDataSource(pr pipeline.Runner, jb job.Job, spec pipeline.Spec, lggr logger.Logger, rr chan pipeline.Run, enhancedTelemChan chan ocrcommon.EnhancedTelemetryMercuryData, chainHeadTracker ChainHeadTracker) *datasource { - return &datasource{pr, jb, spec, lggr, rr, sync.RWMutex{}, enhancedTelemChan, chainHeadTracker} +func NewDataSource(pr pipeline.Runner, jb job.Job, spec pipeline.Spec, lggr logger.Logger, rr chan pipeline.Run, enhancedTelemChan chan ocrcommon.EnhancedTelemetryMercuryData, chainHeadTracker ChainHeadTracker, fetcher relaymercury.Fetcher) *datasource { + return &datasource{pr, jb, spec, lggr, rr, sync.RWMutex{}, enhancedTelemChan, chainHeadTracker, fetcher} } -func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestamp) (relaymercury.Observation, error) { - run, trrs, err := ds.executeRun(ctx) - if err != nil { - return relaymercury.Observation{}, fmt.Errorf("Observe failed while executing run: %w", err) - } - select { - case ds.runResults <- run: - default: - ds.lggr.Warnf("unable to enqueue run save for job ID %d, buffer full", ds.spec.JobID) +func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestamp, fetchMaxFinalizedBlockNum bool) (obs relaymercury.Observation, err error) { + var wg sync.WaitGroup + if fetchMaxFinalizedBlockNum { + wg.Add(1) + go func() { + defer wg.Done() + obs.MaxFinalizedBlockNumber.Val, obs.MaxFinalizedBlockNumber.Err = ds.fetcher.FetchInitialMaxFinalizedBlockNumber(ctx) + }() + } else { + obs.MaxFinalizedBlockNumber.Err = errors.New("fetchMaxFinalizedBlockNum=false") } + var trrs pipeline.TaskRunResults + wg.Add(1) + go func() { + defer wg.Done() + var run pipeline.Run + run, trrs, err = ds.executeRun(ctx) + if err != nil { + err = fmt.Errorf("Observe failed while executing run: %w", err) + return + } + select { + case ds.runResults <- run: + default: + ds.lggr.Warnf("unable to enqueue run save for job ID %d, buffer full", ds.spec.JobID) + } - // NOTE: trrs comes back as _all_ tasks, but we only want the terminal ones - // They are guaranteed to be sorted by index asc so should be in the correct order - var finaltrrs []pipeline.TaskRunResult - for _, trr := range trrs { - if trr.IsTerminal() { - finaltrrs = append(finaltrrs, trr) + // NOTE: trrs comes back as _all_ tasks, but we only want the terminal ones + // They are guaranteed to be sorted by index asc so should be in the correct order + var finaltrrs []pipeline.TaskRunResult + for _, trr := range trrs { + if trr.IsTerminal() { + finaltrrs = append(finaltrrs, trr) + } } - } - parsed, err := ds.parse(finaltrrs) - if err != nil { - return relaymercury.Observation{}, fmt.Errorf("Observe failed while parsing run results: %w", err) - } - ds.setCurrentBlock(ctx, &parsed) + var parsed parseOutput + parsed, err = ds.parse(finaltrrs) + if err != nil { + err = fmt.Errorf("Observe failed while parsing run results: %w", err) + return + } + obs.BenchmarkPrice = parsed.benchmarkPrice + obs.Bid = parsed.bid + obs.Ask = parsed.ask + }() + wg.Add(1) + go func() { + defer wg.Done() + ds.setCurrentBlock(ctx, &obs) + }() + wg.Wait() if ocrcommon.ShouldCollectEnhancedTelemetryMercury(&ds.jb) { ocrcommon.EnqueueEnhancedTelem(ds.chEnhancedTelem, ocrcommon.EnhancedTelemetryMercuryData{ TaskRunResults: trrs, - Observation: parsed, + Observation: obs, RepTimestamp: repts, }) } - return parsed, nil + return obs, err } func toBigInt(val interface{}) (*big.Int, error) { @@ -92,13 +126,19 @@ func toBigInt(val interface{}) (*big.Int, error) { return dec.BigInt(), nil } +type parseOutput struct { + benchmarkPrice relaymercury.ObsResult[*big.Int] + bid relaymercury.ObsResult[*big.Int] + ask relaymercury.ObsResult[*big.Int] +} + // parse expects the output of observe to be three values, in the following order: // 1. benchmark price // 2. bid // 3. ask // // returns error on parse errors: if something is the wrong type -func (ds *datasource) parse(trrs pipeline.TaskRunResults) (obs relaymercury.Observation, merr error) { +func (ds *datasource) parse(trrs pipeline.TaskRunResults) (o parseOutput, merr error) { var finaltrrs []pipeline.TaskRunResult for _, trr := range trrs { // only return terminal trrs from executeRun @@ -110,46 +150,46 @@ func (ds *datasource) parse(trrs pipeline.TaskRunResults) (obs relaymercury.Obse // pipeline.TaskRunResults comes ordered asc by index, this is guaranteed // by the pipeline executor if len(finaltrrs) != 3 { - return obs, fmt.Errorf("invalid number of results, expected: 3, got: %d", len(finaltrrs)) + return o, fmt.Errorf("invalid number of results, expected: 3, got: %d", len(finaltrrs)) } merr = errors.Join( - setBenchmarkPrice(&obs, finaltrrs[0].Result), - setBid(&obs, finaltrrs[1].Result), - setAsk(&obs, finaltrrs[2].Result), + setBenchmarkPrice(&o, finaltrrs[0].Result), + setBid(&o, finaltrrs[1].Result), + setAsk(&o, finaltrrs[2].Result), ) - return obs, merr + return o, merr } -func setBenchmarkPrice(obs *relaymercury.Observation, res pipeline.Result) error { +func setBenchmarkPrice(o *parseOutput, res pipeline.Result) error { if res.Error != nil { - obs.BenchmarkPrice.Err = res.Error + o.benchmarkPrice.Err = res.Error } else if val, err := toBigInt(res.Value); err != nil { return fmt.Errorf("failed to parse BenchmarkPrice: %w", err) } else { - obs.BenchmarkPrice.Val = val + o.benchmarkPrice.Val = val } return nil } -func setBid(obs *relaymercury.Observation, res pipeline.Result) error { +func setBid(o *parseOutput, res pipeline.Result) error { if res.Error != nil { - obs.Bid.Err = res.Error + o.bid.Err = res.Error } else if val, err := toBigInt(res.Value); err != nil { return fmt.Errorf("failed to parse Bid: %w", err) } else { - obs.Bid.Val = val + o.bid.Val = val } return nil } -func setAsk(obs *relaymercury.Observation, res pipeline.Result) error { +func setAsk(o *parseOutput, res pipeline.Result) error { if res.Error != nil { - obs.Ask.Err = res.Error + o.ask.Err = res.Error } else if val, err := toBigInt(res.Value); err != nil { return fmt.Errorf("failed to parse Ask: %w", err) } else { - obs.Ask.Val = val + o.ask.Val = val } return nil } diff --git a/core/services/relay/evm/mercury/data_source_test.go b/core/services/relay/evm/mercury/data_source_test.go index d286c1a9273..e451a743abc 100644 --- a/core/services/relay/evm/mercury/data_source_test.go +++ b/core/services/relay/evm/mercury/data_source_test.go @@ -2,7 +2,9 @@ package mercury import ( "context" + "fmt" "math/big" + "math/rand" "testing" "time" @@ -10,18 +12,288 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" "github.com/smartcontractkit/chainlink/v2/core/assets" + evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" evmclimocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" htmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/mocks" + httypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" mercurymocks "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/mocks" "github.com/smartcontractkit/chainlink/v2/core/utils" ) -func TestMercurySetCurrentBlock(t *testing.T) { +var _ relaymercury.Fetcher = &mockFetcher{} + +type mockFetcher struct { + num int64 + err error +} + +func (m *mockFetcher) FetchInitialMaxFinalizedBlockNumber(context.Context) (int64, error) { + return m.num, m.err +} + +var _ Runner = &mockRunner{} + +type mockRunner struct { + trrs pipeline.TaskRunResults + err error +} + +func (m *mockRunner) ExecuteRun(ctx context.Context, spec pipeline.Spec, vars pipeline.Vars, l logger.Logger) (run pipeline.Run, trrs pipeline.TaskRunResults, err error) { + return pipeline.Run{ID: 42}, m.trrs, m.err +} + +var _ pipeline.Task = &mockTask{} + +type mockTask struct { + result pipeline.Result +} + +func (m *mockTask) Type() pipeline.TaskType { return "MockTask" } +func (m *mockTask) ID() int { return 0 } +func (m *mockTask) DotID() string { return "" } +func (m *mockTask) Run(ctx context.Context, lggr logger.Logger, vars pipeline.Vars, inputs []pipeline.Result) (pipeline.Result, pipeline.RunInfo) { + return m.result, pipeline.RunInfo{} +} +func (m *mockTask) Base() *pipeline.BaseTask { return nil } +func (m *mockTask) Outputs() []pipeline.Task { return nil } +func (m *mockTask) Inputs() []pipeline.TaskDependency { return nil } +func (m *mockTask) OutputIndex() int32 { return 0 } +func (m *mockTask) TaskTimeout() (time.Duration, bool) { return 0, false } +func (m *mockTask) TaskRetries() uint32 { return 0 } +func (m *mockTask) TaskMinBackoff() time.Duration { return 0 } +func (m *mockTask) TaskMaxBackoff() time.Duration { return 0 } + +var _ ChainHeadTracker = &mockHeadTracker{} + +type mockHeadTracker struct { + c evmclient.Client + h httypes.HeadTracker +} + +func (m *mockHeadTracker) Client() evmclient.Client { return m.c } +func (m *mockHeadTracker) HeadTracker() httypes.HeadTracker { return m.h } + +func TestMercury_Observe(t *testing.T) { + ds := &datasource{lggr: logger.TestLogger(t)} + ctx := testutils.Context(t) + repts := ocrtypes.ReportTimestamp{} + + fetcher := &mockFetcher{} + ds.fetcher = fetcher + + trrs := []pipeline.TaskRunResult{ + pipeline.TaskRunResult{ + // benchmark price + Result: pipeline.Result{Value: "122.345"}, + Task: &mockTask{}, + }, + pipeline.TaskRunResult{ + // bid + Result: pipeline.Result{Value: "121.993"}, + Task: &mockTask{}, + }, + pipeline.TaskRunResult{ + // ask + Result: pipeline.Result{Value: "123.111"}, + Task: &mockTask{}, + }, + } + + runner := &mockRunner{ + trrs: trrs, + } + ds.pipelineRunner = runner + + spec := pipeline.Spec{} + ds.spec = spec + + h := htmocks.NewHeadTracker(t) + c := evmtest.NewEthClientMock(t) + ht := &mockHeadTracker{ + c: c, + h: h, + } + ds.chainHeadTracker = ht + + head := &evmtypes.Head{ + Number: int64(rand.Int31()), + Hash: utils.NewHash(), + Timestamp: time.Now(), + } + h.On("LatestChain").Return(head) + + t.Run("when fetchMaxFinalizedBlockNum=true", func(t *testing.T) { + t.Run("if FetchInitialMaxFinalizedBlockNumber returns error", func(t *testing.T) { + fetcher.err = errors.New("mock fetcher error") + + obs, err := ds.Observe(ctx, repts, true) + assert.NoError(t, err) + + assert.EqualError(t, obs.MaxFinalizedBlockNumber.Err, "mock fetcher error") + assert.Zero(t, obs.MaxFinalizedBlockNumber.Val) + }) + t.Run("if FetchInitialMaxFinalizedBlockNumber succeeds", func(t *testing.T) { + fetcher.err = nil + fetcher.num = 32 + + obs, err := ds.Observe(ctx, repts, true) + assert.NoError(t, err) + + assert.NoError(t, obs.MaxFinalizedBlockNumber.Err) + assert.Equal(t, int64(32), obs.MaxFinalizedBlockNumber.Val) + }) + }) + t.Run("when fetchMaxFinalizedBlockNum=false", func(t *testing.T) { + t.Run("when run execution fails, returns error", func(t *testing.T) { + t.Cleanup(func() { + runner.err = nil + }) + runner.err = errors.New("run execution failed") + + _, err := ds.Observe(ctx, repts, false) + assert.EqualError(t, err, "Observe failed while executing run: error executing run for spec ID 0: run execution failed") + }) + t.Run("makes observation using pipeline, when all tasks succeed", func(t *testing.T) { + obs, err := ds.Observe(ctx, repts, false) + assert.NoError(t, err) + + assert.Equal(t, big.NewInt(122), obs.BenchmarkPrice.Val) + assert.NoError(t, obs.BenchmarkPrice.Err) + assert.Equal(t, big.NewInt(121), obs.Bid.Val) + assert.NoError(t, obs.Bid.Err) + assert.Equal(t, big.NewInt(123), obs.Ask.Val) + assert.NoError(t, obs.Ask.Err) + assert.Equal(t, head.Number, obs.CurrentBlockNum.Val) + assert.NoError(t, obs.CurrentBlockNum.Err) + assert.Equal(t, fmt.Sprintf("%x", head.Hash), fmt.Sprintf("%x", obs.CurrentBlockHash.Val)) + assert.NoError(t, obs.CurrentBlockHash.Err) + assert.Equal(t, uint64(head.Timestamp.Unix()), obs.CurrentBlockTimestamp.Val) + assert.NoError(t, obs.CurrentBlockTimestamp.Err) + + assert.Zero(t, obs.MaxFinalizedBlockNumber.Val) + assert.EqualError(t, obs.MaxFinalizedBlockNumber.Err, "fetchMaxFinalizedBlockNum=false") + }) + t.Run("makes observation using pipeline, with erroring tasks", func(t *testing.T) { + for i := range trrs { + trrs[i].Result.Error = fmt.Errorf("task error %d", i) + } + + obs, err := ds.Observe(ctx, repts, false) + assert.NoError(t, err) + + assert.Zero(t, obs.BenchmarkPrice.Val) + assert.EqualError(t, obs.BenchmarkPrice.Err, "task error 0") + assert.Zero(t, obs.Bid.Val) + assert.EqualError(t, obs.Bid.Err, "task error 1") + assert.Zero(t, obs.Ask.Val) + assert.EqualError(t, obs.Ask.Err, "task error 2") + assert.Equal(t, head.Number, obs.CurrentBlockNum.Val) + assert.NoError(t, obs.CurrentBlockNum.Err) + assert.Equal(t, fmt.Sprintf("%x", head.Hash), fmt.Sprintf("%x", obs.CurrentBlockHash.Val)) + assert.NoError(t, obs.CurrentBlockHash.Err) + assert.Equal(t, uint64(head.Timestamp.Unix()), obs.CurrentBlockTimestamp.Val) + assert.NoError(t, obs.CurrentBlockTimestamp.Err) + + assert.Zero(t, obs.MaxFinalizedBlockNumber.Val) + assert.EqualError(t, obs.MaxFinalizedBlockNumber.Err, "fetchMaxFinalizedBlockNum=false") + }) + t.Run("makes partial observation using pipeline, if only some results have errored", func(t *testing.T) { + trrs[0].Result.Error = fmt.Errorf("task failed") + trrs[1].Result.Value = "33" + trrs[1].Result.Error = nil + trrs[2].Result.Value = nil + trrs[2].Result.Error = fmt.Errorf("task failed") + + obs, err := ds.Observe(ctx, repts, false) + assert.NoError(t, err) + + assert.Zero(t, obs.BenchmarkPrice.Val) + assert.EqualError(t, obs.BenchmarkPrice.Err, "task failed") + assert.Equal(t, big.NewInt(33), obs.Bid.Val) + assert.NoError(t, obs.Bid.Err) + assert.Zero(t, obs.Ask.Val) + assert.EqualError(t, obs.Ask.Err, "task failed") + }) + t.Run("returns error if at least one result is unparseable", func(t *testing.T) { + trrs[0].Result.Error = fmt.Errorf("task failed") + trrs[1].Result.Value = "foo" + trrs[1].Result.Error = nil + trrs[2].Result.Value = "123456" + trrs[2].Result.Error = nil + + _, err := ds.Observe(ctx, repts, false) + assert.EqualError(t, err, "Observe failed while parsing run results: failed to parse Bid: can't convert foo to decimal") + }) + t.Run("sends run to runResults channel", func(t *testing.T) { + for i := range trrs { + trrs[i].Result.Value = "123" + trrs[i].Result.Error = nil + } + + ch := make(chan pipeline.Run, 1) + ds.runResults = ch + + _, err := ds.Observe(ctx, repts, false) + assert.NoError(t, err) + + select { + case run := <-ch: + assert.Equal(t, int64(42), run.ID) + default: + t.Fatal("expected run on channel") + } + }) + t.Run("if head tracker returns nil, falls back to RPC method", func(t *testing.T) { + t.Run("if call succeeds", func(t *testing.T) { + h = htmocks.NewHeadTracker(t) + h.On("LatestChain").Return(nil) + ht.h = h + c.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(head, nil).Once() + + obs, err := ds.Observe(ctx, repts, false) + assert.NoError(t, err) + + assert.Equal(t, head.Number, obs.CurrentBlockNum.Val) + assert.NoError(t, obs.CurrentBlockNum.Err) + assert.Equal(t, fmt.Sprintf("%x", head.Hash), fmt.Sprintf("%x", obs.CurrentBlockHash.Val)) + assert.NoError(t, obs.CurrentBlockHash.Err) + assert.Equal(t, uint64(head.Timestamp.Unix()), obs.CurrentBlockTimestamp.Val) + assert.NoError(t, obs.CurrentBlockTimestamp.Err) + + h.AssertExpectations(t) + c.AssertExpectations(t) + }) + t.Run("if call fails, returns error for that observation", func(t *testing.T) { + c = evmtest.NewEthClientMock(t) + ht.c = c + c.On("HeadByNumber", mock.Anything, (*big.Int)(nil)).Return(nil, errors.New("client call failed")).Once() + + obs, err := ds.Observe(ctx, repts, false) + assert.NoError(t, err) + + assert.Zero(t, obs.CurrentBlockNum.Val) + assert.EqualError(t, obs.CurrentBlockNum.Err, "client call failed") + assert.Zero(t, obs.CurrentBlockHash.Val) + assert.EqualError(t, obs.CurrentBlockHash.Err, "client call failed") + assert.Zero(t, obs.CurrentBlockTimestamp.Val) + assert.EqualError(t, obs.CurrentBlockTimestamp.Err, "client call failed") + + c.AssertExpectations(t) + }) + }) + }) +} + +func TestMercury_SetCurrentBlock(t *testing.T) { lggr := logger.TestLogger(t) ds := datasource{ lggr: lggr, diff --git a/core/services/relay/evm/mercury/helpers_test.go b/core/services/relay/evm/mercury/helpers_test.go index 8f79941fcb6..608b77e59d6 100644 --- a/core/services/relay/evm/mercury/helpers_test.go +++ b/core/services/relay/evm/mercury/helpers_test.go @@ -6,8 +6,8 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/smartcontractkit/libocr/offchainreporting2/chains/evmutil" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/reportcodec" "github.com/smartcontractkit/chainlink/v2/core/utils" diff --git a/core/services/relay/evm/mercury/offchain_config_digester.go b/core/services/relay/evm/mercury/offchain_config_digester.go index fa9f5c04727..ba3276d825a 100644 --- a/core/services/relay/evm/mercury/offchain_config_digester.go +++ b/core/services/relay/evm/mercury/offchain_config_digester.go @@ -6,15 +6,11 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" - "github.com/smartcontractkit/libocr/offchainreporting2/types" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/wsrpc/credentials" ) -// TODO: Replace this value with the proper value in -// libocr/offchainreporting2/types later! -const ConfigDigestPrefixMercuryV02 types.ConfigDigestPrefix = 6 - // Originally sourced from: https://github.com/smartcontractkit/offchain-reporting/blob/991ebe1462fd56826a1ddfb34287d542acb2baee/lib/offchainreporting2/chains/evmutil/offchain_config_digester.go var _ ocrtypes.OffchainConfigDigester = OffchainConfigDigester{} @@ -68,7 +64,5 @@ func (d OffchainConfigDigester) ConfigDigest(cc types.ContractConfig) (types.Con } func (d OffchainConfigDigester) ConfigDigestPrefix() (types.ConfigDigestPrefix, error) { - // TODO: Replace this value with the proper value in - // libocr/offchainreporting2/types later! - return ConfigDigestPrefixMercuryV02, nil + return types.ConfigDigestPrefixMercuryV02, nil } diff --git a/core/services/relay/evm/mercury/offchain_config_digester_test.go b/core/services/relay/evm/mercury/offchain_config_digester_test.go index f8bd7936a61..599c30de396 100644 --- a/core/services/relay/evm/mercury/offchain_config_digester_test.go +++ b/core/services/relay/evm/mercury/offchain_config_digester_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/ethereum/go-ethereum/common" - "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/stretchr/testify/require" ) diff --git a/core/services/relay/evm/mercury/queue.go b/core/services/relay/evm/mercury/queue.go index 35af9daff0c..71597510f47 100644 --- a/core/services/relay/evm/mercury/queue.go +++ b/core/services/relay/evm/mercury/queue.go @@ -10,7 +10,8 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services" diff --git a/core/services/relay/evm/mercury/queue_test.go b/core/services/relay/evm/mercury/queue_test.go index 1b31f655966..8a3c252ba59 100644 --- a/core/services/relay/evm/mercury/queue_test.go +++ b/core/services/relay/evm/mercury/queue_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" diff --git a/core/services/relay/evm/mercury/reportcodec/factories_test.go b/core/services/relay/evm/mercury/reportcodec/factories_test.go new file mode 100644 index 00000000000..89cf6cee7a9 --- /dev/null +++ b/core/services/relay/evm/mercury/reportcodec/factories_test.go @@ -0,0 +1,94 @@ +package reportcodec + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common/hexutil" + + "github.com/smartcontractkit/libocr/commontypes" + + relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" +) + +func NewValidParsedAttributedObservations() []relaymercury.ParsedAttributedObservation { + return []relaymercury.ParsedAttributedObservation{ + relaymercury.ParsedAttributedObservation{ + Timestamp: 1676484822, + Observer: commontypes.OracleID(1), + + BenchmarkPrice: big.NewInt(345), + Bid: big.NewInt(343), + Ask: big.NewInt(347), + PricesValid: true, + + CurrentBlockNum: 16634364, + CurrentBlockHash: hexutil.MustDecode("8f30cda279821c5bb6f72f7ab900aa5118215ce59fcf8835b12d0cdbadc9d7b0"), + CurrentBlockTimestamp: 1682908180, + CurrentBlockValid: true, + + MaxFinalizedBlockNumber: 16634355, + MaxFinalizedBlockNumberValid: true, + }, + relaymercury.ParsedAttributedObservation{ + Timestamp: 1676484826, + Observer: commontypes.OracleID(2), + + BenchmarkPrice: big.NewInt(335), + Bid: big.NewInt(332), + Ask: big.NewInt(336), + PricesValid: true, + + CurrentBlockNum: 16634364, + CurrentBlockHash: hexutil.MustDecode("8f30cda279821c5bb6f72f7ab900aa5118215ce59fcf8835b12d0cdbadc9d7b0"), + CurrentBlockTimestamp: 1682908180, + CurrentBlockValid: true, + + MaxFinalizedBlockNumber: 16634355, + MaxFinalizedBlockNumberValid: true, + }, + relaymercury.ParsedAttributedObservation{ + Timestamp: 1676484828, + Observer: commontypes.OracleID(3), + + BenchmarkPrice: big.NewInt(347), + Bid: big.NewInt(345), + Ask: big.NewInt(350), + PricesValid: true, + + CurrentBlockNum: 16634365, + CurrentBlockHash: hexutil.MustDecode("40044147503a81e9f2a225f4717bf5faf5dc574f69943bdcd305d5ed97504a7e"), + CurrentBlockTimestamp: 1682591344, + CurrentBlockValid: true, + + MaxFinalizedBlockNumber: 16634355, + MaxFinalizedBlockNumberValid: true, + }, + relaymercury.ParsedAttributedObservation{ + Timestamp: 1676484830, + Observer: commontypes.OracleID(4), + + BenchmarkPrice: big.NewInt(346), + Bid: big.NewInt(347), + Ask: big.NewInt(350), + PricesValid: true, + + CurrentBlockNum: 16634365, + CurrentBlockHash: hexutil.MustDecode("40044147503a81e9f2a225f4717bf5faf5dc574f69943bdcd305d5ed97504a7e"), + CurrentBlockTimestamp: 1682591344, + CurrentBlockValid: true, + + MaxFinalizedBlockNumber: 16634355, + MaxFinalizedBlockNumberValid: true, + }, + } +} + +func NewInvalidParsedAttributedObservations() []relaymercury.ParsedAttributedObservation { + invalidPaos := NewValidParsedAttributedObservations() + for i := range invalidPaos { + invalidPaos[i].PricesValid = false + invalidPaos[i].CurrentBlockValid = false + invalidPaos[i].MaxFinalizedBlockNumberValid = false + } + return invalidPaos +} diff --git a/core/services/relay/evm/mercury/reportcodec/report_codec.go b/core/services/relay/evm/mercury/reportcodec/report_codec.go index d8d8908e812..4aac9d9d8c5 100644 --- a/core/services/relay/evm/mercury/reportcodec/report_codec.go +++ b/core/services/relay/evm/mercury/reportcodec/report_codec.go @@ -6,7 +6,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/pkg/errors" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" @@ -52,7 +52,7 @@ func NewEVMReportCodec(feedID [32]byte, lggr logger.Logger) *EVMReportCodec { return &EVMReportCodec{lggr, feedID} } -func (r *EVMReportCodec) BuildReport(paos []relaymercury.ParsedAttributedObservation, f int) (ocrtypes.Report, error) { +func (r *EVMReportCodec) BuildReport(paos []relaymercury.ParsedAttributedObservation, f int, validFromBlockNum int64) (ocrtypes.Report, error) { if len(paos) == 0 { return nil, errors.Errorf("cannot build report from empty attributed observations") } @@ -61,18 +61,22 @@ func (r *EVMReportCodec) BuildReport(paos []relaymercury.ParsedAttributedObserva paos = append([]relaymercury.ParsedAttributedObservation{}, paos...) timestamp := relaymercury.GetConsensusTimestamp(paos) - benchmarkPrice := relaymercury.GetConsensusBenchmarkPrice(paos) - bid := relaymercury.GetConsensusBid(paos) - ask := relaymercury.GetConsensusAsk(paos) - - currentBlockHash, currentBlockNum, currentBlockTimestamp, err := relaymercury.GetConsensusCurrentBlock(paos, f) + benchmarkPrice, err := relaymercury.GetConsensusBenchmarkPrice(paos, f) if err != nil { - return nil, errors.Wrap(err, "GetConsensusCurrentBlock failed") + return nil, errors.Wrap(err, "GetConsensusBenchmarkPrice failed") + } + bid, err := relaymercury.GetConsensusBid(paos, f) + if err != nil { + return nil, errors.Wrap(err, "GetConsensusBid failed") + } + ask, err := relaymercury.GetConsensusAsk(paos, f) + if err != nil { + return nil, errors.Wrap(err, "GetConsensusAsk failed") } - validFromBlockNum, err := relaymercury.GetConsensusValidFromBlock(paos, f) + currentBlockHash, currentBlockNum, currentBlockTimestamp, err := relaymercury.GetConsensusCurrentBlock(paos, f) if err != nil { - return nil, errors.Wrap(err, "GetConsensusValidFromBlock failed") + return nil, errors.Wrap(err, "GetConsensusCurrentBlock failed") } if validFromBlockNum > currentBlockNum { @@ -124,3 +128,26 @@ func (r *EVMReportCodec) CurrentBlockNumFromReport(report ocrtypes.Report) (int6 return int64(blockNum), nil } + +func (r *EVMReportCodec) ValidFromBlockNumFromReport(report ocrtypes.Report) (int64, error) { + reportElems := map[string]interface{}{} + if err := ReportTypes.UnpackIntoMap(reportElems, report); err != nil { + return 0, errors.Errorf("error during unpack: %v", err) + } + + blockNumIface, ok := reportElems["validFromBlockNum"] + if !ok { + return 0, errors.Errorf("unpacked report has no 'validFromBlockNum' field") + } + + blockNum, ok := blockNumIface.(uint64) + if !ok { + return 0, errors.Errorf("cannot cast blockNum to int64, type is %T", blockNumIface) + } + + if blockNum > math.MaxInt64 { + return 0, errors.Errorf("blockNum overflows max int64, got: %d", blockNum) + } + + return int64(blockNum), nil +} diff --git a/core/services/relay/evm/mercury/reportcodec/report_codec_test.go b/core/services/relay/evm/mercury/reportcodec/report_codec_test.go index 1f2abfa7dc2..851e67ce171 100644 --- a/core/services/relay/evm/mercury/reportcodec/report_codec_test.go +++ b/core/services/relay/evm/mercury/reportcodec/report_codec_test.go @@ -10,7 +10,7 @@ import ( "github.com/stretchr/testify/require" "github.com/smartcontractkit/libocr/commontypes" - "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" @@ -24,7 +24,7 @@ func Test_ReportCodec_BuildReport(t *testing.T) { t.Run("BuildReport errors if observations are empty", func(t *testing.T) { paos := []relaymercury.ParsedAttributedObservation{} - _, err := r.BuildReport(paos, f) + _, err := r.BuildReport(paos, f, 1) require.Error(t, err) assert.Contains(t, err.Error(), "cannot build report from empty attributed observation") }) @@ -36,51 +36,63 @@ func Test_ReportCodec_BuildReport(t *testing.T) { paos := []relaymercury.ParsedAttributedObservation{ { - Timestamp: uint32(42), - BenchmarkPrice: big.NewInt(43), - Bid: big.NewInt(44), - Ask: big.NewInt(45), + Timestamp: uint32(42), + Observer: commontypes.OracleID(49), + + BenchmarkPrice: big.NewInt(43), + Bid: big.NewInt(44), + Ask: big.NewInt(45), + PricesValid: true, + CurrentBlockNum: 48, CurrentBlockHash: hash, CurrentBlockTimestamp: uint64(123), - ValidFromBlockNum: 46, - Observer: commontypes.OracleID(49), + CurrentBlockValid: true, }, { - Timestamp: uint32(142), - BenchmarkPrice: big.NewInt(143), - Bid: big.NewInt(144), - Ask: big.NewInt(145), + Timestamp: uint32(142), + Observer: commontypes.OracleID(149), + + BenchmarkPrice: big.NewInt(143), + Bid: big.NewInt(144), + Ask: big.NewInt(145), + PricesValid: true, + CurrentBlockNum: 48, CurrentBlockHash: hash, CurrentBlockTimestamp: uint64(123), - ValidFromBlockNum: 46, - Observer: commontypes.OracleID(149), + CurrentBlockValid: true, }, { - Timestamp: uint32(242), - BenchmarkPrice: big.NewInt(243), - Bid: big.NewInt(244), - Ask: big.NewInt(245), + Timestamp: uint32(242), + Observer: commontypes.OracleID(249), + + BenchmarkPrice: big.NewInt(243), + Bid: big.NewInt(244), + Ask: big.NewInt(245), + PricesValid: true, + CurrentBlockNum: 248, CurrentBlockHash: hash, CurrentBlockTimestamp: uint64(789), - ValidFromBlockNum: 246, - Observer: commontypes.OracleID(249), + CurrentBlockValid: true, }, { - Timestamp: uint32(342), - BenchmarkPrice: big.NewInt(343), - Bid: big.NewInt(344), - Ask: big.NewInt(345), + Timestamp: uint32(342), + Observer: commontypes.OracleID(250), + + BenchmarkPrice: big.NewInt(343), + Bid: big.NewInt(344), + Ask: big.NewInt(345), + PricesValid: true, + CurrentBlockNum: 348, CurrentBlockHash: hash, CurrentBlockTimestamp: uint64(123456), - ValidFromBlockNum: 346, - Observer: commontypes.OracleID(250), + CurrentBlockValid: true, }, } - report, err := r.BuildReport(paos, f) + report, err := r.BuildReport(paos, f, 46) require.NoError(t, err) reportElems := make(map[string]interface{}) diff --git a/core/services/relay/evm/mercury/transmitter.go b/core/services/relay/evm/mercury/transmitter.go index b22e44453da..a75997c476e 100644 --- a/core/services/relay/evm/mercury/transmitter.go +++ b/core/services/relay/evm/mercury/transmitter.go @@ -12,14 +12,16 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/jpillora/backoff" pkgerrors "github.com/pkg/errors" - "github.com/smartcontractkit/libocr/offchainreporting2/chains/evmutil" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" "golang.org/x/exp/maps" + "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/reportcodec" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb" "github.com/smartcontractkit/chainlink/v2/core/utils" @@ -44,9 +46,10 @@ var _ Transmitter = &mercuryTransmitter{} type mercuryTransmitter struct { utils.StartStopOnce - lggr logger.Logger - rpcClient wsrpc.Client - cfgTracker ConfigTracker + lggr logger.Logger + rpcClient wsrpc.Client + cfgTracker ConfigTracker + initialBlockNumber int64 feedID [32]byte fromAccount string @@ -75,12 +78,13 @@ func getPayloadTypes() abi.Arguments { }) } -func NewTransmitter(lggr logger.Logger, cfgTracker ConfigTracker, rpcClient wsrpc.Client, fromAccount ed25519.PublicKey, feedID [32]byte) *mercuryTransmitter { +func NewTransmitter(lggr logger.Logger, cfgTracker ConfigTracker, rpcClient wsrpc.Client, fromAccount ed25519.PublicKey, feedID [32]byte, initialBlockNumber int64) *mercuryTransmitter { return &mercuryTransmitter{ utils.StartStopOnce{}, - lggr.Named("MercuryTransmitter"), + lggr.Named("MercuryTransmitter").With("feedID", fmt.Sprintf("%x", feedID[:])), rpcClient, cfgTracker, + initialBlockNumber, feedID, fmt.Sprintf("%x", fromAccount), make(chan (struct{})), @@ -150,7 +154,7 @@ func (mt *mercuryTransmitter) runloop() { mt.lggr.Error("Failed to push report to transmit queue; queue is closed") return } - // Wait a backoff duration before pulling the latest back off + // Wait a backoff duration before pulling the most recent transmission // the heap select { case <-time.After(b.Duration()): @@ -171,7 +175,23 @@ func (mt *mercuryTransmitter) runloop() { case DuplicateReport: mt.lggr.Debugw("Transmit report succeeded; duplicate report", "code", res.Code) default: - mt.lggr.Errorw("Transmit report failed; mercury server returned error", "req", t.Req, "response", res, "reportCtx", t.ReportCtx, "err", res.Error, "code", res.Code) + elems := map[string]interface{}{} + var validFrom int64 + var currentBlock int64 + if err = PayloadTypes.UnpackIntoMap(elems, t.Req.Payload); err != nil { + mt.lggr.Errorw("failed to unpack report", "err", err) + } else { + report := elems["report"].([]byte) + validFrom, err = (&reportcodec.EVMReportCodec{}).ValidFromBlockNumFromReport(report) + if err != nil { + mt.lggr.Errorw("failed to unpack report", "err", err) + } + currentBlock, err = (&reportcodec.EVMReportCodec{}).CurrentBlockNumFromReport(report) + if err != nil { + mt.lggr.Errorw("failed to unpack report", "err", err) + } + } + mt.lggr.Errorw("Transmit report failed; mercury server returned error", "validFromBlock", validFrom, "currentBlock", currentBlock, "req", t.Req, "response", res, "reportCtx", t.ReportCtx, "err", res.Error, "code", res.Code) } } } @@ -217,39 +237,7 @@ func (mt *mercuryTransmitter) FromAccount() (ocrtypes.Account, error) { // LatestConfigDigestAndEpoch retrieves the latest config digest and epoch from the OCR2 contract. func (mt *mercuryTransmitter) LatestConfigDigestAndEpoch(ctx context.Context) (cd ocrtypes.ConfigDigest, epoch uint32, err error) { - mt.lggr.Debug("LatestConfigDigestAndEpoch") - req := &pb.LatestReportRequest{ - FeedId: mt.feedID[:], - } - resp, err := mt.rpcClient.LatestReport(ctx, req) - if err != nil { - mt.lggr.Errorw("LatestConfigDigestAndEpoch failed", "err", err) - return cd, epoch, pkgerrors.Wrap(err, "LatestConfigDigestAndEpoch failed to fetch LatestReport") - } - if resp == nil { - return cd, epoch, errors.New("LatestConfigDigestAndEpoch expected LatestReport to return non-nil response") - } - if resp.Error != "" { - err = errors.New(resp.Error) - mt.lggr.Errorw("LatestConfigDigestAndEpoch failed; mercury server returned error", "err", err) - return cd, epoch, err - } - if resp.Report == nil { - _, cd, err = mt.cfgTracker.LatestConfigDetails(ctx) - mt.lggr.Info("LatestConfigDigestAndEpoch returned empty LatestReport, this is a brand new feed") - return cd, epoch, pkgerrors.Wrap(err, "fallback to LatestConfigDetails on empty LatestReport failed") - } - cd, err = ocrtypes.BytesToConfigDigest(resp.Report.ConfigDigest) - if err != nil { - return cd, epoch, pkgerrors.Wrapf(err, "LatestConfigDigestAndEpoch failed; response contained invalid config digest, got: 0x%x", resp.Report.ConfigDigest) - } - if !bytes.Equal(resp.Report.FeedId, mt.feedID[:]) { - return cd, epoch, fmt.Errorf("LatestConfigDigestAndEpoch failed; mismatched feed IDs, expected: 0x%x, got: 0x%x", mt.feedID, resp.Report.FeedId) - } - - mt.lggr.Debugw("LatestConfigDigestAndEpoch success", "cd", cd, "epoch", epoch) - - return cd, resp.Report.Epoch, nil + panic("not needed for OCR3") } func (mt *mercuryTransmitter) FetchInitialMaxFinalizedBlockNumber(ctx context.Context) (int64, error) { @@ -271,8 +259,15 @@ func (mt *mercuryTransmitter) FetchInitialMaxFinalizedBlockNumber(ctx context.Co return 0, err } if resp.Report == nil { - mt.lggr.Infow("FetchInitialMaxFinalizedBlockNumber returned empty LatestReport; this is a new feed so initial block number is 0", "currentBlockNum", 0) - return 0, nil + maxFinalizedBlockNumber := mt.initialBlockNumber - 1 + mt.lggr.Infof("FetchInitialMaxFinalizedBlockNumber returned empty LatestReport; this is a new feed so maxFinalizedBlockNumber=%d (initialBlockNumber=%d)", maxFinalizedBlockNumber, mt.initialBlockNumber) + // NOTE: It's important to return -1 if the server is missing any past + // report (brand new feed) since we will add 1 to the + // maxFinalizedBlockNumber to get the first validFromBlockNum, which + // ought to be zero. + // + // If "initialBlockNumber" is unset, this will give a starting block of zero. + return maxFinalizedBlockNumber, nil } else if !bytes.Equal(resp.Report.FeedId, mt.feedID[:]) { return 0, fmt.Errorf("FetchInitialMaxFinalizedBlockNumber failed; mismatched feed IDs, expected: 0x%x, got: 0x%x", mt.feedID, resp.Report.FeedId) } diff --git a/core/services/relay/evm/mercury/transmitter_test.go b/core/services/relay/evm/mercury/transmitter_test.go index d01c7af2ebe..95fbde197d5 100644 --- a/core/services/relay/evm/mercury/transmitter_test.go +++ b/core/services/relay/evm/mercury/transmitter_test.go @@ -9,13 +9,12 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb" - "github.com/smartcontractkit/chainlink/v2/core/utils" ) type MockWSRPCClient struct { @@ -63,21 +62,18 @@ func Test_MercuryTransmitter_Transmit(t *testing.T) { return out, nil }, } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID) + mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, 0) err := mt.Transmit(testutils.Context(t), sampleReportContext, sampleReport, sampleSigs) require.NoError(t, err) }) } -func Test_MercuryTransmitter_LatestConfigDigestAndEpoch(t *testing.T) { +func Test_MercuryTransmitter_FetchInitialMaxFinalizedBlockNumber(t *testing.T) { t.Parallel() lggr := logger.TestLogger(t) - sampleConfigDigest := utils.NewHash().Bytes() - wrongFeedID := []byte{1, 2, 3, 4} - t.Run("successful query", func(t *testing.T) { c := MockWSRPCClient{ latestReport: func(ctx context.Context, in *pb.LatestReportRequest) (out *pb.LatestReportResponse, err error) { @@ -86,116 +82,45 @@ func Test_MercuryTransmitter_LatestConfigDigestAndEpoch(t *testing.T) { out = new(pb.LatestReportResponse) out.Report = new(pb.Report) out.Report.FeedId = sampleFeedID[:] - out.Report.ConfigDigest = sampleConfigDigest - out.Report.Epoch = 42 + out.Report.CurrentBlockNumber = 42 return out, nil }, } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID) - cd, epoch, err := mt.LatestConfigDigestAndEpoch(testutils.Context(t)) + mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, 0) + bn, err := mt.FetchInitialMaxFinalizedBlockNumber(testutils.Context(t)) require.NoError(t, err) - assert.Equal(t, hexutil.Encode(sampleConfigDigest[:]), hexutil.Encode(cd[:])) - assert.Equal(t, 42, int(epoch)) - }) - t.Run("failing query", func(t *testing.T) { - c := MockWSRPCClient{ - latestReport: func(ctx context.Context, in *pb.LatestReportRequest) (out *pb.LatestReportResponse, err error) { - return nil, errors.New("something exploded") - }, - } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID) - _, _, err := mt.LatestConfigDigestAndEpoch(testutils.Context(t)) - require.Error(t, err) - assert.Contains(t, err.Error(), "something exploded") - }) - t.Run("return feed ID is wrong", func(t *testing.T) { - c := MockWSRPCClient{ - latestReport: func(ctx context.Context, in *pb.LatestReportRequest) (out *pb.LatestReportResponse, err error) { - require.NotNil(t, in) - assert.Equal(t, hexutil.Encode(sampleFeedID[:]), hexutil.Encode(in.FeedId)) - out = new(pb.LatestReportResponse) - out.Report = new(pb.Report) - out.Report.FeedId = wrongFeedID - out.Report.ConfigDigest = sampleConfigDigest - out.Report.Epoch = 42 - return out, nil - }, - } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID) - _, _, err := mt.LatestConfigDigestAndEpoch(testutils.Context(t)) - require.Error(t, err) - assert.Contains(t, err.Error(), "LatestConfigDigestAndEpoch failed; mismatched feed IDs, expected: 0x1c916b4aa7e57ca7b68ae1bf45653f56b656fd3aa335ef7fae696b663f1b8472, got: 0x01020304") - }) - t.Run("LatestReport returns nil response", func(t *testing.T) { - c := MockWSRPCClient{ - latestReport: func(ctx context.Context, in *pb.LatestReportRequest) (out *pb.LatestReportResponse, err error) { - return - }, - } - tracker := &MockTracker{} - mt := NewTransmitter(lggr, tracker, c, sampleClientPubKey, sampleFeedID) - _, _, err := mt.LatestConfigDigestAndEpoch(testutils.Context(t)) - require.Error(t, err) - assert.Contains(t, err.Error(), "LatestConfigDigestAndEpoch expected LatestReport to return non-nil response") + assert.Equal(t, 42, int(bn)) }) - - t.Run("falls back to latest config details if report is nil", func(t *testing.T) { - c := MockWSRPCClient{ - latestReport: func(ctx context.Context, in *pb.LatestReportRequest) (out *pb.LatestReportResponse, err error) { - out = new(pb.LatestReportResponse) - return - }, - } - t.Run("LatestConfigDetails succeeds", func(t *testing.T) { - tracker := &MockTracker{ - latestConfigDetails: func(ctx context.Context) (changedInBlock uint64, configDigest ocrtypes.ConfigDigest, err error) { - return 123, ocrtypes.ConfigDigest(sampleConfigDigest), nil + t.Run("successful query returning nil report (new feed)", func(t *testing.T) { + t.Run("when initialBlockNumber is unset (0)", func(t *testing.T) { + c := MockWSRPCClient{ + latestReport: func(ctx context.Context, in *pb.LatestReportRequest) (out *pb.LatestReportResponse, err error) { + out = new(pb.LatestReportResponse) + out.Report = nil + return out, nil }, } - mt := NewTransmitter(lggr, tracker, c, sampleClientPubKey, sampleFeedID) - cd, epoch, err := mt.LatestConfigDigestAndEpoch(testutils.Context(t)) + mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, 0) + bn, err := mt.FetchInitialMaxFinalizedBlockNumber(testutils.Context(t)) require.NoError(t, err) - assert.Equal(t, ocrtypes.ConfigDigest(sampleConfigDigest), cd) - assert.Equal(t, 0, int(epoch)) // always returns zero epoch if latest report is empty + assert.Equal(t, -1, int(bn)) }) - t.Run("LatestConfigDetails fails", func(t *testing.T) { - tracker := &MockTracker{ - latestConfigDetails: func(ctx context.Context) (changedInBlock uint64, configDigest ocrtypes.ConfigDigest, err error) { - return changedInBlock, configDigest, errors.New("something exploded") + t.Run("when initialBlockNumber is set to some non-zero value", func(t *testing.T) { + c := MockWSRPCClient{ + latestReport: func(ctx context.Context, in *pb.LatestReportRequest) (out *pb.LatestReportResponse, err error) { + out = new(pb.LatestReportResponse) + out.Report = nil + return out, nil }, } - mt := NewTransmitter(lggr, tracker, c, sampleClientPubKey, sampleFeedID) - _, _, err := mt.LatestConfigDigestAndEpoch(testutils.Context(t)) - require.Error(t, err) - assert.Contains(t, err.Error(), "something exploded") - }) - }) -} - -func Test_MercuryTransmitter_FetchInitialMaxFinalizedBlockNumber(t *testing.T) { - t.Parallel() - - lggr := logger.TestLogger(t) - - t.Run("successful query", func(t *testing.T) { - c := MockWSRPCClient{ - latestReport: func(ctx context.Context, in *pb.LatestReportRequest) (out *pb.LatestReportResponse, err error) { - require.NotNil(t, in) - assert.Equal(t, hexutil.Encode(sampleFeedID[:]), hexutil.Encode(in.FeedId)) - out = new(pb.LatestReportResponse) - out.Report = new(pb.Report) - out.Report.FeedId = sampleFeedID[:] - out.Report.CurrentBlockNumber = 42 - return out, nil - }, - } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID) - bn, err := mt.FetchInitialMaxFinalizedBlockNumber(testutils.Context(t)) - require.NoError(t, err) + mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, 42) + bn, err := mt.FetchInitialMaxFinalizedBlockNumber(testutils.Context(t)) + require.NoError(t, err) - assert.Equal(t, 42, int(bn)) + assert.Equal(t, 41, int(bn)) + }) }) t.Run("failing query", func(t *testing.T) { c := MockWSRPCClient{ @@ -203,7 +128,7 @@ func Test_MercuryTransmitter_FetchInitialMaxFinalizedBlockNumber(t *testing.T) { return nil, errors.New("something exploded") }, } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID) + mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, 0) _, err := mt.FetchInitialMaxFinalizedBlockNumber(testutils.Context(t)) require.Error(t, err) assert.Contains(t, err.Error(), "something exploded") @@ -220,7 +145,7 @@ func Test_MercuryTransmitter_FetchInitialMaxFinalizedBlockNumber(t *testing.T) { return out, nil }, } - mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID) + mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, 0) _, err := mt.FetchInitialMaxFinalizedBlockNumber(testutils.Context(t)) require.Error(t, err) assert.Contains(t, err.Error(), "FetchInitialMaxFinalizedBlockNumber failed; mismatched feed IDs, expected: 0x1c916b4aa7e57ca7b68ae1bf45653f56b656fd3aa335ef7fae696b663f1b8472, got: 0x") diff --git a/core/services/relay/evm/mercury_provider.go b/core/services/relay/evm/mercury_provider.go index 9b74dfbe278..eab855784b2 100644 --- a/core/services/relay/evm/mercury_provider.go +++ b/core/services/relay/evm/mercury_provider.go @@ -4,7 +4,7 @@ import ( "context" "errors" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "golang.org/x/exp/maps" relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury" diff --git a/core/services/relay/evm/ocr2keeper.go b/core/services/relay/evm/ocr2keeper.go index 8027954e7f7..ea32b0100d4 100644 --- a/core/services/relay/evm/ocr2keeper.go +++ b/core/services/relay/evm/ocr2keeper.go @@ -9,12 +9,12 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" - "github.com/smartcontractkit/libocr/offchainreporting2/chains/evmutil" + "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" "github.com/smartcontractkit/sqlx" relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm" "github.com/smartcontractkit/chainlink/v2/core/logger" diff --git a/core/services/relay/evm/ocr2vrf.go b/core/services/relay/evm/ocr2vrf.go index 5349c6816a3..fa4d6294dc9 100644 --- a/core/services/relay/evm/ocr2vrf.go +++ b/core/services/relay/evm/ocr2vrf.go @@ -9,8 +9,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" - "github.com/smartcontractkit/libocr/offchainreporting2/chains/evmutil" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/sqlx" relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types" @@ -19,7 +19,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/dkg/config" - types "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" ) // DKGProvider provides all components needed for a DKG plugin. diff --git a/core/services/relay/evm/request_round_db.go b/core/services/relay/evm/request_round_db.go index cb9ef3426d7..331d663918a 100644 --- a/core/services/relay/evm/request_round_db.go +++ b/core/services/relay/evm/request_round_db.go @@ -6,7 +6,7 @@ import ( "github.com/pkg/errors" "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/pg" diff --git a/core/services/relay/evm/request_round_tracker.go b/core/services/relay/evm/request_round_tracker.go index bfc7616e6fa..47851afbd0f 100644 --- a/core/services/relay/evm/request_round_tracker.go +++ b/core/services/relay/evm/request_round_tracker.go @@ -9,7 +9,7 @@ import ( gethTypes "github.com/ethereum/go-ethereum/core/types" "github.com/pkg/errors" "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/sqlx" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" diff --git a/core/services/relay/evm/request_round_tracker_test.go b/core/services/relay/evm/request_round_tracker_test.go index e6bfef941c4..509c55e8857 100644 --- a/core/services/relay/evm/request_round_tracker_test.go +++ b/core/services/relay/evm/request_round_tracker_test.go @@ -7,7 +7,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/pkg/errors" "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" - ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" diff --git a/core/store/migrate/migrations/0177_add_ocr_protocol_state.sql b/core/store/migrate/migrations/0177_add_ocr_protocol_state.sql new file mode 100644 index 00000000000..4193d876e84 --- /dev/null +++ b/core/store/migrate/migrations/0177_add_ocr_protocol_state.sql @@ -0,0 +1,12 @@ +-- +goose Up +CREATE TABLE IF NOT EXISTS ocr_protocol_states ( + config_digest bytea NOT NULL CHECK (octet_length(config_digest) = 32), + key text NOT NULL CHECK (key != ''), + value bytea NOT NULL +); + +CREATE UNIQUE INDEX IF NOT EXISTS idx_ocr_protocol_states ON ocr_protocol_states (config_digest, key); + + +-- +goose Down +DROP TABLE ocr_protocol_states; diff --git a/core/web/presenters/csa_key.go b/core/web/presenters/csa_key.go index 70236fda8d5..cdf5294d530 100644 --- a/core/web/presenters/csa_key.go +++ b/core/web/presenters/csa_key.go @@ -1,6 +1,8 @@ package presenters import ( + "fmt" + "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/csakey" ) @@ -19,7 +21,7 @@ func (CSAKeyResource) GetName() string { func NewCSAKeyResource(key csakey.KeyV2) *CSAKeyResource { r := &CSAKeyResource{ JAID: NewJAID(key.ID()), - PubKey: key.PublicKeyString(), + PubKey: fmt.Sprintf("csa_%s", key.PublicKeyString()), Version: 1, } diff --git a/core/web/presenters/csa_key_test.go b/core/web/presenters/csa_key_test.go index 74810e44db4..06f84db7dd5 100644 --- a/core/web/presenters/csa_key_test.go +++ b/core/web/presenters/csa_key_test.go @@ -27,7 +27,7 @@ func TestCSAKeyResource(t *testing.T) { "type":"csaKeys", "id":"%s", "attributes":{ - "publicKey": "%s", + "publicKey": "csa_%s", "version": 1 } } diff --git a/core/web/presenters/ocr_keys.go b/core/web/presenters/ocr_keys.go index 0befb240a47..8988971063e 100644 --- a/core/web/presenters/ocr_keys.go +++ b/core/web/presenters/ocr_keys.go @@ -3,6 +3,7 @@ package presenters import ( "encoding/hex" "fmt" + "sort" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocrkey" @@ -70,6 +71,13 @@ func NewOCR2KeysBundleResources(keys []ocr2key.KeyBundle) []OCR2KeysBundleResour for _, key := range keys { rs = append(rs, *NewOCR2KeysBundleResource(key)) } + // sort by chain type alphabetical, tie-break with ID + sort.SliceStable(rs, func(i, j int) bool { + if rs[i].ChainType == rs[j].ChainType { + return rs[i].ID < rs[j].ID + } + return rs[i].ChainType < rs[j].ChainType + }) return rs } diff --git a/core/web/resolver/csa_keys.go b/core/web/resolver/csa_keys.go index 4596e3859fe..267592b4280 100644 --- a/core/web/resolver/csa_keys.go +++ b/core/web/resolver/csa_keys.go @@ -1,6 +1,8 @@ package resolver import ( + "fmt" + "github.com/graph-gophers/graphql-go" "github.com/pkg/errors" @@ -24,7 +26,7 @@ func (r *CSAKeyResolver) ID() graphql.ID { // PubKey resolves the CSA Key public key string. func (r *CSAKeyResolver) PublicKey() string { - return r.key.PublicKeyString() + return fmt.Sprintf("csa_%s", r.key.PublicKeyString()) } // Version resolves the CSA Key version number. diff --git a/core/web/resolver/csa_keys_test.go b/core/web/resolver/csa_keys_test.go index 648761da9f0..a94a934efa3 100644 --- a/core/web/resolver/csa_keys_test.go +++ b/core/web/resolver/csa_keys_test.go @@ -40,7 +40,7 @@ func Test_CSAKeysQuery(t *testing.T) { expectedKeys = append(expectedKeys, expectedKey{ ID: k.ID(), Version: k.Version, - PubKey: k.PublicKeyString(), + PubKey: fmt.Sprintf("csa_%s", k.PublicKeyString()), }) } @@ -97,7 +97,7 @@ func Test_CreateCSAKey(t *testing.T) { "csaKey": { "id": "%s", "version": %d, - "publicKey": "%s" + "publicKey": "csa_%s" } } } @@ -165,7 +165,7 @@ func Test_DeleteCSAKey(t *testing.T) { "csaKey": { "id": "%s", "version": %d, - "publicKey": "%s" + "publicKey": "csa_%s" } } } diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 366be4905fa..4b70ab3922d 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -26,6 +26,11 @@ Order = 5 `JobPipeline.DefaultHTTPLimit`/`JobPipeline.DefaultHTTPTimeout`. To migrate to these new fields, set their values to be identical to `JobPipeline.DefaultHTTPLimit`/`JobPipeline.DefaultHTTPTimeout`. +- Low latency oracle jobs now support in-protocol block range guarantees. This + is necessary in order to produce reports with block number ranges that do not + overlap. It can now be guaranteed at the protocol level, so we can use local + state instead of relying on an unreliable round-trip to the Mercury server. + ### Fixed ### Changed diff --git a/go.mod b/go.mod index 31a58fd372c..9730cb6a4d6 100644 --- a/go.mod +++ b/go.mod @@ -65,12 +65,12 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/caigo v0.0.0-20230530082629-53a5a4bdb25e github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230525203711-20bed74ac906 - github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230606192102-72eb65f16e5e + github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230606234201-cca3103bf8a6 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230531071550-c058f7c3964f github.com/smartcontractkit/chainlink-starknet/relayer v0.0.0-20230601080524-3d8186742482 - github.com/smartcontractkit/libocr v0.0.0-20230525150148-a75f6e244bb3 - github.com/smartcontractkit/ocr2keepers v0.6.15 - github.com/smartcontractkit/ocr2vrf v0.0.0-20230605190626-969219bf1df9 + github.com/smartcontractkit/libocr v0.0.0-20230606215712-82b910bef5c1 + github.com/smartcontractkit/ocr2keepers v0.6.16-0.20230607110245-0809f2a4a41d + github.com/smartcontractkit/ocr2vrf v0.0.0-20230607140106-3de6d0aed120 github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb github.com/smartcontractkit/wsrpc v0.7.2 github.com/spf13/cast v1.5.1 @@ -310,7 +310,7 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect - github.com/sirupsen/logrus v1.9.0 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/afero v1.9.2 // indirect diff --git a/go.sum b/go.sum index 31a5d4c4211..0f0fef77053 100644 --- a/go.sum +++ b/go.sum @@ -1387,24 +1387,24 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartcontractkit/caigo v0.0.0-20230530082629-53a5a4bdb25e h1:XY8DncHICYQ1WDVpoXM7Tv3tztNHa1/DctDlSmqgU10= github.com/smartcontractkit/caigo v0.0.0-20230530082629-53a5a4bdb25e/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230525203711-20bed74ac906 h1:u7Lw7oqLEjADlJPJQnzlCLNSbj038QttaKY0lCa3V78= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230525203711-20bed74ac906/go.mod h1:MH+MRJaG4SZAbRq5g7//AFY9H9sg5+lLDQnm85aHP6A= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230606192102-72eb65f16e5e h1:wgVIpUakH0bwHVK2TnPxIXLU70X8iwyXzRvVVCtQHnE= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230606192102-72eb65f16e5e/go.mod h1:mCOS1RSmUcQwbxEChrNrOa2N/93rVU0WRP+JGfuPtPc= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230606234201-cca3103bf8a6 h1:dQG7RYxvMk9b/oJZ7sPDdm8oloFnH+YO6qLvto4Y7Nc= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230606234201-cca3103bf8a6/go.mod h1:MfZBUifutkv3aK7abyw5YmTJbqt8iFwcQDFikrxC/uI= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230531071550-c058f7c3964f h1:XtumoxAyCO4JnDbhUjD+BT3H3NohfpVG3IOLKWE5m+k= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230531071550-c058f7c3964f/go.mod h1:km46XAo6xebV4Q+WyRFfo3E2t80YqTkegJM4FEfo5/Y= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.0-20230601080524-3d8186742482 h1:ZblU/X27pIHAZ7c/37TZf7ykZ4jkfVUmvIcchyO2rnw= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.0-20230601080524-3d8186742482/go.mod h1:bQmQtng05ueHYaLRKtAr1/LCaUWvOaE5ch008u5yJ+M= -github.com/smartcontractkit/libocr v0.0.0-20230525150148-a75f6e244bb3 h1:/Gel/U5eIZ/BGGr25OrHaXiVDTAJ5DYX5+UlXp3q7Gg= -github.com/smartcontractkit/libocr v0.0.0-20230525150148-a75f6e244bb3/go.mod h1:5JnCHuYgmIP9ZyXzgAfI5Iwu0WxBtBKp+ApeT5o1Cjw= -github.com/smartcontractkit/ocr2keepers v0.6.15 h1:dFhg+qT+tc6b3G8N4qnAHuHe8N0m8CSA8g4YGSeTGPo= -github.com/smartcontractkit/ocr2keepers v0.6.15/go.mod h1:gqIksJFzdXFsHfGdCWm1uTxbwvAltgcwcaqIgAStC1A= -github.com/smartcontractkit/ocr2vrf v0.0.0-20230605190626-969219bf1df9 h1:qLzqm5g2fzkvaDRE3LB75t9a0BRo+5a8yabawoBxlMA= -github.com/smartcontractkit/ocr2vrf v0.0.0-20230605190626-969219bf1df9/go.mod h1:AZbOisIoA3cOUku8suZ+KWBnzbRiafmhi7UKiXoezrk= +github.com/smartcontractkit/libocr v0.0.0-20230606215712-82b910bef5c1 h1:caG9BWjnCxN/HPBA5ltDGadDraZAsjGIct4S8lh8D5c= +github.com/smartcontractkit/libocr v0.0.0-20230606215712-82b910bef5c1/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= +github.com/smartcontractkit/ocr2keepers v0.6.16-0.20230607110245-0809f2a4a41d h1:AVpFTCA9lyB0qdBP/kADxMka6QBHUtqL6PkeA7mtLK0= +github.com/smartcontractkit/ocr2keepers v0.6.16-0.20230607110245-0809f2a4a41d/go.mod h1:ueL+ADZm47x+UpfHAY9bd0soStL9YDwbUN265AJF788= +github.com/smartcontractkit/ocr2vrf v0.0.0-20230607140106-3de6d0aed120 h1:iG9aRJxfZRxlPNKPqbUioEHyfvHvp1B1V11Fo+BK4pc= +github.com/smartcontractkit/ocr2vrf v0.0.0-20230607140106-3de6d0aed120/go.mod h1:AT1OrDDOCd8vzmMsCnA70N+tZdq9AbdZAiAw+gQq260= github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb h1:OMaBUb4X9IFPLbGbCHsMU+kw/BPCrewaVwWGIBc0I4A= github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb/go.mod h1:HNUu4cJekUdsJbwRBCiOybtkPJEfGRELQPe2tkoDEyk= github.com/smartcontractkit/wsrpc v0.7.2 h1:iBXzMeg7vc5YoezIQBq896y25BARw7OKbhrb6vPbtRQ= diff --git a/integration-tests/actions/automation_ocr_helpers.go b/integration-tests/actions/automation_ocr_helpers.go index 6b8a87450f0..f4f8d7c75d1 100644 --- a/integration-tests/actions/automation_ocr_helpers.go +++ b/integration-tests/actions/automation_ocr_helpers.go @@ -15,16 +15,15 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/utils" - "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" + "github.com/smartcontractkit/chainlink/integration-tests/client" + "github.com/smartcontractkit/chainlink/integration-tests/contracts" + "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" + "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" types2 "github.com/smartcontractkit/ocr2keepers/pkg/types" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" "github.com/smartcontractkit/chainlink/v2/core/store/models" - - "github.com/smartcontractkit/chainlink/integration-tests/client" - "github.com/smartcontractkit/chainlink/integration-tests/contracts" - "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" ) func BuildAutoOCR2ConfigVars( diff --git a/integration-tests/actions/ocr2_helpers.go b/integration-tests/actions/ocr2_helpers.go index fe9ff746191..db9a92883bc 100644 --- a/integration-tests/actions/ocr2_helpers.go +++ b/integration-tests/actions/ocr2_helpers.go @@ -19,9 +19,9 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" "github.com/smartcontractkit/chainlink/v2/core/store/models" - "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median" - "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" diff --git a/integration-tests/actions/ocr2vrf_actions/ocr2vrf_config_helpers.go b/integration-tests/actions/ocr2vrf_actions/ocr2vrf_config_helpers.go index 78e101ef378..83033710f41 100644 --- a/integration-tests/actions/ocr2vrf_actions/ocr2vrf_config_helpers.go +++ b/integration-tests/actions/ocr2vrf_actions/ocr2vrf_config_helpers.go @@ -19,8 +19,8 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/utils" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" - "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" - "github.com/smartcontractkit/libocr/offchainreporting2/types" + "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/smartcontractkit/ocr2vrf/altbn_128" "github.com/smartcontractkit/ocr2vrf/dkg" "github.com/smartcontractkit/ocr2vrf/ocr2vrf" diff --git a/integration-tests/contracts/contract_models.go b/integration-tests/contracts/contract_models.go index a2d0a8ea7b5..be25b84ff63 100644 --- a/integration-tests/contracts/contract_models.go +++ b/integration-tests/contracts/contract_models.go @@ -12,7 +12,7 @@ import ( "github.com/smartcontractkit/libocr/gethwrappers/offchainaggregator" "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" ocrConfigHelper "github.com/smartcontractkit/libocr/offchainreporting/confighelper" - ocrConfigHelper2 "github.com/smartcontractkit/libocr/offchainreporting2/confighelper" + ocrConfigHelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/flux_aggregator_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/functions_billing_registry_events_mock" diff --git a/integration-tests/go.mod b/integration-tests/go.mod index c2d9b38d9b7..7323503d2d8 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -20,9 +20,9 @@ require ( github.com/smartcontractkit/chainlink-env v0.32.5 github.com/smartcontractkit/chainlink-testing-framework v1.11.6 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 - github.com/smartcontractkit/libocr v0.0.0-20230525150148-a75f6e244bb3 - github.com/smartcontractkit/ocr2keepers v0.6.15 - github.com/smartcontractkit/ocr2vrf v0.0.0-20230605190626-969219bf1df9 + github.com/smartcontractkit/libocr v0.0.0-20230606215712-82b910bef5c1 + github.com/smartcontractkit/ocr2keepers v0.6.16-0.20230607110245-0809f2a4a41d + github.com/smartcontractkit/ocr2vrf v0.0.0-20230607140106-3de6d0aed120 github.com/stretchr/testify v1.8.4 github.com/test-go/testify v1.1.4 github.com/umbracle/ethgo v0.1.3 @@ -287,9 +287,9 @@ require ( github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.22.12 // indirect github.com/shopspring/decimal v1.3.1 // indirect - github.com/sirupsen/logrus v1.9.0 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/caigo v0.0.0-20230530082629-53a5a4bdb25e // indirect - github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230606192102-72eb65f16e5e // indirect + github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230606234201-cca3103bf8a6 // indirect github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb // indirect github.com/smartcontractkit/wsrpc v0.7.2 // indirect github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index c4e9de39c44..7c25dafe8c5 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1360,8 +1360,8 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/slack-go/slack v0.12.2 h1:x3OppyMyGIbbiyFhsBmpf9pwkUzMhthJMRNmNlA4LaQ= github.com/slack-go/slack v0.12.2/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= github.com/smartcontractkit/caigo v0.0.0-20230530082629-53a5a4bdb25e h1:XY8DncHICYQ1WDVpoXM7Tv3tztNHa1/DctDlSmqgU10= @@ -1369,18 +1369,18 @@ github.com/smartcontractkit/caigo v0.0.0-20230530082629-53a5a4bdb25e/go.mod h1:2 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230525203711-20bed74ac906 h1:u7Lw7oqLEjADlJPJQnzlCLNSbj038QttaKY0lCa3V78= github.com/smartcontractkit/chainlink-env v0.32.5 h1:xwlaie96Q+BO//Wl4DHyzwktgLg/62j/JiX12hUSV0A= github.com/smartcontractkit/chainlink-env v0.32.5/go.mod h1:9c0Czq4a6wZKY20BcoAlK29DnejQIiLo/MwKYtSFnHk= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230606192102-72eb65f16e5e h1:wgVIpUakH0bwHVK2TnPxIXLU70X8iwyXzRvVVCtQHnE= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230606192102-72eb65f16e5e/go.mod h1:mCOS1RSmUcQwbxEChrNrOa2N/93rVU0WRP+JGfuPtPc= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230606234201-cca3103bf8a6 h1:dQG7RYxvMk9b/oJZ7sPDdm8oloFnH+YO6qLvto4Y7Nc= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230606234201-cca3103bf8a6/go.mod h1:MfZBUifutkv3aK7abyw5YmTJbqt8iFwcQDFikrxC/uI= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230531071550-c058f7c3964f h1:XtumoxAyCO4JnDbhUjD+BT3H3NohfpVG3IOLKWE5m+k= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.0-20230601080524-3d8186742482 h1:ZblU/X27pIHAZ7c/37TZf7ykZ4jkfVUmvIcchyO2rnw= github.com/smartcontractkit/chainlink-testing-framework v1.11.6 h1:W5BfxVDRWZ/PepyMUyJqR8w8XcnFbP4aZqL+ha+DiaA= github.com/smartcontractkit/chainlink-testing-framework v1.11.6/go.mod h1:76JD6PEhH9QActeOUKfPjm/4Cfyn+cpp3u0ASoq0RpU= -github.com/smartcontractkit/libocr v0.0.0-20230525150148-a75f6e244bb3 h1:/Gel/U5eIZ/BGGr25OrHaXiVDTAJ5DYX5+UlXp3q7Gg= -github.com/smartcontractkit/libocr v0.0.0-20230525150148-a75f6e244bb3/go.mod h1:5JnCHuYgmIP9ZyXzgAfI5Iwu0WxBtBKp+ApeT5o1Cjw= -github.com/smartcontractkit/ocr2keepers v0.6.15 h1:dFhg+qT+tc6b3G8N4qnAHuHe8N0m8CSA8g4YGSeTGPo= -github.com/smartcontractkit/ocr2keepers v0.6.15/go.mod h1:gqIksJFzdXFsHfGdCWm1uTxbwvAltgcwcaqIgAStC1A= -github.com/smartcontractkit/ocr2vrf v0.0.0-20230605190626-969219bf1df9 h1:qLzqm5g2fzkvaDRE3LB75t9a0BRo+5a8yabawoBxlMA= -github.com/smartcontractkit/ocr2vrf v0.0.0-20230605190626-969219bf1df9/go.mod h1:AZbOisIoA3cOUku8suZ+KWBnzbRiafmhi7UKiXoezrk= +github.com/smartcontractkit/libocr v0.0.0-20230606215712-82b910bef5c1 h1:caG9BWjnCxN/HPBA5ltDGadDraZAsjGIct4S8lh8D5c= +github.com/smartcontractkit/libocr v0.0.0-20230606215712-82b910bef5c1/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= +github.com/smartcontractkit/ocr2keepers v0.6.16-0.20230607110245-0809f2a4a41d h1:AVpFTCA9lyB0qdBP/kADxMka6QBHUtqL6PkeA7mtLK0= +github.com/smartcontractkit/ocr2keepers v0.6.16-0.20230607110245-0809f2a4a41d/go.mod h1:ueL+ADZm47x+UpfHAY9bd0soStL9YDwbUN265AJF788= +github.com/smartcontractkit/ocr2vrf v0.0.0-20230607140106-3de6d0aed120 h1:iG9aRJxfZRxlPNKPqbUioEHyfvHvp1B1V11Fo+BK4pc= +github.com/smartcontractkit/ocr2vrf v0.0.0-20230607140106-3de6d0aed120/go.mod h1:AT1OrDDOCd8vzmMsCnA70N+tZdq9AbdZAiAw+gQq260= github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb h1:OMaBUb4X9IFPLbGbCHsMU+kw/BPCrewaVwWGIBc0I4A= github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb/go.mod h1:HNUu4cJekUdsJbwRBCiOybtkPJEfGRELQPe2tkoDEyk= github.com/smartcontractkit/wsrpc v0.7.2 h1:iBXzMeg7vc5YoezIQBq896y25BARw7OKbhrb6vPbtRQ=