diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index 615bcbc67b..966014b239 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -293,7 +293,7 @@ func (d *Delegate) cleanupEVM(jb job.Job, q pg.Queryer, relayID relay.ID) error } return nil case types.CCIPExecution: - err = ccip.UnregisterExecPluginLpFilters(context.Background(), spec, d.legacyChains, pg.WithQueryer(q)) + err = ccip.UnregisterExecPluginLpFilters(context.Background(), d.lggr, spec, d.legacyChains, pg.WithQueryer(q)) if err != nil { d.lggr.Errorw("failed to unregister ccip exec plugin filters", "err", err, "spec", spec) } diff --git a/core/services/ocr2/plugins/ccip/execution_plugin.go b/core/services/ocr2/plugins/ccip/execution_plugin.go index 3c9855b7b8..2d00333d93 100644 --- a/core/services/ocr2/plugins/ccip/execution_plugin.go +++ b/core/services/ocr2/plugins/ccip/execution_plugin.go @@ -116,7 +116,7 @@ func NewExecutionServices(lggr logger.Logger, jb job.Job, chainSet evm.LegacyCha sourceChainEventClient := ccipdata.NewLogPollerReader(sourceChain.LogPoller(), execLggr, sourceChain.Client()) - tokenDataProviders, err := getTokenDataProviders(pluginConfig, offRampConfig.OnRamp, sourceChainEventClient) + tokenDataProviders, err := getTokenDataProviders(lggr, pluginConfig, offRampConfig.OnRamp, sourceChainEventClient) if err != nil { return nil, errors.Wrap(err, "could not get token data providers") } @@ -173,10 +173,11 @@ func NewExecutionServices(lggr logger.Logger, jb job.Job, chainSet evm.LegacyCha return []job.ServiceCtx{job.NewServiceAdapter(oracle)}, nil } -func getTokenDataProviders(pluginConfig ccipconfig.ExecutionPluginJobSpecConfig, onRampAddress common.Address, sourceChainEventClient *ccipdata.LogPollerReader) (map[common.Address]tokendata.Reader, error) { +func getTokenDataProviders(lggr logger.Logger, pluginConfig ccipconfig.ExecutionPluginJobSpecConfig, onRampAddress common.Address, sourceChainEventClient *ccipdata.LogPollerReader) (map[common.Address]tokendata.Reader, error) { tokenDataProviders := make(map[common.Address]tokendata.Reader) if pluginConfig.USDCConfig.AttestationAPI != "" { + lggr.Infof("USDC token data provider enabled") err := pluginConfig.USDCConfig.ValidateUSDCConfig() if err != nil { return nil, err @@ -262,7 +263,7 @@ func getExecutionPluginDestLpChainFilters(commitStore, offRamp, priceRegistry co } // UnregisterExecPluginLpFilters unregisters all the registered filters for both source and dest chains. -func UnregisterExecPluginLpFilters(ctx context.Context, spec *job.OCR2OracleSpec, chainSet evm.LegacyChainContainer, qopts ...pg.QOpt) error { +func UnregisterExecPluginLpFilters(ctx context.Context, lggr logger.Logger, spec *job.OCR2OracleSpec, chainSet evm.LegacyChainContainer, qopts ...pg.QOpt) error { if spec == nil { return errors.New("spec is nil") } @@ -309,11 +310,12 @@ func UnregisterExecPluginLpFilters(ctx context.Context, spec *job.OCR2OracleSpec return errors.Wrap(err, "failed loading onRamp") } - return unregisterExecutionPluginLpFilters(ctx, sourceChain.LogPoller(), destChain.LogPoller(), offRamp, offRampConfig, sourceOnRamp, sourceChain.Client(), pluginConfig, qopts...) + return unregisterExecutionPluginLpFilters(ctx, lggr, sourceChain.LogPoller(), destChain.LogPoller(), offRamp, offRampConfig, sourceOnRamp, sourceChain.Client(), pluginConfig, qopts...) } func unregisterExecutionPluginLpFilters( ctx context.Context, + lggr logger.Logger, sourceLP logpoller.LogPoller, destLP logpoller.LogPoller, destOffRamp evm_2_evm_offramp.EVM2EVMOffRampInterface, @@ -333,7 +335,7 @@ func unregisterExecutionPluginLpFilters( } // SourceChainEventClient can be nil because it is not used in unregisterExecutionPluginLpFilters - tokenDataProviders, err := getTokenDataProviders(pluginConfig, destOffRampConfig.OnRamp, nil) + tokenDataProviders, err := getTokenDataProviders(lggr, pluginConfig, destOffRampConfig.OnRamp, nil) if err != nil { return err } diff --git a/core/services/ocr2/plugins/ccip/execution_plugin_test.go b/core/services/ocr2/plugins/ccip/execution_plugin_test.go index db43d888ce..dec6e2f5ad 100644 --- a/core/services/ocr2/plugins/ccip/execution_plugin_test.go +++ b/core/services/ocr2/plugins/ccip/execution_plugin_test.go @@ -12,6 +12,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/mocks" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" + "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" @@ -56,7 +57,7 @@ func TestGetExecutionPluginFilterNamesFromSpec(t *testing.T) { for _, tc := range testCases { chainSet := &mocks.LegacyChainContainer{} t.Run(tc.description, func(t *testing.T) { - err := UnregisterExecPluginLpFilters(context.Background(), tc.spec, chainSet) + err := UnregisterExecPluginLpFilters(context.Background(), logger.TestLogger(t), tc.spec, chainSet) if tc.expectingErr { assert.Error(t, err) } else { @@ -111,6 +112,7 @@ func TestGetExecutionPluginFilterNames(t *testing.T) { err := unregisterExecutionPluginLpFilters( context.Background(), + logger.TestLogger(t), srcLP, dstLP, mockOffRamp, diff --git a/core/services/ocr2/plugins/ccip/execution_reporting_plugin.go b/core/services/ocr2/plugins/ccip/execution_reporting_plugin.go index 0feb38c865..805366217e 100644 --- a/core/services/ocr2/plugins/ccip/execution_reporting_plugin.go +++ b/core/services/ocr2/plugins/ccip/execution_reporting_plugin.go @@ -513,7 +513,7 @@ func (r *ExecutionReportingPlugin) buildBatch( // Chain holds existing nonce. nonce, err := r.config.offRamp.GetSenderNonce(nil, msg.Sender) if err != nil { - lggr.Errorw("unable to get sender nonce", "err", err) + lggr.Errorw("unable to get sender nonce", "err", err, "seqNr", msg.SequenceNumber) continue } expectedNonces[msg.Sender] = nonce + 1 @@ -542,9 +542,9 @@ func (r *ExecutionReportingPlugin) buildBatch( continue } - tokenData, ready, err2 := getTokenData(ctx, msg, r.config.tokenDataProviders) + tokenData, ready, err2 := getTokenData(ctx, msgLggr, msg, r.config.tokenDataProviders) if err2 != nil { - msgLggr.Errorw("Skipping message unable to check attestation", "err", err2) + msgLggr.Errorw("Skipping message unable to check token data", "err", err2) continue } if !ready { @@ -633,23 +633,25 @@ func (r *ExecutionReportingPlugin) buildBatch( return executableMessages } -func getTokenData(ctx context.Context, msg internal.EVM2EVMOnRampCCIPSendRequestedWithMeta, tokenDataProviders map[common.Address]tokendata.Reader) (tokenData [][]byte, allReady bool, err error) { +func getTokenData(ctx context.Context, lggr logger.Logger, msg internal.EVM2EVMOnRampCCIPSendRequestedWithMeta, tokenDataProviders map[common.Address]tokendata.Reader) (tokenData [][]byte, allReady bool, err error) { for _, token := range msg.TokenAmounts { - if offchainTokenDataProvider, ok := tokenDataProviders[token.Token]; ok { - attestation, err2 := offchainTokenDataProvider.ReadTokenData(ctx, msg) - if err2 != nil { - if errors.Is(err2, tokendata.ErrNotReady) { - return [][]byte{}, false, nil - } - return [][]byte{}, false, err2 - } - - tokenData = append(tokenData, attestation) + offchainTokenDataProvider, ok := tokenDataProviders[token.Token] + if !ok { + // No token data required + tokenData = append(tokenData, []byte{}) continue } + lggr.Infow("Fetching token data", "token", token.Token.Hex()) + tknData, err2 := offchainTokenDataProvider.ReadTokenData(ctx, msg) + if err2 != nil { + if errors.Is(err2, tokendata.ErrNotReady) { + lggr.Infof("Token data not ready yet for token %s", token.Token.Hex()) + return [][]byte{}, false, nil + } + return [][]byte{}, false, err2 + } - // No token data required - tokenData = append(tokenData, []byte{}) + tokenData = append(tokenData, tknData) } return tokenData, true, nil } diff --git a/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc.go b/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc.go index 8da8023897..3b1f1b6177 100644 --- a/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc.go +++ b/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc.go @@ -34,7 +34,7 @@ type TokenDataReader struct { } type attestationResponse struct { - Status AttestationStatus `json:"status"` + Status attestationStatus `json:"status"` Attestation string `json:"attestation"` } @@ -44,11 +44,11 @@ const ( MESSAGE_SENT_FILTER_NAME = "USDC message sent" ) -type AttestationStatus string +type attestationStatus string const ( - AttestationStatusSuccess AttestationStatus = "complete" - AttestationStatusPending AttestationStatus = "pending_confirmations" + attestationStatusSuccess attestationStatus = "complete" + attestationStatusPending attestationStatus = "pending_confirmations" ) var _ tokendata.Reader = &TokenDataReader{} @@ -70,7 +70,7 @@ func (s *TokenDataReader) ReadTokenData(ctx context.Context, msg internal.EVM2EV return []byte{}, err } - if response.Status == AttestationStatusSuccess { + if response.Status == attestationStatusSuccess { attestationBytes, err := hex.DecodeString(response.Attestation) if err != nil { return nil, fmt.Errorf("decode response attestation: %w", err) diff --git a/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_blackbox_test.go b/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_blackbox_test.go index 19860d8221..6e61be5ed3 100644 --- a/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_blackbox_test.go +++ b/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_blackbox_test.go @@ -29,13 +29,13 @@ var ( ) type attestationResponse struct { - Status usdc.AttestationStatus `json:"status"` - Attestation string `json:"attestation"` + Status string `json:"status"` + Attestation string `json:"attestation"` } func TestUSDCReader_ReadTokenData(t *testing.T) { response := attestationResponse{ - Status: usdc.AttestationStatusSuccess, + Status: "complete", Attestation: "720502893578a89a8a87982982ef781c18b193", } @@ -93,5 +93,4 @@ func TestUSDCReader_ReadTokenData(t *testing.T) { require.NoError(t, err) require.Equal(t, attestationBytes, attestation) - require.Equal(t, response.Status, usdc.AttestationStatusSuccess) } diff --git a/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_test.go b/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_test.go index 76049a2da7..d61ef530d5 100644 --- a/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_test.go +++ b/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_test.go @@ -34,13 +34,13 @@ func TestUSDCReader_callAttestationApi(t *testing.T) { attestation, err := usdcService.callAttestationApi(context.Background(), [32]byte(common.FromHex(usdcMessageHash))) require.NoError(t, err) - require.Equal(t, AttestationStatusPending, attestation.Status) + require.Equal(t, attestationStatusPending, attestation.Status) require.Equal(t, "PENDING", attestation.Attestation) } func TestUSDCReader_callAttestationApiMock(t *testing.T) { response := attestationResponse{ - Status: AttestationStatusSuccess, + Status: attestationStatusSuccess, Attestation: "720502893578a89a8a87982982ef781c18b193", }