Skip to content

Commit 08d9683

Browse files
WIP
1 parent 39ff8f0 commit 08d9683

File tree

12 files changed

+442
-44
lines changed

12 files changed

+442
-44
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ tools/clroot/db.sqlite3-wal
3232
debug.env
3333
operator_ui/install
3434
.devenv
35+
CLAUDE.md
3536

3637
# neovim
3738
.nvim.lua

core/cmd/shell_local.go

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import (
3737
evmtypes "github.com/smartcontractkit/chainlink-evm/pkg/types"
3838

3939
"github.com/smartcontractkit/chainlink/v2/core/build"
40+
"github.com/smartcontractkit/chainlink/v2/core/config"
4041
"github.com/smartcontractkit/chainlink/v2/core/logger"
4142
"github.com/smartcontractkit/chainlink/v2/core/services/keystore"
4243
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype"
@@ -317,6 +318,27 @@ func (s *Shell) RunNode(c *cli.Context) error {
317318
return nil
318319
}
319320

321+
type ks[K any] interface {
322+
Import(ctx context.Context, keyJSON []byte, password string) (K, error)
323+
}
324+
325+
func importKeyIfProvided[K any](ctx context.Context, lggr logger.Logger, keyType string, importableKey config.ImportableKey, k ks[K]) error {
326+
if importableKey.JSON() == "" {
327+
return nil
328+
}
329+
330+
lggr.Debugf("Importing %s %s", keyType, importableKey.JSON())
331+
_, err := k.Import(ctx, []byte(importableKey.JSON()), importableKey.Password())
332+
if errors.Is(err, keystore.ErrKeyExists) {
333+
lggr.Debugf("%s key already exists %s", keyType, importableKey.JSON())
334+
return nil
335+
} else if err != nil {
336+
return fmt.Errorf("error importing %s key: %w", keyType, err)
337+
}
338+
339+
return nil
340+
}
341+
320342
func (s *Shell) runNode(c *cli.Context) error {
321343
ctx := s.ctx()
322344
lggr := logger.Sugared(s.Logger.Named("RunNode"))
@@ -423,6 +445,11 @@ func (s *Shell) runNode(c *cli.Context) error {
423445
}
424446
}
425447
if s.Config.OCR2().Enabled() {
448+
err2 := importKeyIfProvided(rootCtx, lggr, "OCR2Key", s.Config.ImportedOCR2Key(), app.GetKeyStore().OCR2())
449+
if err2 != nil {
450+
return s.errorOut(err2)
451+
}
452+
426453
var enabledChains []chaintype.ChainType
427454
if s.Config.EVMEnabled() {
428455
enabledChains = append(enabledChains, chaintype.EVM)
@@ -448,23 +475,19 @@ func (s *Shell) runNode(c *cli.Context) error {
448475
if s.Config.SuiEnabled() {
449476
enabledChains = append(enabledChains, chaintype.Sui)
450477
}
451-
err2 := app.GetKeyStore().OCR2().EnsureKeys(rootCtx, enabledChains...)
478+
err2 = app.GetKeyStore().OCR2().EnsureKeys(rootCtx, enabledChains...)
452479
if err2 != nil {
453480
return fmt.Errorf("failed to ensure ocr key: %w", err2)
454481
}
455482
}
456483

457484
if s.Config.P2P().Enabled() {
458-
if s.Config.ImportedP2PKey().JSON() != "" {
459-
lggr.Debugf("Importing p2p key %s", s.Config.ImportedP2PKey().JSON())
460-
_, err2 := app.GetKeyStore().P2P().Import(rootCtx, []byte(s.Config.ImportedP2PKey().JSON()), s.Config.ImportedP2PKey().Password())
461-
if errors.Is(err2, keystore.ErrKeyExists) {
462-
lggr.Debugf("P2P key already exists %s", s.Config.ImportedP2PKey().JSON())
463-
} else if err2 != nil {
464-
return s.errorOut(fmt.Errorf("error importing p2p key: %w", err2))
465-
}
485+
err2 := importKeyIfProvided(rootCtx, lggr, "P2P", s.Config.ImportedP2PKey(), app.GetKeyStore().P2P())
486+
if err2 != nil {
487+
return s.errorOut(err2)
466488
}
467-
err2 := app.GetKeyStore().P2P().EnsureKey(rootCtx)
489+
490+
err2 = app.GetKeyStore().P2P().EnsureKey(rootCtx)
468491
if err2 != nil {
469492
return fmt.Errorf("failed to ensure p2p key: %w", err2)
470493
}
@@ -525,17 +548,12 @@ func (s *Shell) runNode(c *cli.Context) error {
525548
}
526549
}
527550
if s.Config.CRE().EnableDKGRecipient() {
528-
if s.Config.ImportedDKGRecipientKey().JSON() != "" {
529-
lggr.Debugf("Importing DKG recipient key %s", s.Config.ImportedDKGRecipientKey().JSON())
530-
_, err2 := app.GetKeyStore().DKGRecipient().Import(rootCtx, []byte(s.Config.ImportedDKGRecipientKey().JSON()), s.Config.ImportedDKGRecipientKey().Password())
531-
if errors.Is(err2, keystore.ErrKeyExists) {
532-
lggr.Debugf("DKG recipient key already exists %s", s.Config.ImportedDKGRecipientKey().JSON())
533-
} else if err2 != nil {
534-
return s.errorOut(fmt.Errorf("error importing dkg recipient key: %w", err2))
535-
}
551+
err2 := importKeyIfProvided(rootCtx, lggr, "DKG Recipient", s.Config.ImportedDKGRecipientKey(), app.GetKeyStore().DKGRecipient())
552+
if err2 != nil {
553+
return s.errorOut(err2)
536554
}
537555

538-
err2 := app.GetKeyStore().DKGRecipient().EnsureKey(rootCtx)
556+
err2 = app.GetKeyStore().DKGRecipient().EnsureKey(rootCtx)
539557
if err2 != nil {
540558
return fmt.Errorf("failed to ensure dkg recipient key: %w", err2)
541559
}
@@ -546,6 +564,11 @@ func (s *Shell) runNode(c *cli.Context) error {
546564
return fmt.Errorf("failed to ensure workflow key: %w", err2)
547565
}
548566

567+
err2 = importKeyIfProvided(rootCtx, lggr, "CSA", s.Config.ImportedCSAKey(), app.GetKeyStore().CSA())
568+
if err2 != nil {
569+
return s.errorOut(err2)
570+
}
571+
549572
err2 = app.GetKeyStore().CSA().EnsureKey(rootCtx)
550573
if err2 != nil {
551574
return fmt.Errorf("failed to ensure CSA key: %w", err2)

core/config/toml/types.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ type Secrets struct {
146146

147147
P2PKey P2PKey `toml:",omitempty"`
148148
DKGRecipientKey DKGRecipientKey `toml:",omitempty"`
149+
CSAKey CSAKey `toml:",omitempty"`
150+
OCR2Key OCR2Key `toml:",omitempty"`
149151

150152
CRE CreSecrets `toml:",omitempty"`
151153
CCV CCVSecrets `toml:",omitempty"`
@@ -496,6 +498,78 @@ func (p *DKGRecipientKey) ValidateConfig() (err error) {
496498
return err
497499
}
498500

501+
type CSAKey struct {
502+
JSON *models.Secret
503+
Password *models.Secret
504+
}
505+
506+
func (p *CSAKey) SetFrom(f *CSAKey) (err error) {
507+
err = p.validateMerge(f)
508+
if err != nil {
509+
return err
510+
}
511+
if v := f.JSON; v != nil {
512+
p.JSON = v
513+
}
514+
if v := f.Password; v != nil {
515+
p.Password = v
516+
}
517+
return nil
518+
}
519+
520+
func (p *CSAKey) validateMerge(f *CSAKey) (err error) {
521+
if p.JSON != nil && f.JSON != nil {
522+
err = errors.Join(err, configutils.ErrOverride{Name: "JSON"})
523+
}
524+
if p.Password != nil && f.Password != nil {
525+
err = errors.Join(err, configutils.ErrOverride{Name: "Password"})
526+
}
527+
return err
528+
}
529+
530+
func (p *CSAKey) ValidateConfig() (err error) {
531+
if (p.JSON != nil) != (p.Password != nil) {
532+
err = errors.Join(err, configutils.ErrInvalid{Name: "CSAKey", Value: p.JSON, Msg: "all fields must be nil or non-nil"})
533+
}
534+
return err
535+
}
536+
537+
type OCR2Key struct {
538+
JSON *models.Secret
539+
Password *models.Secret
540+
}
541+
542+
func (p *OCR2Key) SetFrom(f *OCR2Key) (err error) {
543+
err = p.validateMerge(f)
544+
if err != nil {
545+
return err
546+
}
547+
if v := f.JSON; v != nil {
548+
p.JSON = v
549+
}
550+
if v := f.Password; v != nil {
551+
p.Password = v
552+
}
553+
return nil
554+
}
555+
556+
func (p *OCR2Key) validateMerge(f *OCR2Key) (err error) {
557+
if p.JSON != nil && f.JSON != nil {
558+
err = errors.Join(err, configutils.ErrOverride{Name: "JSON"})
559+
}
560+
if p.Password != nil && f.Password != nil {
561+
err = errors.Join(err, configutils.ErrOverride{Name: "Password"})
562+
}
563+
return err
564+
}
565+
566+
func (p *OCR2Key) ValidateConfig() (err error) {
567+
if (p.JSON != nil) != (p.Password != nil) {
568+
err = errors.Join(err, configutils.ErrInvalid{Name: "OCR2Key", Value: p.JSON, Msg: "all fields must be nil or non-nil"})
569+
}
570+
return err
571+
}
572+
499573
type Passwords struct {
500574
Keystore *models.Secret
501575
VRF *models.Secret

core/services/chainlink/config_general.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,14 @@ func (g *generalConfig) ImportedP2PKey() coreconfig.ImportableKey {
573573
return &importedP2PKeyConfig{s: g.secrets.P2PKey}
574574
}
575575

576+
func (g *generalConfig) ImportedCSAKey() coreconfig.ImportableKey {
577+
return &importedCSAKeyConfig{s: g.secrets.CSAKey}
578+
}
579+
580+
func (g *generalConfig) ImportedOCR2Key() coreconfig.ImportableKey {
581+
return &importedOCR2KeyConfig{s: g.secrets.OCR2Key}
582+
}
583+
576584
func (g *generalConfig) Tracing() coreconfig.Tracing {
577585
return &tracingConfig{s: g.c.Tracing}
578586
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package chainlink
2+
3+
import "github.com/smartcontractkit/chainlink/v2/core/config/toml"
4+
5+
type importedCSAKeyConfig struct {
6+
s toml.CSAKey
7+
}
8+
9+
func (t *importedCSAKeyConfig) JSON() string {
10+
if t.s.JSON == nil {
11+
return ""
12+
}
13+
return string(*t.s.JSON)
14+
}
15+
16+
func (t *importedCSAKeyConfig) Password() string {
17+
if t.s.Password == nil {
18+
return ""
19+
}
20+
return string(*t.s.Password)
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package chainlink
2+
3+
import "github.com/smartcontractkit/chainlink/v2/core/config/toml"
4+
5+
type importedOCR2KeyConfig struct {
6+
s toml.OCR2Key
7+
}
8+
9+
func (t *importedOCR2KeyConfig) JSON() string {
10+
if t.s.JSON == nil {
11+
return ""
12+
}
13+
return string(*t.s.JSON)
14+
}
15+
16+
func (t *importedOCR2KeyConfig) Password() string {
17+
if t.s.Password == nil {
18+
return ""
19+
}
20+
return string(*t.s.Password)
21+
}

core/services/chainlink/mocks/general_config.go

Lines changed: 94 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/services/chainlink/types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,6 @@ type ImportedSecretConfig interface {
3030
ImportedEthKeys() coreconfig.ImportableChainKeyLister
3131
ImportedSolKeys() coreconfig.ImportableChainKeyLister
3232
ImportedDKGRecipientKey() coreconfig.ImportableKey
33+
ImportedCSAKey() coreconfig.ImportableKey
34+
ImportedOCR2Key() coreconfig.ImportableKey
3335
}

0 commit comments

Comments
 (0)