Skip to content

Commit

Permalink
move code; add test for ocr3 config
Browse files Browse the repository at this point in the history
  • Loading branch information
krehermann committed Nov 22, 2024
1 parent 5554f07 commit 13b88df
Show file tree
Hide file tree
Showing 6 changed files with 477 additions and 70 deletions.
44 changes: 0 additions & 44 deletions deployment/keystone/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry"
kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry"
kf "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/forwarder"
kocr3 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/ocr3_capability"

"github.com/smartcontractkit/chainlink-common/pkg/logger"
)
Expand Down Expand Up @@ -923,46 +922,3 @@ func configureForwarder(lggr logger.Logger, chain deployment.Chain, fwdr *kf.Key
}
return nil
}

type configureOCR3Request struct {
cfg *OracleConfigWithSecrets
chain deployment.Chain
contract *kocr3.OCR3Capability
nodes []deployment.Node
dryRun bool
}
type configureOCR3Response struct {
ocrConfig OCR2OracleConfig
}

func configureOCR3contract(req configureOCR3Request) (*configureOCR3Response, error) {
if req.contract == nil {
return nil, fmt.Errorf("OCR3 contract is nil")
}
nks := makeNodeKeysSlice(req.nodes, req.chain.Selector)
ocrConfig, err := GenerateOCR3Config(*req.cfg, nks)
if err != nil {
return nil, fmt.Errorf("failed to generate OCR3 config: %w", err)
}
if req.dryRun {
return &configureOCR3Response{ocrConfig}, nil
}
tx, err := req.contract.SetConfig(req.chain.DeployerKey,
ocrConfig.Signers,
ocrConfig.Transmitters,
ocrConfig.F,
ocrConfig.OnchainConfig,
ocrConfig.OffchainConfigVersion,
ocrConfig.OffchainConfig,
)
if err != nil {
err = DecodeErr(kocr3.OCR3CapabilityABI, err)
return nil, fmt.Errorf("failed to call SetConfig for OCR3 contract %s: %w", req.contract.Address().String(), err)
}
_, err = req.chain.Confirm(tx)
if err != nil {
err = DecodeErr(kocr3.OCR3CapabilityABI, err)
return nil, fmt.Errorf("failed to confirm SetConfig for OCR3 contract %s: %w", req.contract.Address().String(), err)
}
return &configureOCR3Response{ocrConfig}, nil
}
18 changes: 8 additions & 10 deletions deployment/keystone/deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,24 @@ import (
"testing"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/stretchr/testify/assert"
"github.com/test-go/testify/require"
"go.uber.org/zap/zapcore"
"golang.org/x/exp/maps"

chainsel "github.com/smartcontractkit/chain-selectors"

"github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/chainlink-common/pkg/utils/tests"

"github.com/smartcontractkit/chainlink/deployment"
"github.com/smartcontractkit/chainlink/deployment/environment/clo"
"github.com/smartcontractkit/chainlink/deployment/environment/clo/models"
"github.com/smartcontractkit/chainlink/deployment/environment/memory"
"github.com/smartcontractkit/chainlink/deployment/keystone"
kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry"
"github.com/smartcontractkit/chainlink/v2/core/logger"

"github.com/stretchr/testify/assert"
"github.com/test-go/testify/require"
"go.uber.org/zap/zapcore"
"golang.org/x/exp/maps"
)

