Skip to content

Commit

Permalink
feat(keystone): enable multiple OCR contracts per chain
Browse files Browse the repository at this point in the history
  • Loading branch information
MStreet3 committed Dec 23, 2024
1 parent 7314c07 commit 52a98c0
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 10 deletions.
2 changes: 2 additions & 0 deletions deployment/keystone/changeset/configure_contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ var _ deployment.ChangeSet[InitialContractsCfg] = ConfigureInitialContractsChang
type InitialContractsCfg struct {
RegistryChainSel uint64
Dons []kslib.DonCapabilities
OCR3Address string // Address of the OCR3 contract on the registry chain to configure
OCR3Config *kslib.OracleConfig
}

Expand All @@ -23,6 +24,7 @@ func ConfigureInitialContractsChangeset(e deployment.Environment, cfg InitialCon
Env: &e,
RegistryChainSel: cfg.RegistryChainSel,
Dons: cfg.Dons,
OCR3Address: cfg.OCR3Address,
OCR3Config: cfg.OCR3Config,
}
return ConfigureInitialContracts(e.Logger, req)
Expand Down
1 change: 1 addition & 0 deletions deployment/keystone/changeset/deploy_ocr3.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ var _ deployment.ChangeSet[ConfigureOCR3Config] = ConfigureOCR3Contract
type ConfigureOCR3Config struct {
ChainSel uint64
NodeIDs []string
Address string // hex encoded address of the OCR3 contract to configure
OCR3Config *kslib.OracleConfig
DryRun bool
WriteGeneratedConfig io.Writer // if not nil, write the generated config to this writer as JSON [OCR2OracleConfig]
Expand Down
31 changes: 24 additions & 7 deletions deployment/keystone/changeset/internal/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (

capabilities_registry "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry_1_1_0"
kf "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/forwarder_1_0_0"
ocr3_capability "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/ocr3_capability_1_0_0"

"github.com/smartcontractkit/chainlink-common/pkg/logger"
)
Expand All @@ -38,8 +39,9 @@ type ConfigureContractsRequest struct {
RegistryChainSel uint64
Env *deployment.Environment

Dons []DonCapabilities // externally sourced based on the environment
OCR3Config *OracleConfig // TODO: probably should be a map of don to config; but currently we only have one wf don therefore one config
Dons []DonCapabilities // externally sourced based on the environment
OCR3Address string // Address of the OCR3 contract on the registry chain to configure
OCR3Config *OracleConfig // TODO: probably should be a map of don to config; but currently we only have one wf don therefore one config

// TODO rm this option; unused
DoContractDeploy bool // if false, the contracts are assumed to be deployed and the address book is used
Expand Down Expand Up @@ -99,7 +101,7 @@ func ConfigureContracts(ctx context.Context, lggr logger.Logger, req ConfigureCo
return nil, fmt.Errorf("failed to configure forwarder contracts: %w", err)
}

err = ConfigureOCR3Contract(req.Env, req.RegistryChainSel, dons, req.OCR3Config)
err = ConfigureOCR3Contract(req.Env, req.RegistryChainSel, req.OCR3Address, dons, req.OCR3Config)
if err != nil {
return nil, fmt.Errorf("failed to configure OCR3 contract: %w", err)
}
Expand Down Expand Up @@ -298,7 +300,7 @@ func ConfigureRegistry(ctx context.Context, lggr logger.Logger, req ConfigureCon

// Depreciated: use changeset.ConfigureOCR3Contract instead
// ocr3 contract on the registry chain for the wf dons
func ConfigureOCR3Contract(env *deployment.Environment, chainSel uint64, dons []RegisteredDon, cfg *OracleConfig) error {
func ConfigureOCR3Contract(env *deployment.Environment, chainSel uint64, ocr3Addr string, dons []RegisteredDon, cfg *OracleConfig) error {
registryChain, ok := env.Chains[chainSel]
if !ok {
return fmt.Errorf("chain %d not found in environment", chainSel)
Expand All @@ -321,9 +323,14 @@ func ConfigureOCR3Contract(env *deployment.Environment, chainSel uint64, dons []
if !ok {
return fmt.Errorf("failed to get contract set for chain %d", chainSel)
}
contract := contracts.OCR3

var contract *ocr3_capability.OCR3Capability
if contract, ok = contracts.OCR3[ocr3Addr]; !ok {
return fmt.Errorf("OCR contract address %s not found in contract set", ocr3Addr)
}

if contract == nil {
return fmt.Errorf("no ocr3 contract found for chain %d", chainSel)
return fmt.Errorf("no ocr3 contract found for chain %d at %s", chainSel, ocr3Addr)
}

_, err := configureOCR3contract(configureOCR3Request{
Expand All @@ -349,6 +356,7 @@ type ConfigureOCR3Resp struct {
type ConfigureOCR3Config struct {
ChainSel uint64
NodeIDs []string
Address string // hex encoded address of the OCR3 contract to configure
OCR3Config *OracleConfig
DryRun bool

Expand Down Expand Up @@ -377,7 +385,16 @@ func ConfigureOCR3ContractFromJD(env *deployment.Environment, cfg ConfigureOCR3C
if !ok {
return nil, fmt.Errorf("failed to get contract set for chain %d", cfg.ChainSel)
}
contract := contracts.OCR3

// get the OCR3 contract
if cfg.Address == "" {
return nil, errors.New("OCR contract address is unspecified")
}

var contract *ocr3_capability.OCR3Capability
if contract, ok = contracts.OCR3[cfg.Address]; !ok {
return nil, fmt.Errorf("OCR contract address %s not found in contract set", cfg.Address)
}
if contract == nil {
return nil, fmt.Errorf("no ocr3 contract found for chain %d", cfg.ChainSel)
}
Expand Down
11 changes: 8 additions & 3 deletions deployment/keystone/changeset/internal/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ type GetContractSetsResponse struct {

type ContractSet struct {
commonchangeset.MCMSWithTimelockState
OCR3 *ocr3_capability.OCR3Capability
OCR3 map[string]*ocr3_capability.OCR3Capability
Forwarder *forwarder.KeystoneForwarder
CapabilitiesRegistry *capabilities_registry.CapabilitiesRegistry
WorkflowRegistry *workflow_registry.WorkflowRegistry
Expand All @@ -37,7 +37,9 @@ type ContractSet struct {
func (cs ContractSet) TransferableContracts() []common.Address {
var out []common.Address
if cs.OCR3 != nil {
out = append(out, cs.OCR3.Address())
for _, ocr := range cs.OCR3 {
out = append(out, ocr.Address())
}
}
if cs.Forwarder != nil {
out = append(out, cs.Forwarder.Address())
Expand Down Expand Up @@ -109,7 +111,10 @@ func loadContractSet(lggr logger.Logger, chain deployment.Chain, addresses map[s
if err != nil {
return nil, fmt.Errorf("failed to create OCR3Capability contract from address %s: %w", addr, err)
}
out.OCR3 = c
if out.OCR3 == nil {
out.OCR3 = make(map[string]*ocr3_capability.OCR3Capability)
}
out.OCR3[addr] = c
case WorkflowRegistry:
c, err := workflow_registry.NewWorkflowRegistry(common.HexToAddress(addr), chain.Client)
if err != nil {
Expand Down
13 changes: 13 additions & 0 deletions deployment/keystone/changeset/test/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,18 @@ func SetupTestEnv(t *testing.T, c TestConfig) TestEnv {
err = env.ExistingAddresses.Merge(e.ExistingAddresses)
require.NoError(t, err)

// Get the OCR3 address from the address book
var ocr3Addr string
addrs, err := env.ExistingAddresses.AddressesForChain(registryChainSel)
require.NoError(t, err)

for k, tv := range addrs {
if tv.Type == internal.OCR3Capability {
ocr3Addr = k
break
}
}

var ocr3Config = internal.OracleConfig{
MaxFaultyOracles: len(wfNodes) / 3,
}
Expand All @@ -203,6 +215,7 @@ func SetupTestEnv(t *testing.T, c TestConfig) TestEnv {
csOut, err := kschangeset.ConfigureInitialContractsChangeset(env, kschangeset.InitialContractsCfg{
RegistryChainSel: registryChainSel,
Dons: allDons,
OCR3Address: ocr3Addr, // Address of the OCR3 contract on the registry chain to configure
OCR3Config: &ocr3Config,
})
require.NoError(t, err)
Expand Down

0 comments on commit 52a98c0

Please sign in to comment.