diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 9c33e4896e2..ffba3123c13 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -46,7 +46,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v0.8.1 github.com/smartcontractkit/chainlink-ccip v0.1.1-solana.0.20260303213437-47af98c8ae82 - github.com/smartcontractkit/chainlink-common v0.10.1-0.20260309113338-432602d809cc + github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310204254-f3e84643d9cd github.com/smartcontractkit/chainlink-common/keystore v1.0.2 github.com/smartcontractkit/chainlink-data-streams v0.1.12-0.20260227110503-42b236799872 github.com/smartcontractkit/chainlink-deployments-framework v0.86.0 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 1510354f77c..f770ed1973a 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1620,8 +1620,8 @@ github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260303213437-47af github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260303213437-47af98c8ae82/go.mod h1:r6gOO/602z5FQyRxsBHd93/oNsAgboo2+DMhPoisPuU= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260306124118-a6395a14f619 h1:mM4TnyNkRnNXZ+3WkjL+B1/CvepoQ+Aw+Y1AuRIzJQY= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260306124118-a6395a14f619/go.mod h1:RnuNcn7DZmjmzEkeEWX0uL5y1oslB3c9URPLOjFU+jE= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260309113338-432602d809cc h1:euYwd49PgzksFd9RBQ+qEObafDDz7fJu/9Oibc0G3Fk= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260309113338-432602d809cc/go.mod h1:0ghbAr7tRO0tT5ZqBXhOyzgUO37tNNe33Yn0hskauVM= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310204254-f3e84643d9cd h1:9hEKLyqLGl8juNUKRkNQDGRplchkSobV12BX0tE8RVQ= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310204254-f3e84643d9cd/go.mod h1:0ghbAr7tRO0tT5ZqBXhOyzgUO37tNNe33Yn0hskauVM= github.com/smartcontractkit/chainlink-common/keystore v1.0.2 h1:AWisx4JT3QV8tcgh6J5NCrex+wAgTYpWyHsyNPSXzsQ= github.com/smartcontractkit/chainlink-common/keystore v1.0.2/go.mod h1:rSkIHdomyak3YnUtXLenl6poIq8q0V3UZPiiyYqPdGA= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.11-0.20251211140724-319861e514c4 h1:NOUsjsMzNecbjiPWUQGlRSRAutEvCFrqqyETDJeh5q4= diff --git a/core/services/ocr2/plugins/vault/plugin.go b/core/services/ocr2/plugins/vault/plugin.go index c701a30db30..0bff2ef57ea 100644 --- a/core/services/ocr2/plugins/vault/plugin.go +++ b/core/services/ocr2/plugins/vault/plugin.go @@ -33,7 +33,6 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/capabilities/consensus/requests" pkgconfig "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/contexts" - "github.com/smartcontractkit/chainlink-common/pkg/settings" "github.com/smartcontractkit/chainlink-common/pkg/settings/cresettings" "github.com/smartcontractkit/chainlink-common/pkg/settings/limits" vaultcap "github.com/smartcontractkit/chainlink/v2/core/capabilities/vault" @@ -42,28 +41,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/logger" ) -const ( - // The query is empty in this plugin. - defaultLimitsMaxQueryLength = 100 - - // Back of the envelope calculation: - // - An item can contain 2KB of ciphertext, 192 bytes of metadata (key, owner, namespace), - // a UUID (16 bytes) plus some overhead = ~2.5KB per item - // There can be 10 such items in a request, and 20 per batch, so 2.5KB * 10 * 20 = 500KB - defaultLimitsMaxObservationLength = 500 * 1024 // 500KB - defaultLimitsMaxReportsPlusPrecursorLength = 500 * 1024 // 500KB - defaultLimitsMaxReportLength = 500 * 1024 // 500KB - defaultLimitsMaxReportCount = 20 - defaultLimitsMaxKeyValueModifiedKeysPlusValuesLength = 1024 * 1024 // 1MB - defaultLimitsMaxKeyValueModifiedKeys = 500 // BatchSize (20) * ItemsPerBatch (10) * 2 keys (secret + metadata) + buffer (100) - - // Per above, a request is max 25KB, we add a bit of buffer to allow some room. - defaultLimitsMaxBlobPayloadLength = 25 * 1024 // 25KB - // Per docs, this should allow some additional buffer to allow for reaping time. - defaultLimitsMaxPerOracleUnexpiredBlobCumulativePayloadBytes = 30 * 1024 * 1024 // 30 MB - defaultLimitsMaxPerOracleUnexpiredBlobCount = 1000 -) - var ( isValidIDComponent = regexp.MustCompile(`^[a-zA-Z0-9_]+$`).MatchString ) @@ -82,8 +59,7 @@ type ReportingPluginConfig struct { MaxIdentifierNamespaceLengthBytes limits.BoundLimiter[pkgconfig.Size] MaxShareLengthBytes limits.BoundLimiter[pkgconfig.Size] MaxRequestBatchSize limits.BoundLimiter[int] - - MaxBatchSize limits.BoundLimiter[int] + MaxBatchSize limits.BoundLimiter[int] } func NewReportingPluginFactory( @@ -160,117 +136,140 @@ func (r *ReportingPluginFactory) getKeyMaterial(ctx context.Context, instanceID return publicKey, privateKeyShare, nil } -func (r *ReportingPluginFactory) makeSizeLimiter(defaultSize settings.Setting[pkgconfig.Size], configSize int32) (limits.BoundLimiter[pkgconfig.Size], error) { - if configSize != 0 { - defaultSize.DefaultValue = pkgconfig.Size(configSize) * pkgconfig.Byte +func initializePluginLimits(ctx context.Context, limitsFactory limits.Factory) (ocr3_1types.ReportingPluginLimits, error) { + maxQueryBytes, err := cresettings.Default.VaultMaxQuerySizeLimit.GetOrDefault(ctx, limitsFactory.Settings) + if err != nil { + return ocr3_1types.ReportingPluginLimits{}, fmt.Errorf("VaultMaxQuerySizeLimit: %w", err) } - - return limits.MakeUpperBoundLimiter[pkgconfig.Size](r.limitsFactory, defaultSize) -} - -func logLimit[N limits.Number](ctx context.Context, lggr logger.Logger, limiter limits.BoundLimiter[N]) N { - ctx = contexts.WithCRE(ctx, contexts.CRE{Owner: "DUMMY-OWNER-FOR-LOGGING"}) - limit, err := limiter.Limit(ctx) + maxObservationBytes, err := cresettings.Default.VaultMaxObservationSizeLimit.GetOrDefault(ctx, limitsFactory.Settings) if err != nil { - lggr.Errorw("could not fetch limit", "error", err) + return ocr3_1types.ReportingPluginLimits{}, fmt.Errorf("VaultMaxObservationSizeLimit: %w", err) } - return limit -} - -func (r *ReportingPluginFactory) NewReportingPlugin(ctx context.Context, config ocr3types.ReportingPluginConfig, fetcher ocr3_1types.BlobBroadcastFetcher) (ocr3_1types.ReportingPlugin[[]byte], ocr3_1types.ReportingPluginInfo, error) { - var configProto vaultcommon.ReportingPluginConfig - if err := proto.Unmarshal(config.OffchainConfig, &configProto); err != nil { - return nil, ocr3_1types.ReportingPluginInfo1{}, fmt.Errorf("could not unmarshal reporting plugin config: %w", err) + maxReportsPlusPrecursorBytes, err := cresettings.Default.VaultMaxReportsPlusPrecursorSizeLimit.GetOrDefault(ctx, limitsFactory.Settings) + if err != nil { + return ocr3_1types.ReportingPluginLimits{}, fmt.Errorf("VaultMaxReportsPlusPrecursorSizeLimit: %w", err) } - - maxSecretsPerOwnerLimit := cresettings.Default.PerOwner.VaultSecretsLimit - if configProto.MaxSecretsPerOwner != 0 { - maxSecretsPerOwnerLimit.DefaultValue = int(configProto.MaxSecretsPerOwner) + maxReportBytes, err := cresettings.Default.VaultMaxReportSizeLimit.GetOrDefault(ctx, limitsFactory.Settings) + if err != nil { + return ocr3_1types.ReportingPluginLimits{}, fmt.Errorf("VaultMaxReportSizeLimit: %w", err) } - - maxSecretsPerOwnerLimiter, err := limits.MakeUpperBoundLimiter(r.limitsFactory, maxSecretsPerOwnerLimit) + maxReportCount, err := cresettings.Default.VaultMaxReportCount.GetOrDefault(ctx, limitsFactory.Settings) if err != nil { - return nil, ocr3_1types.ReportingPluginInfo1{}, fmt.Errorf("could not create max secrets per owner limiter: %w", err) + return ocr3_1types.ReportingPluginLimits{}, fmt.Errorf("VaultMaxReportCount: %w", err) } - - batchSize := cresettings.Default.VaultPluginBatchSizeLimit - if configProto.BatchSize != 0 { - batchSize.DefaultValue = int(configProto.BatchSize) + maxKVModifiedKeysPlusValuesBytes, err := cresettings.Default.VaultMaxKeyValueModifiedKeysPlusValuesSizeLimit.GetOrDefault(ctx, limitsFactory.Settings) + if err != nil { + return ocr3_1types.ReportingPluginLimits{}, fmt.Errorf("VaultMaxKeyValueModifiedKeysPlusValuesSizeLimit: %w", err) } - - maxBatchSizeLimiter, err := limits.MakeUpperBoundLimiter(r.limitsFactory, batchSize) + maxKVModifiedKeys, err := cresettings.Default.VaultMaxKeyValueModifiedKeys.GetOrDefault(ctx, limitsFactory.Settings) if err != nil { - return nil, ocr3_1types.ReportingPluginInfo1{}, fmt.Errorf("could not create max batch size limiter: %w", err) + return ocr3_1types.ReportingPluginLimits{}, fmt.Errorf("VaultMaxKeyValueModifiedKeys: %w", err) } - - maxCiphertextLengthBytesLimiter, err := r.makeSizeLimiter(cresettings.Default.VaultCiphertextSizeLimit, configProto.MaxCiphertextLengthBytes) + maxBlobPayloadBytes, err := cresettings.Default.VaultMaxBlobPayloadSizeLimit.GetOrDefault(ctx, limitsFactory.Settings) if err != nil { - return nil, ocr3_1types.ReportingPluginInfo1{}, fmt.Errorf("could not create default max ciphertext length limiter: %w", err) + return ocr3_1types.ReportingPluginLimits{}, fmt.Errorf("VaultMaxBlobPayloadSizeLimit: %w", err) } - - maxIdentifierKeyLengthBytesLimiter, err := r.makeSizeLimiter(cresettings.Default.VaultIdentifierKeySizeLimit, configProto.MaxIdentifierKeyLengthBytes) + maxPerOracleUnexpiredBlobCumulativePayloadBytes, err := cresettings.Default.VaultMaxPerOracleUnexpiredBlobCumulativePayloadSizeLimit.GetOrDefault(ctx, limitsFactory.Settings) if err != nil { - return nil, ocr3_1types.ReportingPluginInfo1{}, fmt.Errorf("could not create default max identifier key length limiter: %w", err) + return ocr3_1types.ReportingPluginLimits{}, fmt.Errorf("VaultMaxPerOracleUnexpiredBlobCumulativePayloadSizeLimit: %w", err) } + maxPerOracleUnexpiredBlobCount, err := cresettings.Default.VaultMaxPerOracleUnexpiredBlobCount.GetOrDefault(ctx, limitsFactory.Settings) + if err != nil { + return ocr3_1types.ReportingPluginLimits{}, fmt.Errorf("VaultMaxPerOracleUnexpiredBlobCount: %w", err) + } + + return ocr3_1types.ReportingPluginLimits{ + MaxQueryBytes: int(maxQueryBytes), + MaxObservationBytes: int(maxObservationBytes), + MaxReportsPlusPrecursorBytes: int(maxReportsPlusPrecursorBytes), + MaxReportBytes: int(maxReportBytes), + MaxReportCount: maxReportCount, + MaxKeyValueModifiedKeysPlusValuesBytes: int(maxKVModifiedKeysPlusValuesBytes), + MaxKeyValueModifiedKeys: maxKVModifiedKeys, + MaxBlobPayloadBytes: int(maxBlobPayloadBytes), + MaxPerOracleUnexpiredBlobCumulativePayloadBytes: int(maxPerOracleUnexpiredBlobCumulativePayloadBytes), + MaxPerOracleUnexpiredBlobCount: maxPerOracleUnexpiredBlobCount, + }, nil +} - maxIdentifierOwnerLengthBytesLimiter, err := r.makeSizeLimiter(cresettings.Default.VaultIdentifierOwnerSizeLimit, configProto.MaxIdentifierOwnerLengthBytes) +func newReportingPluginConfigLimiters(factory limits.Factory) (*ReportingPluginConfig, error) { + maxCiphertextLengthBytesLimiter, err := limits.MakeUpperBoundLimiter(factory, cresettings.Default.VaultCiphertextSizeLimit) if err != nil { - return nil, ocr3_1types.ReportingPluginInfo1{}, fmt.Errorf("could not create default max identifier owner length limiter: %w", err) + return nil, fmt.Errorf("VaultCiphertextSizeLimit: %w", err) } - maxIdentifierNamespaceLengthBytesLimiter, err := r.makeSizeLimiter(cresettings.Default.VaultIdentifierNamespaceSizeLimit, configProto.MaxIdentifierNamespaceLengthBytes) + maxIdentifierKeyLengthBytesLimiter, err := limits.MakeUpperBoundLimiter(factory, cresettings.Default.VaultIdentifierKeySizeLimit) if err != nil { - return nil, ocr3_1types.ReportingPluginInfo1{}, fmt.Errorf("could not create default max identifier namespace length limiter: %w", err) + return nil, fmt.Errorf("VaultIdentifierKeySizeLimit: %w", err) } - maxShareLengthBytesLimiter, err := r.makeSizeLimiter(cresettings.Default.VaultShareSizeLimit, 0) + maxIdentifierOwnerLengthBytesLimiter, err := limits.MakeUpperBoundLimiter(factory, cresettings.Default.VaultIdentifierOwnerSizeLimit) if err != nil { - return nil, ocr3_1types.ReportingPluginInfo1{}, fmt.Errorf("could not create default max share length bytes limiter: %w", err) + return nil, fmt.Errorf("VaultIdentifierOwnerSizeLimit: %w", err) } - maxRequestBatchSizeLimiter, err := limits.MakeUpperBoundLimiter(r.limitsFactory, cresettings.Default.VaultRequestBatchSizeLimit) + maxIdentifierNamespaceLengthBytesLimiter, err := limits.MakeUpperBoundLimiter(factory, cresettings.Default.VaultIdentifierNamespaceSizeLimit) if err != nil { - return nil, ocr3_1types.ReportingPluginInfo1{}, fmt.Errorf("could not create default max request batch size limiter: %w", err) + return nil, fmt.Errorf("VaultIdentifierNamespaceSizeLimit: %w", err) } - if configProto.LimitsMaxQueryLength == 0 { - configProto.LimitsMaxQueryLength = defaultLimitsMaxQueryLength + maxShareLengthBytesLimiter, err := limits.MakeUpperBoundLimiter(factory, cresettings.Default.VaultShareSizeLimit) + if err != nil { + return nil, fmt.Errorf("VaultShareSizeLimit: %w", err) } - if configProto.LimitsMaxObservationLength == 0 { - configProto.LimitsMaxObservationLength = defaultLimitsMaxObservationLength + maxRequestBatchSizeLimiter, err := limits.MakeUpperBoundLimiter(factory, cresettings.Default.VaultRequestBatchSizeLimit) + if err != nil { + return nil, fmt.Errorf("VaultRequestBatchSizeLimit: %w", err) } - if configProto.LimitsMaxReportsPlusPrecursorLength == 0 { - configProto.LimitsMaxReportsPlusPrecursorLength = defaultLimitsMaxReportsPlusPrecursorLength - } + return &ReportingPluginConfig{ + MaxShareLengthBytes: maxShareLengthBytesLimiter, + MaxRequestBatchSize: maxRequestBatchSizeLimiter, + MaxCiphertextLengthBytes: maxCiphertextLengthBytesLimiter, + MaxIdentifierKeyLengthBytes: maxIdentifierKeyLengthBytesLimiter, + MaxIdentifierOwnerLengthBytes: maxIdentifierOwnerLengthBytesLimiter, + MaxIdentifierNamespaceLengthBytes: maxIdentifierNamespaceLengthBytesLimiter, + }, nil +} - if configProto.LimitsMaxReportLength == 0 { - configProto.LimitsMaxReportLength = defaultLimitsMaxReportLength +func logLimit[N limits.Number](ctx context.Context, lggr logger.Logger, limiter limits.BoundLimiter[N]) N { + ctx = contexts.WithCRE(ctx, contexts.CRE{Owner: "DUMMY-OWNER-FOR-LOGGING"}) + limit, err := limiter.Limit(ctx) + if err != nil { + lggr.Errorw("could not fetch limit", "error", err) } + return limit +} - if configProto.LimitsMaxReportCount == 0 { - configProto.LimitsMaxReportCount = defaultLimitsMaxReportCount +func (r *ReportingPluginFactory) NewReportingPlugin(ctx context.Context, config ocr3types.ReportingPluginConfig, fetcher ocr3_1types.BlobBroadcastFetcher) (ocr3_1types.ReportingPlugin[[]byte], ocr3_1types.ReportingPluginInfo, error) { + var configProto vaultcommon.ReportingPluginConfig + if err := proto.Unmarshal(config.OffchainConfig, &configProto); err != nil { + return nil, ocr3_1types.ReportingPluginInfo1{}, fmt.Errorf("could not unmarshal reporting plugin config: %w", err) } - if configProto.LimitsMaxKeyValueModifiedKeysPlusValuesLength == 0 { - configProto.LimitsMaxKeyValueModifiedKeysPlusValuesLength = defaultLimitsMaxKeyValueModifiedKeysPlusValuesLength + cfg, err := newReportingPluginConfigLimiters(r.limitsFactory) + if err != nil { + return nil, ocr3_1types.ReportingPluginInfo1{}, fmt.Errorf("could not create reporting plugin config limiters: %w", err) } - if configProto.LimitsMaxKeyValueModifiedKeys == 0 { - configProto.LimitsMaxKeyValueModifiedKeys = defaultLimitsMaxKeyValueModifiedKeys + maxSecretsPerOwnerLimit := cresettings.Default.PerOwner.VaultSecretsLimit + if configProto.MaxSecretsPerOwner != 0 { + maxSecretsPerOwnerLimit.DefaultValue = int(configProto.MaxSecretsPerOwner) } - if configProto.LimitsMaxBlobPayloadLength == 0 { - configProto.LimitsMaxBlobPayloadLength = defaultLimitsMaxBlobPayloadLength + cfg.MaxSecretsPerOwner, err = limits.MakeUpperBoundLimiter(r.limitsFactory, maxSecretsPerOwnerLimit) + if err != nil { + return nil, ocr3_1types.ReportingPluginInfo1{}, fmt.Errorf("could not create max secrets per owner limiter: %w", err) } - if configProto.LimitsMaxPerOracleUnexpiredBlobCumulativePayloadBytes == 0 { - configProto.LimitsMaxPerOracleUnexpiredBlobCumulativePayloadBytes = defaultLimitsMaxPerOracleUnexpiredBlobCumulativePayloadBytes + batchSize := cresettings.Default.VaultPluginBatchSizeLimit + if configProto.BatchSize != 0 { + batchSize.DefaultValue = int(configProto.BatchSize) } - - if configProto.LimitsMaxPerOracleUnexpiredBlobCount == 0 { - configProto.LimitsMaxPerOracleUnexpiredBlobCount = defaultLimitsMaxPerOracleUnexpiredBlobCount + cfg.MaxBatchSize, err = limits.MakeUpperBoundLimiter(r.limitsFactory, batchSize) + if err != nil { + return nil, ocr3_1types.ReportingPluginInfo1{}, fmt.Errorf("could not create max batch size limiter: %w", err) } if configProto.DKGInstanceID == nil { @@ -285,35 +284,30 @@ func (r *ReportingPluginFactory) NewReportingPlugin(ctx context.Context, config r.cfg.LazyPublicKey.Set(publicKey) + cfg.PublicKey = publicKey + cfg.PrivateKeyShare = privateKeyShare + r.lggr.Debugw("instantiating VaultReportingPlugin with config", - "maxSecretsPerOwner", logLimit(ctx, r.lggr, maxSecretsPerOwnerLimiter), - "maxCiphertextLengthBytes", logLimit(ctx, r.lggr, maxCiphertextLengthBytesLimiter), - "maxIdentifierKeyLengthBytes", logLimit(ctx, r.lggr, maxIdentifierKeyLengthBytesLimiter), - "maxIdentifierOwnerLengthBytes", logLimit(ctx, r.lggr, maxIdentifierOwnerLengthBytesLimiter), - "maxIdentifierNamespaceLengthBytes", logLimit(ctx, r.lggr, maxIdentifierNamespaceLengthBytesLimiter), - "maxRequestBatchSize", logLimit(ctx, r.lggr, maxRequestBatchSizeLimiter), - "maxShareLengthBytes", logLimit(ctx, r.lggr, maxShareLengthBytesLimiter), - "batchSize", logLimit(ctx, r.lggr, maxBatchSizeLimiter), + "maxSecretsPerOwner", logLimit(ctx, r.lggr, cfg.MaxSecretsPerOwner), + "maxCiphertextLengthBytes", logLimit(ctx, r.lggr, cfg.MaxCiphertextLengthBytes), + "maxIdentifierKeyLengthBytes", logLimit(ctx, r.lggr, cfg.MaxIdentifierKeyLengthBytes), + "maxIdentifierOwnerLengthBytes", logLimit(ctx, r.lggr, cfg.MaxIdentifierOwnerLengthBytes), + "maxIdentifierNamespaceLengthBytes", logLimit(ctx, r.lggr, cfg.MaxIdentifierNamespaceLengthBytes), + "maxRequestBatchSize", logLimit(ctx, r.lggr, cfg.MaxRequestBatchSize), + "maxShareLengthBytes", logLimit(ctx, r.lggr, cfg.MaxShareLengthBytes), + "batchSize", logLimit(ctx, r.lggr, cfg.MaxBatchSize), ) - cfg := &ReportingPluginConfig{ - PublicKey: publicKey, - PrivateKeyShare: privateKeyShare, - MaxSecretsPerOwner: maxSecretsPerOwnerLimiter, - MaxShareLengthBytes: maxShareLengthBytesLimiter, - MaxRequestBatchSize: maxRequestBatchSizeLimiter, - MaxCiphertextLengthBytes: maxCiphertextLengthBytesLimiter, - MaxIdentifierKeyLengthBytes: maxIdentifierKeyLengthBytesLimiter, - MaxIdentifierOwnerLengthBytes: maxIdentifierOwnerLengthBytesLimiter, - MaxIdentifierNamespaceLengthBytes: maxIdentifierNamespaceLengthBytesLimiter, - MaxBatchSize: maxBatchSizeLimiter, - } - metrics, err := newPluginMetrics(config.ConfigDigest.String()) if err != nil { return nil, ocr3_1types.ReportingPluginInfo1{}, fmt.Errorf("could not create plugin metrics: %w", err) } + pluginLimits, err := initializePluginLimits(ctx, r.limitsFactory) + if err != nil { + return nil, ocr3_1types.ReportingPluginInfo1{}, fmt.Errorf("could not resolve plugin limits: %w", err) + } + return &ReportingPlugin{ lggr: r.lggr.Named("VaultReportingPlugin"), store: r.store, @@ -329,19 +323,8 @@ func (r *ReportingPluginFactory) NewReportingPlugin(ctx context.Context, config return handle.MarshalBinary() }, }, ocr3_1types.ReportingPluginInfo1{ - Name: "VaultReportingPlugin", - Limits: ocr3_1types.ReportingPluginLimits{ - MaxQueryBytes: int(configProto.LimitsMaxQueryLength), - MaxObservationBytes: int(configProto.LimitsMaxObservationLength), - MaxReportsPlusPrecursorBytes: int(configProto.LimitsMaxReportsPlusPrecursorLength), - MaxReportBytes: int(configProto.LimitsMaxReportLength), - MaxReportCount: int(configProto.LimitsMaxReportCount), - MaxKeyValueModifiedKeysPlusValuesBytes: int(configProto.LimitsMaxKeyValueModifiedKeysPlusValuesLength), - MaxKeyValueModifiedKeys: int(configProto.LimitsMaxKeyValueModifiedKeys), - MaxBlobPayloadBytes: int(configProto.LimitsMaxBlobPayloadLength), - MaxPerOracleUnexpiredBlobCumulativePayloadBytes: int(configProto.LimitsMaxPerOracleUnexpiredBlobCumulativePayloadBytes), - MaxPerOracleUnexpiredBlobCount: int(configProto.LimitsMaxPerOracleUnexpiredBlobCount), - }, + Name: "VaultReportingPlugin", + Limits: pluginLimits, }, nil } @@ -2227,5 +2210,14 @@ func (r *ReportingPlugin) ShouldTransmitAcceptedReport(ctx context.Context, seqN } func (r *ReportingPlugin) Close() error { - return nil + return errors.Join( + r.cfg.MaxSecretsPerOwner.Close(), + r.cfg.MaxCiphertextLengthBytes.Close(), + r.cfg.MaxIdentifierKeyLengthBytes.Close(), + r.cfg.MaxIdentifierOwnerLengthBytes.Close(), + r.cfg.MaxIdentifierNamespaceLengthBytes.Close(), + r.cfg.MaxShareLengthBytes.Close(), + r.cfg.MaxRequestBatchSize.Close(), + r.cfg.MaxBatchSize.Close(), + ) } diff --git a/core/services/ocr2/plugins/vault/plugin_test.go b/core/services/ocr2/plugins/vault/plugin_test.go index c3c78ea7b4c..390462fb0f9 100644 --- a/core/services/ocr2/plugins/vault/plugin_test.go +++ b/core/services/ocr2/plugins/vault/plugin_test.go @@ -2,12 +2,14 @@ package vault import ( "crypto/rand" + "encoding/base64" "encoding/hex" "fmt" "strings" "testing" "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/libocr/commontypes" "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3_1types" "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types" "github.com/smartcontractkit/libocr/offchainreporting2plus/types" @@ -94,7 +96,7 @@ func TestPlugin_ReportingPluginFactory_UsesDefaultsIfNotProvidedInOffchainConfig require.NoError(t, err) typedRP := rp.(*ReportingPlugin) - assertLimit(t, 20, typedRP.cfg.MaxBatchSize) + assertLimit(t, cresettings.Default.VaultPluginBatchSizeLimit.DefaultValue, typedRP.cfg.MaxBatchSize) assert.NotNil(t, typedRP.cfg.PublicKey) assert.NotNil(t, typedRP.cfg.PrivateKeyShare) assertLimit(t, 100, typedRP.cfg.MaxSecretsPerOwner) @@ -106,14 +108,19 @@ func TestPlugin_ReportingPluginFactory_UsesDefaultsIfNotProvidedInOffchainConfig infoObject, ok := info.(ocr3_1types.ReportingPluginInfo1) assert.True(t, ok, "ReportingPluginInfo not of type ReportingPluginInfo1") assert.Equal(t, "VaultReportingPlugin", infoObject.Name) - assert.Equal(t, 100, infoObject.Limits.MaxQueryBytes) - assert.Equal(t, 512000, infoObject.Limits.MaxObservationBytes) - assert.Equal(t, 512000, infoObject.Limits.MaxReportsPlusPrecursorBytes) - assert.Equal(t, 512000, infoObject.Limits.MaxReportBytes) - assert.Equal(t, 20, infoObject.Limits.MaxReportCount) - assert.Equal(t, 1024*1024, infoObject.Limits.MaxKeyValueModifiedKeysPlusValuesBytes) - assert.Equal(t, 25*1024, infoObject.Limits.MaxBlobPayloadBytes) - + assert.Equal(t, int(cresettings.Default.VaultMaxQuerySizeLimit.DefaultValue), infoObject.Limits.MaxQueryBytes) + assert.Equal(t, int(cresettings.Default.VaultMaxObservationSizeLimit.DefaultValue), infoObject.Limits.MaxObservationBytes) + assert.Equal(t, int(cresettings.Default.VaultMaxReportsPlusPrecursorSizeLimit.DefaultValue), infoObject.Limits.MaxReportsPlusPrecursorBytes) + assert.Equal(t, int(cresettings.Default.VaultMaxReportSizeLimit.DefaultValue), infoObject.Limits.MaxReportBytes) + assert.Equal(t, cresettings.Default.VaultMaxReportCount.DefaultValue, infoObject.Limits.MaxReportCount) + assert.Equal(t, int(cresettings.Default.VaultMaxKeyValueModifiedKeysPlusValuesSizeLimit.DefaultValue), infoObject.Limits.MaxKeyValueModifiedKeysPlusValuesBytes) + assert.Equal(t, cresettings.Default.VaultMaxKeyValueModifiedKeys.DefaultValue, infoObject.Limits.MaxKeyValueModifiedKeys) + assert.Equal(t, int(cresettings.Default.VaultMaxBlobPayloadSizeLimit.DefaultValue), infoObject.Limits.MaxBlobPayloadBytes) + assert.Equal(t, int(cresettings.Default.VaultMaxPerOracleUnexpiredBlobCumulativePayloadSizeLimit.DefaultValue), infoObject.Limits.MaxPerOracleUnexpiredBlobCumulativePayloadBytes) + assert.Equal(t, cresettings.Default.VaultMaxPerOracleUnexpiredBlobCount.DefaultValue, infoObject.Limits.MaxPerOracleUnexpiredBlobCount) + + // Verify that configProto overrides apply to BatchSize and MaxSecretsPerOwner, + // while other fields remain at cresettings defaults. cfg = vaultcommon.ReportingPluginConfig{ BatchSize: 2, MaxSecretsPerOwner: 2, @@ -139,22 +146,21 @@ func TestPlugin_ReportingPluginFactory_UsesDefaultsIfNotProvidedInOffchainConfig typedRP = rp.(*ReportingPlugin) assertLimit(t, 2, typedRP.cfg.MaxBatchSize) assertLimit(t, 2, typedRP.cfg.MaxSecretsPerOwner) - assertLimit(t, 2, typedRP.cfg.MaxCiphertextLengthBytes) - assertLimit(t, 2, typedRP.cfg.MaxCiphertextLengthBytes) - assertLimit(t, 2, typedRP.cfg.MaxIdentifierOwnerLengthBytes) - assertLimit(t, 2, typedRP.cfg.MaxIdentifierNamespaceLengthBytes) - assertLimit(t, 2, typedRP.cfg.MaxIdentifierKeyLengthBytes) + assertLimit(t, 2000, typedRP.cfg.MaxCiphertextLengthBytes) + assertLimit(t, 64, typedRP.cfg.MaxIdentifierOwnerLengthBytes) + assertLimit(t, 64, typedRP.cfg.MaxIdentifierNamespaceLengthBytes) + assertLimit(t, 64, typedRP.cfg.MaxIdentifierKeyLengthBytes) infoObject, ok = info.(ocr3_1types.ReportingPluginInfo1) assert.True(t, ok, "ReportingPluginInfo not of type ReportingPluginInfo1") assert.Equal(t, "VaultReportingPlugin", infoObject.Name) - assert.Equal(t, 2, infoObject.Limits.MaxQueryBytes) - assert.Equal(t, 2, infoObject.Limits.MaxObservationBytes) - assert.Equal(t, 2, infoObject.Limits.MaxReportsPlusPrecursorBytes) - assert.Equal(t, 2, infoObject.Limits.MaxReportBytes) - assert.Equal(t, 2, infoObject.Limits.MaxReportCount) - assert.Equal(t, 2, infoObject.Limits.MaxKeyValueModifiedKeysPlusValuesBytes) - assert.Equal(t, 2, infoObject.Limits.MaxBlobPayloadBytes) + assert.Equal(t, int(cresettings.Default.VaultMaxQuerySizeLimit.DefaultValue), infoObject.Limits.MaxQueryBytes) + assert.Equal(t, int(cresettings.Default.VaultMaxObservationSizeLimit.DefaultValue), infoObject.Limits.MaxObservationBytes) + assert.Equal(t, int(cresettings.Default.VaultMaxReportsPlusPrecursorSizeLimit.DefaultValue), infoObject.Limits.MaxReportsPlusPrecursorBytes) + assert.Equal(t, int(cresettings.Default.VaultMaxReportSizeLimit.DefaultValue), infoObject.Limits.MaxReportBytes) + assert.Equal(t, cresettings.Default.VaultMaxReportCount.DefaultValue, infoObject.Limits.MaxReportCount) + assert.Equal(t, int(cresettings.Default.VaultMaxKeyValueModifiedKeysPlusValuesSizeLimit.DefaultValue), infoObject.Limits.MaxKeyValueModifiedKeysPlusValuesBytes) + assert.Equal(t, int(cresettings.Default.VaultMaxBlobPayloadSizeLimit.DefaultValue), infoObject.Limits.MaxBlobPayloadBytes) } func TestPlugin_ReportingPluginFactory_UseDKGResult(t *testing.T) { @@ -188,7 +194,7 @@ func TestPlugin_ReportingPluginFactory_UseDKGResult(t *testing.T) { require.NoError(t, err) typedRP := rp.(*ReportingPlugin) - assertLimit(t, 20, typedRP.cfg.MaxBatchSize) + assertLimit(t, cresettings.Default.VaultPluginBatchSizeLimit.DefaultValue, typedRP.cfg.MaxBatchSize) pkBytes, err := typedRP.cfg.PublicKey.Marshal() require.NoError(t, err) @@ -2172,6 +2178,74 @@ func TestPlugin_Observation_CreateSecretsRequest_Success(t *testing.T) { assert.Empty(t, resp.GetError()) } +func makeEncryptedShares(t *testing.T, ciphertext *tdh2easy.Ciphertext, privateShare *tdh2easy.PrivateShare, keys []string) []*vaultcommon.EncryptedShares { + t.Helper() + share, err := tdh2easy.Decrypt(ciphertext, privateShare) + require.NoError(t, err) + shareBytes, err := share.Marshal() + require.NoError(t, err) + + result := make([]*vaultcommon.EncryptedShares, len(keys)) + for i, pk := range keys { + pkBytes, err := hex.DecodeString(pk) + require.NoError(t, err) + pubKey := [32]byte(pkBytes) + encrypted, err := box.SealAnonymous(nil, shareBytes, &pubKey, rand.Reader) + require.NoError(t, err) + result[i] = &vaultcommon.EncryptedShares{ + EncryptionKey: pk, + Shares: []string{base64.StdEncoding.EncodeToString(encrypted)}, + } + } + return result +} + +func makeGetSecretsObservations( + t *testing.T, + numRequests int, + owner string, + namespace string, + encryptionKeys []string, + encryptedValue string, + ciphertext *tdh2easy.Ciphertext, + privateShare *tdh2easy.PrivateShare, +) []byte { + t.Helper() + obs := make([]observation, 0, numRequests) + for i := range numRequests { + maxKey := fmt.Sprintf("%s%d", strings.Repeat("c", 64-1), i) + + id := &vaultcommon.SecretIdentifier{ + Owner: owner, + Namespace: namespace, + Key: maxKey, + } + req := &vaultcommon.GetSecretsRequest{ + Requests: []*vaultcommon.SecretRequest{ + { + Id: id, + EncryptionKeys: encryptionKeys, + }, + }, + } + resp := &vaultcommon.GetSecretsResponse{ + Responses: []*vaultcommon.SecretResponse{ + { + Id: id, + Result: &vaultcommon.SecretResponse_Data{ + Data: &vaultcommon.SecretData{ + EncryptedValue: encryptedValue, + EncryptedDecryptionKeyShares: makeEncryptedShares(t, ciphertext, privateShare, encryptionKeys), + }, + }, + }, + }, + } + obs = append(obs, observation{id, req, resp}) + } + return marshalObservations(t, obs...) +} + type observation struct { id *vaultcommon.SecretIdentifier req proto.Message @@ -2320,6 +2394,80 @@ func TestPlugin_StateTransition_InsufficientObservations(t *testing.T) { assert.Equal(t, 1, observed.FilterMessage("insufficient observations found for id").Len()) } +func TestPlugin_StateTransition_GetSecretsRequest_ResponseSizeWithinLimit(t *testing.T) { + lggr := logger.TestLogger(t) + store := requests.NewStore[*vaulttypes.Request]() + _, pk, shares, err := tdh2easy.GenerateKeys(4, 10) + require.NoError(t, err) + + numObservers := 10 + r := &ReportingPlugin{ + lggr: lggr, + onchainCfg: ocr3types.ReportingPluginConfig{ + N: 10, + F: 3, + }, + store: store, + cfg: makeReportingPluginConfig( + t, + 10, + pk, + shares[0], + 100, + 2000, + 64, + 64, + 64, + 10, + ), + } + + maxOwner := strings.Repeat("a", 64) + maxNamespace := strings.Repeat("b", 64) + + numEncryptionKeys := 10 + encryptionKeys := make([]string, numEncryptionKeys) + for i := range numEncryptionKeys { + pubK, _, err2 := box.GenerateKey(rand.Reader) + require.NoError(t, err2) + encryptionKeys[i] = hex.EncodeToString(pubK[:]) + } + + plaintext := make([]byte, 1) + _, err = rand.Read(plaintext) + require.NoError(t, err) + var label [32]byte + copy(label[:], maxOwner[:32]) + ciphertext, err := tdh2easy.EncryptWithLabel(pk, plaintext, label) + require.NoError(t, err) + ciphertextBytes, err := ciphertext.Marshal() + require.NoError(t, err) + require.LessOrEqual(t, len(ciphertextBytes), 2000) + encryptedValue := hex.EncodeToString(ciphertextBytes) + + // Create 10 observations from different observers, each with a distinct decryption share. + aos := make([]types.AttributedObservation, numObservers) + for i := range numObservers { + aos[i] = types.AttributedObservation{ + Observer: commontypes.OracleID(i), //nolint:gosec // G115 range is well within uint8 bounds + Observation: types.Observation(makeGetSecretsObservations(t, 10, maxOwner, maxNamespace, encryptionKeys, encryptedValue, ciphertext, shares[i])), + } + } + + kvStore := &kv{m: make(map[string]response)} + reportPrecursor, err := r.StateTransition( + t.Context(), + 1, + types.AttributedQuery{}, + aos, kvStore, nil) + require.NoError(t, err) + + t.Logf("StateTransition response size: %d bytes (%.2f KB)", len(reportPrecursor), float64(len(reportPrecursor))/1024.0) + maxResponseSize := 512 * 1024 + assert.LessOrEqual(t, len(reportPrecursor), maxResponseSize, + "StateTransition response size %d exceeds 512KB limit", len(reportPrecursor)) +} + func TestPlugin_ValidateObservations_InvalidObservations(t *testing.T) { lggr, _ := logger.TestLoggerObserved(t, zapcore.DebugLevel) store := requests.NewStore[*vaulttypes.Request]() diff --git a/deployment/go.mod b/deployment/go.mod index add96f04720..40ae16e5213 100644 --- a/deployment/go.mod +++ b/deployment/go.mod @@ -43,7 +43,7 @@ require ( github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260121163256-85accaf3d28d github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260303213437-47af98c8ae82 - github.com/smartcontractkit/chainlink-common v0.10.1-0.20260309113338-432602d809cc + github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310204254-f3e84643d9cd github.com/smartcontractkit/chainlink-common/keystore v1.0.2 github.com/smartcontractkit/chainlink-deployments-framework v0.86.0 github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260309171438-f10976da0b9b diff --git a/deployment/go.sum b/deployment/go.sum index cb87fef6d58..08734c90fb0 100644 --- a/deployment/go.sum +++ b/deployment/go.sum @@ -1383,8 +1383,8 @@ github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260303213437-47af github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260303213437-47af98c8ae82/go.mod h1:r6gOO/602z5FQyRxsBHd93/oNsAgboo2+DMhPoisPuU= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260306124118-a6395a14f619 h1:mM4TnyNkRnNXZ+3WkjL+B1/CvepoQ+Aw+Y1AuRIzJQY= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260306124118-a6395a14f619/go.mod h1:RnuNcn7DZmjmzEkeEWX0uL5y1oslB3c9URPLOjFU+jE= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260309113338-432602d809cc h1:euYwd49PgzksFd9RBQ+qEObafDDz7fJu/9Oibc0G3Fk= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260309113338-432602d809cc/go.mod h1:0ghbAr7tRO0tT5ZqBXhOyzgUO37tNNe33Yn0hskauVM= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310204254-f3e84643d9cd h1:9hEKLyqLGl8juNUKRkNQDGRplchkSobV12BX0tE8RVQ= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310204254-f3e84643d9cd/go.mod h1:0ghbAr7tRO0tT5ZqBXhOyzgUO37tNNe33Yn0hskauVM= github.com/smartcontractkit/chainlink-common/keystore v1.0.2 h1:AWisx4JT3QV8tcgh6J5NCrex+wAgTYpWyHsyNPSXzsQ= github.com/smartcontractkit/chainlink-common/keystore v1.0.2/go.mod h1:rSkIHdomyak3YnUtXLenl6poIq8q0V3UZPiiyYqPdGA= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 h1:FJAFgXS9oqASnkS03RE1HQwYQQxrO4l46O5JSzxqLgg= diff --git a/go.mod b/go.mod index ee63be68348..ce8b2bb9f8d 100644 --- a/go.mod +++ b/go.mod @@ -85,7 +85,7 @@ require ( github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260121163256-85accaf3d28d github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 github.com/smartcontractkit/chainlink-ccv v0.0.0-20260306124118-a6395a14f619 - github.com/smartcontractkit/chainlink-common v0.10.1-0.20260309113338-432602d809cc + github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310204254-f3e84643d9cd github.com/smartcontractkit/chainlink-common/keystore v1.0.2 github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 github.com/smartcontractkit/chainlink-data-streams v0.1.12-0.20260227110503-42b236799872 diff --git a/go.sum b/go.sum index 78d599a63a5..42ecb1bc856 100644 --- a/go.sum +++ b/go.sum @@ -1183,8 +1183,8 @@ github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250 github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5/go.mod h1:xtZNi6pOKdC3sLvokDvXOhgHzT+cyBqH/gWwvxTxqrg= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260306124118-a6395a14f619 h1:mM4TnyNkRnNXZ+3WkjL+B1/CvepoQ+Aw+Y1AuRIzJQY= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260306124118-a6395a14f619/go.mod h1:RnuNcn7DZmjmzEkeEWX0uL5y1oslB3c9URPLOjFU+jE= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260309113338-432602d809cc h1:euYwd49PgzksFd9RBQ+qEObafDDz7fJu/9Oibc0G3Fk= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260309113338-432602d809cc/go.mod h1:0ghbAr7tRO0tT5ZqBXhOyzgUO37tNNe33Yn0hskauVM= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310204254-f3e84643d9cd h1:9hEKLyqLGl8juNUKRkNQDGRplchkSobV12BX0tE8RVQ= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310204254-f3e84643d9cd/go.mod h1:0ghbAr7tRO0tT5ZqBXhOyzgUO37tNNe33Yn0hskauVM= github.com/smartcontractkit/chainlink-common/keystore v1.0.2 h1:AWisx4JT3QV8tcgh6J5NCrex+wAgTYpWyHsyNPSXzsQ= github.com/smartcontractkit/chainlink-common/keystore v1.0.2/go.mod h1:rSkIHdomyak3YnUtXLenl6poIq8q0V3UZPiiyYqPdGA= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 h1:FJAFgXS9oqASnkS03RE1HQwYQQxrO4l46O5JSzxqLgg= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index ec8d370663b..d3e3b3b8b28 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -50,7 +50,7 @@ require ( github.com/smartcontractkit/chainlink-ccip v0.1.1-solana.0.20260303213437-47af98c8ae82 github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260121163256-85accaf3d28d github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 - github.com/smartcontractkit/chainlink-common v0.10.1-0.20260309113338-432602d809cc + github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310204254-f3e84643d9cd github.com/smartcontractkit/chainlink-common/keystore v1.0.2 github.com/smartcontractkit/chainlink-deployments-framework v0.86.0 github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260309171438-f10976da0b9b diff --git a/integration-tests/go.sum b/integration-tests/go.sum index abb7bdfca30..9ade30e2a75 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1624,8 +1624,8 @@ github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260303213437-47af github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260303213437-47af98c8ae82/go.mod h1:r6gOO/602z5FQyRxsBHd93/oNsAgboo2+DMhPoisPuU= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260306124118-a6395a14f619 h1:mM4TnyNkRnNXZ+3WkjL+B1/CvepoQ+Aw+Y1AuRIzJQY= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260306124118-a6395a14f619/go.mod h1:RnuNcn7DZmjmzEkeEWX0uL5y1oslB3c9URPLOjFU+jE= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260309113338-432602d809cc h1:euYwd49PgzksFd9RBQ+qEObafDDz7fJu/9Oibc0G3Fk= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260309113338-432602d809cc/go.mod h1:0ghbAr7tRO0tT5ZqBXhOyzgUO37tNNe33Yn0hskauVM= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310204254-f3e84643d9cd h1:9hEKLyqLGl8juNUKRkNQDGRplchkSobV12BX0tE8RVQ= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310204254-f3e84643d9cd/go.mod h1:0ghbAr7tRO0tT5ZqBXhOyzgUO37tNNe33Yn0hskauVM= github.com/smartcontractkit/chainlink-common/keystore v1.0.2 h1:AWisx4JT3QV8tcgh6J5NCrex+wAgTYpWyHsyNPSXzsQ= github.com/smartcontractkit/chainlink-common/keystore v1.0.2/go.mod h1:rSkIHdomyak3YnUtXLenl6poIq8q0V3UZPiiyYqPdGA= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 h1:FJAFgXS9oqASnkS03RE1HQwYQQxrO4l46O5JSzxqLgg= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 13fc237cadc..bf383b3d1b0 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -32,7 +32,7 @@ require ( github.com/smartcontractkit/chainlink-ccip v0.1.1-solana.0.20260303213437-47af98c8ae82 github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260121163256-85accaf3d28d github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 - github.com/smartcontractkit/chainlink-common v0.10.1-0.20260309113338-432602d809cc + github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310204254-f3e84643d9cd github.com/smartcontractkit/chainlink-deployments-framework v0.86.0 github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260309171438-f10976da0b9b github.com/smartcontractkit/chainlink-evm/gethwrappers v0.0.0-20251222115927-36a18321243c diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 601b5b59141..1a2d1bab467 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1602,8 +1602,8 @@ github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260303213437-47af github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260303213437-47af98c8ae82/go.mod h1:r6gOO/602z5FQyRxsBHd93/oNsAgboo2+DMhPoisPuU= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260306124118-a6395a14f619 h1:mM4TnyNkRnNXZ+3WkjL+B1/CvepoQ+Aw+Y1AuRIzJQY= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260306124118-a6395a14f619/go.mod h1:RnuNcn7DZmjmzEkeEWX0uL5y1oslB3c9URPLOjFU+jE= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260309113338-432602d809cc h1:euYwd49PgzksFd9RBQ+qEObafDDz7fJu/9Oibc0G3Fk= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260309113338-432602d809cc/go.mod h1:0ghbAr7tRO0tT5ZqBXhOyzgUO37tNNe33Yn0hskauVM= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310204254-f3e84643d9cd h1:9hEKLyqLGl8juNUKRkNQDGRplchkSobV12BX0tE8RVQ= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310204254-f3e84643d9cd/go.mod h1:0ghbAr7tRO0tT5ZqBXhOyzgUO37tNNe33Yn0hskauVM= github.com/smartcontractkit/chainlink-common/keystore v1.0.2 h1:AWisx4JT3QV8tcgh6J5NCrex+wAgTYpWyHsyNPSXzsQ= github.com/smartcontractkit/chainlink-common/keystore v1.0.2/go.mod h1:rSkIHdomyak3YnUtXLenl6poIq8q0V3UZPiiyYqPdGA= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 h1:FJAFgXS9oqASnkS03RE1HQwYQQxrO4l46O5JSzxqLgg= diff --git a/system-tests/lib/go.mod b/system-tests/lib/go.mod index d51631da27e..cce61e24cc6 100644 --- a/system-tests/lib/go.mod +++ b/system-tests/lib/go.mod @@ -32,7 +32,7 @@ require ( github.com/sethvargo/go-retry v0.3.0 github.com/smartcontractkit/chain-selectors v1.0.97 github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260121163256-85accaf3d28d - github.com/smartcontractkit/chainlink-common v0.10.1-0.20260309113338-432602d809cc + github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310204254-f3e84643d9cd github.com/smartcontractkit/chainlink-common/keystore v1.0.2 github.com/smartcontractkit/chainlink-deployments-framework v0.86.0 github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260309171438-f10976da0b9b diff --git a/system-tests/lib/go.sum b/system-tests/lib/go.sum index 75eb0446a57..196cdf962e0 100644 --- a/system-tests/lib/go.sum +++ b/system-tests/lib/go.sum @@ -1583,8 +1583,8 @@ github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260303213437-47af github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260303213437-47af98c8ae82/go.mod h1:r6gOO/602z5FQyRxsBHd93/oNsAgboo2+DMhPoisPuU= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260306124118-a6395a14f619 h1:mM4TnyNkRnNXZ+3WkjL+B1/CvepoQ+Aw+Y1AuRIzJQY= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260306124118-a6395a14f619/go.mod h1:RnuNcn7DZmjmzEkeEWX0uL5y1oslB3c9URPLOjFU+jE= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260309113338-432602d809cc h1:euYwd49PgzksFd9RBQ+qEObafDDz7fJu/9Oibc0G3Fk= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260309113338-432602d809cc/go.mod h1:0ghbAr7tRO0tT5ZqBXhOyzgUO37tNNe33Yn0hskauVM= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310204254-f3e84643d9cd h1:9hEKLyqLGl8juNUKRkNQDGRplchkSobV12BX0tE8RVQ= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310204254-f3e84643d9cd/go.mod h1:0ghbAr7tRO0tT5ZqBXhOyzgUO37tNNe33Yn0hskauVM= github.com/smartcontractkit/chainlink-common/keystore v1.0.2 h1:AWisx4JT3QV8tcgh6J5NCrex+wAgTYpWyHsyNPSXzsQ= github.com/smartcontractkit/chainlink-common/keystore v1.0.2/go.mod h1:rSkIHdomyak3YnUtXLenl6poIq8q0V3UZPiiyYqPdGA= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 h1:FJAFgXS9oqASnkS03RE1HQwYQQxrO4l46O5JSzxqLgg= diff --git a/system-tests/tests/go.mod b/system-tests/tests/go.mod index 0cc70f2c76d..a5be76b1e19 100644 --- a/system-tests/tests/go.mod +++ b/system-tests/tests/go.mod @@ -54,7 +54,7 @@ require ( github.com/rs/zerolog v1.34.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.97 - github.com/smartcontractkit/chainlink-common v0.10.1-0.20260309113338-432602d809cc + github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310204254-f3e84643d9cd github.com/smartcontractkit/chainlink-common/keystore v1.0.2 github.com/smartcontractkit/chainlink-data-streams v0.1.12-0.20260227110503-42b236799872 github.com/smartcontractkit/chainlink-deployments-framework v0.86.0 diff --git a/system-tests/tests/go.sum b/system-tests/tests/go.sum index 4fa631441c3..393d88fb8a7 100644 --- a/system-tests/tests/go.sum +++ b/system-tests/tests/go.sum @@ -1790,8 +1790,8 @@ github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260303213437-47af github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260303213437-47af98c8ae82/go.mod h1:r6gOO/602z5FQyRxsBHd93/oNsAgboo2+DMhPoisPuU= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260306124118-a6395a14f619 h1:mM4TnyNkRnNXZ+3WkjL+B1/CvepoQ+Aw+Y1AuRIzJQY= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260306124118-a6395a14f619/go.mod h1:RnuNcn7DZmjmzEkeEWX0uL5y1oslB3c9URPLOjFU+jE= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260309113338-432602d809cc h1:euYwd49PgzksFd9RBQ+qEObafDDz7fJu/9Oibc0G3Fk= -github.com/smartcontractkit/chainlink-common v0.10.1-0.20260309113338-432602d809cc/go.mod h1:0ghbAr7tRO0tT5ZqBXhOyzgUO37tNNe33Yn0hskauVM= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310204254-f3e84643d9cd h1:9hEKLyqLGl8juNUKRkNQDGRplchkSobV12BX0tE8RVQ= +github.com/smartcontractkit/chainlink-common v0.10.1-0.20260310204254-f3e84643d9cd/go.mod h1:0ghbAr7tRO0tT5ZqBXhOyzgUO37tNNe33Yn0hskauVM= github.com/smartcontractkit/chainlink-common/keystore v1.0.2 h1:AWisx4JT3QV8tcgh6J5NCrex+wAgTYpWyHsyNPSXzsQ= github.com/smartcontractkit/chainlink-common/keystore v1.0.2/go.mod h1:rSkIHdomyak3YnUtXLenl6poIq8q0V3UZPiiyYqPdGA= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.11-0.20251211140724-319861e514c4 h1:NOUsjsMzNecbjiPWUQGlRSRAutEvCFrqqyETDJeh5q4= diff --git a/system-tests/tests/smoke/cre/v2_vault_don_test.go b/system-tests/tests/smoke/cre/v2_vault_don_test.go index 8985a4f073f..1b6ce9e1b82 100644 --- a/system-tests/tests/smoke/cre/v2_vault_don_test.go +++ b/system-tests/tests/smoke/cre/v2_vault_don_test.go @@ -62,9 +62,6 @@ func ExecuteVaultTest(t *testing.T, testEnv *ttypes.TestEnvironment) { return false }, time.Second*300, time.Second*5) - // Wait a bit to ensure the Vault plugin is ready. - time.Sleep(30 * time.Second) - testLogger.Info().Msg("Getting gateway configuration...") require.NotEmpty(t, testEnv.Dons.GatewayConnectors.Configurations, "expected at least one gateway configuration") gatewayURL, err := url.Parse(testEnv.Dons.GatewayConnectors.Configurations[0].Incoming.Protocol + "://" + testEnv.Dons.GatewayConnectors.Configurations[0].Incoming.Host + ":" + strconv.Itoa(testEnv.Dons.GatewayConnectors.Configurations[0].Incoming.ExternalPort) + testEnv.Dons.GatewayConnectors.Configurations[0].Incoming.Path) diff --git a/system-tests/tests/smoke/cre/v2_vault_don_test_helpers.go b/system-tests/tests/smoke/cre/v2_vault_don_test_helpers.go index 30f0b87bb38..a9a493e2e8a 100644 --- a/system-tests/tests/smoke/cre/v2_vault_don_test_helpers.go +++ b/system-tests/tests/smoke/cre/v2_vault_don_test_helpers.go @@ -6,6 +6,7 @@ import ( "io" "net/http" "testing" + "time" "github.com/google/uuid" "github.com/stretchr/testify/require" @@ -30,6 +31,10 @@ func FetchVaultPublicKey(t *testing.T, gatewayURL string) (publicKey string) { requestBody, err := json.Marshal(getPublicKeyRequest) require.NoError(t, err, "failed to marshal public key request") + require.Eventually(t, func() bool { + statusCode, _ := sendVaultRequestToGateway(t, gatewayURL, requestBody) + return statusCode == http.StatusOK + }, time.Second*120, time.Second*5) statusCode, httpResponseBody := sendVaultRequestToGateway(t, gatewayURL, requestBody) require.Equal(t, http.StatusOK, statusCode, "Gateway endpoint should respond with 200 OK")