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
199 changes: 199 additions & 0 deletions crecore/docs/CONFIG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
# main Configuration

## Example

```toml
# ----- Global Configuration -----
proxy-listen-address = ':50051'
capabilities-registry-address = '0xYourRegistryAddress'
capabilities-registry-sync-interval = '12s'
[database]
url = 'postgresql://user:password@localhost:5432/chainlink?sslmode=disable'
[ocr]
listen-addresses = ['127.0.0.1:1234']
delta-reconcile = '1m0s'
delta-dial = '5s'
incoming-buffer-size = 100
outgoing-buffer-size = 100
keystore-password = 'xxxxx'
[evm]
http-url = ['https://rpc.example.com']
chain-id = '1'
chain-type = ''
finality-tag-enabled = true
finality-depth = 50
poll-interval = '10s'


```

## Global
```toml
proxy-listen-address = ':50051' # Default
capabilities-registry-address = '0xYourRegistryAddress' # Example
capabilities-registry-sync-interval = '12s' # Default
```


# Global Configuration

### proxy-listen-address
```toml
proxy-listen-address = ':50051' # Default
```
proxy-listen-address address the proxy gRPC server listens on

### capabilities-registry-address
```toml
capabilities-registry-address = '0xYourRegistryAddress' # Example
```
capabilities-registry-address on-chain CapabilitiesRegistry (v2) contract address

### capabilities-registry-sync-interval
```toml
capabilities-registry-sync-interval = '12s' # Default
```
capabilities-registry-sync-interval how often the on-chain registry is re-read

### fake
```toml
fake = false # Docs only
```
fake use fake dependencies instead of real ones

## database
```toml
[database]
url = 'postgresql://user:password@localhost:5432/chainlink?sslmode=disable' # Example
```


### url
```toml
url = 'postgresql://user:password@localhost:5432/chainlink?sslmode=disable' # Example
```
url database url; required unless running with --fake and without --real-db

### real-db
```toml
real-db = false # Docs only
```
real-db use a real database even though --fake is set; requires --fake, and a url to point at

## ocr
```toml
[ocr]
listen-addresses = ['127.0.0.1:1234'] # Example
announce-addresses = [] # Default
delta-reconcile = '1m0s' # Default
delta-dial = '5s' # Default
incoming-buffer-size = 100 # Default
outgoing-buffer-size = 100 # Default
keystore-password = 'xxxxx' # Example
proxy-address = '' # Default
```


### listen-addresses
```toml
listen-addresses = ['127.0.0.1:1234'] # Example
```
listen-addresses rage p2p V2 listen addresses (host:port); creates a local peer (required unless proxy-address is set; must not be set when proxy-address is set)

### announce-addresses
```toml
announce-addresses = [] # Default
```
announce-addresses rage p2p V2 announce addresses (host:port); defaults to the listen addresses (must not be set unless listen-addresses is set)

### delta-reconcile
```toml
delta-reconcile = '1m0s' # Default
```
delta-reconcile rage p2p V2 delta reconcile interval

### delta-dial
```toml
delta-dial = '5s' # Default
```
delta-dial rage p2p V2 minimum interval between dial attempts

### incoming-buffer-size
```toml
incoming-buffer-size = 100 # Default
```
incoming-buffer-size per-remote incoming message buffer size

### outgoing-buffer-size
```toml
outgoing-buffer-size = 100 # Default
```
outgoing-buffer-size per-remote outgoing message buffer size

### keystore-password
```toml
keystore-password = 'xxxxx' # Example
```
keystore-password password for the node keystore holding the shared P2P identity

### proxy-address
```toml
proxy-address = '' # Default
```
proxy-address delegate rage networking to a proxy at this gRPC address instead of creating a local peer (must not be set when listen-addresses is set)

## evm
```toml
[evm]
http-url = ['https://rpc.example.com'] # Example
ws-url = [] # Default
chain-id = '1' # Example
chain-type = '' # Default
finality-tag-enabled = true # Default
finality-depth = 50 # Default
poll-interval = '10s' # Default
```


### http-url
```toml
http-url = ['https://rpc.example.com'] # Example
```
http-url EVM RPC HTTP URL(s); repeat or comma-separate for a multinode pool

### ws-url
```toml
ws-url = [] # Default
```
ws-url EVM RPC WebSocket URL(s), positionally paired with --evm.http-url; optional (must not be set unless http-url is set)

### chain-id
```toml
chain-id = '1' # Example
```
chain-id EVM chain ID

### chain-type
```toml
chain-type = '' # Default
```
chain-type EVM chain type (empty for a generic EVM chain)

### finality-tag-enabled
```toml
finality-tag-enabled = true # Default
```
finality-tag-enabled use the finalized block tag instead of a finality depth