func TestDeploy(t *testing.T) {
lggr := logger.TestLogger(t)
lggr := logger.Test(t)

// sepolia; all nodes are on the this chain
sepoliaChainId := uint64(11155111)
Expand Down Expand Up @@ -226,7 +224,7 @@ func nodeOperatorsToIDs(t *testing.T, nops []*models.NodeOperator) (nodeIDs []ke
}

func TestDeployCLO(t *testing.T) {
lggr := logger.TestLogger(t)
lggr := logger.Test(t)

wfNops := loadTestNops(t, "testdata/workflow_nodes.json")
cwNops := loadTestNops(t, "testdata/chain_writer_nodes.json")
Expand Down
49 changes: 49 additions & 0 deletions deployment/keystone/ocr3config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/smartcontractkit/libocr/offchainreporting2plus/types"

"github.com/smartcontractkit/chainlink/deployment"
kocr3 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/ocr3_capability"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype"
"github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm"
Expand Down Expand Up @@ -237,3 +238,51 @@ func GenerateOCR3Config(cfg OracleConfigWithSecrets, nca []NodeKeys) (OCR2Oracle

return config, nil
}

type configureOCR3Request struct {
cfg *OracleConfigWithSecrets
chain deployment.Chain
contract *kocr3.OCR3Capability
nodes []deployment.Node
dryRun bool
}

func (r configureOCR3Request) generateOCR3Config() (OCR2OracleConfig, error) {
nks := makeNodeKeysSlice(r.nodes, r.chain.Selector)
return GenerateOCR3Config(*r.cfg, nks)
}

type configureOCR3Response struct {
ocrConfig OCR2OracleConfig
}

func configureOCR3contract(req configureOCR3Request) (*configureOCR3Response, error) {
if req.contract == nil {
return nil, fmt.Errorf("OCR3 contract is nil")
}
ocrConfig, err := req.generateOCR3Config()
if err != nil {
return nil, fmt.Errorf("failed to generate OCR3 config: %w", err)
}
if req.dryRun {
return &configureOCR3Response{ocrConfig}, nil
}
tx, err := req.contract.SetConfig(req.chain.DeployerKey,
ocrConfig.Signers,
ocrConfig.Transmitters,
ocrConfig.F,
ocrConfig.OnchainConfig,
ocrConfig.OffchainConfigVersion,
ocrConfig.OffchainConfig,
)
if err != nil {
err = DecodeErr(kocr3.OCR3CapabilityABI, err)
return nil, fmt.Errorf("failed to call SetConfig for OCR3 contract %s: %w", req.contract.Address().String(), err)
}
_, err = req.chain.Confirm(tx)
if err != nil {
err = DecodeErr(kocr3.OCR3CapabilityABI, err)
return nil, fmt.Errorf("failed to confirm SetConfig for OCR3 contract %s: %w", req.contract.Address().String(), err)
}
return &configureOCR3Response{ocrConfig}, nil
}
158 changes: 158 additions & 0 deletions deployment/keystone/ocr3config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
// TODO: KS-458 copied from https://github.com/smartcontractkit/chainlink/blob/65924811dc53a211613927c814d7f04fd85439a4/core/scripts/keystone/src/88_gen_ocr3_config.go#L1
// to unblock go mod issues when trying to import the scripts package
package keystone

import (
"encoding/json"
"os"
"sort"
"testing"

chain_selectors "github.com/smartcontractkit/chain-selectors"
"github.com/smartcontractkit/chainlink/deployment"
"github.com/smartcontractkit/chainlink/deployment/common/view"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey"
types2 "github.com/smartcontractkit/libocr/offchainreporting2/types"
"github.com/smartcontractkit/libocr/offchainreporting2plus/types"
"github.com/test-go/testify/require"
)

var wantOCR3Config = `{
"Signers": [
"011400b35409a8d4f9a18da55c5b2bb08a3f5f68d44442052000b8834eaa062f0df4ccfe7832253920071ec14dc4f78b13ecdda10b824e2dd3b6",
"0114008258f4c4761cc445333017608044a204fd0c006a052000247d0189f65f58be83a4e7d87ff338aaf8956e9acb9fcc783f34f9edc29d1b40",
"011400d4dcc573e9d24a8b27a07bba670ba3a2ab36e5bb052000ba20d3da9b07663f1e8039081a514649fd61a48be2d241bc63537ee47d028fcd",
"0114006607c140e558631407f33bafbabd103863cee876052000046faf34ebfe42510251e6098bc34fa3dd5f2de38ac07e47f2d1b34ac770639f",
"011400a6f35436cb7bffd615cc47a0a04aa0a78696a1440520001221e131ef21014a6a99ed22376eb869746a3b5e30fd202cf79e44efaeb8c5c2",
"011400657587eb55cecd6f90b97297b611c3024e488cc0052000425d1354a7b8180252a221040c718cac0ba0251c7efe31a2acefbba578dc2153",
"0114004885973b2fcf061d5cdfb8f74c5139bd3056e9da0520004a94c75cb9fe8b1fba86fd4b71ad130943281fdefad10216c46eb2285d60950f",
"011400213803bb9f9715379aaf11aadb0212369701dc0a05200096dc85670c49caa986de4ad288e680e9afb0f5491160dcbb4868ca718e194fc8",
"0114008c2aa1e6fad88a6006dfb116eb866cbad2910314052000bddafb20cc50d89e0ae2f244908c27b1d639615d8186b28c357669de3359f208",
"011400679296b7c1eb4948efcc87efc550940a182e610c0520004fa557850e4d5c21b3963c97414c1f37792700c4d3b8abdb904b765fd47e39bf"
],
"Transmitters": [
"0x2877F08d9c5Cc9F401F730Fa418fAE563A9a2FF3",
"0x415aa1E9a1bcB3929ed92bFa1F9735Dc0D45AD31",
"0xCea84bC1881F3cE14BA13Dc3a00DC1Ff3D553fF0",
"0xA9eFB53c513E413762b2Be5299D161d8E6e7278e",
"0x6F5cAb24Fb7412bB516b3468b9F3a9c471d25fE5",
"0xdAd1F3F8ec690cf335D46c50EdA5547CeF875161",
"0x19e10B063a62B1574AE19020A64fDe6419892dA6",
"0x9ad9f3AD49e5aB0F28bD694d211a90297bD90D7f",
"0x31B179dcF8f9036C30f04bE578793e51bF14A39E",
"0x0b04cE574E80Da73191Ec141c0016a54A6404056"
],
"F": 3,
"OnchainConfig": "0x",
"OffchainConfigVersion": 30,
"OffchainConfig": "0xc80180e497d012d00180e497d012d80180a8d6b907e00180cab5ee01e80180d88ee16ff0010afa01010a82022003dacd15fc96c965c648e3623180de002b71a97cf6eeca9affb91f461dcd6ce1820220255096a3b7ade10e29c648e0b407fc486180464f713446b1da04f013df6179c8820220dba3c61e5f8bec594be481bcaf67ecea0d1c2950edb15b158ce3dbc77877def3820220b4c4993d6c15fee63800db901a8b35fa419057610962caab1c1d7bed557091278202202a4c7dec127fdd8145e48c5edb9467225098bd8c8ad1dade868325b787affbde820220283471ed66d61fbe11f64eff65d738b59a0301c9a4f846280db26c64c9fdd3f8820220aa3419628ea3536783742d17d8adf05681aa6a6bd2b206fbde78c7e5aa38586d82022001496edce35663071d74472e02119432ba059b3904d205e4358014410e4f2be3820220ad08c2a5878cada53521f4e2bb449f191ccca7899246721a0deeea19f7b83f70820220c805572b813a072067eab2087ddbee8aa719090e12890b15c01094f0d3f74a5f8a0234313244334b6f6f574d57554b646f41633272755a663966353570374e56466a37414669506d3637786a5138425a42776b717959768a0234313244334b6f6f57436244694c3773503942566279354b615a7150706156503152426f6b6f613953687a483557686b59583436768a0234313244334b6f6f5747446d424b5a37423350796e4772766648544a4d456563706a6648747339594b354e576b386f4a757863416f8a0234313244334b6f6f574363564c797471696e4438784d6e32374e766f6d6351686a326d714d567a7947656d7a366f50777631534d548a0234313244334b6f6f57487152317732367948617454535a5157337862526374395378577a566a3958345370553931364879386a59678a0234313244334b6f6f57523864356b625a6237596951574b7054314a3150664d714e6147416d62346a4246783944576167346870535a8a0234313244334b6f6f574e4a38646533505555525a326f7563725654706e5254714e4254555977484c516a4b394c7a4e3345364d666e8a0234313244334b6f6f57514d436a37335635786d436436433556734a723772624647325446394c7756634c69694271587073394d67438a0234313244334b6f6f5741556167714d796373726f32376b467a6e5351524862686643424c78386e4b443470745469554744653338638a0234313244334b6f6f5742434d43435a5a387835374158764a767043756a71685a7a546a57586252656152453854784e7235644d345598028094ebdc03a0028094ebdc03a8028094ebdc03b0028094ebdc03ba02f8010a20476c1e732eb19b1f886add30e151badf8a1868f8d960ae00b99b950dda395e011220903850e3ae4f308b1b7a1f6e8549bf9c1c7e7b830c7be30510bac9f88cdb788f1a1020f89b177363d50265622879420a6f4d1a10eec43158cd5c6c22bd0e5f37344598671a107d407e41edb3c5815ef8619c57822a2b1a10d35756ed867948a34f937f6496567d361a104ffce3643dc297486e52a926bc4d89f71a106d174b4ca9855b00ad9abbe05a1cbd551a101563f5427677eee4418ea19eb3824ce81a10a2c6f6930d0f935aa0cf7bcde695c3c51a1004c383e9cecb347851a2edca1df0ca671a10fc415be74f36b392c14defa1f9aff8dbc00280e497d012c8028094ebdc03"
}`

var ocr3Cfg = `
{
"MaxQueryLengthBytes": 1000000,
"MaxObservationLengthBytes": 1000000,
"MaxReportLengthBytes": 1000000,
"MaxRequestBatchSize": 1000,
"UniqueReports": true,
"DeltaProgressMillis": 5000,
"DeltaResendMillis": 5000,
"DeltaInitialMillis": 5000,
"DeltaRoundMillis": 2000,
"DeltaGraceMillis": 500,
"DeltaCertifiedCommitRequestMillis": 1000,
"DeltaStageMillis": 30000,
"MaxRoundsPerEpoch": 10,
"TransmissionSchedule": [
10
],
"MaxDurationQueryMillis": 1000,
"MaxDurationObservationMillis": 1000,
"MaxDurationReportMillis": 1000,
"MaxDurationAcceptMillis": 1000,
"MaxDurationTransmitMillis": 1000,
"MaxFaultyOracles": 3
}`

func Test_configureOCR3Request_generateOCR3Config(t *testing.T) {
nodes := loadTestData(t, "testdata/testnet_wf_view.json")

var cfg OracleConfig
err := json.Unmarshal([]byte(ocr3Cfg), &cfg)
require.NoError(t, err)

r := configureOCR3Request{
cfg: &OracleConfigWithSecrets{OracleConfig: cfg, OCRSecrets: deployment.XXXGenerateTestOCRSecrets()},
nodes: nodes,
chain: deployment.Chain{
Selector: chain_selectors.ETHEREUM_TESTNET_SEPOLIA.Selector,
},
}
got, err := r.generateOCR3Config()
require.NoError(t, err)
b, err := json.MarshalIndent(got, "", " ")
require.NoError(t, err)
require.Equal(t, wantOCR3Config, string(b))
}

func loadTestData(t *testing.T, path string) []deployment.Node {
data, err := os.ReadFile(path)
require.NoError(t, err)
var nodeViews map[string]*view.NopView
err = json.Unmarshal(data, &nodeViews)
require.NoError(t, err)
require.Len(t, nodeViews, 10)

names := make([]string, 0)
for k := range nodeViews {
names = append(names, k)
}
sort.Strings(names)

// in general we can map from the view to the node, but we know the test data
var nodes []deployment.Node
//for _, nv := range nodeViews {
for _, name := range names {
nv := nodeViews[name]
node := deployment.Node{
NodeID: nv.NodeID,
IsBootstrap: nv.IsBootstrap,
SelToOCRConfig: make(map[chain_selectors.ChainDetails]deployment.OCRConfig),
AdminAddr: nv.PayeeAddress,
}
for chain, ocrKey := range nv.OCRKeys {
p, err := p2pkey.MakePeerID(ocrKey.PeerID)
require.NoError(t, err)

ocrCfg := deployment.OCRConfig{
KeyBundleID: ocrKey.KeyBundleID,
OffchainPublicKey: types2.OffchainPublicKey([]byte(ocrKey.OffchainPublicKey)),
OnchainPublicKey: types2.OnchainPublicKey(ocrKey.OnchainPublicKey),
PeerID: p,
TransmitAccount: types.Account(ocrKey.TransmitAccount),
ConfigEncryptionPublicKey: types2.ConfigEncryptionPublicKey([]byte(ocrKey.ConfigEncryptionPublicKey)),
}
var k chain_selectors.ChainDetails
switch chain {
case "aptos-testnet":
k = chain_selectors.ChainDetails{
ChainSelector: chain_selectors.APTOS_TESTNET.Selector,
ChainName: chain,
}

case "ethereum-testnet-sepolia":
k = chain_selectors.ChainDetails{
ChainSelector: chain_selectors.ETHEREUM_TESTNET_SEPOLIA.Selector,
ChainName: chain,
}
default:
t.Fatalf("unexpected chain %s", chain)
}
node.SelToOCRConfig[k] = ocrCfg
}

nodes = append(nodes, node)
}
require.Len(t, nodes, 10)
return nodes
}
Loading

0 comments on commit 13b88df

Please sign in to comment.