Skip to content
Draft
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
3 changes: 3 additions & 0 deletions pkg/settings/cresettings/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,9 @@ flowchart
%% enclave → gateway → relay DON node is likewise its own entry point
HandleGatewayMessage

%% TODO placating test for now since this flowchart no longer renders
DonTimeSequencedTimestampsEnabled

classDef bound stroke:#f00
classDef gate stroke:#0f0
classDef queue stroke:#00f
Expand Down
1 change: 1 addition & 0 deletions pkg/settings/cresettings/defaults.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"VaultMaxBlobPayloadSizeLimit": "25.6kb",
"VaultMaxPerOracleUnexpiredBlobCumulativePayloadSizeLimit": "31.45728mb",
"VaultMaxPerOracleUnexpiredBlobCount": "1000",
"DonTimeSequencedTimestampsEnabled": "[2100-01-01 00:00:00 +0000 UTC,2101-01-01 00:00:00 +0000 UTC]",
"ConfidentialCompute": {
"GlobalRate": "1000rps:1000",
"MaxRetries": "3",
Expand Down
1 change: 1 addition & 0 deletions pkg/settings/cresettings/defaults.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ VaultMaxKeyValueModifiedKeys = '300'
VaultMaxBlobPayloadSizeLimit = '25.6kb'
VaultMaxPerOracleUnexpiredBlobCumulativePayloadSizeLimit = '31.45728mb'
VaultMaxPerOracleUnexpiredBlobCount = '1000'
DonTimeSequencedTimestampsEnabled = '[2100-01-01 00:00:00 +0000 UTC,2101-01-01 00:00:00 +0000 UTC]'

[ConfidentialCompute]
GlobalRate = '1000rps:1000'
Expand Down
42 changes: 18 additions & 24 deletions pkg/settings/cresettings/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ var DefaultGetter Getter
// Deprecated: use Default
var Config Schema

var (
year2100 = time.Date(2100, 1, 1, 0, 0, 0, 0, time.UTC)
disabledFeatureTimeRange = TimeRange(year2100, time.Date(2101, 1, 1, 0, 0, 0, 0, time.UTC))
)

var Default = Schema{
WorkflowLimit: Int(1000),
WorkflowExecutionConcurrencyLimit: Int(1000),
Expand Down Expand Up @@ -151,6 +156,8 @@ var Default = Schema{
VaultMaxPerOracleUnexpiredBlobCumulativePayloadSizeLimit: Size(31457280 * config.Byte),
VaultMaxPerOracleUnexpiredBlobCount: Int(1000),

DonTimeSequencedTimestampsEnabled: disabledFeatureTimeRange,

// Confidential Compute (San Marino framework) node-level settings. Defaults
// mirror the previous hardcoded executor defaults so behavior is unchanged
// until explicitly overridden.
Expand Down Expand Up @@ -326,39 +333,24 @@ var Default = Schema{
RequestTimeout: Duration(30 * time.Second),
},

FeatureMultiTriggerExecutionIDsActiveAt: Time(time.Date(2100, 1, 1, 0, 0, 0, 0, time.UTC)),
FeatureMultiTriggerExecutionIDsActivePeriod: TimeRange(
time.Date(2100, 1, 1, 0, 0, 0, 0, time.UTC),
time.Date(2101, 1, 1, 0, 0, 0, 0, time.UTC)),
FeatureHTTPTriggerNewExecutionIDsActivePeriod: TimeRange(
time.Date(2100, 1, 1, 0, 0, 0, 0, time.UTC),
time.Date(2101, 1, 1, 0, 0, 0, 0, time.UTC)),
FeatureUseSingleDONTimeProviderPerExecutionActivePeriod: TimeRange(
time.Date(2100, 1, 1, 0, 0, 0, 0, time.UTC),
time.Date(2101, 1, 1, 0, 0, 0, 0, time.UTC)),
FeatureChainCapabilityHashBasedOCRActivePeriod: TimeRange(
time.Date(2100, 1, 1, 0, 0, 0, 0, time.UTC),
time.Date(2101, 1, 1, 0, 0, 0, 0, time.UTC)),
FeatureEVMWriteReportL1FeeActivePeriod: TimeRange(
time.Date(2100, 1, 1, 0, 0, 0, 0, time.UTC),
time.Date(2101, 1, 1, 0, 0, 0, 0, time.UTC)),
FeatureAptosWriteReportBlockTimestampActivePeriod: TimeRange(
time.Date(2100, 1, 1, 0, 0, 0, 0, time.UTC),
time.Date(2101, 1, 1, 0, 0, 0, 0, time.UTC)),
FeatureMultiTriggerExecutionIDsActiveAt: Time(year2100),
FeatureMultiTriggerExecutionIDsActivePeriod: disabledFeatureTimeRange,
FeatureHTTPTriggerNewExecutionIDsActivePeriod: disabledFeatureTimeRange,
FeatureUseSingleDONTimeProviderPerExecutionActivePeriod: disabledFeatureTimeRange,
FeatureChainCapabilityHashBasedOCRActivePeriod: disabledFeatureTimeRange,
FeatureEVMWriteReportL1FeeActivePeriod: disabledFeatureTimeRange,
FeatureAptosWriteReportBlockTimestampActivePeriod: disabledFeatureTimeRange,
// ON by default: covers all possible timestamps including zero time.Time{},
// so WorkflowTag is included in the hash matching current prod behavior.
// After rollout, set to far-future window to exclude WorkflowTag.
FeatureRequestHashIncludeWorkflowTagActivePeriod: TimeRange(
time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC),
time.Date(2100, 1, 1, 0, 0, 0, 0, time.UTC)),
time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC), year2100),
// OFF by default: the workflow_specs_v2.workflow_tag reconcile backfill
// is intentionally disabled on a fresh deploy. Ops narrows the range to
// cover "now" only after FeatureRequestHashIncludeWorkflowTag is muted
// on every DON member, so DBs can heal without producing tag-driven
// hash divergence during the fill window.
FeatureWorkflowTagBackfillActivePeriod: TimeRange(
time.Date(2100, 1, 1, 0, 0, 0, 0, time.UTC),
time.Date(2101, 1, 1, 0, 0, 0, 0, time.UTC)),
FeatureWorkflowTagBackfillActivePeriod: disabledFeatureTimeRange,
},
}

