Skip to content

Commit f71416d

Browse files
OCRSetupInputs multiple contracts (#117)
* OCRSetupInputs multiple contracts * fix * lint * PR changes
1 parent 0bb4e93 commit f71416d

File tree

4 files changed

+126
-102
lines changed

4 files changed

+126
-102
lines changed

suite/chaos/chaos_ocr_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ var _ = XDescribeTable("OCR chaos tests @chaos-ocr", func(
1919
i := &testcommon.OCRSetupInputs{}
2020
Context("Runs OCR test with a chaos modifier", func() {
2121
testcommon.DeployOCRForEnv(i, envInit)
22-
testcommon.SetupOCRTest(i)
22+
testcommon.FundNodes(i)
23+
testcommon.DeployOCRContracts(i, 1)
2324
testcommon.SendOCRJobs(i)
2425
_, err := i.SuiteSetup.Environment().ApplyChaos(chaosSpec)
2526
Expect(err).ShouldNot(HaveOccurred())

suite/contracts/contracts_ocr_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ var _ = Describe("OCR Feed @ocr", func() {
1414
) {
1515
i := &testcommon.OCRSetupInputs{}
1616
testcommon.DeployOCRForEnv(i, envInit)
17-
testcommon.SetupOCRTest(i)
17+
testcommon.FundNodes(i)
18+
testcommon.DeployOCRContracts(i, 1)
1819
testcommon.SendOCRJobs(i)
1920
testcommon.CheckRound(i)
2021
By("Printing gas stats", func() {

suite/steps/alerts_steps.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
11
package steps
22

33
import (
4+
"fmt"
45
. "github.com/onsi/gomega"
56
"github.com/smartcontractkit/integrations-framework/client"
7+
"github.com/smartcontractkit/integrations-framework/contracts"
68
)
79

8-
// GetMockserverInitializerDataForOTPE crates mocked weiwatchers data needed for otpe
9-
func GetMockserverInitializerDataForOTPE(offChainAggregatorInstanceAddress string, chainlinkNodes []client.Chainlink) interface{} {
10-
contractInfo := client.ContractInfoJSON{
11-
ContractVersion: 4,
12-
Path: "test",
13-
Status: "live",
14-
ContractAddress: offChainAggregatorInstanceAddress,
15-
}
10+
// GetMockserverInitializerDataForOTPE creates mocked weiwatchers data needed for otpe
11+
func GetMockserverInitializerDataForOTPE(OCRInstances []contracts.OffchainAggregator, chainlinkNodes []client.Chainlink) interface{} {
12+
var contractsInfo []client.ContractInfoJSON
13+
14+
for index, OCRInstance := range OCRInstances {
15+
contractInfo := client.ContractInfoJSON{
16+
ContractVersion: 4,
17+
Path: fmt.Sprintf("contract_%d", index),
18+
Status: "live",
19+
ContractAddress: OCRInstance.Address(),
20+
}
1621

17-
contractsInfo := []client.ContractInfoJSON{contractInfo}
22+
contractsInfo = append(contractsInfo, contractInfo)
23+
}
1824

1925
contractsInitializer := client.HttpInitializer{
2026
Request: client.HttpRequest{Path: "/contracts.json"},

suite/testcommon/ocr.go

Lines changed: 107 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ type OCRSetupInputs struct {
2525
NetworkInfo actions.NetworkInfo
2626
ChainlinkNodes []client.Chainlink
2727
DefaultWallet client.BlockchainWallet
28-
OCRInstance contracts.OffchainAggregator
28+
OCRInstances []contracts.OffchainAggregator
2929
Mockserver *client.MockserverClient
3030
}
3131

@@ -50,83 +50,88 @@ func DeployOCRForEnv(i *OCRSetupInputs, envInit environment.K8sEnvSpecInit) {
5050
})
5151
}
5252

53-
// SetupOCRTest setup for an ocr test
54-
func SetupOCRTest(i *OCRSetupInputs) {
55-
By("Funding nodes and deploying OCR contract", func() {
56-
ethAmount, err := i.NetworkInfo.Deployer.CalculateETHForTXs(i.NetworkInfo.Wallets.Default(), i.NetworkInfo.Network.Config(), 2)
57-
Expect(err).ShouldNot(HaveOccurred())
58-
err = actions.FundChainlinkNodes(
59-
i.ChainlinkNodes,
60-
i.NetworkInfo.Client,
61-
i.DefaultWallet,
62-
ethAmount,
63-
big.NewFloat(2),
64-
)
65-
Expect(err).ShouldNot(HaveOccurred())
66-
67-
// Deploy and config OCR contract
68-
deployer, err := contracts.NewContractDeployer(i.NetworkInfo.Client)
69-
Expect(err).ShouldNot(HaveOccurred())
53+
// DeployOCRContracts deploys and funds a certain number of offchain aggregator contracts
54+
func DeployOCRContracts(i *OCRSetupInputs, nrOfOCRContracts int) {
55+
deployer, err := contracts.NewContractDeployer(i.NetworkInfo.Client)
56+
Expect(err).ShouldNot(HaveOccurred())
7057

71-
i.OCRInstance, err = deployer.DeployOffChainAggregator(i.DefaultWallet, contracts.DefaultOffChainAggregatorOptions())
58+
for nr := 0; nr < nrOfOCRContracts; nr++ {
59+
OCRInstance, err := deployer.DeployOffChainAggregator(i.DefaultWallet, contracts.DefaultOffChainAggregatorOptions())
7260
Expect(err).ShouldNot(HaveOccurred())
73-
err = i.OCRInstance.SetConfig(
61+
err = OCRInstance.SetConfig(
7462
i.DefaultWallet,
7563
i.ChainlinkNodes[1:],
7664
contracts.DefaultOffChainAggregatorConfig(len(i.ChainlinkNodes[1:])),
7765
)
7866
Expect(err).ShouldNot(HaveOccurred())
79-
err = i.OCRInstance.Fund(i.DefaultWallet, nil, big.NewFloat(2))
67+
err = OCRInstance.Fund(i.DefaultWallet, nil, big.NewFloat(2))
8068
Expect(err).ShouldNot(HaveOccurred())
8169
err = i.NetworkInfo.Client.WaitForEvents()
8270
Expect(err).ShouldNot(HaveOccurred())
83-
})
71+
i.OCRInstances = append(i.OCRInstances, OCRInstance)
72+
}
73+
}
74+
75+
// FundNodes funds all chainlink nodes
76+
func FundNodes(i *OCRSetupInputs) {
77+
ethAmount, err := i.NetworkInfo.Deployer.CalculateETHForTXs(i.NetworkInfo.Wallets.Default(), i.NetworkInfo.Network.Config(), 2)
78+
Expect(err).ShouldNot(HaveOccurred())
79+
err = actions.FundChainlinkNodes(
80+
i.ChainlinkNodes,
81+
i.NetworkInfo.Client,
82+
i.DefaultWallet,
83+
ethAmount,
84+
big.NewFloat(2),
85+
)
86+
Expect(err).ShouldNot(HaveOccurred())
8487
}
8588

8689
// SendOCRJobs bootstraps the first node and to the other nodes sends ocr jobs that
8790
// read from different adapters
8891
func SendOCRJobs(i *OCRSetupInputs) {
8992
By("Sending OCR jobs to chainlink nodes", func() {
90-
bootstrapNode := i.ChainlinkNodes[0]
91-
bootstrapP2PIds, err := bootstrapNode.ReadP2PKeys()
92-
Expect(err).ShouldNot(HaveOccurred())
93-
bootstrapP2PId := bootstrapP2PIds.Data[0].Attributes.PeerID
94-
bootstrapSpec := &client.OCRBootstrapJobSpec{
95-
ContractAddress: i.OCRInstance.Address(),
96-
P2PPeerID: bootstrapP2PId,
97-
IsBootstrapPeer: true,
98-
}
99-
_, err = bootstrapNode.CreateJob(bootstrapSpec)
100-
Expect(err).ShouldNot(HaveOccurred())
101-
102-
for index := 1; index < len(i.ChainlinkNodes); index++ {
103-
nodeP2PIds, err := i.ChainlinkNodes[index].ReadP2PKeys()
104-
Expect(err).ShouldNot(HaveOccurred())
105-
nodeP2PId := nodeP2PIds.Data[0].Attributes.PeerID
106-
nodeTransmitterAddress, err := i.ChainlinkNodes[index].PrimaryEthAddress()
93+
for OCRInstanceIndex, OCRInstance := range i.OCRInstances {
94+
bootstrapNode := i.ChainlinkNodes[0]
95+
bootstrapP2PIds, err := bootstrapNode.ReadP2PKeys()
10796
Expect(err).ShouldNot(HaveOccurred())
108-
nodeOCRKeys, err := i.ChainlinkNodes[index].ReadOCRKeys()
109-
Expect(err).ShouldNot(HaveOccurred())
110-
nodeOCRKeyId := nodeOCRKeys.Data[0].ID
111-
112-
bta := client.BridgeTypeAttributes{
113-
Name: fmt.Sprintf("node_%d", index),
114-
URL: fmt.Sprintf("%s/node_%d", i.Mockserver.Config.ClusterURL, index),
97+
bootstrapP2PId := bootstrapP2PIds.Data[0].Attributes.PeerID
98+
bootstrapSpec := &client.OCRBootstrapJobSpec{
99+
ContractAddress: OCRInstance.Address(),
100+
P2PPeerID: bootstrapP2PId,
101+
IsBootstrapPeer: true,
115102
}
116-
117-
err = i.ChainlinkNodes[index].CreateBridge(&bta)
103+
_, err = bootstrapNode.CreateJob(bootstrapSpec)
118104
Expect(err).ShouldNot(HaveOccurred())
119105

120-
ocrSpec := &client.OCRTaskJobSpec{
121-
ContractAddress: i.OCRInstance.Address(),
122-
P2PPeerID: nodeP2PId,
123-
P2PBootstrapPeers: []client.Chainlink{bootstrapNode},
124-
KeyBundleID: nodeOCRKeyId,
125-
TransmitterAddress: nodeTransmitterAddress,
126-
ObservationSource: client.ObservationSourceSpecBridge(bta),
106+
for nodeIndex := 1; nodeIndex < len(i.ChainlinkNodes); nodeIndex++ {
107+
nodeP2PIds, err := i.ChainlinkNodes[nodeIndex].ReadP2PKeys()
108+
Expect(err).ShouldNot(HaveOccurred())
109+
nodeP2PId := nodeP2PIds.Data[0].Attributes.PeerID
110+
nodeTransmitterAddress, err := i.ChainlinkNodes[nodeIndex].PrimaryEthAddress()
111+
Expect(err).ShouldNot(HaveOccurred())
112+
nodeOCRKeys, err := i.ChainlinkNodes[nodeIndex].ReadOCRKeys()
113+
Expect(err).ShouldNot(HaveOccurred())
114+
nodeOCRKeyId := nodeOCRKeys.Data[0].ID
115+
116+
bta := client.BridgeTypeAttributes{
117+
Name: fmt.Sprintf("node_%d_contract_%d", nodeIndex, OCRInstanceIndex),
118+
URL: fmt.Sprintf("%s/node_%d_contract_%d", i.Mockserver.Config.ClusterURL, nodeIndex, OCRInstanceIndex),
119+
}
120+
121+
err = i.ChainlinkNodes[nodeIndex].CreateBridge(&bta)
122+
Expect(err).ShouldNot(HaveOccurred())
123+
124+
ocrSpec := &client.OCRTaskJobSpec{
125+
ContractAddress: OCRInstance.Address(),
126+
P2PPeerID: nodeP2PId,
127+
P2PBootstrapPeers: []client.Chainlink{bootstrapNode},
128+
KeyBundleID: nodeOCRKeyId,
129+
TransmitterAddress: nodeTransmitterAddress,
130+
ObservationSource: client.ObservationSourceSpecBridge(bta),
131+
}
132+
_, err = i.ChainlinkNodes[nodeIndex].CreateJob(ocrSpec)
133+
Expect(err).ShouldNot(HaveOccurred())
127134
}
128-
_, err = i.ChainlinkNodes[index].CreateJob(ocrSpec)
129-
Expect(err).ShouldNot(HaveOccurred())
130135
}
131136
})
132137
}
@@ -145,9 +150,11 @@ func CheckRound(i *OCRSetupInputs) {
145150
StartNewRound(i, 1)
146151

147152
// Check answer is as expected
148-
answer, err := i.OCRInstance.GetLatestAnswer(context.Background())
149-
Expect(err).ShouldNot(HaveOccurred())
150-
Expect(answer.Int64()).Should(Equal(int64(5)), "Latest answer from OCR is not as expected")
153+
for _, OCRInstance := range i.OCRInstances {
154+
answer, err := OCRInstance.GetLatestAnswer(context.Background())
155+
Expect(err).ShouldNot(HaveOccurred())
156+
Expect(answer.Int64()).Should(Equal(int64(5)), "Latest answer from OCR is not as expected")
157+
}
151158

152159
// Change adapters answer to 10
153160
adapterResults = []int{}
@@ -160,26 +167,29 @@ func CheckRound(i *OCRSetupInputs) {
160167
StartNewRound(i, 2)
161168

162169
// Check answer is as expected
163-
answer, err = i.OCRInstance.GetLatestAnswer(context.Background())
164-
Expect(err).ShouldNot(HaveOccurred())
165-
Expect(answer.Int64()).Should(Equal(int64(10)), "Latest answer from OCR is not as expected")
170+
for _, OCRInstance := range i.OCRInstances {
171+
answer, err := OCRInstance.GetLatestAnswer(context.Background())
172+
Expect(err).ShouldNot(HaveOccurred())
173+
Expect(answer.Int64()).Should(Equal(int64(10)), "Latest answer from OCR is not as expected")
174+
}
166175
})
167176
}
168177

169178
// StartNewRound requests a new round from the ocr contract and waits for confirmation
170179
func StartNewRound(i *OCRSetupInputs, roundNr int64) {
171180
roundTimeout := time.Minute * 2
181+
for _, OCRInstance := range i.OCRInstances {
182+
err := OCRInstance.RequestNewRound(i.DefaultWallet)
183+
Expect(err).ShouldNot(HaveOccurred())
184+
err = i.SuiteSetup.DefaultNetwork().Client.WaitForEvents()
185+
Expect(err).ShouldNot(HaveOccurred())
172186

173-
err := i.OCRInstance.RequestNewRound(i.DefaultWallet)
174-
Expect(err).ShouldNot(HaveOccurred())
175-
err = i.SuiteSetup.DefaultNetwork().Client.WaitForEvents()
176-
Expect(err).ShouldNot(HaveOccurred())
177-
178-
// Wait for the second round
179-
ocrRound := contracts.NewOffchainAggregatorRoundConfirmer(i.OCRInstance, big.NewInt(roundNr), roundTimeout)
180-
i.SuiteSetup.DefaultNetwork().Client.AddHeaderEventSubscription(i.OCRInstance.Address(), ocrRound)
181-
err = i.SuiteSetup.DefaultNetwork().Client.WaitForEvents()
182-
Expect(err).ShouldNot(HaveOccurred())
187+
// Wait for the second round
188+
ocrRound := contracts.NewOffchainAggregatorRoundConfirmer(OCRInstance, big.NewInt(roundNr), roundTimeout)
189+
i.SuiteSetup.DefaultNetwork().Client.AddHeaderEventSubscription(OCRInstance.Address(), ocrRound)
190+
err = i.SuiteSetup.DefaultNetwork().Client.WaitForEvents()
191+
Expect(err).ShouldNot(HaveOccurred())
192+
}
183193
}
184194

185195
// SetAdapterResults sets the mock responses in mockserver that are read by chainlink nodes
@@ -189,40 +199,46 @@ func SetAdapterResults(i *OCRSetupInputs, results []int) {
189199

190200
log.Info().Interface("New Adapter results", results).Msg("Setting new values")
191201

192-
for index := 1; index < len(i.ChainlinkNodes); index++ {
193-
pathSelector := client.PathSelector{Path: fmt.Sprintf("/node_%d", index)}
194-
err := i.Mockserver.ClearExpectation(pathSelector)
195-
Expect(err).ShouldNot(HaveOccurred())
196-
}
202+
for OCRInstanceIndex := range i.OCRInstances {
203+
for nodeIndex := 1; nodeIndex < len(i.ChainlinkNodes); nodeIndex++ {
204+
pathSelector := client.PathSelector{Path: fmt.Sprintf("/node_%d_contract_%d", nodeIndex, OCRInstanceIndex)}
205+
err := i.Mockserver.ClearExpectation(pathSelector)
206+
Expect(err).ShouldNot(HaveOccurred())
207+
}
197208

209+
}
198210
var initializers []client.HttpInitializer
199-
for index := 1; index < len(i.ChainlinkNodes); index++ {
200-
adResp := client.AdapterResponse{
201-
Id: "",
202-
Data: client.AdapterResult{Result: results[index-1]},
203-
Error: nil,
204-
}
205-
nodesInitializer := client.HttpInitializer{
206-
Request: client.HttpRequest{Path: fmt.Sprintf("/node_%d", index)},
207-
Response: client.HttpResponse{Body: adResp},
211+
212+
for OCRInstanceIndex := range i.OCRInstances {
213+
for nodeIndex := 1; nodeIndex < len(i.ChainlinkNodes); nodeIndex++ {
214+
adResp := client.AdapterResponse{
215+
Id: "",
216+
Data: client.AdapterResult{Result: results[nodeIndex-1]},
217+
Error: nil,
218+
}
219+
nodesInitializer := client.HttpInitializer{
220+
Request: client.HttpRequest{Path: fmt.Sprintf("/node_%d_contract_%d", nodeIndex, OCRInstanceIndex)},
221+
Response: client.HttpResponse{Body: adResp},
222+
}
223+
initializers = append(initializers, nodesInitializer)
208224
}
209-
initializers = append(initializers, nodesInitializer)
210225
}
211226

212227
err := i.Mockserver.PutExpectations(initializers)
213228
Expect(err).ShouldNot(HaveOccurred())
214229
}
215230

216231
// NewOCRSetupInputForObservability deploys and setups env and clients for testing observability
217-
func NewOCRSetupInputForObservability(i *OCRSetupInputs, nodeCount int, rules map[string]*os.File) {
232+
func NewOCRSetupInputForObservability(i *OCRSetupInputs, nodeCount int, contractCount int, rules map[string]*os.File) {
218233
DeployOCRForEnv(
219234
i,
220235
environment.NewChainlinkClusterForObservabilityTesting(nodeCount),
221236
)
222-
SetupOCRTest(i)
237+
FundNodes(i)
238+
DeployOCRContracts(i, contractCount)
223239

224240
err := i.Mockserver.PutExpectations(steps.GetMockserverInitializerDataForOTPE(
225-
i.OCRInstance.Address(),
241+
i.OCRInstances,
226242
i.ChainlinkNodes,
227243
))
228244
Expect(err).ShouldNot(HaveOccurred())

0 commit comments

Comments
 (0)