Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci-core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@

- name: Notify Slack
# Skip for now as it's always failing on scheduled runs
if: false

Check failure on line 199 in .github/workflows/ci-core.yml

View workflow job for this annotation

GitHub Actions / Validate Github Action Workflows

[actionlint] reported by reviewdog 🐶 constant expression "false" in condition. remove the if: section [if-cond] Raw Output: e:.github/workflows/ci-core.yml:199:13: constant expression "false" in condition. remove the if: section [if-cond]
# if: ${{ failure() && needs.run-frequency.outputs.one-per-day-frequency == 'true' }}
uses: slackapi/slack-github-action@485a9d42d3a73031f12ec201c457e2162c45d02d # v2.0.0
with:
Expand Down Expand Up @@ -365,6 +365,7 @@
with:
tmpfs: "true"
image-tag: "16-alpine"
postgres-options: "-c max_connections=1000 -c shared_buffers=2GB -c fsync=off -c synchronous_commit=off -c full_page_writes=off -c client_min_messages=warning" # Turn off some prod-protections to make postgres go brrr. https://github.com/peterldowns/pgtestdb#how-do-i-make-it-go-faster

- name: Touching core/web/assets/index.html
if: ${{ matrix.type.should-run == 'true' }}
Expand Down Expand Up @@ -434,7 +435,7 @@
GH_REPO: ${{ github.repository }}
GH_RUN_ID: ${{ github.run_id }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |

Check warning on line 438 in .github/workflows/ci-core.yml

View workflow job for this annotation

GitHub Actions / Validate Github Action Workflows

[actionlint] reported by reviewdog 🐶 shellcheck reported issue in this script: SC2038:warning:1:1: Use 'find .. -print0 | xargs -0 ..' or 'find .. -exec .. +' to allow non-alphanumeric filenames [shellcheck] Raw Output: w:.github/workflows/ci-core.yml:438:9: shellcheck reported issue in this script: SC2038:warning:1:1: Use 'find .. -print0 | xargs -0 ..' or 'find .. -exec .. +' to allow non-alphanumeric filenames [shellcheck]
find race.* | xargs cat >> races.txt
if [[ -s races.txt ]]; then
cat races.txt
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/ci-deployments.yml
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ jobs:
with:
tmpfs: "true"
image-tag: "16-alpine"
postgres-options: "-c max_connections=1000 -c shared_buffers=2GB -c fsync=off -c synchronous_commit=off -c full_page_writes=off -c client_min_messages=warning" # Turn off some prod-protections to make postgres go brrr. https://github.com/peterldowns/pgtestdb#how-do-i-make-it-go-faster
- name: Download Go vendor packages
run: go mod download
- name: Setup DB
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ core/services/job/testdata/wasm/testmodule.wasm
core/services/job/testdata/wasm/testmodule.br
temp-repo
diagnose-*/
diagnose-attempted-fixes-*.jsonl

# DB state
./db/
Expand Down
4 changes: 2 additions & 2 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
golang 1.26.2
golang 1.26.3
mockery 2.53.0
nodejs 20.13.1
pnpm 10.6.5
postgres 15.1
helm 3.18.4
golangci-lint 2.11.4
golangci-lint 2.12.2
protoc 29.3
python 3.10.5
6 changes: 2 additions & 4 deletions core/services/ocr2/plugins/llo/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,8 @@ func (p PluginConfig) Validate() (merr error) {
if err := json.Unmarshal([]byte(p.ChannelDefinitions), &cd); err != nil {
merr = errors.Join(merr, fmt.Errorf("channelDefinitions is invalid JSON: %w", err))
}
} else {
if p.ChannelDefinitionsContractAddress == (common.Address{}) {
merr = errors.Join(merr, errors.New("llo: ChannelDefinitionsContractAddress is required if ChannelDefinitions is not specified"))
}
} else if p.ChannelDefinitionsContractAddress == (common.Address{}) {
merr = errors.Join(merr, errors.New("llo: ChannelDefinitionsContractAddress is required if ChannelDefinitions is not specified"))
}

merr = errors.Join(merr, validateKeyBundleIDs(p.KeyBundleIDs))
Expand Down
5 changes: 2 additions & 3 deletions core/services/ocr2/plugins/llo/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,7 @@ func Test_Config(t *testing.T) {
assert.False(t, mc.BenchmarkMode)

err = mc.Validate()
require.Error(t, err)
assert.EqualError(t, err, "llo: ChannelDefinitionsContractAddress is required if ChannelDefinitions is not specified")
require.EqualError(t, err, "llo: ChannelDefinitionsContractAddress is required if ChannelDefinitions is not specified")
})