### finality-depth
```toml
finality-depth = 50 # Default
```
finality-depth finality depth, used when --evm.finality-tag-enabled=false

### poll-interval
```toml
poll-interval = '10s' # Default
```
poll-interval per-node health poll interval

4 changes: 2 additions & 2 deletions crecore/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ go 1.26.2

require (
github.com/ethereum/go-ethereum v1.17.3
github.com/smartcontractkit/capabilities/libs v0.0.0-20260806142134-6ce85e626bf1
github.com/smartcontractkit/chainlink-common v0.11.2-0.20260805174449-86b0bd040b49
github.com/smartcontractkit/capabilities/libs v0.0.0-20260807195051-f3d5f6d13400
github.com/smartcontractkit/chainlink-common v0.11.2-0.20260807193849-47d010760510
github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260728111445-96c471be2872
github.com/smartcontractkit/chainlink-evm/gethwrappers v0.0.0-20260512150409-b4068bf735e6
github.com/smartcontractkit/chainlink-protos/cre/impl v0.0.0-20260724132051-f39bd9ab890d
Expand Down
8 changes: 4 additions & 4 deletions crecore/go.sum

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

44 changes: 18 additions & 26 deletions crecore/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"embed"
"log"
"time"

"github.com/spf13/cobra"

Expand All @@ -13,8 +12,7 @@ import (
"github.com/smartcontractkit/capabilities/libs/standalone/evm"
"github.com/smartcontractkit/capabilities/libs/standalone/ocr"

"github.com/smartcontractkit/capabilities/crecore/registry"

"github.com/smartcontractkit/chainlink-common/pkg/config/flags"
"github.com/smartcontractkit/chainlink-common/pkg/services"
evmclient "github.com/smartcontractkit/chainlink-evm/pkg/client"
)
Expand All @@ -35,48 +33,42 @@ func main() {
}

func run() error {
cfg := &Config{}

var (
registryAddress string
registrySyncInterval time.Duration
)
cfg := defaultConfig

root := &cobra.Command{
Use: "main",
Short: "P2P proxy for the CRE",
Long: `Runs a single shared rage (libocr) peer and exposes it over gRPC so that
core can delegate its OCR networking (and, in future, DON-to-DON networking) to
this process. The peer's identity is loaded from the node's keystore (shared DB
via CL_DATABASE_URL, decrypted with CL_PASSWORD_KEYSTORE).

Provide exactly one networking mode: --listen-addresses to run a local libocr
peer, or --proxy-address to delegate to another proxy.
this process. The peer's identity is the node's own, loaded from the keystore in
the database the two share.

It also serves the CapabilitiesRegistry on that same gRPC address, read directly
from chain with an EVM client (no relayer). Core uses that in place of its own
registrysyncer whenever it is delegating rage networking to this process, so
--capabilities-registry-address is required: this process running is what enables
the registry, and core does not start without it.`,
registrysyncer whenever it is delegating rage networking to this process, which
is why the registry address is required: this process running is what enables the
registry, and core does not start without it.

Settings can come from flags, from CRE_/CL_ env vars, or from a --config file;
run "docs" to write the full reference to docs/CONFIG.md.`,
}
root.PersistentFlags().String("config", "", "Path to config file")

root.PersistentFlags().StringVar(&cfg.ProxyListenAddress, "proxy-listen-address", ":50051", "address the proxy gRPC server listens on")
root.PersistentFlags().StringVar(&registryAddress, "capabilities-registry-address", "", "on-chain CapabilitiesRegistry (v2) contract address (required)")
root.PersistentFlags().DurationVar(&registrySyncInterval, "capabilities-registry-sync-interval", registry.DefaultSyncInterval, "how often the on-chain registry is re-read")
if err := root.MarkPersistentFlagRequired("capabilities-registry-address"); err != nil {
if err := flags.RegisterCommandFlags(root, &cfg, flags.DefaultTOMLOptions("CRE", "CL")); err != nil {
return err
}

bootstrapper := standalone.NewBootstrapper(root, standalone.WithOtelViews(metricViews()))
lggr := bootstrapper.Logger()

// The ocr dependency owns the libocr networking config (create vs proxy
// mode) and wraps the database dependency it needs for the P2P identity and
// OCR discoverer table.
// mode, and the keystore password that unlocks the peer identity) and wraps
// the database dependency it needs for that identity and the OCR discoverer
// table.
dbDep := db.Dependency(embeddedMigrations, migrationsTable)
ocrDep := ocr.Dependency(lggr.Named("OCR"), dbDep, ocrDiscovererTable)
// The registry always runs, so the EVM client is always resolved and the
// --evm-* flags are as required in practice as the registry address is.
// evm settings are as required in practice as the registry address is.
evmDep := evm.Dependency(lggr.Named("EVM"))

return standalone.Run2(bootstrapper, func(
Expand All @@ -85,11 +77,11 @@ the registry, and core does not start without it.`,
factories standalone.Dependency[*ocr.Factories],
evmClient standalone.Dependency[evmclient.Client],
) []services.Service {
regSvc := newRegistryService(registryAddress, registrySyncInterval,
regSvc := newRegistryService(cfg.RegistryAddress, cfg.RegistrySyncInterval.Duration(),
scfg.Logger.Named("capabilities registry"), evmClient, factories)
// The registry attaches to the proxy's gRPC server, so core reaches both
// over the single --proxy-listen-address it already configures.
proxySvc := newProxyService(cfg, scfg.Logger.Named("proxy service"), factories, regSvc.Register)
proxySvc := newProxyService(&cfg, scfg.Logger.Named("proxy service"), factories, regSvc.Register)
return []services.Service{proxySvc, regSvc}
}, ocrDep, evmDep)
}
22 changes: 18 additions & 4 deletions crecore/proxy_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,34 @@ import (

"google.golang.org/grpc"

"github.com/smartcontractkit/capabilities/crecore/registry"
"github.com/smartcontractkit/capabilities/libs/standalone"
"github.com/smartcontractkit/capabilities/libs/standalone/ocr"

"github.com/smartcontractkit/chainlink-common/pkg/config"
"github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/chainlink-common/pkg/services"
creproxy "github.com/smartcontractkit/chainlink-protos/cre/impl/proxy"
)

// Config is the proxy gRPC server configuration, populated from CLI flags (see
// main.go). The libocr peer / proxy-client configuration lives on the ocr
// bootstrap dependency instead.
// Config is the root command's configuration, populated by flags.RegisterCommandFlags (see
// main.go). The libocr peer / proxy-client configuration lives on the ocr bootstrap dependency
// instead.
type Config struct {
// ProxyListenAddress is the address the proxy gRPC server listens on.
ProxyListenAddress string
ProxyListenAddress string `toml:"proxy-listen-address" usage:"address the proxy gRPC server listens on"`

// RegistryAddress is the on-chain CapabilitiesRegistry (v2) contract address. The registry
// always runs, so this is as required in practice as the registry itself.
RegistryAddress string `toml:"capabilities-registry-address" usage:"on-chain CapabilitiesRegistry (v2) contract address" validate:"required" example:"'0xYourRegistryAddress'"`

// RegistrySyncInterval is how often the on-chain registry is re-read.
RegistrySyncInterval config.Duration `toml:"capabilities-registry-sync-interval" usage:"how often the on-chain registry is re-read"`
}

var defaultConfig = Config{
ProxyListenAddress: ":50051",
RegistrySyncInterval: *config.MustNewDuration(registry.DefaultSyncInterval),
}

// proxyService exposes the libocr rage networking factories over gRPC so that
Expand Down
4 changes: 2 additions & 2 deletions libs/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@ require (
github.com/pressly/goose/v3 v3.27.1
github.com/prometheus/client_golang v1.23.2
github.com/shopspring/decimal v1.4.0
github.com/smartcontractkit/chainlink-common v0.11.2-0.20260805174449-86b0bd040b49
github.com/smartcontractkit/chainlink-common v0.11.2-0.20260807193849-47d010760510
github.com/smartcontractkit/chainlink-common/keystore v1.3.0
github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260728111445-96c471be2872
github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260622152157-c8e129347b8b
github.com/smartcontractkit/chainlink-protos/cre/impl v0.0.0-20260724132051-f39bd9ab890d
github.com/smartcontractkit/libocr v0.0.0-20260529134643-c101335a64cd
github.com/spf13/cobra v1.10.2
github.com/spf13/pflag v1.0.10
github.com/spf13/viper v1.21.0
github.com/stretchr/testify v1.11.1
go.opentelemetry.io/contrib/bridges/prometheus v0.68.0
Expand Down Expand Up @@ -223,6 +222,7 @@ require (
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
github.com/spf13/afero v1.15.0 // indirect
github.com/spf13/cast v1.10.0 // indirect
github.com/spf13/pflag v1.0.10 // indirect
github.com/stellar/go-stellar-sdk v0.4.0 // indirect
github.com/stellar/go-xdr v0.0.0-20260312225820-cc2b0611aabf // indirect
github.com/streamingfast/logging v0.0.0-20230608130331-f22c91403091 // indirect
Expand Down
4 changes: 2 additions & 2 deletions libs/go.sum

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

Loading
Loading