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
5 changes: 5 additions & 0 deletions .changeset/org-resolver-cache.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"chainlink": minor
---

#added Durable caching of OrgResolver owner->orgID mappings (backed by Postgres, `CRE.Linking.CacheEnabled`, enabled by default).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

nit: can you update PR description / link JIRA to clarify why durable caching is needed.

2 changes: 2 additions & 0 deletions core/config/cre_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,6 @@ type CRELinking interface {
TLSEnabled() bool
// RequestTimeout bounds each organization lookup against the linking service.
RequestTimeout() time.Duration
// CacheEnabled turns on durable caching of owner->orgID mappings (backed by Postgres).
CacheEnabled() bool
}
2 changes: 2 additions & 0 deletions core/config/docs/core.toml
Original file line number Diff line number Diff line change
Expand Up @@ -997,6 +997,8 @@ URL = "" # Default
TLSEnabled = true # Default
# RequestTimeout bounds each organization lookup against the linking service.
RequestTimeout = '2s' # Default
# CacheEnabled turns on durable Postgres-backed caching of owner->orgID mappings.
CacheEnabled = true # Default

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

nit: probably call it DurableCacheEnabled to underscore that the durable cache is enabled (the inmemory one is always on)


# Billing holds settings for connecting to the billing service.
[Billing]
Expand Down
9 changes: 9 additions & 0 deletions core/config/toml/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -2058,6 +2058,8 @@ type LinkingConfig struct {
URL *string `toml:",omitempty"`
TLSEnabled *bool `toml:",omitempty"`
RequestTimeout *commonconfig.Duration `toml:",omitempty"`
// CacheEnabled turns on durable Postgres-backed caching of owner->orgID mappings.
CacheEnabled *bool `toml:",omitempty"`
}