t.Run("with invalid values", func(t *testing.T) {
Expand All @@ -124,7 +123,7 @@ func Test_Config(t *testing.T) {
var mc PluginConfig
err := toml.Unmarshal([]byte(rawToml), &mc)
require.Error(t, err)
assert.EqualError(t, err, `toml: cannot decode TOML string into struct field config.PluginConfig.ChannelDefinitionsContractFromBlock of type int64`)
require.EqualError(t, err, `toml: cannot decode TOML string into struct field config.PluginConfig.ChannelDefinitionsContractFromBlock of type int64`)
assert.False(t, mc.BenchmarkMode)

rawToml = `
Expand Down
46 changes: 24 additions & 22 deletions core/services/ocr2/plugins/llo/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ type mercuryServer struct {

func startMercuryServer(t *testing.T, srv *mercuryServer, pubKeys []ed25519.PublicKey) (serverURL string) {
// Set up the grpc server
lis, err := net.Listen("tcp", "127.0.0.1:0")
var lc net.ListenConfig
lis, err := lc.Listen(testutils.Context(t), "tcp", "127.0.0.1:0")
if err != nil {
t.Fatalf("[MAIN] failed to listen: %v", err)
}
Expand Down Expand Up @@ -170,44 +171,44 @@ func setupNode(

config, _ := heavyweight.FullTestDBV2(t, func(c *chainlink.Config, s *chainlink.Secrets) {
// [JobPipeline]
c.JobPipeline.MaxSuccessfulRuns = ptr(uint64(0))
c.JobPipeline.VerboseLogging = ptr(true)
c.JobPipeline.MaxSuccessfulRuns = new(uint64(0))
c.JobPipeline.VerboseLogging = new(true)

// [Feature]
c.Feature.UICSAKeys = ptr(true)
c.Feature.LogPoller = ptr(true)
c.Feature.FeedsManager = ptr(false)
c.Feature.UICSAKeys = new(true)
c.Feature.LogPoller = new(true)
c.Feature.FeedsManager = new(false)

// [OCR]
c.OCR.Enabled = ptr(false)
c.OCR.Enabled = new(false)

// [OCR2]
c.OCR2.Enabled = ptr(true)
c.OCR2.Enabled = new(true)
c.OCR2.ContractPollInterval = commonconfig.MustNewDuration(100 * time.Millisecond)

// [P2P]
c.P2P.PeerID = ptr(p2pKey.PeerID())
c.P2P.TraceLogging = ptr(true)
c.P2P.PeerID = new(p2pKey.PeerID())
c.P2P.TraceLogging = new(true)

// [P2P.V2]
c.P2P.V2.Enabled = ptr(true)
c.P2P.V2.Enabled = new(true)
c.P2P.V2.AnnounceAddresses = &p2paddresses
c.P2P.V2.ListenAddresses = &p2paddresses
c.P2P.V2.DeltaDial = commonconfig.MustNewDuration(500 * time.Millisecond)
c.P2P.V2.DeltaReconcile = commonconfig.MustNewDuration(5 * time.Second)

// [Mercury]
c.Mercury.VerboseLogging = ptr(true)
c.Mercury.VerboseLogging = new(true)

// [Log]
c.Log.Level = ptr(toml.LogLevel(zapcore.DebugLevel)) // generally speaking we want debug level for logs unless overridden
c.Log.Level = new(toml.LogLevel(zapcore.DebugLevel)) // generally speaking we want debug level for logs unless overridden

// [CRE]
c.CRE.UseLocalTimeProvider = ptr(true)
c.CRE.UseLocalTimeProvider = new(true)

// [EVM.Transactions]
for _, evmCfg := range c.EVM {
evmCfg.Transactions.Enabled = ptr(false) // don't need txmgr
evmCfg.Transactions.Enabled = new(false) // don't need txmgr
}

// Optional overrides
Expand All @@ -232,8 +233,6 @@ func setupNode(
return app, p2pKey.PeerID().Raw(), csaKey.StaticSizedPublicKey(), ocr2kb, observedLogs
}

func ptr[T any](t T) *T { return &t }

// receiveWithTimeout receives from the packet channel with a timeout.
// It returns the packet if a packet was received or an error if the timeout is reached
// or the channel is closed unexpectedly.
Expand Down Expand Up @@ -402,14 +401,18 @@ func createSingleDecimalBridge(t *testing.T, name string, i int, p decimal.Decim
ctx := testutils.Context(t)
bridge := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
b, err := io.ReadAll(req.Body)
require.NoError(t, err)
require.JSONEq(t, `{"data":{"data":"foo"}}`, string(b))
if !assert.NoError(t, err) {
return
}
if !assert.JSONEq(t, `{"data":{"data":"foo"}}`, string(b)) {
return
}

res.WriteHeader(http.StatusOK)
val := p.String()
resp := fmt.Sprintf(`{"result": %s}`, val)
_, err = res.Write([]byte(resp))
require.NoError(t, err)
assert.NoError(t, err)
}))
t.Cleanup(bridge.Close)
u, _ := url.Parse(bridge.URL)
Expand All @@ -418,7 +421,6 @@ func createSingleDecimalBridge(t *testing.T, name string, i int, p decimal.Decim
Name: bridges.BridgeName(bridgeName),
URL: models.WebURL(*u),
}))

return bridgeName
}

Expand Down Expand Up @@ -508,7 +510,7 @@ func addOCRJobsEVMPremiumLegacy(
jobIDs[i] = make(map[uint32]int32)
}
for j, strm := range streams {
// assume that streams are native, link and additionals are quote
// assume that streams are native, link and additional streams are quote
if j < 2 {
var name string
if j == 0 {
Expand Down
58 changes: 25 additions & 33 deletions core/services/ocr2/plugins/llo/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package llo_test

import (
"crypto/ed25519"
sha3 "crypto/sha3"
"encoding/binary"
"encoding/hex"
"encoding/json"
Expand All @@ -25,7 +26,6 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/zap/zapcore"
"golang.org/x/crypto/sha3"
"google.golang.org/grpc/peer"
"google.golang.org/protobuf/proto"

Expand Down Expand Up @@ -357,9 +357,9 @@ func setProductionConfig(t *testing.T, donID uint32, steve *bind.TransactOpts, b
func setBlueGreenConfig(t *testing.T, donID uint32, steve *bind.TransactOpts, backend evmtypes.Backend, configurator *configurator.Configurator, configuratorAddress common.Address, nodes []Node, opts ...OCRConfigOption) ocr2types.ConfigDigest {
signers, _, _, onchainConfig, offchainConfigVersion, offchainConfig := generateConfig(t, opts...)

var onchainPubKeys [][]byte
for _, signer := range signers {
onchainPubKeys = append(onchainPubKeys, signer)
onchainPubKeys := make([][]byte, len(signers))
for i, signer := range signers {
onchainPubKeys[i] = signer
}
offchainTransmitters := make([][32]byte, nNodes)
for i := range nNodes {
Expand Down Expand Up @@ -450,7 +450,7 @@ func testIntegrationLLOEVMPremiumLegacy(t *testing.T, offchainConfig datastreams
clientPubKeys[i] = key.PublicKey
}

steve, backend, _, _, verifier, _, verifierProxy, _, configStore, configStoreAddress, legacyVerifier, legacyVerifierAddr, _, _ := setupBlockchain(t)
steve, backend, _, _, verifier, _, _, _, configStore, configStoreAddress, legacyVerifier, legacyVerifierAddr, _, _ := setupBlockchain(t)
fromBlock := 1

// Setup bootstrap
Expand All @@ -476,7 +476,7 @@ func testIntegrationLLOEVMPremiumLegacy(t *testing.T, offchainConfig datastreams

// Setup oracle nodes
oracles, nodes := setupNodes(t, nNodes, backend, clientCSAKeys, func(c *chainlink.Config) {
c.Mercury.Transmitter.Protocol = ptr(config.MercuryTransmitterProtocolGRPC)
c.Mercury.Transmitter.Protocol = new(config.MercuryTransmitterProtocolGRPC)
})

chainID := testutils.SimulatedChainID
Expand Down Expand Up @@ -592,7 +592,8 @@ channelDefinitionsContractFromBlock = %d`, serverURL, serverPubKey, donID, confi
}

var expectedBm, expectedBid, expectedAsk *big.Int
if feedID == quoteStreamFeedID1 { //nolint
//nolint:gocritic,staticcheck // switch case doesn't play nice with these types
if feedID == quoteStreamFeedID1 {
expectedBm = quoteStream1.baseBenchmarkPrice.Mul(multiplier).BigInt()
expectedBid = quoteStream1.baseBid.Mul(multiplier).BigInt()
expectedAsk = quoteStream1.baseAsk.Mul(multiplier).BigInt()
Expand All @@ -601,14 +602,14 @@ channelDefinitionsContractFromBlock = %d`, serverURL, serverPubKey, donID, confi
expectedBid = quoteStream2.baseBid.Mul(multiplier).BigInt()
expectedAsk = quoteStream2.baseAsk.Mul(multiplier).BigInt()
} else {
t.Fatalf("unrecognized feedID: 0x%x", feedID)
require.FailNowf(t, "unrecognized feedID: 0x%x", hex.EncodeToString(feedID[:]))
}

assert.GreaterOrEqual(t, reportElems["validFromTimestamp"].(uint32), uint32(testStartTimeStamp.Unix()))
assert.GreaterOrEqual(t, int(reportElems["observationsTimestamp"].(uint32)), int(testStartTimeStamp.Unix()))
assert.GreaterOrEqual(t, int64(reportElems["validFromTimestamp"].(uint32)), testStartTimeStamp.Unix())
assert.GreaterOrEqual(t, int64(reportElems["observationsTimestamp"].(uint32)), testStartTimeStamp.Unix())
assert.Equal(t, "33597747607000", reportElems["nativeFee"].(*big.Int).String())
assert.Equal(t, "7547169811320755", reportElems["linkFee"].(*big.Int).String())
assert.Equal(t, reportElems["observationsTimestamp"].(uint32)+uint32(expirationWindow), reportElems["expiresAt"].(uint32))
assert.Equal(t, int64(reportElems["observationsTimestamp"].(uint32))+int64(expirationWindow), int64(reportElems["expiresAt"].(uint32)))
assert.Equal(t, expectedBm.String(), reportElems["benchmarkPrice"].(*big.Int).String())
assert.Equal(t, expectedBid.String(), reportElems["bid"].(*big.Int).String())
assert.Equal(t, expectedAsk.String(), reportElems["ask"].(*big.Int).String())
Expand All @@ -629,16 +630,6 @@ channelDefinitionsContractFromBlock = %d`, serverURL, serverPubKey, donID, confi
assert.Subset(t, signerAddresses, reportSigners)
}

// test on-chain verification
t.Run("on-chain verification", func(t *testing.T) {
t.Skip("SKIP - MERC-6637")
// Disabled because it flakes, sometimes returns "execution reverted"
// No idea why
// https://smartcontract-it.atlassian.net/browse/MERC-6637
_, err = verifierProxy.Verify(steve, req.req.Payload, []byte{})
require.NoError(t, err)
})

pr, ok := peer.FromContext(req.ctx)
require.True(t, ok)
t.Logf("oracle %x reported for 0x%x", pr.String(), feedID[:])
Expand Down Expand Up @@ -717,7 +708,7 @@ func testIntegrationLLOMultiFormats(t *testing.T, offchainConfig datastreamsllo.

// Setup oracle nodes
oracles, nodes := setupNodes(t, nNodes, backend, clientCSAKeys, func(c *chainlink.Config) {
c.Mercury.Transmitter.Protocol = ptr(config.MercuryTransmitterProtocolGRPC)
c.Mercury.Transmitter.Protocol = new(config.MercuryTransmitterProtocolGRPC)
})

chainID := testutils.SimulatedChainID
Expand Down Expand Up @@ -1469,7 +1460,7 @@ func TestIntegration_LLO_stress_test_V1(t *testing.T) {
bootstrapCSAKey := csakey.MustNewV2XXXTestingOnly(big.NewInt(salt - 1))
bootstrapNodePort := freeport.GetOne(t)
appBootstrap, bootstrapPeerID, _, bootstrapKb, _ := setupNode(t, bootstrapNodePort, "bootstrap_llo", backend, bootstrapCSAKey, func(c *chainlink.Config) {
c.Log.Level = ptr(logLevel)
c.Log.Level = new(logLevel)
})
bootstrapNode := Node{App: appBootstrap, KeyBundle: bootstrapKb}

Expand All @@ -1490,8 +1481,8 @@ func TestIntegration_LLO_stress_test_V1(t *testing.T) {

// Setup oracle nodes
oracles, nodes := setupNodes(t, nNodes, backend, clientCSAKeys, func(c *chainlink.Config) {
c.Mercury.Transmitter.Protocol = ptr(config.MercuryTransmitterProtocolGRPC)
c.Log.Level = ptr(logLevel)
c.Mercury.Transmitter.Protocol = new(config.MercuryTransmitterProtocolGRPC)
c.Log.Level = new(logLevel)
})

chainID := testutils.SimulatedChainID
Expand Down Expand Up @@ -1546,7 +1537,8 @@ channelDefinitionsContractFromBlock = %d`, serverURL, serverPubKey, donID, confi
}

// Set config on configurator
opts := []OCRConfigOption{WithOracles(oracles)}
opts := make([]OCRConfigOption, 0, 1+len(ocrConfigOpts))
opts = append(opts, WithOracles(oracles))
opts = append(opts, ocrConfigOpts...)
blueDigest := setProductionConfig(
t, donID, steve, backend, configurator, configuratorAddress, nodes, opts...,
Expand Down Expand Up @@ -1694,7 +1686,7 @@ func TestIntegration_LLO_transmit_errors(t *testing.T) {
bootstrapCSAKey := csakey.MustNewV2XXXTestingOnly(big.NewInt(salt - 1))
bootstrapNodePort := freeport.GetOne(t)
appBootstrap, bootstrapPeerID, _, bootstrapKb, _ := setupNode(t, bootstrapNodePort, "bootstrap_llo", backend, bootstrapCSAKey, func(c *chainlink.Config) {
c.Log.Level = ptr(logLevel)
c.Log.Level = new(logLevel)
})
bootstrapNode := Node{App: appBootstrap, KeyBundle: bootstrapKb}

Expand All @@ -1715,9 +1707,9 @@ func TestIntegration_LLO_transmit_errors(t *testing.T) {

// Setup oracle nodes
oracles, nodes := setupNodes(t, nNodes, backend, clientCSAKeys, func(c *chainlink.Config) {
c.Mercury.Transmitter.Protocol = ptr(config.MercuryTransmitterProtocolGRPC)
c.Mercury.Transmitter.TransmitQueueMaxSize = ptr(uint32(maxQueueSize)) // Test queue overflow
c.Log.Level = ptr(logLevel)
c.Mercury.Transmitter.Protocol = new(config.MercuryTransmitterProtocolGRPC)
c.Mercury.Transmitter.TransmitQueueMaxSize = new(uint32(maxQueueSize)) // Test queue overflow
c.Log.Level = new(logLevel)
})

chainID := testutils.SimulatedChainID
Expand Down Expand Up @@ -1869,7 +1861,7 @@ func testIntegrationLLOBlueGreenLifecycle(t *testing.T, offchainConfig datastrea

// Setup oracle nodes
oracles, nodes := setupNodes(t, nNodes, backend, clientCSAKeys, func(c *chainlink.Config) {
c.Mercury.Transmitter.Protocol = ptr(config.MercuryTransmitterProtocolGRPC)
c.Mercury.Transmitter.Protocol = new(config.MercuryTransmitterProtocolGRPC)
})

chainID := testutils.SimulatedChainID
Expand Down Expand Up @@ -2229,7 +2221,7 @@ func TestIntegration_LLO_channel_merging_owners_adders(t *testing.T) {

// Setup oracle nodes
oracles, nodes := setupNodes(t, nNodes, backend, clientCSAKeys, func(c *chainlink.Config) {
c.Mercury.Transmitter.Protocol = ptr(config.MercuryTransmitterProtocolGRPC)
c.Mercury.Transmitter.Protocol = new(config.MercuryTransmitterProtocolGRPC)
})

chainID := testutils.SimulatedChainID
Expand Down Expand Up @@ -2736,7 +2728,7 @@ func TestIntegration_LLO_tombstone_stops_observations_and_reports(t *testing.T)
serverURL := startMercuryServer(t, srv, clientPubKeys)

oracles, nodes := setupNodes(t, nNodes, backend, clientCSAKeys, func(c *chainlink.Config) {
c.Mercury.Transmitter.Protocol = ptr(config.MercuryTransmitterProtocolGRPC)
c.Mercury.Transmitter.Protocol = new(config.MercuryTransmitterProtocolGRPC)
})

chainID := testutils.SimulatedChainID
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ package llo_test

import (
"bytes"
sha3 "crypto/sha3"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"io"
"maps"
"math/rand"
"net/http"
"strconv"
Expand All @@ -19,7 +21,6 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/zap/zapcore"
"golang.org/x/crypto/sha3"

"github.com/smartcontractkit/chainlink-common/pkg/services/servicetest"
llotypes "github.com/smartcontractkit/chainlink-common/pkg/types/llo"
Expand Down Expand Up @@ -120,9 +121,7 @@ func extractChannelDefinitions(defsJSON json.RawMessage) llotypes.ChannelDefinit
}
result := make(llotypes.ChannelDefinitions)
for _, sourceDef := range sourceDefs {
for channelID, def := range sourceDef.Definitions {
result[channelID] = def
}
maps.Copy(result, sourceDef.Definitions)
}
return result
}
Expand Down
Loading
Loading