Expand Down Expand Up @@ -448,6 +440,8 @@ type Schema struct {
VaultMaxPerOracleUnexpiredBlobCumulativePayloadSizeLimit Setting[config.Size]
VaultMaxPerOracleUnexpiredBlobCount Setting[int]

DonTimeSequencedTimestampsEnabled Setting[Range[config.Timestamp]]

// Confidential Compute (San Marino framework) node-level settings.
ConfidentialCompute confidentialCompute

Expand Down
23 changes: 19 additions & 4 deletions pkg/workflows/dontime/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ import (

"github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types"

"github.com/smartcontractkit/chainlink-common/pkg/config"
"github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/chainlink-common/pkg/services"
"github.com/smartcontractkit/chainlink-common/pkg/settings/cresettings"
"github.com/smartcontractkit/chainlink-common/pkg/settings/limits"
"github.com/smartcontractkit/chainlink-common/pkg/types/core"
"github.com/smartcontractkit/chainlink-common/pkg/workflows/dontime/pb"
)
Expand All @@ -26,19 +29,30 @@ const (
var _ core.OCR3ReportingPluginFactory = &Factory{}

type Factory struct {
store *Store
lggr logger.Logger
store *Store
lggr logger.Logger
sequencedTSEnabled limits.RangeLimiter[config.Timestamp]

services.StateMachine
}

func NewFactory(s *Store, lggr logger.Logger) (*Factory, error) {
return &Factory{
store: s,
lggr: logger.Named(lggr, "OCR3DonTimeFactory"),
store: s,
lggr: logger.Named(lggr, "OCR3DonTimeFactory"),
sequencedTSEnabled: limits.NewRangeLimiter(cresettings.Default.DonTimeSequencedTimestampsEnabled.DefaultValue),
}, nil
}

func (o *Factory) InitLimits(lf limits.Factory) error {
sequencedTSEnabled, err := limits.MakeRangeLimiter[config.Timestamp](lf, cresettings.Default.DonTimeSequencedTimestampsEnabled)
if err != nil {
return err
}
o.sequencedTSEnabled = sequencedTSEnabled
return nil
}

func (o *Factory) NewReportingPlugin(_ context.Context, config ocr3types.ReportingPluginConfig) (ocr3types.ReportingPlugin[[]byte], ocr3types.ReportingPluginInfo, error) {
var configProto pb.Config
err := proto.Unmarshal(config.OffchainConfig, &configProto)
Expand Down Expand Up @@ -75,6 +89,7 @@ func (o *Factory) NewReportingPlugin(_ context.Context, config ocr3types.Reporti
if err != nil {
return nil, ocr3types.ReportingPluginInfo{}, err
}
plugin.setSequencedTSEnabled(o.sequencedTSEnabled)
pluginInfo := ocr3types.ReportingPluginInfo{
Name: "DON Time Plugin",
Limits: ocr3types.ReportingPluginLimits{
Expand Down
24 changes: 24 additions & 0 deletions pkg/workflows/dontime/pb/dontime.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package pb

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why in pb?

@jmank88 jmank88 Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seemed fitting as methods, but could be a helper funcs instead 🤷


import "math"

// MaxSeqNum returns the max sequence number from TimestampsBySequence, or 0 if none exist.
func (t *ObservedDonTimes) MaxSeqNum() (maxSeqNum int64) {
for seqNum := range t.TimestampsBySequence {
if seqNum > maxSeqNum {
maxSeqNum = seqNum
}
}
return
}

// EarliestTS returns the earliest timestamp value from TimestampsBySequence, or math.MaxInt64 if none exist.
func (t *ObservedDonTimes) EarliestTS() (earliestTS int64) {
earliestTS = math.MaxInt64
for _, ts := range t.TimestampsBySequence {
if ts < earliestTS {
earliestTS = ts
}
}
return
}
52 changes: 34 additions & 18 deletions pkg/workflows/dontime/pb/dontime.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion pkg/workflows/dontime/pb/dontime.proto
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ message Observation {
}

message ObservedDonTimes {
repeated int64 timestamps = 1;
repeated int64 timestamps = 1 [deprecated = true];
map<int64, int64> timestampsBySequence = 2;
}

message Outcome {
Expand Down
Loading
Loading