func (c *CreConfig) setFrom(f *CreConfig) {
Expand Down Expand Up @@ -2105,6 +2107,9 @@ func (c *CreConfig) setFrom(f *CreConfig) {
if v := f.Linking.RequestTimeout; v != nil {
c.Linking.RequestTimeout = v
}
if v := f.Linking.CacheEnabled; v != nil {
c.Linking.CacheEnabled = v
}
}

if f.DebugMode != nil {
Expand Down Expand Up @@ -2158,6 +2163,10 @@ func (l *LinkingConfig) ValidateConfig() error {
} else if l.RequestTimeout.Duration() <= 0 {
return configutils.ErrInvalid{Name: "RequestTimeout", Value: l.RequestTimeout.String(), Msg: "must be positive"}
}
if l.CacheEnabled == nil {
val := true
l.CacheEnabled = &val
}
return nil
}

Expand Down
2 changes: 1 addition & 1 deletion core/scripts/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ require (
github.com/shopspring/decimal v1.4.0
github.com/smartcontractkit/chain-selectors v1.0.108
github.com/smartcontractkit/chainlink-ccip/chains/evm v0.0.0-20260821001950-7520b255725e
github.com/smartcontractkit/chainlink-common v0.11.2-0.20260903131821-eb4e3f87b067
github.com/smartcontractkit/chainlink-common v0.11.2-0.20260903152135-85b2080c56da
github.com/smartcontractkit/chainlink-common/keystore v1.3.0
github.com/smartcontractkit/chainlink-deployments-framework v0.120.1-0.20260828145648-3e1bcd2ac1da
github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260810110946-8174b6bb7fc9
Expand Down
4 changes: 2 additions & 2 deletions core/scripts/go.sum

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

14 changes: 12 additions & 2 deletions core/services/chainlink/config_cre.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ type linkingConfig struct {
url string
tlsEnabled bool
requestTimeout time.Duration
cacheEnabled bool
}

func (l *linkingConfig) URL() string {
Expand All @@ -97,9 +98,13 @@ func (l *linkingConfig) RequestTimeout() time.Duration {
return l.requestTimeout
}

func (l *linkingConfig) CacheEnabled() bool {
return l.cacheEnabled
}

func (c *creConfig) Linking() config.CRELinking {
if c.c.Linking == nil {
return &linkingConfig{url: "", tlsEnabled: true, requestTimeout: defaultLinkingRequestTimeout}
return &linkingConfig{url: "", tlsEnabled: true, requestTimeout: defaultLinkingRequestTimeout, cacheEnabled: true}
}

url := ""
Expand All @@ -117,7 +122,12 @@ func (c *creConfig) Linking() config.CRELinking {
requestTimeout = c.c.Linking.RequestTimeout.Duration()
}

return &linkingConfig{url: url, tlsEnabled: tlsEnabled, requestTimeout: requestTimeout}
cacheEnabled := true // default
if c.c.Linking.CacheEnabled != nil {
cacheEnabled = *c.c.Linking.CacheEnabled
}

return &linkingConfig{url: url, tlsEnabled: tlsEnabled, requestTimeout: requestTimeout, cacheEnabled: cacheEnabled}
}

type confidentialRelayConfig struct {
Expand Down
1 change: 1 addition & 0 deletions core/services/chainlink/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,7 @@ func TestConfig_Marshal(t *testing.T) {
URL: new(""),
TLSEnabled: new(true),
RequestTimeout: commoncfg.MustNewDuration(2 * time.Second),
CacheEnabled: new(true),
},
ConfidentialRelay: &toml.ConfidentialRelayConfig{
Enabled: new(bool),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@ URL = ''
URL = ''
TLSEnabled = true
RequestTimeout = '2s'
CacheEnabled = true

[CRE.ConfidentialRelay]
Enabled = false
Expand Down
1 change: 1 addition & 0 deletions core/services/chainlink/testdata/config-full.toml
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,7 @@ URL = 'https://workflow.fetcher.url'
URL = ''
TLSEnabled = true
RequestTimeout = '2s'
CacheEnabled = true

[CRE.ConfidentialRelay]
Enabled = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@ URL = ''
URL = ''
TLSEnabled = true
RequestTimeout = '2s'
CacheEnabled = true

[CRE.ConfidentialRelay]
Enabled = false
Expand Down
25 changes: 20 additions & 5 deletions core/services/cre/cre.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,13 +240,12 @@ func (s *Services) newSubservices(

if cfg.CRE().Linking().URL() != "" {
lggr.Debugw("Creating OrgResolver")
inner, ierr := newOrgResolver(cfg, capCfg, opts, lggr)
resolver, ierr := newOrgResolver(cfg, capCfg, opts, ds, lggr)
if ierr != nil {
return nil, fmt.Errorf("could not create org resolver: %w", ierr)
}
fallbackResolver := orgresolver.NewOrgResolverWithFallback(inner, lggr)
s.OrgResolver = fallbackResolver
srvs = append(srvs, fallbackResolver)
s.OrgResolver = resolver
srvs = append(srvs, resolver)
} else {
lggr.Warn("Skipping orgResolver, no linking service configured")
}
Expand Down Expand Up @@ -631,6 +630,7 @@ func newOrgResolver(
cfg Config,
capCfg config.Capabilities,
opts Opts,
ds sqlutil.DataSource,
lggr logger.Logger,
) (orgresolver.OrgResolver, error) {
var wrChainDetails chainselectors.ChainDetails
Expand Down Expand Up @@ -661,7 +661,22 @@ func newOrgResolver(
return nil, fmt.Errorf("failed to create org resolver: %w", err)
}

return resolver, nil
var cache orgresolver.Cache
if cfg.CRE().Linking().CacheEnabled() {
cache = NewOrgResolverStore(ds)
} else {
cache = orgresolver.NewInMemoryCache()
}

cachingResolver, err := orgresolver.NewCachingResolver(resolver, orgresolver.CachingResolverConfig{
Cache: cache,
Meter: opts.Meter,
}, lggr)
if err != nil {
return nil, fmt.Errorf("failed to create caching org resolver: %w", err)
}

return cachingResolver, nil
}

func newBillingClient(lggr logger.Logger, cfg Config, opts Opts) (metering.BillingClient, error) {
Expand Down
56 changes: 56 additions & 0 deletions core/services/cre/org_resolver_store.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package cre

import (
"context"
"database/sql"
"errors"
"fmt"
"time"

"github.com/smartcontractkit/chainlink-common/pkg/services/orgresolver"
"github.com/smartcontractkit/chainlink-common/pkg/sqlutil"
)

// orgResolverCacheTable is the durable owner->orgID mapping table backing the
// OrgResolver cache. See migration 0307_org_resolver_cache.sql.
const orgResolverCacheTable = "cre.org_resolver_cache"

// orgResolverStore is a Postgres-backed implementation of orgresolver.Cache.
type orgResolverStore struct {
ds sqlutil.DataSource
}

// NewOrgResolverStore creates a durable cache store for the OrgResolver.
func NewOrgResolverStore(ds sqlutil.DataSource) *orgResolverStore {
return &orgResolverStore{ds: ds}
}

// Get returns the cached entry for owner. ok is false if no entry exists.
func (s *orgResolverStore) Get(ctx context.Context, owner string) (orgresolver.CacheEntry, bool, error) {
const q = `SELECT org_id, updated_at FROM ` + orgResolverCacheTable + ` WHERE workflow_owner = $1`
var row struct {
OrgID string `db:"org_id"`
UpdatedAt time.Time `db:"updated_at"`
}
if err := s.ds.GetContext(ctx, &row, q, owner); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return orgresolver.CacheEntry{}, false, nil
}
return orgresolver.CacheEntry{}, false, fmt.Errorf("failed to get cached org for owner %s: %w", owner, err)
}
return orgresolver.CacheEntry{OrgID: row.OrgID, RefreshedAt: row.UpdatedAt}, true, nil
}

// Set stores or updates the mapping for owner.
func (s *orgResolverStore) Set(ctx context.Context, owner string, entry orgresolver.CacheEntry) error {
const q = `
INSERT INTO ` + orgResolverCacheTable + ` (workflow_owner, org_id, updated_at)
VALUES ($1, $2, $3)
ON CONFLICT (workflow_owner) DO UPDATE SET org_id = EXCLUDED.org_id, updated_at = EXCLUDED.updated_at`
if _, err := s.ds.ExecContext(ctx, q, owner, entry.OrgID, entry.RefreshedAt); err != nil {
return fmt.Errorf("failed to upsert org for owner %s: %w", owner, err)
}
return nil
}

var _ orgresolver.Cache = (*orgResolverStore)(nil)
11 changes: 11 additions & 0 deletions core/store/migrate/migrations/0307_org_resolver_cache.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
-- +goose Up

CREATE TABLE IF NOT EXISTS cre.org_resolver_cache (
workflow_owner TEXT NOT NULL PRIMARY KEY,
org_id TEXT NOT NULL,
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- +goose Down

DROP TABLE IF EXISTS cre.org_resolver_cache;
1 change: 1 addition & 0 deletions core/web/resolver/testdata/config-empty-effective.toml
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@ URL = ''
URL = ''
TLSEnabled = true
RequestTimeout = '2s'
CacheEnabled = true

[CRE.ConfidentialRelay]
Enabled = false
Expand Down
1 change: 1 addition & 0 deletions core/web/resolver/testdata/config-full.toml
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ URL = 'https://workflow.fetcher.url'
URL = ''
TLSEnabled = true
RequestTimeout = '2s'
CacheEnabled = true

[CRE.ConfidentialRelay]
Enabled = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@ URL = ''
URL = ''
TLSEnabled = true
RequestTimeout = '2s'
CacheEnabled = true

[CRE.ConfidentialRelay]
Enabled = false
Expand Down
2 changes: 1 addition & 1 deletion deployment/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ require (
github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260624154507-ea7ff77a0ddb
github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20260624154507-ea7ff77a0ddb
github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260821001950-7520b255725e
github.com/smartcontractkit/chainlink-common v0.11.2-0.20260903131821-eb4e3f87b067
github.com/smartcontractkit/chainlink-common v0.11.2-0.20260903152135-85b2080c56da
github.com/smartcontractkit/chainlink-common/keystore v1.3.0
github.com/smartcontractkit/chainlink-data-streams v1.1.1
github.com/smartcontractkit/chainlink-deployments-framework v0.120.1-0.20260828145648-3e1bcd2ac1da
Expand Down
4 changes: 2 additions & 2 deletions deployment/go.sum

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

7 changes: 7 additions & 0 deletions docs/CONFIG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2766,6 +2766,7 @@ URL is override URL for the workflow fetcher service.
URL = "" # Default
TLSEnabled = true # Default
RequestTimeout = '2s' # Default
CacheEnabled = true # Default
```


Expand All @@ -2787,6 +2788,12 @@ RequestTimeout = '2s' # Default
```
RequestTimeout bounds each organization lookup against the linking service.

### CacheEnabled
```toml
CacheEnabled = true # Default
```
CacheEnabled turns on durable Postgres-backed caching of owner->orgID mappings.

## Billing
```toml
[Billing]
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ require (
github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260415165642-49f23e4d76cc
github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20260415165642-49f23e4d76cc
github.com/smartcontractkit/chainlink-ccv v0.7.1-0.20260902155726-3ae29777797a
github.com/smartcontractkit/chainlink-common v0.11.2-0.20260903131821-eb4e3f87b067
github.com/smartcontractkit/chainlink-common v0.11.2-0.20260903152135-85b2080c56da
github.com/smartcontractkit/chainlink-common/keystore v1.3.0
github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.11-0.20260724142814-45996a1bcb72
github.com/smartcontractkit/chainlink-data-streams v1.1.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum

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

2 changes: 1 addition & 1 deletion integration-tests/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ require (
github.com/smartcontractkit/chainlink-ccip/chains/evm v0.0.0-20260821001950-7520b255725e
github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260624154507-ea7ff77a0ddb
github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20260624154507-ea7ff77a0ddb
github.com/smartcontractkit/chainlink-common v0.11.2-0.20260903131821-eb4e3f87b067
github.com/smartcontractkit/chainlink-common v0.11.2-0.20260903152135-85b2080c56da
github.com/smartcontractkit/chainlink-common/keystore v1.3.0
github.com/smartcontractkit/chainlink-deployments-framework v0.120.1-0.20260828145648-3e1bcd2ac1da
github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260810110946-8174b6bb7fc9
Expand Down
4 changes: 2 additions & 2 deletions integration-tests/go.sum

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

2 changes: 1 addition & 1 deletion integration-tests/load/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ require (
github.com/smartcontractkit/chainlink-ccip/chains/evm v0.0.0-20260821001950-7520b255725e
github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260624154507-ea7ff77a0ddb
github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20260624154507-ea7ff77a0ddb
github.com/smartcontractkit/chainlink-common v0.11.2-0.20260903131821-eb4e3f87b067
github.com/smartcontractkit/chainlink-common v0.11.2-0.20260903152135-85b2080c56da
github.com/smartcontractkit/chainlink-deployments-framework v0.120.1-0.20260828145648-3e1bcd2ac1da
github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260810110946-8174b6bb7fc9
github.com/smartcontractkit/chainlink-testing-framework/framework v0.16.7
Expand Down
4 changes: 2 additions & 2 deletions integration-tests/load/go.sum

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

2 changes: 1 addition & 1 deletion system-tests/lib/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ require (
github.com/smartcontractkit/chain-selectors v1.0.108
github.com/smartcontractkit/chainlink-aptos v0.0.0-20260828090428-9828cc37ebc2
github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260624154507-ea7ff77a0ddb
github.com/smartcontractkit/chainlink-common v0.11.2-0.20260903131821-eb4e3f87b067
github.com/smartcontractkit/chainlink-common v0.11.2-0.20260903152135-85b2080c56da
github.com/smartcontractkit/chainlink-common/keystore v1.3.0
github.com/smartcontractkit/chainlink-confidential-compute v1.3.0
github.com/smartcontractkit/chainlink-deployments-framework v0.120.1-0.20260828145648-3e1bcd2ac1da
Expand Down
Loading
Loading