Skip to content
Merged
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
142 changes: 80 additions & 62 deletions core/capabilities/ccip/oraclecreator/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@
const (
defaultCommitGasLimit = 500_000
defaultExecGasLimit = 6_500_000

// readerWriterCreationTimeout bounds the per-chain contract reader/writer creation,
// binding, and startup during oracle creation.
// Applied per chain, so it must stay small: a DON can span many chains and the timeout
// is spent serially in the worst case. 10s matches the other blockchain-facing timeouts
// in defaultLocalConfig and rpctimeout.Default.
readerWriterCreationTimeout = 10 * time.Second
)

// pluginOracleCreator creates oracles that reference plugins running
Expand Down Expand Up @@ -639,7 +646,7 @@
//
// Since not every node will support every chain, we may not have a reader/writer for
// every chain that the role DON will be servicing.
func (i *pluginOracleCreator) createReadersAndWriters(

Check warning on line 649 in core/capabilities/ccip/oraclecreator/plugin.go

View check run for this annotation

CL-sonarqube-production / SonarQube Code Analysis

Refactor this method to reduce its Cognitive Complexity from 44 to the 30 allowed.

[S3776] Cognitive Complexity of functions should not be too high See more on https://sonarqube.main.prod.cldev.sh/project/issues?id=smartcontractkit_chainlink&pullRequest=23199&issues=012a3f4f-f552-4adf-ad2e-a02eae3464ee&open=012a3f4f-f552-4adf-ad2e-a02eae3464ee
ctx context.Context,
crcw ccipcommon.MultiChainRW,
destChainID string,
Expand Down Expand Up @@ -684,76 +691,87 @@
extendedReaders := make(map[cciptypes.ChainSelector]contractreader.Extended)
chainWriters := make(map[cciptypes.ChainSelector]types.ContractWriter)
for relayID, relayer := range i.relayers {
chainID := relayID.ChainID
relayChainFamily := relayID.Network
chainDetails, err1 := chainsel.GetChainDetailsByChainIDAndFamily(chainID, relayChainFamily)
chainSelector := cciptypes.ChainSelector(chainDetails.ChainSelector)
if err1 != nil {
return nil, nil, nil, fmt.Errorf("failed to get chain selector from chain ID %s: %w", chainID, err1)
}

cr, err1 := crcw.GetChainReader(ctx, ccipcommon.ChainReaderProviderOpts{
Lggr: i.lggr,
Relayer: relayer,
ChainID: chainID,
DestChainID: destChainID,
HomeChainID: homeChainID,
Ofc: ofc,
ChainSelector: chainSelector,
ChainFamily: relayChainFamily,
DestChainFamily: destChainFamily,
Transmitters: i.transmitters,
})
if err1 != nil {
// Some Chain family might not need crcw to be created, and if createChainAccessorsAndContractTransmitters will catch error if it does
i.lggr.Debugf("skipping creating reader and writers for chain %s, reader creation: %v", chainID, err1)
continue
}
if err := func() error {
// Bound each chain's reader/writer creation with its own deadline so an unavailable
// chain LOOPP fails fast instead of blocking the launcher context
// forever.
chainCtx, cancel := context.WithTimeout(ctx, readerWriterCreationTimeout)
defer cancel()

chainID := relayID.ChainID
relayChainFamily := relayID.Network
chainDetails, err1 := chainsel.GetChainDetailsByChainIDAndFamily(chainID, relayChainFamily)
chainSelector := cciptypes.ChainSelector(chainDetails.ChainSelector)
if err1 != nil {
return fmt.Errorf("failed to get chain selector from chain ID %s: %w", chainID, err1)
}

if chainID == destChainID && destChainFamily == relayChainFamily {
offrampAddress := destAddrStr
err2 := cr.Bind(ctx, []types.BoundContract{
{
Address: offrampAddress,
Name: consts.ContractNameOffRamp,
},
cr, err1 := crcw.GetChainReader(chainCtx, ccipcommon.ChainReaderProviderOpts{
Lggr: i.lggr,
Relayer: relayer,
ChainID: chainID,
DestChainID: destChainID,
HomeChainID: homeChainID,
Ofc: ofc,
ChainSelector: chainSelector,
ChainFamily: relayChainFamily,
DestChainFamily: destChainFamily,
Transmitters: i.transmitters,
})
if err2 != nil {
return nil, nil, nil, fmt.Errorf("failed to bind chain reader for dest chain %s's offramp at %s: %w", chainID, offrampAddress, err2)
if err1 != nil {
// Some Chain family might not need crcw to be created, and if createChainAccessorsAndContractTransmitters will catch error if it does
i.lggr.Debugf("skipping creating reader and writers for chain %s, reader creation: %v", chainID, err1)
return nil
}
}

if err2 := cr.Start(ctx); err2 != nil {
return nil, nil, nil, fmt.Errorf("failed to start contract reader for chain %s: %w", chainID, err2)
}
if chainID == destChainID && destChainFamily == relayChainFamily {
offrampAddress := destAddrStr
err2 := cr.Bind(chainCtx, []types.BoundContract{
{
Address: offrampAddress,
Name: consts.ContractNameOffRamp,
},
})
if err2 != nil {
return fmt.Errorf("failed to bind chain reader for dest chain %s's offramp at %s: %w", chainID, offrampAddress, err2)
}
}

cw, err1 := crcw.GetChainWriter(ctx, ccipcommon.ChainWriterProviderOpts{
ChainID: chainID,
Relayer: relayer,
Transmitters: i.transmitters,
ExecBatchGasLimit: execBatchGasLimit,
CommitEvmBatchGasLimit: commitEvmGasLimit,
ChainFamily: relayChainFamily,
OfframpProgramAddress: config.Config.OfframpAddress,
})
if err1 != nil {
// Some Chain family might not need crcw to be created, and if createChainAccessorsAndContractTransmitters will catch error if it does
i.lggr.Debugf("skipping creating chain writer for chain %s, writer creation: %v", chainID, err1)
continue
}
if err2 := cr.Start(chainCtx); err2 != nil {
return fmt.Errorf("failed to start contract reader for chain %s: %w", chainID, err2)
}

if err4 := cw.Start(ctx); err4 != nil {
return nil, nil, nil, fmt.Errorf("failed to start chain writer for chain %s: %w", chainID, err4)
}
cw, err1 := crcw.GetChainWriter(chainCtx, ccipcommon.ChainWriterProviderOpts{
ChainID: chainID,
Relayer: relayer,
Transmitters: i.transmitters,
ExecBatchGasLimit: execBatchGasLimit,
CommitEvmBatchGasLimit: commitEvmGasLimit,
ChainFamily: relayChainFamily,
OfframpProgramAddress: config.Config.OfframpAddress,
})
if err1 != nil {
// Some Chain family might not need crcw to be created, and if createChainAccessorsAndContractTransmitters will catch error if it does
i.lggr.Debugf("skipping creating chain writer for chain %s, writer creation: %v", chainID, err1)
return nil
}

extendedCr, err := wrapContractReaderInObservedExtended(i.lggr, cr, chainSelector)
if err != nil {
return nil, nil, nil, fmt.Errorf("failed to wrap contract reader for chain %s: %w", chainID, err)
}
if err4 := cw.Start(chainCtx); err4 != nil {
return fmt.Errorf("failed to start chain writer for chain %s: %w", chainID, err4)
}

extendedCr, err := wrapContractReaderInObservedExtended(i.lggr, cr, chainSelector)
if err != nil {
return fmt.Errorf("failed to wrap contract reader for chain %s: %w", chainID, err)
}

contractReaders[chainSelector] = cr
extendedReaders[chainSelector] = extendedCr
chainWriters[chainSelector] = cw
contractReaders[chainSelector] = cr
extendedReaders[chainSelector] = extendedCr
chainWriters[chainSelector] = cw
return nil
}(); err != nil {
return nil, nil, nil, err
}
}
return contractReaders, extendedReaders, chainWriters, nil
}
Expand Down
Binary file not shown.
Binary file not shown.
5 changes: 3 additions & 2 deletions core/capabilities/vault/vaultutils/json_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ func TestToCanonicalJSON_OmitsEmptyFields(t *testing.T) {
withEmptyFields, err := ToCanonicalJSON(msg, false)
require.NoError(t, err)
assert.JSONEq(t, `{
"requestId":"",
"responses":[{"id":{"owner":"owner","namespace":"main","key":"secret1"},"success":true,"error":""}]
}`, string(withEmptyFields))

Expand All @@ -83,7 +84,7 @@ func TestToCanonicalJSON_OmitsEmptyFields(t *testing.T) {

withEmptyFields, err := ToCanonicalJSON(msg, false)
require.NoError(t, err)
assert.JSONEq(t, `{"responses":[]}`, string(withEmptyFields))
assert.JSONEq(t, `{"requestId":"","responses":[]}`, string(withEmptyFields))

canonicalJSON, err := ToCanonicalJSON(msg, true)
require.NoError(t, err)
Expand All @@ -100,7 +101,7 @@ func TestToCanonicalJSON_OmitsEmptyFields(t *testing.T) {

withEmptyFields, err := ToCanonicalJSON(msg, false)
require.NoError(t, err)
assert.JSONEq(t, `{"responses":[]}`, string(withEmptyFields))
assert.JSONEq(t, `{"requestId":"","responses":[]}`, string(withEmptyFields))

canonicalJSON, err := ToCanonicalJSON(msg, true)
require.NoError(t, err)
Expand Down
28 changes: 15 additions & 13 deletions core/scripts/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ require (
github.com/andybalholm/brotli v1.2.1
github.com/avast/retry-go/v4 v4.7.0
github.com/c-bata/go-prompt v0.2.6
github.com/ethereum/go-ethereum v1.17.3
github.com/ethereum/go-ethereum v1.17.4
github.com/gkampitakis/go-snaps v0.5.19
github.com/google/go-cmp v0.7.0
github.com/google/uuid v1.6.0
Expand All @@ -47,7 +47,7 @@ require (
github.com/smartcontractkit/chain-selectors v1.0.104
github.com/smartcontractkit/chainlink-automation v0.8.1
github.com/smartcontractkit/chainlink-ccip/chains/evm v0.0.0-20260624154507-ea7ff77a0ddb
github.com/smartcontractkit/chainlink-common v0.11.2-0.20260701091216-9264d4444ce0
github.com/smartcontractkit/chainlink-common v0.11.2-0.20260713194119-2689c5708c8b
github.com/smartcontractkit/chainlink-common/keystore v1.2.0
github.com/smartcontractkit/chainlink-data-streams v0.1.15-0.20260522094612-5f9f748bd87a
github.com/smartcontractkit/chainlink-deployments-framework v0.111.1-0.20260612191326-e31c0ae4cd54
Expand Down Expand Up @@ -253,6 +253,7 @@ require (
github.com/fbsobreira/gotron-sdk v0.0.0-20250403083053-2943ce8c759b // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/ferranbt/fastssz v0.1.4 // indirect
github.com/fjl/jsonw v0.1.0 // indirect
github.com/fsnotify/fsevents v0.2.0 // indirect
github.com/fsnotify/fsnotify v1.10.1 // indirect
github.com/fvbommel/sortorder v1.1.0 // indirect
Expand Down Expand Up @@ -448,11 +449,10 @@ require (
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect
github.com/pierrec/lz4/v4 v4.1.26 // indirect
github.com/pion/dtls/v2 v2.2.12 // indirect
github.com/pion/logging v0.2.2 // indirect
github.com/pion/stun/v2 v2.0.0 // indirect
github.com/pion/transport/v2 v2.2.10 // indirect
github.com/pion/transport/v3 v3.0.1 // indirect
github.com/pion/dtls/v3 v3.1.2 // indirect
github.com/pion/logging v0.2.4 // indirect
github.com/pion/stun/v3 v3.1.2 // indirect
github.com/pion/transport/v4 v4.0.1 // indirect
github.com/pkg/term v1.2.0-beta.2 // indirect
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
Expand Down Expand Up @@ -487,8 +487,9 @@ require (
github.com/sirupsen/logrus v1.9.4 // indirect
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect
github.com/smartcontractkit/ccip-owner-contracts v0.1.0 // indirect
github.com/smartcontractkit/chainlink-aptos v0.0.0-20260706100550-d43558069754 // indirect
github.com/smartcontractkit/chainlink-ccip v0.1.1-solana.0.20260625091148-e5618f5682ee // indirect
github.com/smartcontractkit/chainlink-aptos v0.0.0-20260708114855-e953eeb028a7 // indirect
github.com/smartcontractkit/chainlink-aptos/codec v0.0.0-20260708114855-e953eeb028a7 // indirect
github.com/smartcontractkit/chainlink-ccip v0.1.1-solana.0.20260715204125-87778cfb9fd3 // indirect
github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260624154507-ea7ff77a0ddb // indirect
github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20260624154507-ea7ff77a0ddb // indirect
github.com/smartcontractkit/chainlink-ccv v0.0.2-0.20260706093831-dad26b360094 // indirect
Expand All @@ -507,7 +508,7 @@ require (
github.com/smartcontractkit/chainlink-protos/chainlink-ccv/verifier v0.0.0-20251211142334-5c3421fe2c8d // indirect
github.com/smartcontractkit/chainlink-protos/data-feeds v0.1.1-0.20260501174546-2e8846986b36 // indirect
github.com/smartcontractkit/chainlink-protos/linking-service/go v0.0.0-20260512230622-65f10f4cd305 // indirect
github.com/smartcontractkit/chainlink-protos/node-platform v0.0.0-20260512230622-65f10f4cd305 // indirect
github.com/smartcontractkit/chainlink-protos/node-platform v0.0.0-20260709145319-7782fb89eb16 // indirect
github.com/smartcontractkit/chainlink-protos/orchestrator v0.11.0 // indirect
github.com/smartcontractkit/chainlink-protos/ring/go v0.0.0-20260331131315-f08a616d8dcd // indirect
github.com/smartcontractkit/chainlink-protos/rmn/v1.6/go v0.0.0-20250131130834-15e0d4cde2a6 // indirect
Expand All @@ -516,7 +517,7 @@ require (
github.com/smartcontractkit/chainlink-protos/workflows/go v0.0.0-20260630073003-fb8da7229930 // indirect
github.com/smartcontractkit/chainlink-solana/contracts v0.0.0-20260513123719-d347eaf314e1 // indirect
github.com/smartcontractkit/chainlink-sui v0.0.0 // indirect
github.com/smartcontractkit/chainlink-sui/codec v0.0.0-20260706170510-94f3a0409ea5 // indirect
github.com/smartcontractkit/chainlink-sui/codec v0.0.0-20260713202800-ac352a2c68f0 // indirect
github.com/smartcontractkit/chainlink-testing-framework/framework/components/chiprouter v1.0.4 // indirect
github.com/smartcontractkit/chainlink-testing-framework/framework/components/fake v0.15.0 // indirect
github.com/smartcontractkit/chainlink-testing-framework/lib v1.54.9 // indirect
Expand Down Expand Up @@ -565,6 +566,7 @@ require (
github.com/urfave/cli/v2 v2.27.7 // indirect
github.com/valyala/fastjson v1.6.10 // indirect
github.com/vektah/gqlparser/v2 v2.5.30 // indirect
github.com/wlynxg/anet v0.0.5 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
Expand Down Expand Up @@ -626,7 +628,7 @@ require (
google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect
google.golang.org/grpc v1.81.1 // indirect
google.golang.org/grpc v1.82.0 // indirect
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
gopkg.in/guregu/null.v4 v4.0.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
Expand Down Expand Up @@ -662,4 +664,4 @@ replace github.com/doyensec/safeurl => github.com/cedric-cordenier/safeurl v0.0.
// yet, so we pin to v0.1.0 which has both the old aliases and the new compression API.
replace github.com/moby/go-archive v0.2.0 => github.com/moby/go-archive v0.1.0

replace github.com/smartcontractkit/chainlink-sui => github.com/smartcontractkit/chainlink-sui v0.0.0-20260707125635-abec997b6eae
replace github.com/smartcontractkit/chainlink-sui => github.com/smartcontractkit/chainlink-sui v0.0.0-20260721212531-dc23bb271beb
Loading
Loading